From: unknown Date: Wed, 9 Nov 2011 17:00:39 +0000 (+0100) Subject: initial commit X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=5909fea6b8ad5b95d9af7cad6824f11d944bdfd6;p=emacs-init.git initial commit --- 5909fea6b8ad5b95d9af7cad6824f11d944bdfd6 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a5a290b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +autosave/ +backups/ +auto-save-list/ +eshell/ +*.elc diff --git a/auto-install.el b/auto-install.el new file mode 100644 index 0000000..81ed16b --- /dev/null +++ b/auto-install.el @@ -0,0 +1,1501 @@ +;;; auto-install.el --- Auto install elisp file +;; $Id: auto-install.el,v 1.53 2011/04/12 06:28:20 rubikitch Exp $ + +;; Filename: auto-install.el +;; Description: Auto install elisp file +;; Author: Andy Stewart +;; rubikitch +;; Maintainer: rubikitch +;; Copyright (C) 2008, 2009, Andy Stewart, all rights reserved. +;; Copyright (C) 2009, rubikitch, all rights reserved. +;; Created: 2008-12-11 13:56:50 +;; Version: $Revision: 1.53 $ +;; URL: http://www.emacswiki.org/emacs/download/auto-install.el +;; Keywords: auto-install +;; Compatibility: GNU Emacs 22 ~ 23 +;; +;; Features that might be required by this library: +;; +;; `backquote', `bytecomp', `dired', `find-func', `ietf-drums', +;; `loadhist', `mail-parse', `mail-prsvr', `mailcap', `mm-util', +;; `qp', `rfc2045', `rfc2047', `rfc2231', `thingatpt', `time-date', +;; `timezone', `url', `url-cookie', `url-expand', `url-history', +;; `url-methods', `url-parse', `url-privacy', `url-proxy', +;; `url-util', `url-vars'. +;; + +(defvar auto-install-version "$Id: auto-install.el,v 1.53 2011/04/12 06:28:20 rubikitch Exp $") +;;; This file is NOT part of GNU Emacs + +;;; License +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. + +;;; Commentary: +;; +;; Automates the installation of Emacs Lisp files and packages. +;; +;; `auto-install' provides an automated way to: +;; +;; (1) Download Emacs Lisp files and packages from common sources +;; (2) View them (diff) and save them to your repository +;; (3) Compile and Load them +;; + +;;; Commands: +;; +;; Below are complete command list: +;; +;; `auto-install-minor-mode' +;; Auto Install minor mode. +;; `auto-install-from-buffer' +;; Install the elisp file in the current buffer. +;; `auto-install-from-url' +;; Install an elisp file from a given url. +;; `auto-install-from-emacswiki' +;; Install an elisp file from EmacsWiki.org. +;; `auto-install-from-gist' +;; Install an elisp file from gist.github.com. +;; `auto-install-from-library' +;; Update an elisp LIBRARY. +;; `auto-install-from-directory' +;; Update elisp files under DIRECTORY from EmacsWiki. +;; `auto-install-from-dired' +;; Update dired marked elisp files from EmacsWiki.org. +;; `auto-install-update-emacswiki-package-name' +;; Update the list of elisp package names from `EmacsWiki'. +;; `auto-install-dired-mark-files' +;; Mark dired files that contain at `EmacsWiki.org'. +;; `auto-install-mode' +;; Major mode for auto-installing elisp code. +;; `auto-install-buffer-quit' +;; Quit from `auto-install' temporary buffer. +;; `auto-install-compatibility-setup' +;; Install Compatibility commands for install-elisp.el users. +;; `auto-install-batch' +;; Batch install many files (libraries and non-elisp files) in some extension. +;; `auto-install-batch-edit' +;; Edit auto-install-batch-list.el +;; `auto-install-buffer-diff' +;; View different between old version. +;; `auto-install-buffer-save' +;; Save downloaded content to file FILENAME. +;; +;;; Customizable Options: +;; +;; Below are customizable option list: +;; +;; `auto-install-directory' +;; The directory for saving elisp files. +;; default = "~/.emacs.d/auto-install/" +;; `auto-install-buffer-name' +;; The temporary buffer for storing download content. +;; default = "auto-install" +;; `auto-install-emacswiki-base-url' +;; The base emacswiki.org url from which to download elisp files. +;; default = "http://www.emacswiki.org/cgi-bin/wiki/download/" +;; `auto-install-gist-base-url' +;; The base gist.github.com url from which to download elisp files. +;; default = "http://gist.github.com/" +;; `auto-install-filter-url' +;; Alist mapping filter url for library. +;; default = (quote (("color-grep" "http://www.bookshelf.jp/elc/"))) +;; `auto-install-save-confirm' +;; Whether confirmation is needed to save downloaded content. +;; default = t +;; `auto-install-replace-confirm' +;; Whether confirmation is needed to replace an existing elisp file. +;; default = nil +;; `auto-install-install-confirm' +;; Whether confirmation is needed to install a downloaded elisp file. +;; default = nil +;; `auto-install-from-dired-confirm' +;; Whether confirmation is needed to download marked files from Dired. +;; default = t +;; `auto-install-wget-command' +;; *Wget command. Use only if `auto-install-use-wget' is non-nil. +;; default = "wget" +;; `auto-install-use-wget' +;; *Use wget instead of `url-retrieve'. +;; default = t +;; `auto-install-batch-list' +;; This list contain packages information for batch install. +;; default = nil + +;;; Tips: +;; +;; Downloading is asynchronous: you can do your work and download +;; files at the same time. The download process won't hang +;; Emacs. +;; +;; `auto-install-from-url' remembers previous installations. So if +;; your search is the same as the previous search, you don't need +;; to type it in, just hit RETURN. +;; +;; `auto-install-from-emacswiki' will complete then names of +;; packages from those in the Elisp area in `EmacsWiki'. +;; +;; `auto-install-from-library' will prompt you library name in +;; you load-path, then it try to download from EmacsWiki if it +;; can't find match in `auto-install-filter-url'. +;; +;; `auto-install-from-directory' can install elisp file +;; under specify directory. +;; +;; `auto-install-from-dired' can install marked files using dired. +;; You can mark the files you want in dired and then use +;; `auto-install-from-dired' to download those files +;; asynchronously. +;; +;; `auto-install-from-buffer' can save and install the contents of +;; the current buffer as a file. You need a valid elisp file name. +;; The default name is the buffer name. +;; +;; `auto-install-from-emacswiki' and `auto-install-from-library' +;; will try to pick up file around point, you can move +;; cursor to file name, and just hit RET for install. +;; +;; Some extension (such as icicles) have many libraries to need install, +;; and install one by one is painful, you can use command +;; `auto-install-batch' install all icicles libraries. +;; And `auto-install-batch' handle max connect limit with some website +;; (such as EmacsWiki) to avoid download failed. +;; +;; All of the above functions support a filename filter. You can +;; input any url to download an elisp file, if the file name suffix is +;; `.el', it will download and install the file automatically. +;; Otherwise, it won't install it unless you input a valid elisp +;; file name. +;; +;; By default, if a file that you download does not exist on your +;; system the file is downloaded to `auto-install-directory'. If +;; you already have a file with the same name in your load +;; directory, `auto-install' will try to replace that file. +;; +;; You can use command `auto-install-dired-mark-files' to mark files +;; that contain at `EmacsWiki.org' for fast update. +;; +;; By default, command `auto-install-from-emacswiki' will initialization +;; current symbol as default value, if default value is you want, +;; just hit RET, so lazy! +;; + +;;; Installation: +;; +;; (1) Put auto-install.el somewhere in your load-path. +;; +;; For example, put it into ~/elisp/. +;; Then add the following to your ~/.emacs: +;; +;; (add-to-list 'load-path (expand-file-name "~/elisp")) +;; +;; (2) And put the following in your ~/.emacs startup file: +;; +;; (require 'auto-install) +;; +;; (3) Add this to your ~/.emacs to optionally specify a download directory: +;; +;; (setq auto-install-directory "~/.emacs.d/auto-install/") +;; +;; If you don't set this, "~/.emacs.d/auto-install/" will be used as the default, +;; and will be created as needed. +;; +;; (4) Optionally, if your computer is always connected Internet when Emacs start up, +;; I recommend you add below to your ~/.emacs, to update package name when start up: +;; +;; (auto-install-update-emacswiki-package-name t) +;; +;; And above setup is not necessary, because AutoInstall will automatically update +;; package name when you just first call `auto-install-from-emacswiki', +;; above setup just avoid *delay* when you first call `auto-install-from-emacswiki'. +;; +;; (5) I recommend you add below to your ~/.emacs for install-elisp users: +;; +;; (auto-install-compatibility-setup) +;; +;; This command `defalias'es `install-elisp', +;; `install-elisp-from-emacswiki' and `install-elisp-from-gist' to +;; `auto-install' ones. +;; +;; (6) If you want to use proxy server, set `url-proxy-services'. For example: +;; +;; (setq url-proxy-services '(("http" . "localhost:8339"))) + +;;; Customize: +;; +;; `auto-install-directory' +;; The default directory for keeping auto-downloaded elisp files. +;; +;; `auto-install-buffer-name' +;; The base buffer name for temporarily storing downloaded download content. +;; +;; `auto-install-emacswiki-base-url' +;; The base url for downloading from EmacsWiki.org. +;; +;; `auto-install-gist-base-url' +;; The base url for downloading from gist.github.com +;; +;; `auto-install-filter-url' +;; Filter url for downloading a special library. +;; +;; `auto-install-save-confirm' +;; Whether to require confirmation when saving downloaded content. +;; +;; `auto-install-replace-confirm' +;; Whether to require confirmation when replacing an already-installed +;; file. +;; +;; `auto-install-install-confirm' +;; Whether to require confirmation when installing a file. +;; +;; `auto-install-from-dired-confirm' +;; Whether to require confirmation when downloading files marked in dired. +;; +;; `auto-install-batch-list' +;; This list contain packages information for batch install. +;; Anyone can add packages information in this list for batch install. +;; +;; And all above option can customize easy through: +;; M-x RET customize-group RET auto-install RET +;; + + +;;; Bug Report: +;; +;; If you have problem, send a bug report via M-x auto-install-send-bug-report. +;; The step is: +;; 0) Setup mail in Emacs, the easiest way is: +;; (setq user-mail-address "your@mail.address") +;; (setq user-full-name "Your Full Name") +;; (setq smtpmail-smtp-server "your.smtp.server.jp") +;; (setq mail-user-agent 'message-user-agent) +;; (setq message-send-mail-function 'message-smtpmail-send-it) +;; 1) Be sure to use the LATEST version of auto-install.el. +;; 2) Enable debugger. M-x toggle-debug-on-error or (setq debug-on-error t) +;; 3) Use Lisp version instead of compiled one: (load "auto-install.el") +;; 4) Do it! +;; 5) If you got an error, please do not close *Backtrace* buffer. +;; 6) M-x auto-install-send-bug-report and M-x insert-buffer *Backtrace* +;; 7) Describe the bug using a precise recipe. +;; 8) Type C-c C-c to send. +;; # If you are a Japanese, please write in Japanese:-) + +;;; Change log: +;; +;; $Log: auto-install.el,v $ +;; Revision 1.53 2011/04/12 06:28:20 rubikitch +;; fix for proxy +;; +;; Revision 1.52 2011/01/29 11:11:47 rubikitch +;; bugfix: auto-install-buffer-save cannot treat auto-install-directory properly if it doesn't end with `/' +;; +;; patched by MaskRay thanks! +;; +;; Revision 1.51 2010/12/10 10:30:58 rubikitch +;; Bugfix when wget is not installed +;; +;; replace auto-install-use-wget with (auto-install-use-wget-p) +;; +;; Revision 1.50 2010/11/29 15:52:57 rubikitch +;; compatibility code for emacs21.1 +;; +;; Revision 1.49 2010/11/10 13:32:37 rubikitch +;; Use `wget -q -O- --no-check-certificate' if wget is available. +;; Change default value: `auto-install-use-wget' = t +;; +;; Revision 1.48 2010/05/20 23:29:10 rubikitch +;; `auto-install-update-emacswiki-package-name': Check whether network is reachable +;; +;; Revision 1.47 2010/05/14 00:09:08 rubikitch +;; Fixed a bug of `auto-install-batch' with argument. +;; +;; Pass extension-name argument to `auto-install-batch-real'. +;; +;; Revision 1.46 2010/05/04 08:46:21 rubikitch +;; Added bug report command +;; +;; Revision 1.45 2010/05/01 01:24:25 rubikitch +;; auto-install-batch: Dependency support +;; +;; Revision 1.44 2010/05/01 00:53:48 rubikitch +;; auto-install-batch-real: refactoring +;; +;; Revision 1.43 2010/04/30 23:41:48 rubikitch +;; Changed default value of `auto-install-use-wget' to nil. +;; +;; Revision 1.42 2010/04/25 02:30:27 rubikitch +;; Avoid `auto-async-byte-compile' +;; +;; Revision 1.41 2010/04/25 01:59:20 rubikitch +;; *** empty log message *** +;; +;; Revision 1.40 2010/04/25 01:58:17 rubikitch +;; Do not save/compile up-to-date files from `auto-install-batch'. +;; +;; Revision 1.39 2010/04/25 01:11:33 rubikitch +;; If downloaded file is not updated, kill download buffer. +;; (auto-install-batch support is not yet) +;; +;; Revision 1.38 2010/04/25 00:10:49 rubikitch +;; code cleanup: remove unneeded `format' +;; +;; Revision 1.37 2010/04/24 23:59:11 rubikitch +;; comment change (no code change) +;; +;; Revision 1.36 2010/04/19 07:10:36 rubikitch +;; Avoid updating time-stamp +;; +;; Revision 1.35 2010/04/07 20:16:10 rubikitch +;; Fixed a typo +;; +;; Revision 1.34 2010/04/05 21:34:07 rubikitch +;; `auto-install-from-gist' can accept gist URL. +;; +;; Revision 1.33 2010/04/05 21:27:30 rubikitch +;; `auto-install-use-wget' is enabled by default when wget command (`auto-install-wget-command') is found. +;; +;; Revision 1.32 2010/04/05 21:24:30 rubikitch +;; * `auto-install-batch' can install non-elisp files because some elisp requires external scripts. +;; * New option: `auto-install-add-exec-path-flag' +;; +;; Revision 1.31 2010/04/01 03:43:17 rubikitch +;; added RCS Id: tag +;; +;; Revision 1.30 2010/04/01 03:42:34 rubikitch +;; document typo +;; +;; Revision 1.29 2010/04/01 03:28:39 rubikitch +;; New command: `auto-install-batch-edit' +;; +;; Revision 1.28 2010/04/01 03:10:38 rubikitch +;; The real value of `auto-install-batch-list' is moved to +;; auto-install-batch-list.el to split program and data. +;; +;; Revision 1.27 2010/03/29 07:36:39 rubikitch +;; Stupid bug fix in auto-install-use-wget +;; +;; Revision 1.26 2010/03/29 02:38:46 rubikitch +;; New option: `auto-install-use-wget', `auto-install-wget-command' +;; +;; Revision 1.25 2010/03/26 00:07:27 rubikitch +;; `url-http-end-of-headers' workaround +;; +;; Revision 1.24 2010/01/05 09:40:04 rubikitch +;; fixed error of auto-complete development version in `auto-install-batch-list' +;; +;; Revision 1.23 2009/12/29 09:31:23 rubikitch +;; add Text Translator to auto-install-batch-list +;; +;; Revision 1.22 2009/12/21 12:51:56 rubikitch +;; Update auto-install-batch anything +;; +;; Revision 1.21 2009/12/21 12:26:54 rubikitch +;; New URL for auto-complete development version +;; +;; Revision 1.20 2009/05/22 20:17:24 rubikitch +;; Merged from dradams' change +;; +;; Revision 1.19 2009/05/22 13:04:56 dadams +;; Split icicles-cmd.el into icicles-cmd[12].el. +;; +;; Revision 1.18 2009/05/20 15:42:54 rubikitch +;; Add php-completion / perl-completion to auto-install-batch-list +;; +;; Revision 1.17 2009/05/20 01:19:15 rubikitch +;; Add document for proxy server +;; +;; Revision 1.16 2009/05/15 20:28:18 rubikitch +;; More readable temporary buffer name. +;; +;; Revision 1.15 2009/05/15 20:12:49 rubikitch +;; Added missing require +;; +;; Revision 1.14 2009/05/15 20:11:44 rubikitch +;; How to save +;; +;; Revision 1.13 2009/05/15 20:09:07 rubikitch +;; Code cleanup +;; +;; Revision 1.12 2009/05/15 19:59:30 rubikitch +;; Fixed a bug of single file installation +;; +;; Revision 1.11 2009/05/15 19:44:32 rubikitch +;; Ordering `auto-install-batch' +;; +;; Revision 1.10 2009/05/15 17:48:09 rubikitch +;; Replace `message' with `error' for error messages. +;; +;; Revision 1.9 2009/05/15 17:40:37 rubikitch +;; refactoring +;; +;; Revision 1.8 2009/05/15 17:19:47 rubikitch +;; refactoring +;; +;; Revision 1.7 2009/05/15 17:17:03 rubikitch +;; Use `view-mode' if `view-read-only'. +;; +;; Revision 1.6 2009/05/15 17:10:22 rubikitch +;; Adjust docstrings of commands to auto-document. +;; Delete `It provides the following commands:' section because of duplication. +;; +;; Revision 1.5 2009/05/15 17:03:13 rubikitch +;; Show downloaded URL in header-line. +;; +;; Revision 1.4 2009/05/15 16:59:32 rubikitch +;; New internal variable: `auto-install-add-load-path-flag' +;; +;; Revision 1.3 2009/05/09 02:41:32 rubikitch +;; Add `auto-install-directory' automatically. +;; +;; Revision 1.2 2009/05/09 02:37:14 rubikitch +;; Changed `auto-install-get-buffer' format (including URL) +;; +;; Revision 1.1 2009/05/09 02:33:09 rubikitch +;; Initial revision +;; +;; 2009/05/01 +;; * Andy Stewart: +;; * Take over by rubikitch. +;; +;; 2009/04/15 +;; * rubikitch: +;; * Encoding detection support. +;; +;; 2009/04/07 +;; * Andy Stewart: +;; * Fix bug of `auto-install-batch'. +;; * Add more sources to `auto-install-batch-list'. +;; +;; 2009/03/30 +;; * Andy Stewart: +;; * Add new command: `auto-install-batch'. +;; * Add new option: `auto-install-batch-list'. +;; +;; 2009/03/29 +;; * Andy Stewart: +;; * Add new function: `auto-install-from-url-list'. +;; +;; 2009/03/11 +;; * Andy Stewart: +;; * Fix bug of `auto-install-download'. +;; +;; 2009/03/03 +;; * rubikitch +;; * Add new command `auto-install-compatibility-setup' +;; for install-elisp users. +;; * Andy Stewart: +;; * `auto-install-region-or-thing' return region string +;; just when `transient-mark-mode' is on. +;; * Fix doc. +;; +;; 2009/02/17 +;; * Andy Stewart: +;; * Modified keybindings, make it more easy to remember. +;; * Make `auto-install-save-confirm' default with `t' +;; for security problem. +;; * Pick up current symbol when use `auto-install-from-library'. +;; * Remove unnecessary completion name from `auto-install-from-library'. +;; * Refactory code. +;; * Fix doc. +;; +;; 2009/02/12 +;; * Andy Stewart: +;; * Remove option `auto-install-update-emacswiki-package-name-when-startup'. +;; * Make current symbol as initialization of `auto-install-from-emacswiki'. +;; * Add option `unforced' to function `auto-install-update-emacswiki-package-name'. +;; * Fix doc. +;; * Fix bug of `auto-install-from-library'. +;; +;; 2009/02/10 +;; * Andy Stewart: +;; * Automatically download package name list when +;; variable `auto-install-package-name-list' is nil. +;; * Reverse `auto-install-package-name-list' for `anything' interface. +;; * New command `auto-install-dired-mark-files', +;; mark files that contain at `EmacsWiki.org'. +;; * New command `auto-install-buffer-diff', +;; view different between current version and old version. +;; +;; 2009/02/06 +;; * Andy Stewart: +;; * Add new command `auto-install-from-directory'. +;; * Remove option `auto-install-create-directory', not necessary. +;; * Documentation improvements (thanks Scot Becker) +;; +;; 2009/02/01 +;; * Andy Stewart: +;; * Make command `auto-install-from-emacswiki' can +;; completing package name for input. +;; * Add new command `auto-install-update-emacswiki-package-name'. +;; * Add new option `auto-install-update-emacswiki-package-name-when-startup' +;; +;; 2009/01/30 +;; * Andy Stewart: +;; * Compatibility with GNU Emacs 22. +;; +;; 2009/01/26 +;; * Andy Stewart: +;; * Add new command `auto-install-from-gist'. +;; +;; 2009/01/21 +;; * Andy Stewart: +;; * Add emacs-lisp syntax highlight for download buffer. +;; * Make notify message display at mode-line instead echo-area. +;; +;; 2009/01/10 +;; * Andy Stewart: +;; * Add new option `auto-install-filter-url' and new function +;; `auto-install-from-library', try to use it. ;) +;; +;; 2009/01/08 +;; * Andy Stewart: +;; * Fix coding bug. +;; +;; 2009/01/07 +;; * Andy Stewart: +;; * Move `w3m' code to file `auto-install-extension.el' to make all +;; user can use this package with standard emacs. +;; +;; 2009/01/06 +;; * Andy Stewart: +;; * Clean code. +;; +;; 2009/01/02 +;; * Andy Stewart: +;; * Add new option `auto-install-create-directory' for create install directory +;; automatically if it doesn't exist. +;; * Improve many document make it more clear. +;; * Thanks document improve and create directory advice of 'Drew Adams'! +;; +;; 2008/12/24 +;; * Andy Stewart: +;; * Remove `auto-install-window-configuration-before-download', `auto-install-init-window-layout' +;; and `auto-install-revert-window-layout'. +;; It's not necessary to revert window layout, `winner-mode' can revert window layout more better, +;; just type `winner-undo'. +;; +;; 2008/12/15 +;; * Andy Stewart: +;; * Fix a little bug of `auto-install-window-configuration-before-download'. +;; +;; 2008/12/11 +;; * Andy Stewart: +;; * Add new function `auto-install-from-buffer', to install elisp file from current buffer. +;; Modified `auto-install-buffer-save' to use `auto-install-from-buffer'. +;; +;; * First released. +;; + +;;; Acknowledgements: +;; +;; rubikitch +;; For install-elisp.el +;; Drew Adams +;; Scot Becker +;; Richard Riley +;; For documentation improvements and advices. +;; + +;;; TODO +;; +;; Fix the problem parallel install process with recursive prompt. +;; Redesign and give more friendly user interface. +;; Scan RSS track package update and notify. +;; + +;;; Require +(require 'url) +(require 'dired) +(require 'find-func) +(require 'bytecomp) +(require 'thingatpt) +(require 'ffap) +(eval-when-compile (require 'cl)) +(when (<= emacs-major-version 22) ;Compatibility with 22. + (autoload 'ignore-errors "cl-macs") + (unless (fboundp 'url-file-nondirectory) + (defun url-file-nondirectory (file) + "Return the nondirectory part of FILE, for a URL." + (cond + ((null file) "") + ((string-match (eval-when-compile (regexp-quote "?")) file) + (file-name-nondirectory (substring file 0 (match-beginning 0)))) + (t (file-name-nondirectory file)))))) + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Customize ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defgroup auto-install nil + "Auto install elisp files." + :group 'external) + +(defcustom auto-install-directory "~/.emacs.d/auto-install/" + "The directory for saving elisp files. +This directory is used when a downloaded +elisp file does not already exist in other directory. +Otherwise, the existing file of the same name is replaced." + :type 'string + :group 'auto-install) + +(defcustom auto-install-buffer-name "auto-install" + "The temporary buffer for storing download content." + :type 'string + :group 'auto-install) + +(defcustom auto-install-emacswiki-base-url "http://www.emacswiki.org/cgi-bin/wiki/download/" + "The base emacswiki.org url from which to download elisp files." + :type 'string + :group 'auto-install) + +(defcustom auto-install-gist-base-url "http://gist.github.com/" + "The base gist.github.com url from which to download elisp files." + :type 'string + :group 'auto-install) + +(defcustom auto-install-filter-url + '(("color-grep" "http://www.bookshelf.jp/elc/")) + "Alist mapping filter url for library. +Default command `auto-install-from-library' will install from EmacsWiki, +if it can't find match in this alist." + :type '(repeat (list (string :tag "Library") + (string :tag "Download URL"))) + :group 'auto-install) + +(defcustom auto-install-save-confirm t + "Whether confirmation is needed to save downloaded content. +Nil means no confirmation is needed. +If non-nil, the downloaded content is shown in a buffer and you are +prompted to confirm saving it to a file." + :type 'boolean + :group 'auto-install) + +(defcustom auto-install-replace-confirm nil + "Whether confirmation is needed to replace an existing elisp file. +Nil means no confirmation is needed." + :type 'boolean + :group 'auto-install) + +(defcustom auto-install-install-confirm nil + "Whether confirmation is needed to install a downloaded elisp file. +Nil means no confirmation is needed." + :type 'boolean + :group 'auto-install) + +(defcustom auto-install-from-dired-confirm t + "Whether confirmation is needed to download marked files from Dired. +Nil means no confirmation is needed." + :type 'boolean + :group 'auto-install) + +(defcustom auto-install-wget-command "wget" + "*Wget command. Use only if `auto-install-use-wget' is non-nil." + :type 'string + :group 'auto-install) + +(defcustom auto-install-use-wget t + "*Use wget instead of `url-retrieve'. + +It is enabled by default when wget is found." + :type 'boolean + :group 'auto-install) + +(defcustom auto-install-batch-list + nil + "This list contain packages information for batch install. + +Have four arguments per list: +First argument is extension name. +Second argument is delay time for batch install. +Third argument is libraries number limit in delay time. +Fourth argument is list of libraries url or extension name. + +If you want to add files, please edit auto-install-batch-list.el in EmacsWiki. +Use M-x `auto-install-batch-edit'. " + :group 'auto-install) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Variable ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defvar auto-install-batch-list-internal nil + "The real value of `auto-install-batch-list'. ") + +(defvar auto-install-batch-list-el-url + "http://www.rubyist.net/~rubikitch/archive/auto-install-batch-list.el" + "The url of auto-install-batch-list.el. +It is downloaded and evaluated just after M-x `auto-install-batch'. ") + +(defvar auto-install-download-buffer nil + "The download buffer used by `url-retrieve'. +This variable is always buffer-local.") +(make-variable-buffer-local 'auto-install-download-buffer) + +(defvar auto-install-download-url nil + "The url from which to download files. +This variable is always buffer-local.") +(make-variable-buffer-local 'auto-install-download-url) + +(defvar auto-install-last-url nil + "The last url used in `auto-install-from-url'.") + +(defvar auto-install-last-gist-id nil + "The last gist id you visit in `auto-install-from-gist'.") + +(defvar auto-install-package-name-list nil + "The package name list for completion input.") + +(defvar auto-install-minor-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-d") 'auto-install-buffer-diff) ;diff + (define-key map (kbd "C-c C-c") 'auto-install-buffer-save) ;save + (define-key map (kbd "C-c C-q") 'auto-install-buffer-quit) ;quit + map) + "Keymap used by variable `auto-install-minor-mode'.") + +(defvar auto-install-add-load-path-flag t + "If non-nil, add `auto-install-directory' to `load-path'. +This variable is intended to be used in test.") + +(defvar auto-install-add-exec-path-flag t + "If non-nil, add `auto-install-directory' to `exec-path'. +This variable is intended to be used in test. + +It is needed because `auto-install-batch' can install non-elisp files.") + +(defvar auto-install-waiting-url-list nil + "URLs in downloading.") +(defvar auto-install-url-queue nil + "Installation order.") +(defvar auto-install-download-buffer-alist nil + "Pairs of URL and downloaded buffer.") +(defvar auto-install-batch-using nil) + +(define-minor-mode auto-install-minor-mode + "Auto Install minor mode." + :init-value nil + :lighter " Auto-Install" + :keymap auto-install-minor-mode-map + :group 'auto-install) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Interactive Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun auto-install-from-buffer () + "Install the elisp file in the current buffer." + (interactive) + (let (filename) + (setq filename (read-string (format "Filename (%s): " (buffer-name)) nil nil (buffer-name))) + (auto-install-mode) + (auto-install-buffer-save filename))) + +(defun auto-install-from-url (&optional url) + "Install an elisp file from a given url." + (interactive) + (or url (setq url (read-string (format "URL (%s): " (or auto-install-last-url "")) nil nil auto-install-last-url))) + (setq auto-install-last-url url) + (auto-install-download url)) + +(defun auto-install-from-emacswiki (&optional file) + "Install an elisp file from EmacsWiki.org." + (interactive) + (cond (auto-install-package-name-list + ;; Install package if `auto-install-package-name-list' is non-nil. + (or file (setq file (auto-install-get-candidate "Package" auto-install-package-name-list))) + (auto-install-download (concat auto-install-emacswiki-base-url file))) + (t + ;; Otherwise update package name and install. + (auto-install-download "http://www.emacswiki.org/cgi-bin/emacs?action=index;raw=1" + 'auto-install-handle-emacswiki-package-install)))) + +(defun auto-install-from-gist (&optional gistid-or-url) + "Install an elisp file from gist.github.com. + +Optional argument GISTID-OR-URL is gist ID or URL for download +elisp file from gist.github.com." + (interactive) + (or gistid-or-url + (setq gistid-or-url (read-string (format "Gist ID or URL (%s): " (or auto-install-last-gist-id "")) + nil nil + auto-install-last-gist-id))) + (let ((gistid (file-name-sans-extension (file-name-nondirectory gistid-or-url)))) + (setq auto-install-last-gist-id gistid) + (auto-install-download (format "%s%s.txt" auto-install-gist-base-url gistid)))) + +(defun auto-install-from-library (&optional library) + "Update an elisp LIBRARY. +Default this function will found 'download url' from `auto-install-filter-url', +if not found, try to download from EmacsWiki." + (interactive + (let* ((dirs load-path) + (suffixes (find-library-suffixes))) + (list (auto-install-get-candidate "Library name" (auto-install-get-library-list))))) + (let ((filename (file-name-nondirectory (find-library-name library))) + (base-url auto-install-emacswiki-base-url) + (library-name (replace-regexp-in-string "\\(\\.el.*$\\)" "" library))) + (if (assoc library-name auto-install-filter-url) + (setq base-url (cadr (assoc library-name auto-install-filter-url)))) + (auto-install-download (concat base-url filename)))) + +(defun auto-install-from-directory (directory) + "Update elisp files under DIRECTORY from EmacsWiki. +You can use this command to update elisp file under DIRECTORY." + (interactive "DDirectory: ") + (let (filename) + (dolist (file (directory-files directory t)) + (if (file-directory-p file) + ;; Don't match . or .. directory. + (unless (string-match "^\\.\\.?$" (file-name-nondirectory file)) + ;; Find files in sub-directory. + (auto-install-from-directory file)) + ;; Get file name. + (setq filename (file-name-nondirectory file)) + ;; Not backup file. + (unless (string-match "^\\.?#" filename) + ;; Match elisp file. + (if (string-match "^.*\\.el" filename) + (auto-install-download (concat auto-install-emacswiki-base-url filename)))))))) + +(defun auto-install-from-dired () + "Update dired marked elisp files from EmacsWiki.org. +You can use this to download marked files in Dired asynchronously." + (interactive) + (if (eq major-mode 'dired-mode) + (if (or (not auto-install-from-dired-confirm) + (yes-or-no-p "Do you want install marked files from EmacsWiki.org?")) + (dolist (file (dired-get-marked-files)) + (auto-install-download (concat auto-install-emacswiki-base-url (file-name-nondirectory file))))) + (error "This command is only for `dired-mode'."))) + +(defun auto-install-network-available-p (host) + (if auto-install-use-wget + (eq (call-process auto-install-wget-command nil nil nil "-q" "--spider" host) 0) + (with-current-buffer (url-retrieve-synchronously (concat "http://" host)) + (prog1 (not (zerop (buffer-size))) + (kill-buffer (current-buffer)))))) +;; (auto-install-network-available-p "www.emacswiki.org") + +(defun auto-install-update-emacswiki-package-name (&optional unforced) + "Update the list of elisp package names from `EmacsWiki'. +By default, this function will update package name forcibly. +If UNFORCED is non-nil, just update package name when `auto-install-package-name-list' is nil." + (interactive) + (unless (and unforced + auto-install-package-name-list) + (if (auto-install-network-available-p "www.emacswiki.org") + (auto-install-download "http://www.emacswiki.org/cgi-bin/emacs?action=index;raw=1" + 'auto-install-handle-emacswiki-package-name) + (message + (concat "Network unreachable!\n" + "Try M-x auto-install-handle-emacswiki-package-name afterward.")) + (sit-for 2)))) + +(defun auto-install-dired-mark-files () + "Mark dired files that contain at `EmacsWiki.org'." + (interactive) + (if (eq major-mode 'dired-mode) + (if auto-install-package-name-list + ;; Mark files that exist at `EmacsWiki'. + (auto-install-dired-mark-files-internal) + ;; Or get package name list and match files. + (auto-install-download "http://www.emacswiki.org/cgi-bin/emacs?action=index;raw=1" + 'auto-install-handle-dired-mark-files)) + (error "This command just use in `dired-mode'."))) + +(defun auto-install-mode () + "Major mode for auto-installing elisp code." + (interactive) + ;; Load emacs-lisp syntax highlight. + (set-syntax-table emacs-lisp-mode-syntax-table) + (lisp-mode-variables) + (setq font-lock-mode t) + (font-lock-fontify-buffer) + ;; Read only. + (setq buffer-read-only t) + (and view-read-only (view-mode 1)) + ;; Load `auto-install' mode. + (auto-install-minor-mode t) + (setq major-mode 'auto-install-minor-mode)) + +(defun auto-install-buffer-quit () + "Quit from `auto-install' temporary buffer." + (interactive) + ;; Quit buffer. + (if (eq major-mode 'auto-install-minor-mode) + (auto-install-quit) + (error "This command just use in `auto-install-minor-mode'."))) + +(defun auto-install-compatibility-setup () + "Install Compatibility commands for install-elisp.el users." + (interactive) + (defalias 'install-elisp 'auto-install-from-url) + (if (require 'anything-auto-install nil t) + (defalias 'install-elisp-from-emacswiki 'anything-auto-install-from-emacswiki) + (defalias 'install-elisp-from-emacswiki 'auto-install-from-emacswiki)) + (defalias 'install-elisp-from-gist 'auto-install-from-gist) + (message "Install-elisp compatibility installed. +install-elisp = %s +install-elisp-from-emacswiki = %s +install-elisp-from-gist = %s" + (symbol-function 'install-elisp) + (symbol-function 'install-elisp-from-emacswiki) + (symbol-function 'install-elisp-from-gist))) + +(defun auto-install-batch (&optional extension-name) + "Batch install many files (libraries and non-elisp files) in some extension. +EXTENSION-NAME is extension name for batch install. + +Note that non-elisp can be installed only via `auto-install-batch'" + (interactive) + (if (and auto-install-batch-list-internal extension-name) + (auto-install-batch-real extension-name) + (auto-install-download + auto-install-batch-list-el-url + (lexical-let ((extension-name extension-name)) + (lambda (buf) + (with-current-buffer buf + (eval-buffer) + (run-at-time 0 nil 'auto-install-batch-real extension-name))))))) + +(defun auto-install-batch-edit () + "Edit auto-install-batch-list.el" + (interactive) + (cond ((fboundp 'yaoddmuse-edit) + (yaoddmuse-edit "EmacsWiki" "auto-install-batch-list.el")) + ((fboundp 'oddmuse-edit) + (oddmuse-edit "EmacsWiki" "auto-install-batch-list.el")) + (t + (browse-url "http://www.emacswiki.org/emacs/?action=edit;id=auto-install-batch-list.el")))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Utilities Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun auto-install-batch-real (&optional extension-name) + (setq auto-install-batch-using t) + (when auto-install-add-exec-path-flag + (add-to-list 'exec-path auto-install-directory)) + (destructuring-bind (name delay-time limit-number (&rest urls)) + (auto-install-batch-get-info + (or + ;; Get information list from give extension name. + extension-name + ;; Otherwise completion from user select. + (completing-read "Extension name: " (mapcar 'car auto-install-batch-list-internal))) + auto-install-batch-list-internal) + (or name (error "Haven't install information for `%s'." extension-name)) + (setq auto-install-waiting-url-list urls + auto-install-url-queue urls) + (if (not (and + ;; Delay time is above 0. + delay-time + (> delay-time 0) + ;; Limit number is above 0. + limit-number + (> limit-number 0))) + (auto-install-from-url-list urls) + (let ((delay-counter 0) + install-list) + (while urls + (if (> (length urls) limit-number) + ;; Install apart libraries list under `limit-number' + (progn + (setq install-list (nthcar limit-number urls)) + (run-with-timer + (* delay-counter delay-time) + nil + 'auto-install-from-url-list install-list) + (setq urls (nthcdr+ limit-number urls)) + (incf delay-counter)) + ;; Install remain libraries list. + (setq install-list urls) + (run-with-timer + (* delay-counter delay-time) + nil + 'auto-install-from-url-list install-list) + (setq urls nil))))))) + +;;; borrowed from eev.el +(defun auto-install-flatten (obj &rest rest) + (cond (rest (append (auto-install-flatten obj) (auto-install-flatten rest))) + ((null obj) nil) + ((listp obj) (append (auto-install-flatten (car obj)) (auto-install-flatten (cdr obj)))) + (t (list obj)))) + +(defun auto-install-batch-get-info (extension batch-list) + (let* ((it (assoc extension batch-list)) + (urls (car (last it))) + (urlp (lambda (url) (string-match "^https?://" url)))) + (cond ((not it) + '(nil nil nil (nil))) + ((loop for url in urls always (funcall urlp url)) + it) + (t + (append + (butlast it) + (list (auto-install-flatten + (loop for url in urls collect + (if (funcall urlp url) + url + (car (last (auto-install-batch-get-info url batch-list)))))))))))) + +;;;; unit test +;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el") +;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-mock.el") +(dont-compile + (when (fboundp 'expectations) + (expectations + (desc "auto-install-flatten") + (expect '(1 2 3 4 5 6 7 8 9) + (auto-install-flatten '((1 2 3) (4 5) (((6)) 7) nil nil 8 9))) + (expect '(1 2 3 4 5 6 7 8 9) + (auto-install-flatten '(1 2 3) '(4 5) '(((6)) 7) nil nil 8 9)) + (desc "auto-install-batch-get-info") + (expect '(nil nil nil (nil)) + (auto-install-batch-get-info + "not-found" + '(("foo" nil nil ("https://example.com/1.el"))))) + (expect '("foo" nil nil ("http://example.com/1.el")) + (auto-install-batch-get-info + "foo" + '(("foo" nil nil ("http://example.com/1.el"))))) + (expect '("withdep" nil nil ("http://example.com/1.el" + "http://example.com/2.el")) + (auto-install-batch-get-info + "withdep" + '(("foo" nil nil ("http://example.com/1.el")) + ("withdep" nil nil ("foo" "http://example.com/2.el"))))) + (expect '("withdep-recursive" nil nil ("http://example.com/1.el" + "http://example.com/2.el" + "http://example.com/3.el")) + (auto-install-batch-get-info + "withdep-recursive" + '(("foo" nil nil ("http://example.com/1.el")) + ("withdep" nil nil ("foo" "http://example.com/2.el")) + ("withdep-recursive" nil nil ("withdep" "http://example.com/3.el"))))) + ))) + + +(defun auto-install-use-wget-p () + (and auto-install-use-wget + (executable-find auto-install-wget-command))) +(defun auto-install-download (url &optional handle-function) + "Download elisp file from URL. +HANDLE-FUNCTION for handle download content, +default is `auto-install-handle-download-content'." + ;; Check and create install directory. + (unless (file-exists-p auto-install-directory) + (make-directory auto-install-directory) + (when auto-install-add-load-path-flag + (add-to-list 'load-path auto-install-directory)) + (message "Create directory %s for install elisp file." auto-install-directory)) + ;; Download. + (funcall + (if (auto-install-use-wget-p) + 'auto-install-download-by-wget + 'auto-install-download-by-url-retrieve) + url handle-function (auto-install-get-buffer url))) + +(defun auto-install-download-by-wget (url handle-function download-buffer) + (with-current-buffer download-buffer + (setq auto-install-download-buffer (get-buffer-create (concat (buffer-name download-buffer) + "-wget"))) + (setq auto-install-download-url url) + (set-process-sentinel + (start-process "auto-install-wget" (current-buffer) + auto-install-wget-command "-q" "-O-" "--no-check-certificate" url) + (lexical-let ((handle-function handle-function)) + (lambda (proc stat) + (auto-install-download-callback-continue (buffer-name (process-buffer proc)) + handle-function)))))) + +(defun auto-install-download-by-url-retrieve (url handle-function download-buffer) + (let* ((url-request-method "GET") + (url-request-extra-headers nil) + (url-mime-accept-string "*/*") + (parsed-url (url-generic-parse-url url)) + (download-buffer-name (buffer-name download-buffer))) + (with-current-buffer download-buffer + ;; Bind download url with local buffer. + (setq auto-install-download-url url) + ;; Bind download buffer with local buffer. + ;; + ;; Use buffer-local variable receive + ;; data from `url-retrieve' to make asynchronously + ;; download file with special buffer. + ;; + ;; Because the buffer name is unique that generate + ;; through `current-time', so can download many elisp file + ;; asynchronously and won't conflict each other. + (setq auto-install-download-buffer + (url-retrieve parsed-url + 'auto-install-download-callback + (list download-buffer-name handle-function)))))) + +(defun auto-install-download-callback (&optional redirect download-buffer-name handle-function) + "The callback for `auto-install-download'. +With `auto-install-download', this downloads elisp files asynchronously. +REDIRECT is the argument for check download status. +DOWNLOAD-BUFFER-NAME is the name of download buffer. +HANDLE-FUNCTION is function for handle download content." + (if (eq (car redirect) ':error) + ;; Notify user and kill buffer when occur error. + (with-current-buffer (get-buffer download-buffer-name) + (message "Download from '%s' failed." auto-install-download-url) + (kill-buffer download-buffer-name)) + ;; Otherwise continue install process. + (auto-install-download-callback-continue download-buffer-name handle-function))) + +(defun auto-install-download-callback-continue (download-buffer-name handle-function) + (auto-install-retrieve-decode download-buffer-name) ;decode retrieve information. + (with-current-buffer (get-buffer download-buffer-name) + ;; Show successful message + (message "Download from '%s' successful." auto-install-download-url) + ;; Handle download content. + (funcall (or handle-function 'auto-install-handle-download-content) + (current-buffer)))) + +(defun auto-install-retrieve-decode (retrieve-buffer-name) + "Decode the RETRIEVE-BUFFER-NAME with coding detection." + (declare (special url-http-end-of-headers)) + (with-current-buffer (get-buffer retrieve-buffer-name) + (insert + (with-current-buffer auto-install-download-buffer + (set-buffer-multibyte t) + ;; I do not know why the case url-http-end-of-headers is nil exists!! + ;; I HATE url-retrieve. + (if (and (boundp 'url-http-end-of-headers) + (numberp url-http-end-of-headers)) + (goto-char (1+ url-http-end-of-headers)) + ;; workaround + (if (auto-install-use-wget-p) + (goto-char (point-min)) + (search-forward "\n\n" nil t))) + (decode-coding-region + (point) (point-max) + (coding-system-change-eol-conversion + ;; rubikitch: encoding detection is better because of + ;; non-utf8 Japanese encodings. + (detect-coding-region (point-min) (point-max) t) 'dos)) + (buffer-substring (point) (point-max)))) + (goto-char (point-min)))) + +(defun auto-install-handle-download-content (download-buffer) + "Handle the content downloaded to buffer DOWNLOAD-BUFFER." + (with-current-buffer download-buffer + ;; Load mode. + (auto-install-mode) + ;; Display help information in mode-line. + (setq mode-line-format (list "Type C-c C-c to continue; Type C-c C-d for view diff; Type C-c C-q to quit.")) + + (setq header-line-format (list auto-install-download-url)) + (setq auto-install-download-buffer-alist + (cons (cons auto-install-download-url download-buffer) + auto-install-download-buffer-alist)) + (setq auto-install-waiting-url-list + (remove auto-install-download-url auto-install-waiting-url-list)) + ;; When all files are downloaded + (unless auto-install-waiting-url-list + ;; Select first file + (switch-to-buffer (or (assoc-default (car auto-install-url-queue) + auto-install-download-buffer-alist) + ;; if single file + download-buffer)) + (if (not (and (not auto-install-batch-using) (auto-install-check-update))) + (unless auto-install-save-confirm + (auto-install-buffer-save)) + (message "%s is up-to-date" (url-file-nondirectory auto-install-download-url)) + (kill-buffer)) + ;; (unless auto-install-save-confirm + ;; (auto-install-buffer-save)) + ))) + +(defun auto-install-check-update () + (let* ((new-file (url-file-nondirectory auto-install-download-url)) + (old-file (auto-install-get-path new-file)) + (old-content (and old-file + (with-temp-buffer + (insert-file-contents-literally old-file) + (buffer-string))))) + (equal old-content (buffer-string)))) + +(defun auto-install-handle-emacswiki-package-name (download-buffer &optional prompt-install) + "Handle elisp package name from `EmacsWiki'. +DOWNLOAD-BUFFER is the name of download buffer. +PROMPT-INSTALL is non-nil, will prompt package name for install." + ;; Update package name list. + (auto-install-update-emacswiki-package-list download-buffer) + ;; Prompt package name for install. + (when prompt-install + (auto-install-download + (concat auto-install-emacswiki-base-url + (auto-install-get-candidate "Package" auto-install-package-name-list))))) + +(defun auto-install-handle-dired-mark-files (download-buffer) + "Handle dired mark files that exist at `EmacsWiki'. +DOWNLOAD-BUFFER is the name of download buffer." + ;; Update package name list. + (auto-install-update-emacswiki-package-list download-buffer) + ;; Mark dired files. + (auto-install-dired-mark-files-internal)) + +(defun auto-install-handle-emacswiki-package-install (download-buffer) + "Handle elisp package install from `EmacsWiki'. +DOWNLOAD-BUFFER is the name of download buffer." + (auto-install-handle-emacswiki-package-name download-buffer t)) + +(defun auto-install-update-emacswiki-package-list (download-buffer) + "Filter and update package name list from `EmacsWiki'. +DOWNLOAD-BUFFER is the name of download buffer." + (goto-char (point-min)) + (setq auto-install-package-name-list + (loop while (re-search-forward "^.*\\.el$" nil t) + collect (match-string 0))) + ;; Kill buffer. + (kill-buffer download-buffer) + ;; Display successful message. + (message "Update package name from `EmacsWiki' successful.")) + +(defun auto-install-buffer-diff () + "View different between old version. +This command just run when have exist old version." + (interactive) + (let* ((new-file (url-file-nondirectory auto-install-download-url)) + (old-file (auto-install-get-path new-file))) + (if old-file + ;; View different when have old version exist. + (ediff-buffers (current-buffer) (find-file-noselect old-file)) + ;; Otherwise notify user. + (message "Haven't old version exist.")))) + +(defun auto-install-buffer-save (&optional filename) + "Save downloaded content to file FILENAME." + (interactive) + (if (eq major-mode 'auto-install-minor-mode) + (let (file-path) + ;; Get filename + (unless filename + (setq filename (url-file-nondirectory auto-install-download-url))) + (unless auto-install-batch-using + ;; Make sure file suffix with `.el'. + (while (not (string-match ".*\.el$" filename)) + (setq filename (read-string "Please input file name suffix with `.el': ")))) + ;; Get file path. + (setq file-path + (or + ;; Replace file if have exist. + (auto-install-get-path filename) + ;; Otherwise, install in directory `auto-install-directory'. + (expand-file-name filename auto-install-directory))) + ;; Save file. + (if (and (file-exists-p file-path) + (file-writable-p file-path) + auto-install-replace-confirm + (not (yes-or-no-p (format "Do you want replace file: '%s' ?" file-path)))) + (auto-install-quit) + (if (auto-install-check-update) + (auto-install-install-next-file) + (let ((before-save-hook before-save-hook) + (auto-async-byte-compile-exclude-files-regexp + (regexp-quote file-path))) + (remove-hook 'before-save-hook 'time-stamp) + (write-file file-path) + (auto-install-install file-path))))) + (error "This command just use in `auto-install-minor-mode'."))) + +(defun auto-install-install (file-path) + "Install elisp file FILE-PATH." + (if (and auto-install-install-confirm + (not (yes-or-no-p (format "Do you want install file: '%s' ?" file-path)))) + (auto-install-quit) + (let (byte-compile-warnings) ;; suppress compile warnings + ;; Compile and load file. + (when (and (string= "el" (file-name-extension file-path)) + (not (ignore-errors (byte-compile-file file-path t)))) + ;; Show `ERROR' message if compile failed. + (message "Auto-Install ERROR: Compiled file '%s' failed." file-path)) + (auto-install-install-next-file)))) + +(defun auto-install-install-next-file () + (setq auto-install-url-queue (cdr auto-install-url-queue)) + (let (byte-compile-warnings) + (cond ((car auto-install-url-queue) + (switch-to-buffer (assoc-default (car auto-install-url-queue) + auto-install-download-buffer-alist)) + (unless auto-install-save-confirm + (auto-install-buffer-save))) + (t ;completed + (auto-install-cleanup) + (message "Installation is completed."))))) + +(defun auto-install-cleanup () + (while auto-install-minor-mode + (kill-buffer)) + (setq auto-install-url-queue nil) + (setq auto-install-download-buffer-alist nil) + (setq auto-install-batch-using nil)) + +(defun auto-install-quit () + "Quit auto-install." + ;; Kill buffer + (kill-buffer (current-buffer)) + ;; Show quit message. + (message "Quit auto-install process.")) + +(defun auto-install-get-path (library) + "Return the absolute file path of the Lisp source of LIBRARY." + ;; If the library is byte-compiled, try to find a source library by + ;; the same name. + (if (string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library) + (setq library (replace-match "" t t library))) + (or + (locate-file library + (or find-function-source-path load-path) + (find-library-suffixes)) + (locate-file library + (or find-function-source-path load-path) + load-file-rep-suffixes))) + +(defun auto-install-get-buffer (url) + "Get a buffer for temporary storage of downloaded content. +Uses `current-time' to make buffer name unique." + (get-buffer-create (format "*%s %s <%s>*" + auto-install-buffer-name url + (format-time-string "%m/%d %H:%M:%S")))) + +(defun auto-install-dired-mark-files-internal () + "Mark files that match `auto-install-package-name-list'." + ;; Set buffer visible in select window. + (set-buffer (window-buffer)) + ;; Get mark files. + (save-excursion + (let (filename) + ;; Unmark all markes. + (dired-unmark-all-marks) + ;; Try to mark files. + (goto-char (point-min)) + (while (not (eobp)) + (setq filename (dired-get-filename nil t)) + (if (and filename + (not (file-directory-p filename)) + (member (file-name-nondirectory filename) auto-install-package-name-list)) + (dired-mark 1)) + (dired-next-line 1))))) + +(defun auto-install-region-or-thing (&optional thing) + "Return region or thing around point. +If `mark-active' and variable `transient-mark-mode', return region. +If THING is non-nil, return THING around point; +otherwise return symbol around point." + ;; Return string. + (if (and mark-active + transient-mark-mode) + ;; Return region string just when + ;; `mark-active' and `transient-mark-mode' is on. + (buffer-substring-no-properties (region-beginning) + (region-end)) + ;; Otherwise try to pick-up THING around point. + (setq thing (or thing 'symbol)) + (ignore-errors + (save-excursion + (buffer-substring-no-properties (beginning-of-thing thing) + (end-of-thing thing)))))) + +(defun auto-install-get-library-list (&optional dirs string) + "Do completion for file names passed to `locate-file'. +DIRS is directory to search path. +STRING is string to match." + ;; Use `load-path' as path when ignore `dirs'. + (or dirs (setq dirs load-path)) + ;; Init with blank when ignore `string'. + (or string (setq string "")) + ;; Get library list. + (let ((string-dir (file-name-directory string)) + name + names) + (dolist (dir dirs) + (unless dir + (setq dir default-directory)) + (if string-dir + (setq dir (expand-file-name string-dir dir))) + (when (file-directory-p dir) + (dolist (file (file-name-all-completions + (file-name-nondirectory string) dir)) + ;; Suffixes match `load-file-rep-suffixes'. + (setq name (if string-dir (concat string-dir file) file)) + (if (string-match (format "^.*\\.el%s$" (regexp-opt load-file-rep-suffixes)) name) + (add-to-list 'names name))))) + names)) + +(defun auto-install-get-candidate (prompt collection) + "Get candidate from completing list. +PROMPT is string for prompt. +COLLECTION is list for completing candidates." + (completing-read (format "%s (%s): " prompt (or (auto-install-region-or-thing) "")) + collection + nil nil nil nil + (auto-install-region-or-thing))) + +(defun auto-install-from-url-list (&optional url-list) + "Batch install many packages form URL-LIST." + (if (listp url-list) + (dolist (url url-list) + (auto-install-from-url url)) + (error "Invalid url list for install."))) + +(defun nthcdr+ (n list) + "Take cdr N times on LIST, return the result. +If LIST length below N, return entire list. +If LIST is nil, return nil." + (if (or (null list) + (> n (length list))) + list + (nthcdr n list))) + +(defun nthcar (n list) + "Return first N elements of LIST. +If LIST length below N, return entire list. +If LIST is nil, return nil." + (reverse (nthcdr (- (length list) n) (reverse list)))) + +;;;; Bug report +(defvar auto-install-maintainer-mail-address + (concat "rubiki" "tch@ru" "by-lang.org")) +(defvar auto-install-bug-report-salutation + "Describe bug below, using a precise recipe. + +When I executed M-x ... + +How to send a bug report: + 1) Be sure to use the LATEST version of auto-install.el. + 2) Enable debugger. M-x toggle-debug-on-error or (setq debug-on-error t) + 3) Use Lisp version instead of compiled one: (load \"auto-install.el\") + 4) If you got an error, please paste *Backtrace* buffer. + 5) Type C-c C-c to send. +# If you are a Japanese, please write in Japanese:-)") +(defun auto-install-send-bug-report () + (interactive) + (reporter-submit-bug-report + auto-install-maintainer-mail-address + "auto-install.el" + (apropos-internal "^auto-install-" 'boundp) + nil nil + auto-install-bug-report-salutation)) + + +(provide 'auto-install) + +;; TestCase +;; (find-file-other-window "~/memo/junk/2010-04-25-094621.auto-install-check-update.test.el") + +;; How to save (DO NOT REMOVE!!) +;; (emacswiki-post "auto-install.el") +;;; auto-install.el ends here + +;;; LocalWords: el eol dirs fontify gistid txt func bytecomp DDirectory ediff +;;; LocalWords: noselect Unmark unmark AutoInstall keybindings defalias'es + diff --git a/auto-install/bookmark+-1.el b/auto-install/bookmark+-1.el new file mode 100644 index 0000000..95f208a --- /dev/null +++ b/auto-install/bookmark+-1.el @@ -0,0 +1,7851 @@ +;;; bookmark+-1.el - First part of package Bookmark+. +;; +;; Filename: bookmark+-1.el +;; Description: First part of package Bookmark+. +;; Author: Drew Adams, Thierry Volpiatto +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved. +;; Created: Mon Jul 12 13:43:55 2010 (-0700) +;; Last-Updated: Tue Aug 9 10:57:27 2011 (-0700) +;; By: dradams +;; Update #: 2238 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-1.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `bookmark+-1', `bookmark+-mac', `dired', +;; `dired-aux', `dired-x', `ffap', `pp'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other (non-bmenu) required code (this file) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) + +;;(@> "Index") +;; +;; Index +;; ----- +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Things Defined Here") +;; (@> "User Options (Customizable)") +;; (@> "Internal Variables") +;; (@> "Compatibility Code for Older Emacs Versions") +;; (@> "Core Replacements (`bookmark-*' except `bookmark-bmenu-*')") +;; (@> "Bookmark+ Functions (`bmkp-*')") +;; (@> "Search-and-Replace Locations of Marked Bookmarks") +;; (@> "Tags") +;; (@> "Bookmark Predicates") +;; (@> "Filter Functions") +;; (@> "General Utility Functions") +;; (@> "Bookmark Entry Access Functions") +;; (@> "Sorting - General Functions") +;; (@> "Sorting - Commands") +;; (@> "Sorting - General Predicates") +;; (@> "Sorting - File-Name Predicates") +;; (@> "Indirect Bookmarking Functions") +;; (@> "Other Bookmark+ Functions (`bmkp-*')") +;; (@> "Keymaps") + +;;(@* "Things Defined Here") +;; +;; Things Defined Here +;; ------------------- +;; +;; Commands defined here: +;; +;; `bmkp-add-tags', `bmkp-all-tags-jump', +;; `bmkp-all-tags-jump-other-window', `bmkp-all-tags-regexp-jump', +;; `bmkp-all-tags-regexp-jump-other-window', +;; `bmkp-autofile-add-tags', `bmkp-autofile-jump', +;; `bmkp-autofile-jump-other-window', `bmkp-autofile-remove-tags', +;; `bmkp-autofile-set', `bmkp-autonamed-jump', +;; `bmkp-autonamed-jump-other-window', +;; `bmkp-autonamed-this-buffer-jump', +;; `bmkp-autonamed-this-buffer-jump-other-window', +;; `bmkp-bookmark-a-file' `bmkp-bookmark-file-jump', +;; `bmkp-bookmark-list-jump', +;; `bmkp-choose-navlist-from-bookmark-list', +;; `bmkp-choose-navlist-of-type', `bmkp-compilation-target-set', +;; `bmkp-compilation-target-set-all', `bmkp-copy-tags', +;; `bmkp-crosshairs-highlight', `bmkp-cycle', +;; `bmkp-cycle-autonamed', `bmkp-cycle-autonamed-other-window', +;; `bmkp-cycle-bookmark-list', +;; `bmkp-cycle-bookmark-list-other-window', `bmkp-cycle-desktop', +;; `bmkp-cycle-dired', `bmkp-cycle-dired-other-window', +;; `bmkp-cycle-file', `bmkp-cycle-file-other-window', +;; `bmkp-cycle-gnus', `bmkp-cycle-gnus-other-window', +;; `bmkp-cycle-info', `bmkp-cycle-info-other-window', +;; `bmkp-cycle-lighted', `bmkp-cycle-lighted-other-window', +;; `bmkp-cycle-local-file', `bmkp-cycle-local-file-other-window', +;; `bmkp-cycle-man', `bmkp-cycle-man-other-window', +;; `bmkp-cycle-non-file', `bmkp-cycle-non-file-other-window', +;; `bmkp-cycle-other-window', `bmkp-cycle-remote-file', +;; `bmkp-cycle-remote-file-other-window', +;; `bmkp-cycle-specific-buffers', +;; `bmkp-cycle-specific-buffers-other-window', +;; `bmkp-cycle-specific-files', +;; `bmkp-cycle-specific-files-other-window', +;; `bmkp-cycle-this-buffer', `bmkp-cycle-this-buffer-other-window', +;; `bmkp-cycle-variable-list', `bmkp-cycle-url', +;; `bmkp-cycle-url-other-window', +;; `bmkp-delete-all-autonamed-for-this-buffer', +;; `bmkp-delete-bookmarks', `bmkp-describe-bookmark', +;; `bmkp-describe-bookmark-internals', `bmkp-desktop-change-dir', +;; `bmkp-desktop-delete', `bmkp-desktop-jump', `bmkp-desktop-read', +;; `bmkp-dired-jump', `bmkp-dired-jump-other-window', +;; `bmkp-dired-this-dir-jump', +;; `bmkp-dired-this-dir-jump-other-window', `bmkp-edit-bookmark', +;; `bmkp-edit-bookmark-record', `bmkp-edit-bookmark-record-mode', +;; `bmkp-edit-bookmark-record-send', `bmkp-edit-tags', +;; `bmkp-edit-tags-send', `bmkp-empty-file', +;; `bmkp-file-target-set', `bmkp-file-all-tags-jump', +;; `bmkp-file-all-tags-jump-other-window', +;; `bmkp-file-all-tags-regexp-jump', +;; `bmkp-file-all-tags-regexp-jump-other-window', `bmkp-file-jump', +;; `bmkp-file-jump-other-window', `bmkp-file-some-tags-jump', +;; `bmkp-file-some-tags-jump-other-window', +;; `bmkp-file-some-tags-regexp-jump', +;; `bmkp-file-some-tags-regexp-jump-other-window', +;; `bmkp-file-this-dir-all-tags-jump', +;; `bmkp-file-this-dir-all-tags-jump-other-window', +;; `bmkp-file-this-dir-all-tags-regexp-jump', +;; `bmkp-file-this-dir-all-tags-regexp-jump-other-window', +;; `bmkp-file-this-dir-jump', +;; `bmkp-file-this-dir-jump-other-window', +;; `bmkp-file-this-dir-some-tags-jump', +;; `bmkp-file-this-dir-some-tags-jump-other-window', +;; `bmkp-file-this-dir-some-tags-regexp-jump', +;; `bmkp-file-this-dir-some-tags-regexp-jump-other-window', +;; `bmkp-find-file', `bmkp-find-file-other-window', +;; `bmkp-find-file-all-tags', +;; `bmkp-find-file-all-tags-other-window', +;; `bmkp-find-file-all-tags-regexp', +;; `bmkp-find-file-all-tags-regexp-other-window', +;; `bmkp-find-file-some-tags', +;; `bmkp-find-file-some-tags-other-window', +;; `bmkp-find-file-some-tags-regexp', +;; `bmkp-find-file-some-tags-regexp-other-window', +;; `bmkp-gnus-jump', `bmkp-gnus-jump-other-window', +;; `bmkp-info-jump', `bmkp-info-jump-other-window', +;; `bmkp-jump-in-navlist', `bmkp-jump-in-navlist-other-window', +;; `bmkp-jump-to-type', `bmkp-jump-to-type-other-window', +;; `bmkp-list-all-tags', `bmkp-list-defuns-in-commands-file', +;; `bmkp-local-file-jump', `bmkp-local-file-jump-other-window', +;; `bmkp-make-function-bookmark', `bmkp-man-jump', +;; `bmkp-man-jump-other-window', `bmkp-menu-jump-other-window' +;; (Emacs 20, 21), `bmkp-navlist-bmenu-list', +;; `bmkp-next-autonamed-bookmark', +;; `bmkp-next-autonamed-bookmark-repeat', `bmkp-next-bookmark', +;; `bmkp-next-bookmark-list-bookmark', +;; `bmkp-next-bookmark-list-bookmark-repeat', +;; `bmkp-next-bookmark-repeat', `bmkp-next-bookmark-this-buffer', +;; `bmkp-next-bookmark-this-buffer-repeat', +;; `bmkp-next-bookmark-w32', `bmkp-next-bookmark-w32-repeat', +;; `bmkp-next-desktop-bookmark', +;; `bmkp-next-desktop-bookmark-repeat', `bmkp-next-dired-bookmark', +;; `bmkp-next-dired-bookmark-repeat', `bmkp-next-file-bookmark', +;; `bmkp-next-file-bookmark-repeat', `bmkp-next-gnus-bookmark', +;; `bmkp-next-gnus-bookmark-repeat', `bmkp-next-info-bookmark', +;; `bmkp-next-info-bookmark-repeat', `bmkp-next-lighted-bookmark', +;; `bmkp-next-lighted-bookmark-repeat', +;; `bmkp-next-local-file-bookmark', +;; `bmkp-next-local-file-bookmark-repeat', +;; `bmkp-next-man-bookmark', `bmkp-next-man-bookmark-repeat', +;; `bmkp-next-non-file-bookmark', +;; `bmkp-next-non-file-bookmark-repeat', +;; `bmkp-next-remote-file-bookmark', +;; `bmkp-next-remote-file-bookmark-repeat', +;; `bmkp-next-specific-buffers-bookmark', +;; `bmkp-next-specific-buffers-bookmark-repeat', +;; `bmkp-next-specific-files-bookmark', +;; `bmkp-next-specific-files-bookmark-repeat', +;; `bmkp-next-variable-list-bookmark', +;; `bmkp-next-variable-list-bookmark-repeat', +;; `bmkp-next-url-bookmark', `bmkp-next-url-bookmark-repeat', +;; `bmkp-non-file-jump', `bmkp-non-file-jump-other-window', +;; `bmkp-occur-create-autonamed-bookmarks', +;; `bmkp-occur-target-set', `bmkp-occur-target-set-all', +;; `bmkp-paste-add-tags', `bmkp-paste-replace-tags', +;; `bmkp-previous-bookmark', `bmkp-previous-bookmark-repeat', +;; `bmkp-previous-bookmark-this-buffer', +;; `bmkp-previous-bookmark-this-buffer-repeat', +;; `bmkp-previous-bookmark-w32', +;; `bmkp-previous-bookmark-w32-repeat', +;; `bmkp-purge-notags-autofiles', `bmkp-read-bookmark-for-type', +;; `bmkp-region-jump', `bmkp-region-jump-other-window', +;; `bmkp-remote-file-jump', `bmkp-remote-file-jump-other-window', +;; `bmkp-remove-all-tags', `bmkp-remove-tags', +;; `bmkp-remove-tags-from-all', `bmkp-rename-tag', +;; `bmkp-save-menu-list-state', `bmkp-send-bug-report', +;; `bmkp-set-autonamed-bookmark', +;; `bmkp-set-autonamed-bookmark-at-line', +;; `bmkp-set-autonamed-regexp-buffer', +;; `bmkp-set-autonamed-regexp-region', +;; `bmkp-set-bookmark-file-bookmark', `bmkp-set-desktop-bookmark', +;; `bmkp-set-restrictions-bookmark', `bmkp-set-tag-value', +;; `bmkp-set-tag-value-for-navlist', +;; `bmkp-set-variable-list-bookmark', `bmkp-some-tags-jump', +;; `bmkp-some-tags-jump-other-window', +;; `bmkp-some-tags-regexp-jump', +;; `bmkp-some-tags-regexp-jump-other-window', +;; `bmkp-specific-buffers-jump', +;; `bmkp-specific-buffers-jump-other-window', +;; `bmkp-specific-files-jump', +;; `bmkp-specific-files-jump-other-window', +;; `bmkp-switch-bookmark-file', +;; `bmkp-switch-to-last-bookmark-file', `bmkp-tag-a-file', +;; `bmkp-this-buffer-bmenu-list', `bmkp-this-buffer-jump', +;; `bmkp-this-buffer-jump-other-window', +;; `bmkp-toggle-autonamed-bookmark-set/delete', +;; `bmkp-toggle-bookmark-set-refreshes', +;; `bmkp-toggle-saving-bookmark-file', +;; `bmkp-toggle-saving-menu-list-state', +;; `bmkp-toggle-bookmark-set-refreshes', `bmkp-unomit-all', +;; `bmkp-untag-a-file', `bmkp-url-target-set', `bmkp-url-jump', +;; `bmkp-url-jump-other-window', `bmkp-use-bookmark-file-create', +;; `bmkp-variable-list-jump', `bmkp-version', `bmkp-w3m-jump', +;; `bmkp-w3m-jump-other-window', `old-bookmark-insert', +;; `old-bookmark-relocate'. +;; +;; User options defined here: +;; +;; `bmkp-autoname-bookmark-function', `bmkp-autoname-format', +;; `bmkp-bookmark-name-length-max', `bmkp-crosshairs-flag', +;; `bmkp-default-bookmark-name', +;; `bmkp-default-handler-associations', +;; `bmkp-desktop-no-save-vars', +;; `bmkp-guess-default-handler-for-file-flag', +;; `bmkp-handle-region-function', `bmkp-incremental-filter-delay', +;; `bmkp-menu-popup-max-length', `bmkp-other-window-pop-to-flag', +;; `bmkp-prompt-for-tags-flag', `bmkp-region-search-size', +;; `bmkp-save-new-location-flag', +;; `bmkp-sequence-jump-display-function', +;; `bmkp-show-end-of-region', `bmkp-sort-comparer', +;; `bmkp-su-or-sudo-regexp', +;; `bmkp-this-buffer-cycle-sort-comparer', `bmkp-use-region', +;; `bmkp-w3m-allow-multi-tabs'. +;; +;; Non-interactive functions defined here: +;; +;; `bmkext-jump-gnus', `bmkext-jump-man', `bmkext-jump-w3m', +;; `bmkext-jump-woman', `bmkp-all-exif-data', +;; `bmkp-all-tags-alist-only', `bmkp-all-tags-regexp-alist-only', +;; `bmkp-alpha-cp', `bmkp-alpha-p', `bmkp-annotated-alist-only', +;; `bmkp-autofile-alist-only', `bmkp-autofile-bookmark-p', +;; `bmkp-autoname-bookmark', `bmkp-autonamed-alist-only', +;; `bmkp-autonamed-bookmark-for-buffer-p', +;; `bmkp-autonamed-bookmark-p', +;; `bmkp-autonamed-this-buffer-alist-only', +;; `bmkp-bookmark-creation-cp', `bmkp-bookmark-description', +;; `bmkp-bookmark-last-access-cp', `bmkp-bookmark-file-alist-only', +;; `bmkp-bookmark-list-alist-only', +;; `bmkp-bookmark-file-bookmark-p', +;; `bmkp-bookmark-image-bookmark-p', +;; `bmkp-bookmark-list-bookmark-p', `bmkp-bookmark-name-member', +;; `bmkp-bookmark-type', `bmkp-buffer-last-access-cp', +;; `bmkp-buffer-names', `bmkp-compilation-file+line-at', +;; `bmkp-completing-read-1', `bmkp-completing-read-buffer-name', +;; `bmkp-completing-read-file-name', `bmkp-completing-read-lax', +;; `bmkp-cp-not', `bmkp-create-variable-list-bookmark', +;; `bmkp-current-bookmark-list-state', `bmkp-current-sort-order', +;; `bmkp-cycle-1', `bmkp-default-bookmark-name', +;; `bmkp-default-handler-for-file', `bmkp-default-handler-user', +;; `bmkp-delete-autonamed-no-confirm', +;; `bmkp-delete-autonamed-this-buffer-no-confirm', +;; `bmkp-delete-bookmark-name-from-list', +;; `bmkp-desktop-alist-only', `bmkp-desktop-bookmark-p', +;; `bmkp-desktop-kill', `bmkp-dired-alist-only', +;; `bmkp-dired-bookmark-p', `bmkp-dired-subdirs', +;; `bmkp-dired-this-dir-alist-only', +;; `bmkp-dired-this-dir-bookmark-p', `bmkp-edit-tags-mode', +;; `bmkp-end-position-post-context', +;; `bmkp-end-position-pre-context', `bmkp-every', `bmkp-face-prop', +;; `bmkp-file-alist-only', `bmkp-file-all-tags-alist-only', +;; `bmkp-file-all-tags-regexp-alist-only', `bmkp-file-alpha-cp', +;; `bmkp-file-attribute-0-cp', `bmkp-file-attribute-1-cp', +;; `bmkp-file-attribute-2-cp', `bmkp-file-attribute-3-cp', +;; `bmkp-file-attribute-4-cp', `bmkp-file-attribute-5-cp', +;; `bmkp-file-attribute-6-cp', `bmkp-file-attribute-7-cp', +;; `bmkp-file-attribute-8-cp', `bmkp-file-attribute-9-cp', +;; `bmkp-file-attribute-10-cp', `bmkp-file-attribute-11-cp', +;; `bmkp-file-bookmark-p', `bmkp-file-names', `bmkp-file-remote-p', +;; `bmkp-file-some-tags-alist-only', +;; `bmkp-file-some-tags-regexp-alist-only', +;; `bmkp-file-this-dir-alist-only', +;; `bmkp-file-this-dir-all-tags-alist-only', +;; `bmkp-file-this-dir-all-tags-regexp-alist-only', +;; `bmkp-file-this-dir-bookmark-p', +;; `bmkp-file-this-dir-some-tags-alist-only', +;; `bmkp-file-this-dir-some-tags-regexp-alist-only', +;; `bmkp-float-time', `bmkp-full-tag', `bmkp-function-bookmark-p', +;; `bmkp-get-autofile-bookmark', `bmkp-get-buffer-name', +;; `bmkp-get-end-position', `bmkp-get-tag-value', `bmkp-get-tags', +;; `bmkp-get-visit-time', `bmkp-get-visits-count', +;; `bmkp-gnus-alist-only', `bmkp-gnus-bookmark-p', `bmkp-gnus-cp', +;; `bmkp-goto-position', `bmkp-handle-region-default', +;; `bmkp-handler-cp', `bmkp-has-tag-p', `bmkp-info-alist-only', +;; `bmkp-info-bookmark-p', `bmkp-info-cp', `bmkp-isearch-bookmarks' +;; (Emacs 23+), `bmkp-isearch-bookmarks-regexp' (Emacs 23+), +;; `bmkp-isearch-next-bookmark-buffer' (Emacs 23+), `bmkp-jump-1', +;; `bmkp-jump-bookmark-file', `bmkp-jump-bookmark-list', +;; `bmkp-jump-desktop', `bmkp-jump-dired', `bmkp-jump-function', +;; `bmkp-jump-gnus', `bmkp-jump-man', `bmkp-jump-sequence', +;; `bmkp-jump-url-browse', `bmkp-jump-variable-list', +;; `bmkp-jump-w3m', `bmkp-jump-w3m-new-session', +;; `bmkp-jump-w3m-only-one-tab', `bmkp-jump-woman', +;; `bmkp-last-specific-buffer-alist-only', +;; `bmkp-last-specific-buffer-p', +;; `bmkp-last-specific-file-alist-only', +;; `bmkp-last-specific-file-p', `bmkp-line-number-at-pos', +;; `bmkp-list-position', `bmkp-local-directory-bookmark-p', +;; `bmkp-local-file-accessed-more-recently-cp', +;; `bmkp-local-file-alist-only', `bmkp-local-file-bookmark-p', +;; `bmkp-local-file-size-cp', `bmkp-local-file-type-cp', +;; `bmkp-local-file-updated-more-recently-cp', +;; `bmkp-make-bookmark-file-record', +;; `bmkp-make-bookmark-list-record', `bmkp-make-desktop-record', +;; `bmkp-make-dired-record', `bmkp-make-gnus-record', +;; `bmkp-make-man-record', `bmkp-make-plain-predicate', +;; `bmkp-make-record-for-target-file', +;; `bmkp-make-url-browse-record', `bmkp-make-variable-list-record', +;; `bmkp-make-w3m-record', `bmkp-make-woman-record' (Emacs 21+), +;; `bmkp-man-alist-only', `bmkp-man-bookmark-p', +;; `bmkp-marked-bookmark-p', `bmkp-marked-bookmarks-only', +;; `bmkp-marked-cp', `bmkp-maybe-save-bookmarks', +;; `bmkp-msg-about-sort-order', `bmkp-multi-sort', +;; `bmkp-names-same-bookmark-p', `bmkp-non-autonamed-alist-only', +;; `bmkp-non-file-alist-only', `bmkp-non-file-bookmark-p', +;; `bmkp-omitted-alist-only', `bmkp-position-after-whitespace', +;; `bmkp-position-before-whitespace', `bmkp-position-cp', +;; `bmkp-position-post-context', +;; `bmkp-position-post-context-region', +;; `bmkp-position-pre-context', `bmkp-position-pre-context-region', +;; `bmkp-printable-p', `bmkp-printable-vars+vals', +;; `bmkp-read-bookmark-file-name', `bmkp-read-tag-completing', +;; `bmkp-read-tags', `bmkp-read-tags-completing', +;; `bmkp-read-variable', `bmkp-read-variables-completing', +;; `bmkp-record-visit', `bmkp-refresh-latest-bookmark-list', +;; `bmkp-refresh-menu-list', +;; `bmkp-regexp-filtered-annotation-alist-only', +;; `bmkp-regexp-filtered-bookmark-name-alist-only', +;; `bmkp-regexp-filtered-file-name-alist-only', +;; `bmkp-regexp-filtered-tags-alist-only', +;; `bmkp-region-alist-only', `bmkp-region-bookmark-p', +;; `bmkp-remote-file-alist-only', `bmkp-remote-file-bookmark-p', +;; `bmkp-remove-dups', `bmkp-remove-if', `bmkp-remove-if-not', +;; `bmkp-remove-omitted', `bmkp-repeat-command', +;; `bmkp-replace-existing-bookmark', `bmkp-root-or-sudo-logged-p', +;; `bmkp-same-creation-time-p', `bmkp-same-file-p', +;; `bmkp-save-new-region-location', +;; `bmkp-select-buffer-other-window', `bmkp-sequence-bookmark-p', +;; `bmkp-set-tag-value-for-bookmarks', `bmkp-set-union', +;; `bmkp-some', `bmkp-some-marked-p', `bmkp-some-tags-alist-only', +;; `bmkp-some-tags-regexp-alist-only', `bmkp-some-unmarked-p' +;; `bmkp-sort-omit', `bmkp-sound-jump', +;; `bmkp-specific-buffers-alist-only', +;; `bmkp-specific-files-alist-only', `bmkp-tag-name', +;; `bmkp-tags-list', `bmkp-this-buffer-alist-only', +;; `bmkp-this-buffer-p', `bmkp-this-file-alist-only', +;; `bmkp-this-file-p', `bmkp-unmarked-bookmarks-only', +;; `bmkp-upcase', `bmkp-update-autonamed-bookmark', +;; `bmkp-url-alist-only', `bmkp-url-bookmark-p', +;; `bmkp-url-browse-alist-only', `bmkp-url-browse-bookmark-p', +;; `bmkp-url-cp', `bmkp-variable-list-alist-only', +;; `bmkp-variable-list-bookmark-p', `bmkp-visited-more-cp', +;; `bmkp-w3m-alist-only', `bmkp-w3m-bookmark-p', `bmkp-w3m-cp', +;; `bmkp-w3m-set-new-buffer-name'. +;; +;; Internal variables defined here: +;; +;; `bmkp-after-set-hook', `bmkp-bookmark-file-history', +;; `bmkp-bookmark-list-history', `bmkp-current-bookmark-file', +;; `bmkp-current-nav-bookmark', `bmkp-desktop-history', +;; `bmkp-dired-history', `bmkp-edit-bookmark-record-mode-map', +;; `bmkp-edit-tags-mode-map', `bmkp-file-bookmark-handlers', +;; `bmkp-file-history', `bmkp-gnus-history', `bmkp-info-history', +;; `bmkp-isearch-bookmarks' (Emacs 23+), +;; `bmkp-jump-display-function', `bmkp-jump-other-window-map', +;; `bmkp-last-bmenu-state-file', `bmkp-last-bookmark-file', +;; `bmkp-last-save-flag-value', `bmkp-last-specific-buffer', +;; `bmkp-last-specific-file', `bmkp-latest-bookmark-alist', +;; `bmkp-local-file-history', `bmkp-man-history', `bmkp-nav-alist', +;; `bmkp-non-file-filename', `bmkp-non-file-history', +;; `bmkp-region-history', `bmkp-remote-file-history', +;; `bmkp-return-buffer', `bmkp-reverse-multi-sort-p', +;; `bmkp-reverse-sort-p', `bmkp-sorted-alist', +;; `bmkp-specific-buffers-history', `bmkp-specific-files-history', +;; `bmkp-tag-history', `bmkp-tags-alist', `bmkp-types-alist', +;; `bmkp-url-history', `bmkp-use-w32-browser-p', +;; `bmkp-variable-list-history', `bmkp-version-number', +;; `bmkp-w3m-history'. +;; +;; +;; ***** NOTE: The following commands defined in `bookmark.el' +;; have been REDEFINED HERE: +;; +;; `bookmark-delete', `bookmark-edit-annotation', +;; `bookmark-edit-annotation-mode', `bookmark-insert', +;; `bookmark-insert-location', `bookmark-jump', +;; `bookmark-jump-other-window', `bookmark-load', +;; `bookmark-relocate', `bookmark-rename', `bookmark-save', +;; `bookmark-send-edited-annotation', `bookmark-set', +;; `bookmark-yank-word'. +;; +;; +;; ***** NOTE: The following non-interactive functions defined in +;; `bookmark.el' have been REDEFINED HERE: +;; +;; `bookmark--jump-via', `bookmark-all-names', +;; `bookmark-completing-read', `bookmark-default-handler', +;; `bookmark-exit-hook-internal', `bookmark-get-bookmark' (Emacs +;; 20-22), `bookmark-get-bookmark-record' (Emacs 20-22), +;; `bookmark-get-handler' (Emacs 20-22), +;; `bookmark-handle-bookmark', `bookmark-jump-noselect' (Emacs +;; 20-22), `bookmark-location', `bookmark-make-record' (Emacs +;; 20-22), `bookmark-make-record-default', `bookmark-maybe-message' +;; (Emacs 20-21), `bookmark-prop-get' (Emacs 20-22), +;; `bookmark-prop-set', `bookmark-show-annotation', +;; `bookmark-show-all-annotations', `bookmark-store' (Emacs 20-22), +;; `bookmark-write-file'. +;; +;; +;; ***** NOTE: The following variables defined in `bookmark.el' +;; have been REDEFINED HERE: +;; +;; `bookmark-alist' (doc string only), +;; `bookmark-make-record-function' (Emacs 20-22). +;; +;; +;; ***** NOTE: The following functions defined in `info.el' +;; have been REDEFINED HERE: +;; +;; `Info-bookmark-jump' (Emacs 20-22), `Info-bookmark-make-record' +;; (Emacs 20-22). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(unless (fboundp 'file-remote-p) (require 'ffap)) ;; ffap-file-remote-p +(eval-when-compile (require 'gnus)) ;; mail-header-id (really in `nnheader.el') +(eval-when-compile (require 'gnus-sum)) ;; gnus-summary-article-header +(eval-when-compile (require 'cl)) ;; case, multiple-value-bind + +(require 'bookmark) +;; bookmark-alist, bookmark-alist-from-buffer, +;; bookmark-alist-modification-count, bookmark-annotation-name, +;; bookmark-automatically-show-annotations, bookmark-bmenu-bookmark, +;; bookmark-bmenu-surreptitiously-rebuild-list, +;; bookmark-bmenu-toggle-filenames, bookmark-buffer-file-name, +;; bookmark-buffer-name, bookmark-completion-ignore-case, +;; bookmark-current-bookmark, bookmark-default-file, +;; bookmark-edit-annotation, bookmark-get-annotation, +;; bookmark-get-bookmark, bookmark-get-bookmark-record, +;; bookmark-get-filename, bookmark-get-front-context-string, +;; bookmark-get-handler, bookmark-get-position, +;; bookmark-get-rear-context-string, bookmark-import-new-list, +;; bookmark-insert-file-format-version-stamp, bookmark-kill-line, +;; bookmark-make-record, bookmark-maybe-historicize-string, +;; bookmark-maybe-load-default-file, bookmark-maybe-message, +;; bookmark-maybe-upgrade-file-format, bookmark-menu-popup-paned-menu, +;; bookmark-name-from-full-record, bookmark-name-from-record, +;; bookmark-popup-menu-and-apply-function, bookmark-prop-get, +;; bookmarks-already-loaded, bookmark-save-flag, bookmark-search-size, +;; bookmark-set-annotation, bookmark-set-filename, bookmark-set-name, +;; bookmark-set-position, bookmark-store, bookmark-time-to-save-p, +;; bookmark-use-annotations, bookmark-version-control, +;; bookmark-yank-point + +;;; Fix incompatibility introduced by gratuitous Emacs name change. +(cond ((and (fboundp 'bookmark-name-from-record) (not (fboundp 'bookmark-name-from-full-record))) + (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record)) + ((and (fboundp 'bookmark-name-from-full-record) (not (fboundp 'bookmark-name-from-record))) + (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record))) + +(require 'bookmark+-mac) +;; bmkp-define-cycle-command, bmkp-define-file-sort-predicate, bmkp-menu-bar-make-toggle, +;; bmkp-replace-regexp-in-string + +(eval-when-compile (require 'bookmark+-bmu)) +;; bmkp-bmenu-before-hide-marked-alist, +;; bmkp-bmenu-before-hide-unmarked-alist, bmkp-bmenu-commands-file, +;; bmkp-bmenu-filter-function, bmkp-bmenu-filter-pattern, +;; bmkp-bmenu-first-time-p, bmkp-bmenu-goto-bookmark-named, +;; bmkp-bmenu-marked-bookmarks, bmkp-bmenu-omitted-bookmarks, bmkp-bmenu-refresh-menu-list, +;; bmkp-bmenu-show-all, bmkp-bmenu-state-file, bmkp-bmenu-title, +;; bmkp-maybe-unpropertize-bookmark-names, bmkp-sort-orders-alist + +;; (eval-when-compile (require 'bookmark+-lit nil t)) +;; bmkp-light-bookmark, bmkp-light-bookmarks, bmkp-light-this-buffer + + +;; For the redefinition of `bookmark-get-bookmark' in Emacs < 23. +(provide 'bookmark+-1) ; Ensure this library is loaded before we compile it. +(require 'bookmark+-1) ; So be sure to put this library in your `load-path' before + ; trying to byte-compile it. + +;;;;;;;;;;;;;;;;;;;;;;; + +;; Quiet the byte-compiler + +(defvar bmkp-auto-light-when-set) ; Defined in `bookmark+-lit.el'. +(defvar bmkp-auto-light-when-jump) ; Defined in `bookmark+-lit.el'. +(defvar bmkp-light-priorities) ; Defined in `bookmark+-lit.el'. +(defvar bookmark-current-point) ; Defined in `bookmark.el', but not in Emacs 23+. +(defvar bookmark-edit-annotation-text-func) ; Defined in `bookmark.el'. +(defvar bookmark-read-annotation-text-func) ; Defined in `bookmark.el', but not in Emacs 23+. +(defvar bookmark-make-record-function) ; Defined in `bookmark.el'. +(defvar desktop-buffer-args-list) ; Defined in `desktop.el'. +(defvar desktop-delay-hook) ; Defined in `desktop.el'. +(defvar desktop-dirname) ; Defined in `desktop.el'. +(defvar desktop-file-modtime) ; Defined in `desktop.el'. +(defvar desktop-globals-to-save) ; Defined in `desktop.el'. +(defvar desktop-save-mode) ; Defined in `desktop.el'. +(defvar desktop-save) ; Defined in `desktop.el'. +(defvar dired-actual-switches) ; Defined in `dired.el'. +(defvar dired-buffers) ; Defined in `dired.el'. +(defvar dired-directory) ; Defined in `dired.el'. +(defvar dired-guess-shell-case-fold-search) ; Defined in `dired-x.el'. +(defvar dired-subdir-alist) ; Defined in `dired.el'. +(defvar gnus-article-current) ; Defined in `gnus-sum.el'. +(defvar Info-current-node) ; Defined in `info.el'. +(defvar Info-current-file) ; Defined in `info.el'. +(defvar Man-arguments) ; Defined in `man.el'. +(defvar read-file-name-completion-ignore-case) ; Emacs 23+. +(defvar last-repeatable-command) ; Defined in `repeat.el'. +(defvar w3m-current-title) ; Defined in `w3m.el'. +(defvar w3m-current-url) ; Defined in `w3m.el'. +(defvar w3m-mode-map) ; Defined in `w3m.el'. +(defvar wide-n-restrictions) ; Defined in `wide-n.el'. +(defvar woman-last-file-name) ; Defined in `woman.el'. + +;;(@* "User Options (Customizable)") +;;; User Options (Customizable) -------------------------------------- + +;;;###autoload +(defcustom bmkp-autoname-bookmark-function 'bmkp-autoname-bookmark + "*Function to automatically name a bookmark at point (cursor position)." + :type 'function :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-autoname-format (if (> emacs-major-version 21) "^[0-9]\\{9\\} %s" "^[0-9]+ %s") + "*Format string to match an autonamed bookmark name. +It must have a single `%s' that to accept the buffer name." + :type 'string :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-bookmark-name-length-max 70 + "*Max number of chars for default name for a bookmark with a region." + :type 'integer :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-crosshairs-flag (> emacs-major-version 21) + "*Non-nil means highlight with crosshairs when you visit a bookmark. +The highlighting is temporary - until your next action. +You need library `crosshairs.el' for this feature, and you need Emacs +22 or later. + +If you use this option in Lisp code, you will want to add/remove +`bmkp-crosshairs-highlight' to/from `bookmark-after-jump-hook'." + :set (lambda (sym new-val) + (custom-set-default sym new-val) + (if (and bmkp-crosshairs-flag (> emacs-major-version 21) + (condition-case nil (require 'crosshairs nil t) (error nil))) + (add-hook 'bookmark-after-jump-hook 'bmkp-crosshairs-highlight) + (remove-hook 'bookmark-after-jump-hook 'bmkp-crosshairs-highlight))) + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-default-bookmark-name 'highlighted + "*Default bookmark name preference. +In `*Bookmark List*' use the name of the current line's bookmark. +Otherwise, if `bookmark+-lit.el' is not loaded then use the name of + the last-used bookmark in the current file. + +Otherwise, use this option to determine the default, by preferring one +of the following, if available: + +* a highlighted bookmark at point +* the last-used bookmark in the current file" + :type '(choice + (const :tag "Highlighted bookmark at point" highlighted) + (const :tag "Last used bookmark in same file" last-used)) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-default-handler-associations + (and (require 'dired-x) ; It in turn requires `dired-aux.el' + (let ((assns ())) + (dolist (shell-assn dired-guess-shell-alist-user) + (push (cons (car shell-assn) + `(lambda (bmk) + (dired-run-shell-command + (dired-shell-stuff-it ,(cadr shell-assn) (list (bookmark-get-filename bmk)) + nil nil)))) + assns)) + assns)) + "*File associations for bookmark handlers used for indirect bookmarks. +Each element of the alist is (REGEXP . COMMAND). +REGEXP matches a file name. +COMMAND is a sexp that evaluates to either a shell command (a string) + or an Emacs function (a symbol or a lambda form). + +Example value: + + ((\"\\.pdf$\" . \"AcroRd32.exe\") ; Adobe Acrobat Reader + (\"\\.ps$\" . \"gsview32.exe\")) ; Ghostview (PostScript viewer) + +When you change this option using Customize, if you want to use a +literal string as COMMAND then you must double-quote the text: +\"...\". (But do not use double-quotes for the REGEXP.) If you want +to use a symbol as COMMAND, then single-quote it - e.g. 'foo. + +This option is used by `bmkp-default-handler-for-file' to determine +the default handler for a given file. If a given file name does not +match this option, and if `bmkp-guess-default-handler-for-file-flag' +is non-nil, then then `bmkp-default-handler-for-file' tries to guess a +shell command to use in the default handler. For that it uses +`dired-guess-default' and (Emacs 23+ only) mailcap entries, in that +order." + :type '(alist :key-type + regexp :value-type + (sexp :tag "Shell command (string) or Emacs function (symbol or lambda form)")) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-desktop-no-save-vars '(search-ring regexp-search-ring kill-ring) + "*List of variables not to save when creating a desktop bookmark. +They are removed from `desktop-globals-to-save' for the duration of +the save (only)." + :type '(repeat (variable :tag "Variable")) :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-handle-region-function 'bmkp-handle-region-default + "*Function to handle a bookmarked region." + :type 'function :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-incremental-filter-delay 0.6 + "*Seconds to wait before updating display when filtering bookmarks." + :type 'number :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-menu-popup-max-length 20 + "*Max number of bookmarks for `bookmark-completing-read' to use a menu. +When choosing a bookmark from a list of bookmarks using +`bookmark-completing-read', this controls whether to use a menu or +minibuffer input with completion. +If t, then always use a menu. +If nil, then never use a menu. +If an integer, then use a menu only if there are fewer bookmark + choices than the value." + :type '(choice + (integer :tag "Use a menu if there are fewer bookmark choices than this" 20) + (const :tag "Always use a menu to choose a bookmark" t) + (const :tag "Never use a menu to choose a bookmark" nil)) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-other-window-pop-to-flag t + "*Non-nil means other-window bookmark jumping uses `pop-to-buffer'. +Use nil if you want the vanilla Emacs behavior, which uses +`switch-to-buffer-other-window'. That creates a new window even if +there is already another window showing the buffer." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-prompt-for-tags-flag nil + "*Non-nil means `bookmark-set' prompts for tags (when called interactively)." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-region-search-size 40 + "*Same as `bookmark-search-size', but specialized for bookmark regions." + :type 'integer :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-save-new-location-flag t + "*Non-nil means save automatically relocated bookmarks. +If nil, then the new bookmark location is visited, but it is not saved +as part of the bookmark definition." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-sequence-jump-display-function 'pop-to-buffer + "*Function used to display the bookmarks in a bookmark sequence." + :type 'function :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-show-end-of-region t + "*Show end of region with `exchange-point-and-mark' when activating a region. +If nil show only beginning of region." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-sort-comparer '((bmkp-info-cp bmkp-gnus-cp bmkp-url-cp bmkp-local-file-type-cp) + bmkp-alpha-p) ; This corresponds to `s k'. + ;; $$$$$$ An alternative default value: `bmkp-alpha-p', which corresponds to `s n'. + "*Predicate or predicates for sorting (comparing) bookmarks. +This defines the default sort for bookmarks in the bookmark list. + +Various sorting commands, such as \\\ +`\\[bmkp-bmenu-sort-by-bookmark-visit-frequency]', change the value of this +option dynamically (but they do not save the changed value). + +The value must be one of the following: + +* nil, meaning do not sort + +* a predicate that takes two bookmarks as args + +* a list of the form ((PRED...) FINAL-PRED), where each PRED and + FINAL-PRED are predicates that take two bookmarks as args + +If the value is a list of predicates, then each PRED is tried in turn +until one returns a non-nil value. In that case, the result is the +car of that value. If no non-nil value is returned by any PRED, then +FINAL-PRED is used and its value is the result. + +Each PRED should return `(t)' for true, `(nil)' for false, or nil for +undecided. A nil value means that the next PRED decides (or +FINAL-PRED, if there is no next PRED). + +Thus, a PRED is a special kind of predicate that indicates either a +boolean value (as a singleton list) or \"I cannot decide - let the +next guy else decide\". (Essentially, each PRED is a hook function +that is run using `run-hook-with-args-until-success'.) + +Examples: + + nil - No sorting. + + string-lessp - Single predicate that returns nil or non-nil. + + ((p1 p2)) - Two predicates `p1' and `p2', which each return + (t) for true, (nil) for false, or nil for undecided. + + ((p1 p2) string-lessp) + - Same as previous, except if both `p1' and `p2' return + nil, then the return value of `string-lessp' is used. + +Note that these two values are generally equivalent, in terms of their +effect (*): + + ((p1 p2)) + ((p1) p2-plain) where p2-plain is (bmkp-make-plain-predicate p2) + +Likewise, these three values generally act equivalently (*): + + ((p1)) + (() p1-plain) + p1-plain where p1-plain is (bmkp-make-plain-predicate p1) + +The PRED form lets you easily combine predicates: use `p1' unless it +cannot decide, in which case try `p2', and so on. The value ((p2 p1)) +tries the predicates in the opposite order: first `p2', then `p1' if +`p2' returns nil. + +Using a single predicate or FINAL-PRED makes it easy to reuse an +existing predicate that returns nil or non-nil. + +You can also convert a PRED-type predicate (which returns (t), (nil), +or nil) into an ordinary predicate, by using function +`bmkp-make-plain-predicate'. That lets you reuse elsewhere, as +ordinary predicates, any PRED-type predicates you define. + +For example, this defines a plain predicate to compare by URL: + (defalias 'bmkp-url-p (bmkp-make-plain-predicate 'bmkp-url-cp)) + +Note: As a convention, predefined Bookmark+ PRED-type predicate names +have the suffix `-cp' (for \"component predicate\") instead of `-p'. + +-- +* If you use `\\[bmkp-reverse-multi-sort-order]', then there is a difference in \ +behavior between + + (a) using a plain predicate as FINAL-PRED and + (b) using the analogous PRED-type predicate (and no FINAL-PRED). + + In the latter case, `\\[bmkp-reverse-multi-sort-order]' affects when the predicate \ +is tried and + its return value. See `bmkp-reverse-multi-sort-order'." + :type '(choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-su-or-sudo-regexp "\\(/su:\\|/sudo:\\)" + "*Regexp to recognize `su' or `sudo' Tramp bookmarks." + :type 'regexp :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-this-buffer-cycle-sort-comparer '((bmkp-position-cp)) + "*`bmkp-sort-comparer' value for cycling this-buffer bookmarks. +Some values you might want to use: ((bmkp-position-cp)), + ((bmkp-bookmark-creation-cp)), ((bmkp-visited-more-cp)). +See `bmkp-sort-comparer'." + :type '(choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-guess-default-handler-for-file-flag nil + "*Non-nil means guess the default handler when creating a file bookmark. +This is ignored if a handler can be found using option +`bmkp-default-handler-associations'. Otherwise, this is used by +function `bmkp-default-handler-for-file' to determine the default +handler for a given file." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-use-region t + "*Non-nil means visiting a bookmark activates its recorded region." + :type '(choice + (const :tag "Activate bookmark region (except during cycling)" t) + (const :tag "Do not activate bookmark region" nil) + (const :tag "Activate bookmark region even during cycling" cycling-too)) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-w3m-allow-multi-tabs t + "*Non-nil means jump to W3M bookmarks in a new session." + :type 'boolean :group 'bookmark-plus) + +;;(@* "Internal Variables") +;;; Internal Variables ----------------------------------------------- + +(defconst bmkp-non-file-filename " - no file -" + "Name to use for `filename' entry, for non-file bookmarks.") + +(defconst bmkp-types-alist '(("bookmark-file" . bmkp-bookmark-file-history) + ("bookmark-list" . bmkp-bookmark-list-history) + ("desktop" . bmkp-desktop-history) + ("dired" . bmkp-dired-history) + ("dired-this-dir" . bmkp-dired-history) + ("file" . bmkp-file-history) + ("file-this-dir" . bmkp-file-history) + ("gnus" . bmkp-gnus-history) + ("info" . bmkp-info-history) + ("local-file" . bmkp-local-file-history) + ("man" . bmkp-man-history) + ("non-file" . bmkp-non-file-history) + ("region" . bmkp-region-history) + ("remote-file" . bmkp-remote-file-history) + ("specific-buffers" . bmkp-specific-buffers-history) + ("specific-files" . bmkp-specific-files-history) + ("url" . bmkp-url-history) + ("variable-list" . bmkp-variable-list-history)) + "Alist of bookmark types used by `bmkp-jump-to-type'. +Keys are bookmark type names. Values are corresponding history variables.") + +(defvar bmkp-bookmark-file-history () "History for bookmark-file bookmarks.") +(defvar bmkp-bookmark-list-history () "History for bookmark-list bookmarks.") +(defvar bmkp-desktop-history () "History for desktop bookmarks.") +(defvar bmkp-dired-history () "History for Dired bookmarks.") +(defvar bmkp-file-history () "History for file bookmarks.") +(defvar bmkp-gnus-history () "History for Gnus bookmarks.") +(defvar bmkp-info-history () "History for Info bookmarks.") +(defvar bmkp-last-bmenu-state-file nil "Last value of option `bmkp-bmenu-state-file'.") +(defvar bmkp-local-file-history () "History for local-file bookmarks.") +(defvar bmkp-man-history () "History for `man'-page bookmarks.") +(defvar bmkp-non-file-history () "History for buffer (non-file) bookmarks.") +(defvar bmkp-region-history () "History for bookmarks that activate the region.") +(defvar bmkp-remote-file-history () "History for remote-file bookmarks.") +(defvar bmkp-specific-buffers-history () "History for specific-buffers bookmarks.") +(defvar bmkp-specific-files-history () "History for specific-files bookmarks.") +(defvar bmkp-url-history () "History for URL bookmarks.") +(defvar bmkp-variable-list-history () "History for variable-list bookmarks.") +(defvar bmkp-w3m-history () "History for W3M bookmarks.") + +(defvar bmkp-after-set-hook nil "Hook run after `bookmark-set' sets a bookmark.") + +(defvar bmkp-copied-tags () + "List of tags copied from a bookmark, for pasting to other bookmarks.") + +(defvar bmkp-current-bookmark-file bookmark-default-file + "Current bookmark file. +When you start Emacs, this is initialized to `bookmark-default-file'. +When you load bookmarks using `bmkp-switch-bookmark-file', this is set +to the file you load. When you save bookmarks using `bookmark-save' +with no prefix arg, they are saved to this file. + +However, this does not change the value of `bookmark-default-file'. +The value of `bookmark-default-file' is never changed, except by your +customizations. Each Emacs session uses `bookmark-default-file' for +the initial set of bookmarks.") + +(defvar bmkp-file-bookmark-handlers '(bmkp-jump-dired image-bookmark-jump) + "List of functions that handle file or directory bookmarks. +This is used to determine `bmkp-file-bookmark-p'.") + +(defvar bmkp-last-bookmark-file bookmark-default-file + "Last bookmark file used in this session (or default bookmark file). +This is a backup for `bmkp-current-bookmark-file'.") + +(defvar bmkp-current-nav-bookmark nil "Current bookmark for navigation.") + +(defvar bmkp-jump-display-function nil "Function used currently to display a bookmark.") + +(defvar bmkp-last-specific-buffer "" + "Name of buffer used by `bmkp-last-specific-buffer-p'.") + +(defvar bmkp-last-specific-file "" + "(Absolute) file name used by `bmkp-last-specific-file-p'.") + +(defvar bmkp-nav-alist () "Current bookmark alist used for navigation.") + +(defvar bmkp-return-buffer nil "Name of buffer to return to.") + +(defvar bmkp-reverse-sort-p nil "Non-nil means the sort direction is reversed.") + +(defvar bmkp-reverse-multi-sort-p nil + "Non-nil means the truth values returned by predicates are complemented. +This changes the order of the sorting groups, but it does not in +general reverse that order. The order within each group is unchanged +\(not reversed).") + +(defvar bmkp-use-w32-browser-p nil + "Non-nil means use `w32-browser' in the default bookmark handler. +That is, use the default Windows application for the bookmarked file. +This has no effect if `w32-browser' is not defined.") + +(defvar bmkp-latest-bookmark-alist () "Copy of `bookmark-alist' as last filtered.") + +(defvar bmkp-last-save-flag-value nil "Last value of option `bookmark-save-flag'.") + +(defvar bmkp-sorted-alist () + "Copy of current bookmark alist, as sorted for buffer `*Bookmark List*'. +Has the same structure as `bookmark-alist'.") + +(defvar bmkp-tag-history () "History of tags read from the user.") + +(defvar bmkp-tags-alist () + "Alist of all tags, from all bookmarks. +Each entry is a cons whose car is a tag name, a string. +This is set by function `bmkp-tags-list'. +Use that function to update the value.") + + +;; REPLACES ORIGINAL DOC STRING in `bookmark.el'. +;; +;; Doc string reflects Bookmark+ enhancements. +;; +(put 'bookmark-alist 'variable-documentation + "Association list of bookmarks and their records. +Bookmark functions update the value automatically. +You probably do not want to change the value yourself. + +The value is an alist with entries of the form + (BOOKMARK-NAME . PARAM-ALIST) +or the deprecated form (BOOKMARK-NAME PARAM-ALIST). + + BOOKMARK-NAME is the name you gave to the bookmark when creating it. + PARAM-ALIST is an alist of bookmark information. The order of the + entries in PARAM-ALIST is not important. The possible entries are + described below. An entry with a key but null value means the entry + is not used. + +Bookmarks created using vanilla Emacs (`bookmark.el'): + + (filename . FILENAME) + (location . LOCATION) + (position . POS) + (front-context-string . STR-AFTER-POS) + (rear-context-string . STR-BEFORE-POS) + (handler . HANDLER) + (annotation . ANNOTATION) + + FILENAME names the bookmarked file. + LOCATION names the bookmarked file, URL, or other place (Emacs 23+). + FILENAME or LOCATION is what is shown in the bookmark list + (`C-x r l') when you use `M-t'. + POS is the bookmarked buffer position (position in the file). + STR-AFTER-POS is buffer text that immediately follows POS. + STR-BEFORE-POS is buffer text that immediately precedes POS. + ANNOTATION is a string that you can provide to identify the bookmark. + See options `bookmark-use-annotations' and + `bookmark-automatically-show-annotations'. + HANDLER is a function that provides the bookmark-jump behavior + for a specific kind of bookmark. This is the case for Info + bookmarks, for instance (starting with Emacs 23). + +Bookmarks created using Bookmark+ are the same as for vanilla Emacs, +except for the following differences. + +1. Visit information is recorded, using entries `visits' and `time': + + (visits . NUMBER-OF-VISITS) + (time . TIME-LAST-VISITED) + + NUMBER-OF-VISITS is a whole-number counter. + + TIME-LAST-VISITED is an Emacs time representation, such as is + returned by function `current-time'. + +2. The buffer name is recorded, using entry `buffer-name'. It need +not be associated with a file. + +3. If no file is associated with the bookmark, then FILENAME is + ` - no file -'. + +4. Bookmarks can be tagged by users. The tag information is recorded +using entry `tags': + + (tags . TAGS-ALIST) + + TAGS-ALIST is an alist with string keys. + +5. Bookmarks can have individual highlighting, provided by users. +This overrides any default highlighting. + + (lighting . HIGHLIGHTING) + + HIGHLIGHTING is a property list that contain any of these keyword + pairs: + + `:style' - Highlighting style. Cdrs of `bmkp-light-styles-alist' + entries are the possible values. + `:face' - Highlighting face, a symbol. + `:when' - A sexp to be evaluated. Return value of `:no-light' + means do not highlight. + +6. The following additional entries are used to record region +information. When a region is bookmarked, POS represents the region +start position. + + (end-position . END-POS) + (front-context-region-string . STR-BEFORE-END-POS) + (rear-context-region-string . STR-AFTER-END-POS)) + + END-POS is the region end position. + STR-BEFORE-END-POS is buffer text that precedes END-POS. + STR-AFTER-END-POS is buffer text that follows END-POS. + +The two context region strings are non-nil only when a region is +bookmarked. + + NOTE: The relative locations of `front-context-region-string' and + `rear-context-region-string' are reversed from those of + `front-context-string' and `rear-context-string'. For example, + `front-context-string' is the text that *follows* `position', but + `front-context-region-string' *precedes* `end-position'. + +7. The following additional entries are used for a Dired bookmark. + + (dired-marked . MARKED-FILES) + (dired-switches . SWITCHES) + + MARKED-FILES is the list of files that were marked. + SWITCHES is the string of `dired-listing-switches'. + +8. The following additional entries are used for a Gnus bookmark. + + (group . GNUS-GROUP-NAME) + (article . GNUS-ARTICLE-NUMBER) + (message-id . GNUS-MESSAGE-ID) + + GNUS-GROUP-NAME is the name of a Gnus group. + GNUS-ARTICLE-NUMBER is the number of a Gnus article. + GNUS-MESSAGE-ID is the identifier of a Gnus message. + +9. For a URL bookmark, FILENAME or LOCATION is a URL. + +10. A sequence bookmark has this additional entry: + + (sequence . COMPONENT-BOOKMARKS) + + COMPONENT-BOOKMARKS is the list of component bookmark names. + +11. A function bookmark has this additional entry, which records the +FUNCTION: + + (function . FUNCTION) + +12. A bookmark-list bookmark has this additional entry, which records +the state of buffer `*Bookmark List*' at the time it is created: + + (bookmark-list . STATE) + + STATE records the sort order, filter function, omit list, and title.") + +;;(@* "Compatibility Code for Older Emacs Versions") +;;; Compatibility Code for Older Emacs Versions ---------------------- + +(when (< emacs-major-version 23) + + ;; These definitions are for Emacs versions prior to Emacs 23. + ;; They are the same as the vanilla Emacs 23+ definitions, except as noted. + ;; They let older versions of Emacs handle bookmarks created with Emacs 23. + + (defun bookmark-get-bookmark-record (bookmark) + "Return the guts of the entry for BOOKMARK in `bookmark-alist'. +That is, all information but the name. +BOOKMARK is a bookmark name or a bookmark record." + (let ((alist (cdr (bookmark-get-bookmark bookmark)))) + ;; A bookmark record is either (NAME ALIST) or (NAME . ALIST). + (if (and (null (cdr alist)) (consp (caar alist))) + (car alist) + alist))) + + (defun Info-bookmark-make-record () + "Create an Info bookmark record." + `(,Info-current-node + ,@(bookmark-make-record-default 'no-file) + (filename . ,Info-current-file) + (info-node . ,Info-current-node) + (handler . Info-bookmark-jump))) + + ;; Requires `info.el' explicitly (not autoloaded for `Info-find-node'. + (defun Info-bookmark-jump (bookmark) + "Jump to Info bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (require 'info) + ;; Implements the `handler' for the record type returned by `Info-bookmark-make-record'. + (let* ((file (bookmark-prop-get bookmark 'filename)) + (info-node (bookmark-prop-get bookmark 'info-node)) + (buf (save-window-excursion ; VANILLA EMACS FIXME: doesn't work with frames! + (Info-find-node file info-node) (current-buffer)))) + ;; Use `bookmark-default-handler' to move to appropriate location within Info node. + (bookmark-default-handler + `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark))))) + + (add-hook 'Info-mode-hook (lambda () (set (make-local-variable 'bookmark-make-record-function) + 'Info-bookmark-make-record))) + + (defvar bookmark-make-record-function 'bookmark-make-record-default + "Function called with no arguments, to create a bookmark record. +It should return the new record, which should be a cons cell of the +form (NAME . ALIST) or just ALIST, where ALIST is as described in +`bookmark-alist'. If it cannot construct the record, then it should +raise an error. + +NAME is a string that names the new bookmark. NAME can be nil, in +which case a default name is used. + +ALIST can contain an entry (handler . FUNCTION) which sets the handler +to FUNCTION, which is then used instead of `bookmark-default-handler'. +FUNCTION must accept the same arguments as `bookmark-default-handler'. + +You can set this variable buffer-locally to enable bookmarking of +locations that should be treated specially, such as Info nodes, news +posts, images, pdf documents, etc.") + + (defun bookmark-make-record () + "Return a new bookmark record (NAME . ALIST) for the current location." + (let ((record (funcall bookmark-make-record-function))) + ;; Set up default name. + (if (stringp (car record)) + record ; The function already provided a default name. + (when (car record) (push nil record)) + (setcar record (or bookmark-current-bookmark (bookmark-buffer-name))) + record))) + + (defun bookmark-prop-get (bookmark prop) + "Return property PROP of BOOKMARK, or nil if no such property. +BOOKMARK is a bookmark name or a bookmark record." + (cdr (assq prop (bookmark-get-bookmark-record bookmark)))) + + (defun bookmark-get-handler (bookmark) + "Return the `handler' entry for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'handler)) + + (defun bookmark-jump-noselect (bookmark) + "Return the location recorded for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +The return value has the form (BUFFER . POINT), where BUFFER is a +buffer and POINT is the location within BUFFER." + (save-excursion (bookmark-handle-bookmark bookmark) (cons (current-buffer) (point))))) + +(when (< emacs-major-version 22) + + ;; These definitions are for Emacs versions prior to Emacs 22. + ;; They are the same as the vanilla Emacs 22+ definitions, except as noted. + + ;; Emacs 22+ just uses `bookmark-jump-other-window' for the menu also. + (defun bmkp-menu-jump-other-window (event) + "Jump to BOOKMARK (a point in some file) in another window. +See `bookmark-jump-other-window'." + (interactive "e") + (bookmark-popup-menu-and-apply-function 'bookmark-jump-other-window + "Jump to Bookmark (Other Window)" event)) + + (defun bookmark-maybe-message (fmt &rest args) + "Apply `message' to FMT and ARGS, but only if the display is fast enough." + (when (>= baud-rate 9600) (apply 'message fmt args)))) + +;;(@* "Core Replacements (`bookmark-*' except `bookmark-bmenu-*')") +;;; Core Replacements (`bookmark-*' except `bookmark-bmenu-*') ------- + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. If BOOKMARK is a bookmark-name string that has non-nil property `bmkp-full-record' +;; then return the value of that property. +;; 2. Handle the should-not-happen case of non-string, non-cons. +;; 3. Document NOERROR in doc string. +(defun bookmark-get-bookmark (bookmark &optional noerror) + "Return the bookmark record corresponding to BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +If BOOKMARK is a bookmark record, just return it. +Otherwise look for the corresponding bookmark in `bookmark-alist'. +Return the bookmark found or raise an error if none found. + +If BOOKMARK is a bookmark-name string that has non-nil property +`bmkp-full-record' then return the value of that property. + +Non-nil optional arg NOERROR means return nil if BOOKMARK +is not a valid bookmark - do not raise an error." + (cond ((consp bookmark) bookmark) + ((stringp bookmark) + (let ((full (get-text-property 0 'bmkp-full-record bookmark))) + (or full ; If unpropertized string then punt. + (if (fboundp 'assoc-string) ; Emacs 22+. + (assoc-string bookmark bookmark-alist bookmark-completion-ignore-case) + (assoc bookmark bookmark-alist)) + (unless noerror (error "Invalid bookmark: `%s'" bookmark))))) + (t (unless noerror (error "Invalid bookmark: `%s'" bookmark))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Put the full bookmark on the bookmark name as property `bmkp-full-record'. +;; 2. Use `bmkp-maybe-save-bookmarks'. +;; 3. Return the bookmark. +;; +(defun bookmark-store (bookmark-name data no-overwrite) + "Store the bookmark named BOOKMARK-NAME, giving it DATA. +If NO-OVERWRITE is non-nil and bookmark BOOKMARK-NAME already exists, +then record the new bookmark but do not discard the old one. + +The check for existence uses `bookmark-get-bookmark', so if string +BOOKMARK-NAME has property `bmkp-full-record' then the check is for a +particular bookmark with the given name. If BOOKMARK-NAME does not +have that property then the check is for any bookmark with that name. + +Return the new bookmark." + (bookmark-maybe-load-default-file) + (let ((bname (copy-sequence bookmark-name)) + bmk) + (unless (featurep 'xemacs) + ;; XEmacs's `set-text-properties' doesn't work on free-standing strings, apparently. + (set-text-properties 0 (length bname) () bname)) + (if (and (not no-overwrite) (bookmark-get-bookmark bname 'noerror)) + ;; Existing bookmark under that name and no prefix arg means just overwrite existing. + ;; Use the new (NAME . ALIST) format. + (setcdr (setq bmk (bookmark-get-bookmark bname)) data) + (push (setq bmk (cons bname data)) bookmark-alist) + ;; Put the bookmark on the name as property `bmkp-full-record'. + (when (and (> emacs-major-version 20) ; Emacs 21+. Cannot just use (boundp 'print-circle). + bmkp-propertize-bookmark-names-flag) + (put-text-property 0 (length bname) 'bmkp-full-record bmk bname))) + (bmkp-maybe-save-bookmarks) + (setq bookmark-current-bookmark bname) + (bookmark-bmenu-surreptitiously-rebuild-list) + bmk)) ; Return the bookmark. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; BUG fix: Need bookmark arg in `interactive' spec. +;; +;;;###autoload +(defun bookmark-edit-annotation-mode (bookmark) + "Mode for editing the annotation of bookmark BOOKMARK. +When you have finished composing, type \\[bookmark-send-annotation]. +BOOKMARK is a bookmark name or a bookmark record. + +\\{bookmark-edit-annotation-mode-map}" + (interactive (list (bookmark-completing-read "Edit annotation of bookmark" + (bmkp-default-bookmark-name) + (bmkp-annotated-alist-only)))) + (kill-all-local-variables) + (make-local-variable 'bookmark-annotation-name) + (setq bookmark-annotation-name bookmark) + (use-local-map bookmark-edit-annotation-mode-map) + (setq major-mode 'bookmark-edit-annotation-mode + mode-name "Edit Bookmark Annotation") + (insert (funcall (if (boundp 'bookmark-edit-annotation-text-func) + bookmark-edit-annotation-text-func + bookmark-read-annotation-text-func) + bookmark)) + (let ((annotation (bookmark-get-annotation bookmark))) + (if (and annotation (not (string-equal annotation ""))) + (insert annotation))) + (if (fboundp 'run-mode-hooks) + (run-mode-hooks 'text-mode-hook) + (run-hooks 'text-mode-hook))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. BUG fix: Put point back where it was (on the bookmark just annotated). +;; 2. Refresh menu list, to pick up the `a' marker. +;; 3. Make sure it's the annotation buffer that gets killed. +;; 4. Delete window also, if `misc-cmds.el' loaded. +;; +;;;###autoload +(defun bookmark-send-edited-annotation () + "Use buffer contents as annotation for a bookmark. +Lines beginning with `#' are ignored." + (interactive) + (unless (eq major-mode 'bookmark-edit-annotation-mode) + (error "Not in bookmark-edit-annotation-mode")) + (goto-char (point-min)) + (while (< (point) (point-max)) + (if (looking-at "^#") + (bookmark-kill-line t) + (forward-line 1))) + (let ((annotation (buffer-substring-no-properties (point-min) (point-max))) + (bookmark bookmark-annotation-name) + (annotation-buf (current-buffer))) + (bookmark-set-annotation bookmark annotation) + (setq bookmark-alist-modification-count (1+ bookmark-alist-modification-count)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bookmark))) ; So the `a' marker is displayed (updated). + (if (fboundp 'kill-buffer-and-its-windows) + (kill-buffer-and-its-windows annotation-buf) ; Defined in `misc-cmds.el'. + (kill-buffer annotation-buf)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Added `interactive' spec. +;; +;;;###autoload +(defun bookmark-edit-annotation (bookmark) + "Pop up a buffer for editing bookmark BOOKMARK's annotation. +BOOKMARK is a bookmark name or a bookmark record." + (interactive (list (bookmark-completing-read "Edit annotation of bookmark" + (bmkp-default-bookmark-name) + (bmkp-annotated-alist-only)))) + (pop-to-buffer (generate-new-buffer-name "*Bookmark Annotation Compose*")) + (bookmark-edit-annotation-mode bookmark)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Added optional arg ALIST. +;; +(defun bookmark-all-names (&optional alist) + "Return a list of all bookmark names. +The names are those of the bookmarks in ALIST or, if nil, +`bookmark-alist'." + (bookmark-maybe-load-default-file) + (mapcar (lambda (bmk) (bookmark-name-from-full-record bmk)) (or alist bookmark-alist))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional args ALIST, PRED, and HIST. +;; 2. Define using helper function `bmkp-completing-read-1', +;; which binds `icicle-delete-candidate-object' to (essentially) `bookmark-delete'. +;; +(defun bookmark-completing-read (prompt &optional default alist pred hist) + "Read a bookmark name, prompting with PROMPT. +PROMPT is automatically suffixed with \": \", so do not include that. + +Optional arg DEFAULT is a string to return if the user enters the + empty string. +The alist argument used for completion is ALIST or, if nil, + `bookmark-alist'. +Optional arg PRED is a predicate used for completion. +Optional arg HIST is a history variable for completion. Default is + `bookmark-history'. + +If you access this function from a menu, then, depending on the value +of option `bmkp-menu-popup-max-length' and the number of +bookmarks in ALIST, you choose the bookmark using a menu or using +completion. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate." + (bmkp-completing-read-1 prompt default alist pred hist nil)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Handles also regions and non-file buffers. +;; 2. Do not use NO-CONTEXT or POSN if < Emacs 24. +;; +(defun bookmark-make-record-default (&optional no-file no-context position visits) + "Return the record describing the location of a new bookmark. +Point must be where the bookmark is to be set. + +Non-nil NO-FILE means return only the subset of the record that + pertains to the location within the buffer (not also the file name). + +Non-nil NO-CONTEXT means do not include the front and rear context +strings in the record enough. + +Non-nil POSITION means record it, not point, as the `position' entry. + +Non-nil VISITS means record it as the `visits' entry." + (let* ((dired-p (and (boundp 'dired-buffers) (car (rassq (current-buffer) dired-buffers)))) + (buf (buffer-name)) + (ctime (current-time)) + + ;; Begin `let*' dependencies. + (regionp (and transient-mark-mode mark-active (not (eq (mark) (point))))) + (beg (if regionp (region-beginning) (or position (point)))) + (end (if regionp (region-end) (point))) + (fcs (if regionp + (bmkp-position-post-context-region beg end) + (bmkp-position-post-context beg))) + (rcs (if regionp + (bmkp-position-pre-context-region beg) + (bmkp-position-pre-context beg))) + (fcrs (when regionp (bmkp-end-position-pre-context beg end))) + (ecrs (when regionp (bmkp-end-position-post-context end)))) + `(,@(unless no-file + `((filename . ,(cond ((buffer-file-name) + (bookmark-buffer-file-name)) + (dired-p nil) + (t bmkp-non-file-filename))))) + (buffer-name . ,buf) + ,@(unless (and no-context (> emacs-major-version 23)) + `((front-context-string . ,fcs))) + ,@(unless (and no-context (> emacs-major-version 23)) + `((rear-context-string . ,rcs))) + ,@(unless (and no-context (> emacs-major-version 23)) + `((front-context-region-string . ,fcrs))) + ,@(unless (and no-context (> emacs-major-version 23)) + `((rear-context-region-string . ,ecrs))) + (visits . ,(or visits 0)) + (time . ,ctime) + (created . ,ctime) + (position . ,beg) + (end-position . ,end)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Use `bookmark-make-record'. +;; 2. Use special default prompts for active region, W3M, and Gnus. +;; 3. Use `bmkp-completing-read-lax', choosing from current buffer's bookmarks. +;; 4. Numeric prefix arg (diff from plain): all bookmarks as completion candidates. +;; 5. Prompt for tags if `bmkp-prompt-for-tags-flag' is non-nil. +;; 6. Possibly highlight bookmark and other bookmarks in buffer, per `bmkp-auto-light-when-set'. +;; +;;;###autoload +(defun bookmark-set (&optional name parg interactivep) ; `C-x r m' + "Set a bookmark named NAME, then run `bmkp-after-set-hook'. +If the region is active (`transient-mark-mode') and nonempty, then +record the region limits in the bookmark. + +If NAME is nil, then prompt for the bookmark name. The default name +for prompting is as follows (in order of priority): + + * If the region is active and nonempty, then the buffer name followed + by \": \" and the region prefix (up to + `bmkp-bookmark-name-length-max' chars). + + * If in W3M mode, then the current W3M title. + + * If in a Gnus mode, then the Gnus summary article header. + + * If on a `man' page, then the page name (command and section). + + * Otherwise, the current buffer name. + +While entering a bookmark name at the prompt: + + * You can use (lax) completion against bookmarks in the same buffer. + If there are no bookmarks in the current buffer, then all bookmarks + are completion candidates. (See also below, about a numeric prefix + argument.) + + * You can use `C-w' to yank words from the buffer to the minibuffer. + Repeating `C-w' yanks successive words. + + * You can use `C-u' to insert the name of the last bookmark used in + the buffer. This can be useful as an aid to track your progress + through a large file. (If no bookmark has yet been used, then + `C-u' inserts the name of the visited file.) + +A prefix argument changes the behavior as follows: + + * Numeric prefix arg: Use all bookmarks as completion candidates, + instead of just the bookmarks for the current buffer. + + * Plain prefix arg (`C-u'): Do not overwrite a bookmark that has the + same name as NAME, if such a bookmark already exists. Instead, + push the new bookmark onto the bookmark alist. + + The most recently set bookmark named NAME is thus the one in effect + at any given time, but any others named NAME are still available, + should you decide to delete the most recent one. + +Use `\\[bookmark-delete]' to remove bookmarks (you give it a name, and it removes +only the first instance of a bookmark with that name from the list of +bookmarks)." + (interactive (list nil current-prefix-arg t)) + (bookmark-maybe-load-default-file) + (setq bookmark-current-point (point) ; `bookmark-current-point' is a free var here. + bookmark-current-buffer (current-buffer)) + (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point (point))) + (let* ((record (bookmark-make-record)) + (regionp (and transient-mark-mode mark-active (not (eq (mark) (point))))) + (regname (concat (buffer-name) ": " + (buffer-substring (if regionp (region-beginning) (point)) + (if regionp + (region-end) + (save-excursion (end-of-line) (point)))))) + (defname (bmkp-replace-regexp-in-string + "\n" " " + (cond (regionp (save-excursion (goto-char (region-beginning)) + (skip-chars-forward " ") + (setq bookmark-yank-point (point))) + (substring regname 0 (min bmkp-bookmark-name-length-max + (length regname)))) + ((eq major-mode 'w3m-mode) w3m-current-title) + ((eq major-mode 'gnus-summary-mode) (elt (gnus-summary-article-header) 1)) + ((memq major-mode '(Man-mode woman-mode)) + (buffer-substring (point-min) (save-excursion (goto-char (point-min)) + (skip-syntax-forward "^ ") + (point)))) + (t (car record))))) + (bname (or name (bmkp-completing-read-lax + "Set bookmark " defname + (and (or (not parg) (consp parg)) ; No numeric PARG: all bookmarks. + (bmkp-specific-buffers-alist-only)) + nil 'bookmark-history)))) + (when (string-equal bname "") (setq bname defname)) + (bookmark-store bname (cdr record) (consp parg)) + (when (and interactivep bmkp-prompt-for-tags-flag) + (bmkp-add-tags bname (bmkp-read-tags-completing))) + (case (and (boundp 'bmkp-auto-light-when-set) bmkp-auto-light-when-set) + (autonamed-bookmark (when (bmkp-autonamed-bookmark-p bname) + (bmkp-light-bookmark bname))) + (non-autonamed-bookmark (unless (bmkp-autonamed-bookmark-p bname) + (bmkp-light-bookmark bname))) + (any-bookmark (bmkp-light-bookmark bname)) + (autonamed-in-buffer (bmkp-light-bookmarks (bmkp-remove-if-not + #'bmkp-autonamed-bookmark-p + (bmkp-this-buffer-alist-only)) nil 'MSG)) + (non-autonamed-in-buffer (bmkp-light-bookmarks (bmkp-remove-if + #'bmkp-autonamed-bookmark-p + (bmkp-this-buffer-alist-only)) nil 'MSG)) + (all-in-buffer (bmkp-light-this-buffer nil 'MSG))) + (run-hooks 'bmkp-after-set-hook) + (if bookmark-use-annotations + (bookmark-edit-annotation bname) + (goto-char bookmark-current-point)))) ; `bookmark-current-point' is a free var here. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Prevent adding a newline in a bookmark name when yanking. +;; +;;;###autoload +(defun bookmark-yank-word () ; Bound to `C-w' in minibuffer when setting bookmark. + "Yank the word at point in `bookmark-current-buffer'. +Repeat to yank subsequent words from the buffer, appending them. +Newline characters are stripped out." + (interactive) + (let ((string (with-current-buffer bookmark-current-buffer + (goto-char bookmark-yank-point) + (buffer-substring-no-properties (point) + (progn (forward-word 1) + (setq bookmark-yank-point (point))))))) + (setq string (bmkp-replace-regexp-in-string "\n" "" string)) + (insert string))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Save DISPLAY-FUNCTION to `bmkp-jump-display-function' before calling +;; `bookmark-handle-bookmark'. +;; 2. Update the name and position of an autonamed bookmark, in case it moved. +;; 3. Possibly highlight bookmark and other bookmarks in buffer, per `bmkp-auto-light-when-jump'. +;; 4. Added `catch', so a handler can throw to skip the rest of the processing if it wants. +;; +(defun bookmark--jump-via (bookmark display-function) + "Display BOOKMARK using DISPLAY-FUNCTION. +Then run `bookmark-after-jump-hook' and show annotations for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bmkp-record-visit bookmark 'batch) + (setq bmkp-jump-display-function display-function) + (catch 'bookmark--jump-via + (bookmark-handle-bookmark bookmark) + (let ((win (get-buffer-window (current-buffer) 0))) + (when win (set-window-point win (point)))) + ;; If this is an autonamed bookmark, update its name and position, in case it moved. + ;; But don't do it if we're using w32, since we might not have moved to the bookmark position. + (when (and (bmkp-autonamed-bookmark-for-buffer-p bookmark (buffer-name)) + (not bmkp-use-w32-browser-p)) + (setq bookmark (bmkp-update-autonamed-bookmark bookmark))) + (case (and (boundp 'bmkp-auto-light-when-jump) bmkp-auto-light-when-jump) + (autonamed-bookmark (when (bmkp-autonamed-bookmark-p bookmark) + (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT))) + (non-autonamed-bookmark (unless (bmkp-autonamed-bookmark-p bookmark) + (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT))) + (any-bookmark (bmkp-light-bookmark bookmark nil nil nil 'USE-POINT)) + (autonamed-in-buffer (bmkp-light-bookmarks (bmkp-remove-if-not + #'bmkp-autonamed-bookmark-p + (bmkp-this-buffer-alist-only)) nil 'MSG)) + (non-autonamed-in-buffer (bmkp-light-bookmarks (bmkp-remove-if + #'bmkp-autonamed-bookmark-p + (bmkp-this-buffer-alist-only)) nil 'MSG)) + (all-in-buffer (bmkp-light-this-buffer nil 'MSG))) + (let ((orig-buff (current-buffer))) ; Used by `crosshairs-highlight'. + (run-hooks 'bookmark-after-jump-hook)) + (let ((jump-fn (bmkp-get-tag-value bookmark "bmkp-jump"))) + (when jump-fn (funcall jump-fn))) + (when bookmark-automatically-show-annotations (bookmark-show-annotation bookmark)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Add to beginning, not end, of bookmark record. +;; 2. Do not use `nconc'. +;; 3. Respect both old and new bookmark formats. +;; +(defun bookmark-prop-set (bookmark prop val) + "Set the property PROP of BOOKMARK to VAL." + (let* ((bmk (bookmark-get-bookmark bookmark)) + (cell (assq prop (bookmark-get-bookmark-record bmk)))) + (if cell + (setcdr cell val) + (if (consp (car (cadr bmk))) ; Old format: ("name" ((filename . "f")...)) + (setcdr bmk (list (cons (cons prop val) (cadr bmk)))) + (setcdr bmk (cons (cons prop val) (cdr bmk))))))) ; New: ("name" (filename . "f")...) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg USE-REGION-P. +;; 2. Use `bmkp-default-bookmark-name' as default when interactive. +;; 3. Use `bmkp-jump-1'. +;; 4. Added note about Icicles `S-delete' to doc string. +;; +;;;###autoload +(defun bookmark-jump (bookmark ; Bound to `C-x j j', `C-x r b', `C-x p g' + &optional display-function use-region-p) + "Jump to bookmark BOOKMARK. +You may have a problem using this function if the value of variable +`bookmark-alist' is nil. If that happens, you need to load in some +bookmarks. See function `bookmark-load' for more about this. + +If the file pointed to by BOOKMARK no longer exists, you are asked if +you wish to give the bookmark a new location. If so, `bookmark-jump' +jumps to the new location and saves it. + +If the bookmark defines a region, then the region is activated if +`bmkp-use-region' is not-nil or it is nil and you use a prefix +argument. A prefix arg temporarily flips the value of +`bmkp-use-region'. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate. + +In Lisp code: +BOOKMARK is a bookmark name or a bookmark record. +Non-nil DISPLAY-FUNCTION is a function to display the bookmark. By + default, `switch-to-buffer' is used. +Non-nil USE-REGION-P flips the value of `bmkp-use-region'." + (interactive (list (bookmark-completing-read "Jump to bookmark" (bmkp-default-bookmark-name)) + nil + current-prefix-arg)) + (bmkp-jump-1 bookmark (or display-function 'switch-to-buffer) use-region-p)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg USE-REGION-P. +;; 2. Use `bmkp-default-bookmark-name' as default when interactive. +;; 3. Use `bmkp-jump-1'. +;; +;;;###autoload +(defun bookmark-jump-other-window (bookmark &optional use-region-p) ; `C-x 4 j j', `C-x p o' + "Jump to bookmark BOOKMARK in another window. +See `bookmark-jump', in particular for info about using a prefix arg." + (interactive (list (bookmark-completing-read "Jump to bookmark (in another window)" + (bmkp-default-bookmark-name)) + current-prefix-arg)) + (bmkp-jump-1 bookmark 'bmkp-select-buffer-other-window use-region-p)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Different relocation message for non-file bookmark. +;; +(defun bookmark-handle-bookmark (bookmark) + "Call BOOKMARK's handler, or `bookmark-default-handler' if it has none. +The default handler changes the current buffer and point. +BOOKMARK is a bookmark name or a bookmark record. +Returns nil or raises an error. + +If the default handler is used and a file error is raised, the error +is handled as follows: + If BOOKMARK has no `filename' entry, do nothing. + Else prompt to relocate the file. + If relocated, then try again to handle. Else raise a file error." + (if (bookmark-get-handler bookmark) + (funcall (bookmark-get-handler bookmark) (bookmark-get-bookmark bookmark)) + (condition-case err + (funcall 'bookmark-default-handler (bookmark-get-bookmark bookmark)) + (bookmark-error-no-filename ; `file-error' + ;; BOOKMARK can be either a bookmark name or a bookmark record. + ;; If a record, do nothing - assume it is a bookmark used internally by some other package. + (when (stringp bookmark) + (let ((file (bookmark-get-filename bookmark)) + (use-dialog-box nil) + (use-file-dialog nil)) + (when file + ;; Ask user whether to relocate the file. If no, signal the file error. + (unless (string= file bmkp-non-file-filename) (setq file (expand-file-name file))) + (ding) + (cond ((y-or-n-p (if (and (string= file bmkp-non-file-filename) + (bmkp-get-buffer-name bookmark)) + "Bookmark's buffer does not exist. Re-create it? " + (concat (file-name-nondirectory file) " nonexistent. Relocate \"" + bookmark "\"? "))) + (if (string= file bmkp-non-file-filename) + ;; This is probably not the right way to get the correct buffer, but it's + ;; better than nothing, and it gives the user a chance to DTRT. + (pop-to-buffer (bmkp-get-buffer-name bookmark)) ; Create buffer. + (bookmark-relocate bookmark)) ; Relocate to file. + (funcall (or (bookmark-get-handler bookmark) 'bookmark-default-handler) + (bookmark-get-bookmark bookmark))) ; Try again + (t + (message "Bookmark not relocated: `%s'" bookmark) + (signal (car err) (cdr err)))))))))) + (when (stringp bookmark) (setq bookmark-current-bookmark bookmark)) + ;; $$$$$$ The vanilla code returns nil, but there is no explanation of why and no code seems + ;; to use the return value. Perhaps we should return the bookmark instead? + nil) ; Return nil if no error. + +(put 'bookmark-error-no-filename 'error-conditions + '(error bookmark-errors bookmark-error-no-filename)) +(put 'bookmark-error-no-filename 'error-message "Bookmark has no associated file (or directory)") + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Support regions and buffer names. +;; 2. Handles w32 `Open' command if `bmkp-use-w32-browser-p' and if `w32-browser' is defined. +;; +(defun bookmark-default-handler (bookmark) + "Default handler to jump to the location of BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +If BOOKMARK records a nonempty region, and `bmkp-use-region' is + non-nil, then activate the region. + +Non-nil `bmkp-use-w32-browser-p' means just call `w32-browser' + (if defined). That is, use the default MS Windows application for + the bookmarked file. + +Return nil or signal `file-error'." + (let* ((bmk (bookmark-get-bookmark bookmark)) + (file (bookmark-get-filename bmk)) + (buf (bookmark-prop-get bmk 'buffer)) + (bufname (bmkp-get-buffer-name bmk)) + (pos (bookmark-get-position bmk)) + (end-pos (bmkp-get-end-position bmk)) + (old-info-node (and (not (bookmark-get-handler bookmark)) + (bookmark-prop-get bmk 'info-node)))) + (if (and bmkp-use-w32-browser-p (fboundp 'w32-browser) file) + (w32-browser file) + (if old-info-node ; Emacs 20-21 Info bookmarks - no handler entry. + (progn (require 'info) (Info-find-node file old-info-node) (goto-char pos)) + (if (not (and bmkp-use-region end-pos (/= pos end-pos))) + ;; Single-position bookmark (no region). Go to it. + (bmkp-goto-position bmk file buf bufname pos + (bookmark-get-front-context-string bmk) + (bookmark-get-rear-context-string bmk)) + ;; Bookmark with a region. Go to it and activate the region. + (if (and file (file-readable-p file) (not (buffer-live-p buf))) + (with-current-buffer (find-file-noselect file) (setq buf (buffer-name))) + ;; No file found. If no buffer either, then signal that file doesn't exist. + (unless (or (and buf (get-buffer buf)) + (and bufname (get-buffer bufname) (not (string= buf bufname)))) + (signal 'bookmark-error-no-filename (list 'stringp file)))) + (set-buffer (or buf bufname)) + (when bmkp-jump-display-function + (save-current-buffer (funcall bmkp-jump-display-function (current-buffer))) + (raise-frame)) + (goto-char (min pos (point-max))) + (when (> pos (point-max)) (error "Bookmark position is beyond buffer end")) + ;; Activate region. Relocate it if it moved. Save relocated bookmark if confirm. + (funcall bmkp-handle-region-function bmk)))) + ;; $$$$$$ The vanilla code returns nil, but there is no explanation of why and no code seems + ;; to use the return value. Perhaps we should return the bookmark instead? + nil)) ; Return nil if no file error. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added bookmark default for interactive use. +;; 2. Added note about `S-delete' to doc string. +;; 3. Changed arg name: BOOKMARK -> BOOKMARK-NAME. +;; 4. Refresh menu list, to show new location. +;; +(or (fboundp 'old-bookmark-relocate) +(fset 'old-bookmark-relocate (symbol-function 'bookmark-relocate))) + +;;;###autoload +(defun bookmark-relocate (bookmark-name) ; Not bound + "Relocate the bookmark named BOOKMARK-NAME to another file. +You are prompted for the new file name. +Changes the file associated with the bookmark. +Useful when a file has been renamed after a bookmark was set in it. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate." + (interactive (list (bookmark-completing-read "Bookmark to relocate" + (bmkp-default-bookmark-name)))) + (old-bookmark-relocate bookmark-name) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0) + bookmark-bmenu-toggle-filenames) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bookmark-name)))) ; So the new location is displayed. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added bookmark default for interactive use. +;; 2. Do not add any text properties here. That's done in `bmkp-bmenu-propertize-item'. +;; 3. Added note about `S-delete' to doc string. +;; 4. Changed arg name: BOOKMARK -> BOOKMARK-NAME. +;; +;;;###autoload +(defun bookmark-insert-location (bookmark-name &optional no-history) ; `C-x p I' (original: `C-x p f') + "Insert file or buffer name for the bookmark named BOOKMARK-NAME. +If a file is bookmarked, insert the recorded file name. +If a non-file buffer is bookmarked, insert the recorded buffer name. + +Optional second arg NO-HISTORY means do not record this in the +minibuffer history list `bookmark-history'. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate." + (interactive + (let ((bmk (bookmark-completing-read "Insert bookmark location" (bmkp-default-bookmark-name)))) + (if (> emacs-major-version 21) (list bmk) bmk))) + (or no-history (bookmark-maybe-historicize-string bookmark-name)) + (insert (bookmark-location bookmark-name))) ; Return the line inserted. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Pass full bookmark to the various "get" functions. +;; 2. Location returned can be a buffer name, instead of a file name. +;; +(defun bookmark-location (bookmark) + "Return the name of the file or buffer associated with BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Return \"-- Unknown location --\" if no such name can be found." + (bookmark-maybe-load-default-file) + (setq bookmark (bookmark-get-bookmark bookmark)) ; Possibly from the propertized string. + (or (bookmark-prop-get bookmark 'location) + (bookmark-get-filename bookmark) + (bmkp-get-buffer-name bookmark) + (bookmark-prop-get bookmark 'buffer) + "-- Unknown location --")) + ;; $$$$$$$$$ "")) + ;; $$$$ (error "Bookmark has no file or buffer name: %S" bookmark))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added bookmark default for interactive use. +;; 2. Added note about `S-delete' to doc string. +;; 3. Added BATCH arg. +;; 4. Put `bmkp-full-record' property on new name. +;; 5. Refresh menu list, to show new name. +;; +;;;###autoload +(defun bookmark-rename (old &optional new batch) ; Bound to `C-x p r' + "Change bookmark's name from OLD to NEW. +Interactively: + If called from the keyboard, then prompt for OLD. + If called from the menubar, select OLD from a menu. +If NEW is nil, then prompt for its string value. + +If BATCH is non-nil, then do not rebuild the bookmark list. + +While the user enters the new name, repeated `C-w' inserts consecutive +words from the buffer into the new bookmark name. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate." + (interactive (list (bookmark-completing-read "Old bookmark name" + (bmkp-default-bookmark-name)))) + (bookmark-maybe-historicize-string old) + (bookmark-maybe-load-default-file) + (setq bookmark-current-point (point)) ; `bookmark-current-point' is a free var here. + (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point (point))) + (setq bookmark-current-buffer (current-buffer)) + (let ((newname (or new (read-from-minibuffer "New name: " nil + (let ((now-map (copy-keymap minibuffer-local-map))) + (define-key now-map "\C-w" 'bookmark-yank-word) + now-map) + nil 'bookmark-history)))) + (bookmark-set-name old newname) + (when (and (> emacs-major-version 20) ; Emacs 21+. Cannot just use (boundp 'print-circle). + bmkp-propertize-bookmark-names-flag) + (put-text-property 0 (length newname) 'bmkp-full-record (bookmark-get-bookmark newname) newname)) + (setq bookmark-current-bookmark newname) + (unless batch + (bookmark-bmenu-surreptitiously-rebuild-list) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list newname)))) ; So the new name is displayed. + (bmkp-maybe-save-bookmarks) + newname)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added bookmark default for interactive use. +;; 2. Added note about `S-delete' to doc string. +;; 3. Changed arg name: BOOKMARK -> BOOKMARK-NAME. +;; +(or (fboundp 'old-bookmark-insert) +(fset 'old-bookmark-insert (symbol-function 'bookmark-insert))) + +;;;###autoload +(defun bookmark-insert (bookmark-name) ; Bound to `C-x p i' + "Insert the text of a bookmarked file. +BOOKMARK-NAME is the name of the bookmark. +You may have a problem using this function if the value of variable +`bookmark-alist' is nil. If that happens, you need to load in some +bookmarks. See function `bookmark-load' for more about this. + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate." + (interactive (list (bookmark-completing-read "Insert bookmark contents" + (bmkp-default-bookmark-name)))) + (old-bookmark-insert bookmark-name)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Accept a bookmark or a bookmark name as arg. +;; 2. Use `bmkp-default-bookmark-name' as default when interactive. +;; 3. If it is a name and it has property `bmkp-full-record' then use that to find the bookmark to delete. +;; 4. Remove highlighting for the bookmark. +;; 5. Doc string includes note about `S-delete' for Icicles. +;; 6. Update `bmkp-latest-bookmark-alist' and `bmkp-bmenu-omitted-bookmarks'. +;; 7. Increment `bookmark-alist-modification-count' even when using `batch' arg. +;; +;;;###autoload +(defun bookmark-delete (bookmark &optional batch) ; Bound to `C-x p d' + "Delete the BOOKMARK from the bookmark list. +BOOKMARK is a bookmark name or a bookmark record. +Interactively, default to the \"current\" bookmark (that is, the one +most recently used in this file), if it exists. + +If BOOKMARK is a name and it has property `bmkp-full-record' then use +that property along with the name to find the bookmark to delete. +If it is a name without property `bmkp-full-record' then delete (only) +the first bookmark in `bookmark-alist' with that name. + +Optional second arg BATCH means do not update the bookmark list buffer +\(probably because we were called from there). + +If you use Icicles, then you can use `S-delete' during completion of a +bookmark name to delete the bookmark named by the current completion +candidate. In this way, you can delete multiple bookmarks." + (interactive + (list (bookmark-completing-read "Delete bookmark" (bmkp-default-bookmark-name)))) + ;; $$$$$$ Instead of loading unconditionally, maybe we should just try to delete conditionally? + ;; IOW, why not (when bookmarks-already-loaded BODY) instead of `bookmark-maybe-load-default-file'? + ;; If it gets called on a hook that gets run before ever loading, then should probably do nothing. + ;; Leaving it as is for now (2011-04-06). + (bookmark-maybe-load-default-file) + (let* ((bmk (bookmark-get-bookmark bookmark 'NOERROR)) + (bname (and (bookmark-name-from-full-record bmk)))) ; BOOKMARK might have been a bookmark. + (when bname ; Do nothing if BOOKMARK does not represent a bookmark. + (bookmark-maybe-historicize-string bname) + (when (fboundp 'bmkp-unlight-bookmark) (bmkp-unlight-bookmark bmk 'NOERROR)) + (setq bookmark-alist (delq bmk bookmark-alist) + bmkp-latest-bookmark-alist (delq bmk bmkp-latest-bookmark-alist) + bmkp-bmenu-omitted-bookmarks (bmkp-delete-bookmark-name-from-list + bname bmkp-bmenu-omitted-bookmarks)) + ;; Added by DB. `bookmark-current-bookmark' should be nil if last occurrence was deleted. + (unless (bookmark-get-bookmark bookmark-current-bookmark 'noerror) + (setq bookmark-current-bookmark nil)) + ;; Do not rebuild the list when using `batch' arg + (unless batch (bookmark-bmenu-surreptitiously-rebuild-list)) + (bmkp-maybe-save-bookmarks)))) + + +;;; ;; REPLACES ORIGINAL in `bookmark.el'. +;;; ;; +;;; ;; 1. Changed arg name: BOOKMARK -> BOOKMARK-NAME. +;;; ;; 2. If BOOKMARK-NAME has property `bmkp-full-record' then use that to find the bookmark to delete. +;;; ;; 3. Remove highlighting for the bookmark. +;;; ;; 4. Added note about `S-delete' to doc string. +;;; ;; 5. Use `bmkp-default-bookmark-name' as default when interactive. +;;; ;; 6. Update `bmkp-latest-bookmark-alist' and `bmkp-bmenu-omitted-bookmarks'. +;;; ;; 7. Increment `bookmark-alist-modification-count' even when using `batch' arg. +;;; ;; +;;; $$$$$$$ +;;; (defun bookmark-delete (bookmark-name &optional batch) ; Bound to `C-x p d' +;;; "Delete the bookmark named BOOKMARK-NAME from the bookmark list. +;;; Removes only the first instance of a bookmark with that name. +;;; If there are other bookmarks with the same name, they are not deleted. +;;; Defaults to the \"current\" bookmark (that is, the one most recently +;;; used in this file), if it exists. Optional second arg BATCH means do +;;; not update the bookmark list buffer (probably because we were called +;;; from there). + +;;; If BOOKMARK-NAME has property `bmkp-full-record' then that is used +;;; along with the name to find the first matching bookmark to delete. + +;;; If you use Icicles, then you can use `S-delete' during completion of a +;;; bookmark name to delete the bookmark named by the current completion +;;; candidate. In this way, you can delete multiple bookmarks." +;;; (interactive +;;; (list (bookmark-completing-read "Delete bookmark" (bmkp-default-bookmark-name)))) +;;; (bookmark-maybe-historicize-string bookmark-name) +;;; ;; $$$$$$ Instead of loading unconditionally, maybe we should just try to delete conditionally? +;;; ;; IOW, why not (when bookmarks-already-loaded BODY) instead of `bookmark-maybe-load-default-file'? +;;; ;; If it gets called on a hook that gets run before ever loading, then should probably do nothing. +;;; ;; Leaving it as is for now (2011-04-06). +;;; (bookmark-maybe-load-default-file) +;;; (let ((bmk (bookmark-get-bookmark bookmark-name 'NOERROR))) +;;; (when (fboundp 'bmkp-unlight-bookmark) (bmkp-unlight-bookmark bmk 'NOERROR)) +;;; (setq bookmark-alist (delq bmk bookmark-alist) +;;; bmkp-latest-bookmark-alist (delq bmk bmkp-latest-bookmark-alist) +;;; bmkp-bmenu-omitted-bookmarks (bmkp-delete-bookmark-name-from-list +;;; bookmark-name bmkp-bmenu-omitted-bookmarks))) +;;; ;; Added by DB. `bookmark-current-bookmark' should be nil if last occurrence was deleted. +;;; (unless (bookmark-get-bookmark bookmark-current-bookmark 'noerror) +;;; (setq bookmark-current-bookmark nil)) +;;; ;; Do not rebuild the list when using `batch' arg +;;; (unless batch (bookmark-bmenu-surreptitiously-rebuild-list)) +;;; (bmkp-maybe-save-bookmarks)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Use `bmkp-current-bookmark-file', not `bookmark-default-file'. +;; +;;;###autoload +(defun bookmark-save (&optional parg file) ; Bound to `C-x p s' + "Save currently defined bookmarks. +Save by default in the file named by variable +`bmkp-current-bookmark-file'. With a prefix arg, you are prompted for +the file to save to. + +To load bookmarks from a specific file, use `\\[bookmark-load]' +\(`bookmark-load'). + +If called from Lisp: + Witn nil PARG, use file `bmkp-current-bookmark-file'. + With non-nil PARG and non-nil FILE, use file FILE. + With non-nil PARG and nil FILE, prompt the user for the file to use." + (interactive "P") + (bookmark-maybe-load-default-file) + (cond ((and (not parg) (not file)) (bookmark-write-file bmkp-current-bookmark-file)) + ((and (not parg) file) (bookmark-write-file file)) + ((and parg (not file)) + (bookmark-write-file (bmkp-read-bookmark-file-name "File to save bookmarks in: "))) + (t (bookmark-write-file file))) + ;; Indicate by the count that we have synced the current bookmark file. + ;; If an error has already occurred somewhere, the count will not be set, which is what we want. + (setq bookmark-alist-modification-count 0)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg ALT-MSG. +;; 2. Insert code piecewise, to improve performance when saving `bookmark-alist'. +;; (Do not let `pp' parse all of `bookmark-alist' at once.) +;; 3. Unless `bmkp-propertize-bookmark-names-flag', remove text properties from bookmark name and file name. +;; 4. Bind `print-circle' to t around pp, to record bookmark name with `bmkp-full-record' property. +;; 4. Use `case', not `cond'. +;; +(defun bookmark-write-file (file &optional alt-msg) + "Write `bookmark-alist' to FILE. +Non-nil ALT-MSG is a message format string to use in place of the +default, \"Saving bookmarks to file `%s'...\". The string must +contain a `%s' construct, so that it can be passed along with FILE to +`format'. At the end, \"done\" is appended to the message." + (let ((msg (or alt-msg "Saving bookmarks to file `%s'..." file))) + (bookmark-maybe-message (or alt-msg "Saving bookmarks to file `%s'...") file) + (with-current-buffer (get-buffer-create " *Bookmarks*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil) + bname fname last-fname) + (bookmark-insert-file-format-version-stamp) + (insert "(") + (dolist (bmk bookmark-alist) + (setq bname (car bmk) + fname (bookmark-get-filename bmk)) + (when (or (not (> emacs-major-version 20)) ; Emacs 20. Cannot use (not (boundp 'print-circle)). + (not bmkp-propertize-bookmark-names-flag)) + (set-text-properties 0 (length bname) () bname) + (when fname (set-text-properties 0 (length fname) () fname))) + (setcar bmk bname) + (when (setq last-fname (assq 'filename bmk)) (setcdr last-fname fname)) + (let ((print-circle t)) (pp bmk (current-buffer)))) + (insert ")") + (let ((version-control (case bookmark-version-control + ((nil) nil) + (never 'never) + (nospecial version-control) + (t t)))) + (condition-case nil + (write-region (point-min) (point-max) file) + (file-error (message "Cannot write file `%s'" file))) + (kill-buffer (current-buffer)) + (bookmark-maybe-message (concat msg "done") file)))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg means OVERWRITE. +;; 2. Update `bmkp-current-bookmark-file' if OVERWRITE is non-nil. +;; 3. New doc string. +;; 4. Final msg says whether overwritten. +;; 5. Call `bmkp-bmenu-refresh-menu-list' at end. +;; +;;;###autoload +(defun bookmark-load (file &optional overwrite no-msg) ; Bound to `C-x p l' + "Load bookmarks from FILE (which must be in the standard format). +Without a prefix argument (argument OVERWRITE is nil), add the newly +loaded bookmarks to those already current. They will be saved to the +current bookmark file when bookmarks are saved. If you have never +switched bookmark files, then this is the default file, +`bookmark-default-file'. + +If you do not use a prefix argument, then no existing bookmarks are +overwritten. If you load some bookmarks that have the same names as +bookmarks already defined in your Emacs session, numeric suffixes +\"<2>\", \"<3>\",... are appended as needed to the names of those new +bookmarks to distinguish them. + +With a prefix argument, switch the bookmark file currently used, +*replacing* all currently existing bookmarks with the newly loaded +bookmarks. The value of `bmkp-current-bookmark-file' is changed to +FILE, so bookmarks will subsequently be saved to FILE. The value +`bookmark-default-file' is unaffected, so your next Emacs session will +still use the same default set of bookmarks. + +When called from Lisp, non-nil NO-MSG means do not display any +messages while loading. + +You do not need to manually load your default bookmark file +\(`bookmark-default-file') - it is loaded automatically by Emacs the +first time you use bookmarks in a session. Use `bookmark-load' only +to load extra bookmarks (with no prefix arg) or an alternative set of +bookmarks (with a prefix arg). + +If you use `bookmark-load' to load a file that does not contain a +proper bookmark alist, then when bookmarks are saved the current +bookmark file will likely become corrupted. You should load only +bookmark files that were created using the bookmark functions." + (interactive + (list (let ((bfile (if (bmkp-same-file-p bmkp-current-bookmark-file bmkp-last-bookmark-file) + bookmark-default-file + bmkp-last-bookmark-file))) + (bmkp-read-bookmark-file-name + (if current-prefix-arg "Switch to bookmark file: " "Add bookmarks from file: ") + (or (file-name-directory bfile) "~/") + bfile + 'CONFIRM)) + current-prefix-arg)) + (setq file (abbreviate-file-name (expand-file-name file))) + (unless (file-readable-p file) (error "Cannot read bookmark file `%s'" file)) + (unless no-msg (bookmark-maybe-message "Loading bookmarks from `%s'..." file)) + (with-current-buffer (let ((enable-local-variables nil)) (find-file-noselect file)) + (goto-char (point-min)) + (bookmark-maybe-upgrade-file-format) + (let ((blist (bookmark-alist-from-buffer))) + (unless (listp blist) (error "Invalid bookmark list in `%s'" file)) + (if overwrite + (setq bmkp-last-bookmark-file bmkp-current-bookmark-file + bmkp-current-bookmark-file file + bookmark-alist blist + bookmark-alist-modification-count 0) + (bookmark-import-new-list blist) + (setq bookmark-alist-modification-count (1+ bookmark-alist-modification-count))) + (when (string-equal (abbreviate-file-name (expand-file-name bookmark-default-file)) file) + (setq bookmarks-already-loaded t)) + (bookmark-bmenu-surreptitiously-rebuild-list)) + (kill-buffer (current-buffer))) + (unless no-msg (message "%s bookmark file `%s'" (if overwrite "Switched to" "Loaded") file)) + (let ((bmklistbuf (get-buffer "*Bookmark List*"))) + (when bmklistbuf (with-current-buffer bmklistbuf (bmkp-bmenu-refresh-menu-list))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg MSGP. Show message if no annotation. +;; 2. Name buffer after the bookmark. +;; 3. MSGP means message if no annotation. +;; 4. Use `view-mode'. `q' uses `quit-window'. +;; 5. Fit frame to buffer if `one-windowp'. +;; 6. Restore frame selection. +;; +(defun bookmark-show-annotation (bookmark &optional msgp) + "Display the annotation for BOOKMARK. +If no annotation and MSGP is non-nil, show a no-annotation message." + (let* ((bmk (bookmark-get-bookmark bookmark)) + (bmk-name (bookmark-name-from-full-record bmk)) + (ann (bookmark-get-annotation bmk))) + (if (not (and ann (not (string-equal ann "")))) + (when msgp (message "Bookmark has no annotation")) + (let ((oframe (selected-frame))) + (save-selected-window + (pop-to-buffer (get-buffer-create (format "*`%s' Annotation*" bmk-name))) + (let ((buffer-read-only nil)) ; Because buffer might already exist, in view mode. + (delete-region (point-min) (point-max)) + (insert (concat "Annotation for bookmark '" bmk-name "':\n\n")) + (put-text-property (line-beginning-position -1) (line-end-position 1) + 'face 'bmkp-heading) + (insert ann)) + (goto-char (point-min)) + (view-mode-enter (cons (selected-window) (cons nil 'quit-window))) + (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window))) + (select-frame-set-input-focus oframe))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Use name `*Bookmark Annotations*', not `*Bookmark Annotation*'. +;; 2. Don't list bookmarks that have no annotation. +;; 3. Highlight bookmark names. Don't indent annotations. Add a blank line after each annotation. +;; 4. Use `view-mode'. `q' uses `quit-window'. +;; 5. Fit frame to buffer if `one-windowp'. +;; 6. Restore frame selection. +;; +(defun bookmark-show-all-annotations () + "Display the annotations for all bookmarks." + (let ((oframe (selected-frame))) + (save-selected-window + (pop-to-buffer (get-buffer-create "*Bookmark Annotations*")) + (let ((buffer-read-only nil)) ; Because buffer might already exist, in view mode. + (delete-region (point-min) (point-max)) + (dolist (full-record bookmark-alist) ; (Could use `bmkp-annotated-alist-only' here instead.) + (let ((ann (bookmark-get-annotation full-record))) + (when (and ann (not (string-equal ann ""))) + (insert (concat (bookmark-name-from-full-record full-record) ":\n")) + (put-text-property (line-beginning-position 0) (line-end-position 0) + 'face 'bmkp-heading) + (insert ann) (unless (bolp) (insert "\n\n"))))) + (goto-char (point-min)) + (view-mode-enter (cons (selected-window) (cons nil 'quit-window))) + (when (fboundp 'fit-frame-if-one-window) (fit-frame-if-one-window)))) + (select-frame-set-input-focus oframe))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Save menu-list state to `bmkp-bmenu-state-file'. +;; +(defun bookmark-exit-hook-internal () ; This goes on `kill-emacs-hook'. + "Save currently defined bookmarks and perhaps bookmark menu-list state. +Run `bookmark-exit-hook', then save bookmarks if they were updated. +Then save menu-list state to file `bmkp-bmenu-state-file', but only if +that option is non-nil." + (run-hooks 'bookmark-exit-hook) + (when (and bookmark-alist (bookmark-time-to-save-p t)) (bookmark-save)) + (bmkp-save-menu-list-state)) + +;;(@* "Bookmark+ Functions (`bmkp-*')") +;;; Bookmark+ Functions (`bmkp-*') ----------------------------------- + +(defun bmkp-completing-read-lax (prompt &optional default alist pred hist) + "Read a bookmark name, prompting with PROMPT. +Same as `bookmark-completing-read', but completion is lax." + (unwind-protect + (progn (define-key minibuffer-local-completion-map "\C-w" 'bookmark-yank-word) + (define-key minibuffer-local-completion-map "\C-u" 'bookmark-insert-current-bookmark) + (bmkp-completing-read-1 prompt default alist pred hist t)) + (define-key minibuffer-local-completion-map "\C-w" nil) + (define-key minibuffer-local-completion-map "\C-u" nil))) + +(defun bmkp-completing-read-1 (prompt default alist pred hist laxp) + "Helper for `bookmark-completing-read(-lax)'. +LAXP non-nil means use lax completion." + (bookmark-maybe-load-default-file) + (setq alist (or alist bookmark-alist)) + (if (and (not laxp) + (listp last-nonmenu-event) + (or (eq t bmkp-menu-popup-max-length) + (and (integerp bmkp-menu-popup-max-length) + (< (length alist) bmkp-menu-popup-max-length)))) + (bookmark-menu-popup-paned-menu + t prompt + (if bmkp-sort-comparer ; Test whether to sort, but always use `string-lessp'. + (sort (bookmark-all-names alist) 'string-lessp) + (bookmark-all-names alist))) + (let* ((icicle-delete-candidate-object (lambda (cand) ; For `S-delete' in Icicles. + (bookmark-delete + (icicle-transform-multi-completion cand)))) + (completion-ignore-case bookmark-completion-ignore-case) + (default default) + (prompt (if default + (concat prompt (format " (%s): " default)) + (concat prompt ": "))) + (str (completing-read + prompt alist pred (not laxp) nil + (or hist 'bookmark-history) default))) + (if (and (string-equal "" str) default) default str)))) + +(defun bmkp-jump-1 (bookmark display-function use-region-p) + "Helper function for `bookmark-jump' commands. +BOOKMARK is a bookmark name (a string) or a bookmark record. +DISPLAY-FUNCTION is passed to `bookmark--jump-via'. +Non-nil USE-REGION-P means activate the region, if recorded." + (setq bookmark (bookmark-get-bookmark bookmark 'NOERROR)) + (unless bookmark (error "No bookmark specified")) + (bookmark-maybe-historicize-string (bookmark-name-from-full-record bookmark)) + (let ((bmkp-use-region (if use-region-p (not bmkp-use-region) bmkp-use-region))) + (bookmark--jump-via bookmark display-function))) + +(defun bmkp-select-buffer-other-window (buffer) + "Select BUFFER in another window. +If `bmkp-other-window-pop-to-flag' is non-nil, then use +`pop-to-buffer'. Otherwise, use `switch-to-buffer-other-window'." + (if bmkp-other-window-pop-to-flag + (pop-to-buffer buffer t) + (switch-to-buffer-other-window buffer))) + +(defun bmkp-maybe-save-bookmarks () + "Increment save counter and maybe save `bookmark-alist'." + (setq bookmark-alist-modification-count (1+ bookmark-alist-modification-count)) + (when (bookmark-time-to-save-p) (bookmark-save))) + +;;;###autoload +(defun bmkp-edit-bookmark (bookmark &optional internalp) ; Bound to `C-x p E' + "Edit BOOKMARK's name and file name, and maybe save them. +BOOKMARK is a bookmark name (a string) or a bookmark record. +With a prefix argument, edit the complete bookmark record (the +internal, Lisp form). +Return a list of the new bookmark name and new file name." + (interactive + (list (bookmark-completing-read + (concat "Edit " (and current-prefix-arg "internal record for ") "bookmark") + (bmkp-default-bookmark-name)) + current-prefix-arg)) + (setq bookmark (bookmark-get-bookmark bookmark)) + (if internalp + (bmkp-edit-bookmark-record bookmark) + (let* ((bookmark-name (bookmark-name-from-full-record bookmark)) + (bookmark-filename (bookmark-get-filename bookmark-name)) + (new-bmk-name (read-from-minibuffer "New bookmark name: " nil nil nil nil + bookmark-name)) + (new-filename (read-from-minibuffer "New file name (location): " nil nil nil nil + bookmark-filename))) + (when (and (or (not (equal new-bmk-name "")) (not (equal new-filename ""))) + (y-or-n-p "Save changes? ")) + (bookmark-rename bookmark-name new-bmk-name 'batch) + (bookmark-set-filename new-bmk-name new-filename) + ;; Change location for Dired too, but not if different from original file name (e.g. a cons). + (let ((dired-dir (bookmark-prop-get new-bmk-name 'dired-directory))) + (when (and dired-dir (equal dired-dir bookmark-filename)) + (bookmark-prop-set new-bmk-name 'dired-directory new-filename))) + (bmkp-maybe-save-bookmarks) + (list new-bmk-name new-filename))))) + +(define-derived-mode bmkp-edit-bookmark-record-mode emacs-lisp-mode + "Edit Bookmark Record" + "Mode for editing an internal bookmark record. +When you have finished composing, type \\[bmkp-edit-bookmark-record-send]." + :group 'bookmark-plus) + +;; This binding must be defined *after* the mode, so `bmkp-edit-bookmark-record-mode-map' is defined. +;; (Alternatively, we could use a `defvar' to define `bmkp-edit-bookmark-record-mode-map' before +;; calling `define-derived-mode'.) +(define-key bmkp-edit-bookmark-record-mode-map "\C-c\C-c" 'bmkp-edit-bookmark-record-send) + +;;;###autoload +(defun bmkp-edit-bookmark-record (bookmark) + "Edit the internal record for bookmark BOOKMARK. +When you have finished, Use `\\[bmkp-edit-bookmark-record-send]'. +BOOKMARK is a bookmark name (a string) or a bookmark record." + (interactive (list (bookmark-completing-read "Edit internal record for bookmark" + (bmkp-default-bookmark-name)))) + (setq bookmark (bookmark-get-bookmark bookmark)) + (let* ((bmk-name (bookmark-name-from-full-record bookmark)) + (bufname (format "*Edit Bookmark `%s'*" bmk-name))) + (with-output-to-temp-buffer bufname + (princ + (substitute-command-keys + (concat ";; Edit the internal record for bookmark\n;;\n" + ";; " bmk-name "\n;;\n" + ";; Type \\\ +`\\[bmkp-edit-bookmark-record-send]' when done.\n;;\n" + ";; NOTE: If you edit the bookmark *name* within the record, then\n" + ";; a new bookmark is created for the new name, and the\n" + ";; original (unedited) bookmark continues to exist as well.\n\n"))) + (let ((print-circle t)) (pp bookmark)) + (goto-char (point-min))) + (pop-to-buffer bufname) + (buffer-enable-undo) + (with-current-buffer (get-buffer bufname) (bmkp-edit-bookmark-record-mode)))) + +;;;###autoload +(defun bmkp-edit-bookmark-record-send (arg &optional force) + "Use buffer contents as a bookmark record. +Lines beginning with `;;' are ignored. +With a prefix argument, do not update `time' or `visits' entries." + (interactive "P") + (unless (eq major-mode 'bmkp-edit-bookmark-record-mode) + (error "Not in `bmkp-edit-bookmark-record-mode'")) + (goto-char (point-min)) + (let ((bmk (read (current-buffer)))) + (when (or force (bmkp-bookmark-type bmk) ; Must pass BMK, not BMK-NAME, since might be renamed. + (and (interactive-p) + (or (y-or-n-p "Bookmard record not recognized as valid. Save anyway? ") + (error "Canceled")))) + (unless arg (bmkp-record-visit bmk t)) + (bookmark-store (bookmark-name-from-full-record bmk) (bookmark-get-bookmark-record bmk) nil) + (when (interactive-p) (message "Updated bookmark file")))) + (kill-buffer (current-buffer))) + +(define-derived-mode bmkp-edit-tags-mode emacs-lisp-mode + "Edit Bookmark Tags" + "Mode for editing bookmark tags. +When you have finished composing, type \\[bmkp-edit-tags-send]." + :group 'bookmark-plus) + +;; This binding must be defined *after* the mode, so `bmkp-edit-tags-mode-map' is defined. +;; (Alternatively, we could use a `defvar' to define `bmkp-edit-tags-mode-map' before +;; calling `define-derived-mode'.) +(define-key bmkp-edit-tags-mode-map "\C-c\C-c" 'bmkp-edit-tags-send) + +;;;###autoload +(defun bmkp-edit-tags (bookmark) ; Bound to `C-x p t e' + "Edit BOOKMARK's tags, and maybe save the result. +The edited value must be a list each of whose elements is either a + string or a cons whose key is a string. +BOOKMARK is a bookmark name (a string) or a bookmark record." + (interactive (list (bookmark-completing-read "Edit tags for bookmark" (bmkp-default-bookmark-name)))) + (setq bookmark (bookmark-get-bookmark bookmark)) + (let* ((btags (bmkp-get-tags bookmark)) + (bmkname (bookmark-name-from-full-record bookmark)) + (edbuf (format "*Edit Tags for Bookmark `%s'*" bmkname))) + (setq bmkp-return-buffer (current-buffer)) + (with-output-to-temp-buffer edbuf + (princ + (substitute-command-keys + (concat ";; Edit tags for bookmark\n;;\n;; \"" bmkname "\"\n;;\n" + ";; The edited value must be a list each of whose elements is\n" + ";; either a string or a cons whose key is a string.\n;;\n" + ";; DO NOT MODIFY THESE COMMENTS.\n;;\n" + ";; Type \\`\\[bmkp-edit-tags-send]' when done.\n\n"))) + (let ((print-circle t)) (pp btags)) + (goto-char (point-min))) + (pop-to-buffer edbuf) + (buffer-enable-undo) + (with-current-buffer (get-buffer edbuf) (bmkp-edit-tags-mode)))) + +;;;###autoload +(defun bmkp-edit-tags-send () + "Use buffer contents as the internal form of a bookmark's tags. +DO NOT MODIFY the header comment lines, which begin with `;;'." + (interactive) + (unless (eq major-mode 'bmkp-edit-tags-mode) (error "Not in `bmkp-edit-tags-mode'")) + (let (bname) + (unwind-protect + (let (tags bmk) + (goto-char (point-min)) + (unless (search-forward ";; Edit tags for bookmark\n;;\n;; ") + (error "Missing header in edit buffer")) + (unless (stringp (setq bname (read (current-buffer)))) + (error "Bad bookmark name in edit-buffer header")) + (unless (setq bmk (bookmark-get-bookmark bname)) (error "No such bookmark: `%s'" bname)) + (unless (bmkp-bookmark-type bmk) (error "Invalid bookmark")) + (goto-char (point-min)) + (setq tags (read (current-buffer))) + (unless (listp tags) (error "Tags sexp is not a list of strings or an alist with string keys")) + (bookmark-prop-set bmk 'tags tags) + (setq bname (bookmark-name-from-full-record bmk)) + (bmkp-record-visit bmk) ; Not BATCH. + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bname))) ; To update display. + (bmkp-maybe-save-bookmarks) + (when (interactive-p) (message "Updated bookmark file with edited tags"))) + (kill-buffer (current-buffer))) + (when bmkp-return-buffer + (pop-to-buffer bmkp-return-buffer) + (when (equal (buffer-name (current-buffer)) "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bname))))) + +(defun bmkp-bookmark-type (bookmark) + "Return the type of BOOKMARK or nil if no type is recognized. +Return nil if the bookmark record is not recognized (invalid). +See the code for the possible non-nil return values. +BOOKMARK is a bookmark name or a bookmark record." + (condition-case nil + (progn + ;; If BOOKMARK is already a bookmark record, not a bookmark name, then we must use it. + ;; If we used the name instead, then tests such as `bookmark-get-filename' would fail, + ;; because they call `bookmark-get-bookmark', which, for a string, checks whether the + ;; bookmark exists in `bookmark-alist'. But we want to be able to use `bmkp-bookmark-type' + ;; to get the type of any bookmark record, not necessarily one that is in `bookmark-alist'. + (when (stringp bookmark) (setq bookmark (bookmark-get-bookmark bookmark))) + (let ((filep (bookmark-get-filename bookmark))) + (cond ((bmkp-sequence-bookmark-p bookmark) 'bmkp-sequence-bookmark-p) + ((bmkp-function-bookmark-p bookmark) 'bmkp-function-bookmark-p) + ((bmkp-variable-list-bookmark-p bookmark) 'bmkp-variable-list-bookmark-p) + ((bmkp-url-bookmark-p bookmark) 'bmkp-url-bookmark-p) + ((bmkp-gnus-bookmark-p bookmark) 'bmkp-gnus-bookmark-p) + ((bmkp-desktop-bookmark-p bookmark) 'bmkp-desktop-bookmark-p) + ((bmkp-bookmark-file-bookmark-p bookmark) 'bmkp-bookmark-file-bookmark-p) + ((bmkp-bookmark-list-bookmark-p bookmark) 'bmkp-bookmark-list-bookmark-p) + ((bmkp-man-bookmark-p bookmark) 'bmkp-man-bookmark-p) + ((bmkp-info-bookmark-p bookmark) 'bmkp-info-bookmark-p) + ((bookmark-get-handler bookmark) 'bookmark-get-handler) + ((bmkp-region-bookmark-p bookmark) 'bmkp-region-bookmark-p) + ;; Make sure we test for remoteness before any other tests of the file itself + ;; (e.g. `file-exists-p'). We do not want to prompt for a password etc. + ((and filep (bmkp-file-remote-p filep)) 'remote-file) + ((and filep (file-directory-p filep)) 'local-directory) + (filep 'local-file) + ((and (bmkp-get-buffer-name bookmark) + (or (not filep) + (equal filep bmkp-non-file-filename))) 'buffer) + (t nil)))) + (error nil))) + +(defun bmkp-record-visit (bookmark &optional batch) + "Update the data recording a visit to BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +This increments the `visits' entry and sets the `time' entry to the +current time. If either an entry is not present, it is added (with 0 +value for `visits'). +With non-nil optional arg BATCH, do not rebuild the menu list." + (let ((vis (bookmark-prop-get bookmark 'visits))) + (if vis (bookmark-prop-set bookmark 'visits (1+ vis)) (bookmark-prop-set bookmark 'visits 0)) + (bookmark-prop-set bookmark 'time (current-time)) + (unless batch (bookmark-bmenu-surreptitiously-rebuild-list)) + (let ((bookmark-save-flag nil)) (bmkp-maybe-save-bookmarks)))) + +(defun bmkp-default-bookmark-name (&optional alist) + "Default bookmark name. See option `bmkp-default-bookmark-name'. +Non-nil ALIST means return nil unless the default names a bookmark in +ALIST." + (let ((bname (if (equal (buffer-name (current-buffer)) "*Bookmark List*") + (bookmark-bmenu-bookmark) + (if (fboundp 'bmkp-default-lighted) + (if (eq 'highlighted bmkp-default-bookmark-name) + (or (bmkp-default-lighted) bookmark-current-bookmark) + (or bookmark-current-bookmark (bmkp-default-lighted))) + bookmark-current-bookmark)))) + (when (and bname alist) + (let ((bookmark-alist alist)) + (setq bname (bookmark-name-from-full-record (bookmark-get-bookmark bname))))) + bname)) + +(defun bmkp-buffer-names () + "Buffer names used by existing bookmarks that really have buffers. +This excludes buffers for bookmarks such as desktops that are not +really associated with a buffer." + (let ((bufs ()) + buf) + (dolist (bmk bookmark-alist) + (when (and (not (bmkp-desktop-bookmark-p bmk)) + (not (bmkp-bookmark-file-bookmark-p bmk)) + (not (bmkp-sequence-bookmark-p bmk)) + (not (bmkp-function-bookmark-p bmk)) + (not (bmkp-variable-list-bookmark-p bmk)) + (setq buf (bmkp-get-buffer-name bmk))) + (add-to-list 'bufs buf))) + bufs)) + +(defun bmkp-file-names () + "The absolute file names used by the existing bookmarks. +This excludes the pseudo file name `bmkp-non-file-filename'." + (let ((files ()) + file) + (dolist (bmk bookmark-alist) + (when (and (setq file (bookmark-get-filename bmk)) (not (equal file bmkp-non-file-filename))) + (add-to-list 'files file))) + files)) + +;;;###autoload +(defun bmkp-send-bug-report () ; Not bound + "Send a bug report about a Bookmark+ problem." + (interactive) + (browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +Bookmark+ bug: \ +&body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'. \ +Be sure to mention the `Update #' from header of the particular Bookmark+ file header.\ +%%0A%%0AEmacs version: %s") + (emacs-version)))) + +;;;###autoload +(defun bmkp-toggle-bookmark-set-refreshes () ; Not bound + "Toggle `bookmark-set' refreshing `bmkp-latest-bookmark-alist'. +Add/remove `bmkp-refresh-latest-bookmark-list' to/from +`bmkp-after-set-hook'." + (interactive) + (if (member 'bmkp-refresh-latest-bookmark-list bmkp-after-set-hook) + (remove-hook 'bmkp-after-set-hook 'bmkp-refresh-latest-bookmark-list) + (add-hook 'bmkp-after-set-hook 'bmkp-refresh-latest-bookmark-list))) + +(defun bmkp-refresh-latest-bookmark-list () + "Refresh `bmkp-latest-bookmark-alist' to reflect `bookmark-alist'." + (setq bmkp-latest-bookmark-alist (if bmkp-bmenu-filter-function + (funcall bmkp-bmenu-filter-function) + bookmark-alist))) + +;;;###autoload +(defun bmkp-toggle-saving-menu-list-state () ; Bound to `M-l' in bookmark list + "Toggle the value of option `bmkp-bmenu-state-file'. +Tip: You can use this before quitting Emacs, to not save the state. +If the initial value of `bmkp-bmenu-state-file' is nil, then this +command has no effect." + (interactive) + (unless (or bmkp-last-bmenu-state-file bmkp-bmenu-state-file) + (error "Cannot toggle: initial value of `bmkp-bmenu-state-file' is nil")) + (setq bmkp-last-bmenu-state-file (prog1 bmkp-bmenu-state-file + (setq bmkp-bmenu-state-file bmkp-last-bmenu-state-file))) + (message (if bmkp-bmenu-state-file + "Autosaving of bookmark list state is now ON" + "Autosaving of bookmark list state is now OFF"))) + +;;;###autoload +(defun bmkp-save-menu-list-state () ; Used in `bookmark-exit-hook-internal'. + "Save menu-list state, unless not saving or list has not yet been shown. +The state is saved to the value of `bmkp-bmenu-state-file'." + (interactive) + (when (and (not bmkp-bmenu-first-time-p) bmkp-bmenu-state-file) + (let ((config-list + `((last-sort-comparer . ,bmkp-sort-comparer) + (last-reverse-sort-p . ,bmkp-reverse-sort-p) + (last-reverse-multi-sort-p . ,bmkp-reverse-multi-sort-p) + (last-latest-bookmark-alist . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-latest-bookmark-alist)) + (last-bmenu-omitted-bookmarks . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks)) + (last-bmenu-marked-bookmarks . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-marked-bookmarks)) + (last-bmenu-filter-function . ,bmkp-bmenu-filter-function) + (last-bmenu-filter-pattern . ,bmkp-bmenu-filter-pattern) + (last-bmenu-title . ,bmkp-bmenu-title) + (last-bmenu-bookmark . ,(and (get-buffer "*Bookmark List*") + (with-current-buffer + (get-buffer "*Bookmark List*") + (bookmark-bmenu-bookmark)))) + (last-specific-buffer . ,bmkp-last-specific-buffer) + (last-specific-file . ,bmkp-last-specific-file) + (last-bmenu-toggle-filenames . ,bookmark-bmenu-toggle-filenames) + (last-bmenu-before-hide-marked-alist . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-marked-alist)) + (last-bmenu-before-hide-unmarked-alist . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-unmarked-alist)) + (last-bookmark-file . ,(convert-standard-filename + (expand-file-name + bmkp-current-bookmark-file)))))) + (with-current-buffer (get-buffer-create " *Menu-List State*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil) + (print-circle t)) + (pp config-list (current-buffer))) + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-state-file) + (file-error (message "Cannot write `%s'" bmkp-bmenu-state-file))) + (kill-buffer (current-buffer)))))) + +;;;###autoload +(defun bmkp-toggle-saving-bookmark-file () ; Bound to `M-~' in bookmark list + "Toggle the value of option `bookmark-save-flag'. +If the initial value of `bookmark-save-flag' is nil, then this +command has no effect." + (interactive) + (unless (or bmkp-last-save-flag-value bookmark-save-flag) + (error "Cannot toggle: initial value of `bookmark-save-flag' is nil")) + (setq bmkp-last-save-flag-value (prog1 bookmark-save-flag + (setq bookmark-save-flag bmkp-last-save-flag-value))) + (message (if bookmark-save-flag + "Autosaving of current bookmark file is now ON" + "Autosaving of current bookmark file is now OFF"))) + +;;;###autoload +(defun bmkp-make-function-bookmark (bookmark-name function) ; Not bound + "Create a bookmark that invokes FUNCTION when \"jumped\" to. +You are prompted for the bookmark name and the name of the function. +Returns the new bookmark (internal record)." + (interactive + (let ((icicle-unpropertize-completion-result-flag t)) + (list (read-string "Bookmark: ") + (completing-read "Function: " obarray 'functionp)))) + (bookmark-store bookmark-name `((filename . ,bmkp-non-file-filename) + (position . 0) + (function . ,(read function)) + (handler . bmkp-jump-function)) + nil) + (let ((new (bookmark-get-bookmark bookmark-name 'noerror))) + (unless (memq new bmkp-latest-bookmark-alist) + (setq bmkp-latest-bookmark-alist (cons new bmkp-latest-bookmark-alist))) + (bookmark-bmenu-surreptitiously-rebuild-list) + new)) + +;;;###autoload +(defun bmkp-switch-bookmark-file (file &optional no-msg) ; Bound to `L' in bookmark list + "Switch to a different bookmark file, FILE. +Replace all currently existing bookmarks with the newly loaded +bookmarks. Change the value of `bmkp-current-bookmark-file' to FILE, +so bookmarks will subsequently be saved to FILE. + +`bookmark-default-file' is unaffected, so your next Emacs session will +still use `bookmark-default-file' for the initial set of bookmarks." + (interactive + (list + (let ((bfile (if (bmkp-same-file-p bmkp-current-bookmark-file + bmkp-last-bookmark-file) + bookmark-default-file + bmkp-last-bookmark-file))) + (bmkp-read-bookmark-file-name "Switch to bookmark file: " + (or (file-name-directory bfile) "~/") + bfile + 'CONFIRM)))) + (bookmark-load file t no-msg)) + +;;;###autoload +(defun bmkp-switch-to-last-bookmark-file (&optional no-msg) ; Not bound + "Switch back to the last-used bookmarkfile. +Replace all currently existing bookmarks with those newly loaded from +the last-used file. Swap the values of `bmkp-last-bookmark-file' and +`bmkp-current-bookmark-file'." + (interactive) + (bookmark-load (or bmkp-last-bookmark-file bookmark-default-file) t no-msg)) + +;;;###autoload +(defun bmkp-use-bookmark-file-create (file) ; Not bound + "Switch current bookmark file to FILE, creating it if it does not exist. +Interactively, you are prompted for the file name. The default is +`.emacs.bmk' in the current directory, but you can enter any file +name, anywhere. + +If there is no file with the name you provide then a new, an empty +bookmark file with that name is created. + +You are prompted to confirm the bookmark-file switch. + +Returns FILE." + (interactive (list (bmkp-read-bookmark-file-name))) + (unless (file-readable-p file) (bmkp-empty-file file)) + (when (y-or-n-p (format "Use `%s' as the current bookmark file? " file)) + (bmkp-switch-bookmark-file file)) + file) + +(defun bmkp-read-bookmark-file-name (&optional prompt dir default-filename require-match) + "Read and return an (absolute) bookmark file name. +PROMPT is the prompt to use (default: \"Use bookmark file: \"). +The other args are the same as for `read-file-name'." + (let ((insert-default-directory t)) + (expand-file-name + (read-file-name (or prompt "Use bookmark file: ") + dir + (or default-filename + (if (> emacs-major-version 22) + (list ".emacs.bmk" bookmark-default-file) + ".emacs.bmk")) + require-match)))) + +;;;###autoload +(defun bmkp-empty-file (file) ; Bound to `C-x p 0' + "Empty the bookmark file FILE, or create FILE (empty) if it does not exist. +In either case, FILE will become an empty bookmark file. Return FILE. + +NOTE: If FILE already exists and you confirm emptying it, no check is + made that it is in fact a bookmark file before emptying it. + It is simply replaced by an empty bookmark file and saved. + +This does NOT also make FILE the current bookmark file. To do that, +use `\\[bmkp-switch-bookmark-file]' (`bmkp-switch-bookmark-file')." + (interactive (list (read-file-name "Create empty bookmark file: " "~/"))) + (setq file (expand-file-name file)) + (bookmark-maybe-load-default-file) + (when (and (file-exists-p file) + (not (y-or-n-p (format "CONFIRM: Empty the existing file `%s'? " file)))) + (error "OK, cancelled")) + (let ((bookmark-alist ())) + (bookmark-write-file file (if (file-exists-p file) + "Emptying bookmark file `%s'..." + "Creating new, empty bookmark file `%s'..."))) + file) + +;;;###autoload +(defun bmkp-crosshairs-highlight () ; Not bound + "Call `crosshairs-highlight', unless the region is active. +You can add this to hook `bookmark-after-jump-hook'. +You need library `crosshairs.el' to use this command." + (interactive) + (when (> emacs-major-version 21) ; No-op for Emacs 20-21. + (unless (condition-case nil (require 'crosshairs nil t) (error nil)) + (error "You need library `crosshairs.el' to use this command")) + (unless mark-active + (let ((crosshairs-overlay-priority (and (boundp 'bmkp-light-priorities) + (1+ (apply #'max + (mapcar #'cdr bmkp-light-priorities)))))) + (crosshairs-highlight))))) + +;;;###autoload +(defun bmkp-choose-navlist-from-bookmark-list (bookmark-name &optional alist) ; Bound to `C-x p B' + "Choose a bookmark-list bookmark and set the bookmark navigation list. +The navigation-list variable, `bmkp-nav-alist', is set to the list of +bookmarks that would be displayed by `bookmark-bmenu-list' (`C-x r l') +for the chosen bookmark-list bookmark, sorted and filtered as +appropriate. + +Instead of choosing a bookmark-list bookmark, you can choose the +pseudo-bookmark `CURRENT *Bookmark List*'. The bookmarks used for the +navigation list are those that would be currently shown in the +`*Bookmark List*' (even if the list is not currently displayed)." + (interactive + (let ((bookmark-alist (cons (bmkp-current-bookmark-list-state) (bmkp-bookmark-list-alist-only)))) + (list (bmkp-read-bookmark-for-type "bookmark-list " bookmark-alist nil nil + 'bmkp-bookmark-list-history "Choose ") + bookmark-alist))) + (let ((state (let ((bookmark-alist (or alist (cons (bmkp-current-bookmark-list-state) + (bmkp-bookmark-list-alist-only))))) + (bookmark-prop-get bookmark-name 'bookmark-list)))) + (let ((bmkp-sort-comparer (cdr (assq 'last-sort-comparer state))) + (bmkp-reverse-sort-p (cdr (assq 'last-reverse-sort-p state))) + (bmkp-reverse-multi-sort-p (cdr (assq 'last-reverse-multi-sort-p state))) + (bmkp-bmenu-omitted-bookmarks (cdr (assq 'last-bmenu-omitted-bookmarks state))) + (bmkp-bmenu-filter-function (cdr (assq 'last-bmenu-filter-function state))) + (bmkp-bmenu-filter-pattern (or (cdr (assq 'last-bmenu-filter-pattern state)) "")) + (bmkp-bmenu-title (cdr (assq 'last-bmenu-title state))) + (bookmark-bmenu-toggle-filenames (cdr (assq 'last-bmenu-toggle-filenames state)))) + (setq bmkp-nav-alist (bmkp-sort-omit + (if bmkp-bmenu-filter-function + (funcall bmkp-bmenu-filter-function) + (if (string= "CURRENT *Bookmark List*" bookmark-name) + (or bmkp-latest-bookmark-alist bookmark-alist) + bookmark-alist)) + (and (not (eq bmkp-bmenu-filter-function + 'bmkp-omitted-alist-only)) + bmkp-bmenu-omitted-bookmarks)) + bmkp-current-nav-bookmark (car bmkp-nav-alist)))) + (message "Bookmark navigation list is now %s" + (if (and (string= "CURRENT *Bookmark List*" bookmark-name) + (not (get-buffer "*Bookmark List*"))) + "the global bookmark list" + (format "`%s'" bookmark-name)))) + +(defun bmkp-current-bookmark-list-state () + "Pseudo-bookmark for the current `*Bookmark List*' state." + (bookmark-bmenu-surreptitiously-rebuild-list) + (cons "CURRENT *Bookmark List*" (bmkp-make-bookmark-list-record))) + +;;;###autoload +(defun bmkp-choose-navlist-of-type (type) ; Bound to `C-x p :' + "Set the bookmark navigation list to the bookmarks of a type you choose. +The pseudo-type `any' sets the navigation list to all bookmarks. +This sets variable `bmkp-nav-alist'." + (interactive + (let* ((completion-ignore-case t) + (icicle-unpropertize-completion-result-flag t) + (type (completing-read "Type: " + (cons '("any" . bookmark-history) + bmkp-types-alist) + nil t nil nil "any"))) + (list type))) + (setq bmkp-nav-alist (if (equal "any" type) + bookmark-alist + (funcall (intern (format "bmkp-%s-alist-only" type))))) + (unless bmkp-nav-alist (error "No bookmarks")) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist)) + (message "Bookmark navigation list is now %s" + (if (equal "any" type) "all bookmarks" (format "for type `%s'" type)))) + +(defun bmkp-autonamed-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a (valid) autonamed bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (setq bookmark (bookmark-get-bookmark bookmark 'NOERROR)) + (if (not bookmark) + nil + (string-match (format bmkp-autoname-format ".*") + (bookmark-name-from-full-record bookmark)))) + +(defun bmkp-autonamed-bookmark-for-buffer-p (bookmark buffer-name) + "Return non-nil if BOOKMARK is a (valid) autonamed bookmark for BUFFER. +BOOKMARK is a bookmark name or a bookmark record. +BUFFER-NAME is a string matching the buffer-name part of an autoname." + (setq bookmark (bookmark-get-bookmark bookmark 'NOERROR)) + (if (not bookmark) + nil + (string-match (format bmkp-autoname-format (regexp-quote buffer-name)) + (bookmark-name-from-full-record bookmark)))) + +(defun bmkp-update-autonamed-bookmark (bookmark) + "Update the name and position of the autonamed BOOKMARK at point. +BOOKMARK is a bookmark name or a bookmark record. +Return the updated BOOKMARK: If input was a bookmark name, then return + then new name, else the new (full) bookmark. +It is a good idea to set BOOKMARK to the result of this call." + (let ((namep (stringp bookmark))) + (setq bookmark (bookmark-get-bookmark bookmark)) + (bookmark-set-position bookmark (point)) + ;; Autonamed bookmarks do not have regions. Update `end-position' to be the same as `position'. + (when (bmkp-get-end-position bookmark) + (bookmark-prop-set bookmark 'end-position (point))) + (let ((newname (funcall bmkp-autoname-bookmark-function (point)))) + (bookmark-rename (bookmark-name-from-full-record bookmark) newname 'batch) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list (bookmark-name-from-full-record bookmark)))) ; So display new name. + (bmkp-maybe-save-bookmarks)) + (if namep (bookmark-name-from-full-record bookmark) bookmark))) ; Return updated bookmark or name. + +;;;###autoload +(defun bmkp-this-buffer-bmenu-list () ; Bound to `C-x p .' + "Show the bookmark list just for bookmarks for the current buffer. +Set `bmkp-last-specific-buffer' to the current buffer name." + (interactive) + (setq bmkp-last-specific-buffer (buffer-name) + bmkp-bmenu-filter-function 'bmkp-last-specific-buffer-alist-only + bmkp-bmenu-title (format "Buffer `%s' Bookmarks" bmkp-last-specific-buffer)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function)) + (bmkp-bmenu-state-file nil)) ; Prevent restoring saved state. + (unless bookmark-alist (error "No bookmarks for buffer `%s'" bmkp-last-specific-buffer)) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (pop-to-buffer (get-buffer-create "*Bookmark List*")) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + (format "Only bookmarks for buffer `%s' are shown" + bmkp-last-specific-buffer))) + (raise-frame)) + +;;;###autoload +(defun bmkp-navlist-bmenu-list () ; Bound to `C-x p N' + "Show the bookmark list just for bookmarks from the navigation list." + (interactive) + (unless bmkp-nav-alist + (bookmark-maybe-load-default-file) + (setq bmkp-nav-alist bookmark-alist) + (unless bmkp-nav-alist (error "No bookmarks")) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist)) + (message "Bookmark navigation list is now the global bookmark list") (sit-for 2)) + (setq bmkp-bmenu-title "Current Navlist Bookmarks") + (let ((bookmark-alist bmkp-nav-alist) + (bmkp-bmenu-state-file nil)) ; Prevent restoring saved state. + (unless bookmark-alist (error "No bookmarks")) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (pop-to-buffer (get-buffer-create "*Bookmark List*")) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + "Only bookmarks for the navigation list are shown")) + (raise-frame)) + +(defun bmkp-completing-read-buffer-name (&optional no-default-p) + "Read the name of a buffer associated with a bookmark. +The candidates are the buffers in `bmkp-buffer-names'. +Non-nil NO-DEFAULT-P means provide no default value. Used when + called in a loop, to let the user exit using empty input. +If NO-DEFAULT-P is nil, then the default is the current buffer's name, + or the value of `bmkp-last-specific-buffer' if the current buffer has + no bookmarks." + (bookmark-maybe-load-default-file) + (let ((icicle-unpropertize-completion-result-flag t)) + (completing-read "Buffer: " (mapcar #'list (bmkp-buffer-names)) nil t nil 'buffer-name-history + (and (not no-default-p) + (if (member (buffer-name) (bmkp-buffer-names)) + (buffer-name) + bmkp-last-specific-buffer))))) + +(defun bmkp-completing-read-file-name (&optional no-default-p) + "Read the name of a file associated with a bookmark. +The candidates are the absolute file names in `bmkp-file-names'. +Non-nil NO-DEFAULT-P means provide no default value. Used when + called in a loop, to let the user exit using empty input. +If NO-DEFAULT-P is nil, then the default is the current buffer's file + name, if any, or the value of `bmkp-last-specific-file' if the + current buffer has no associated file or the file has no bookmarks." + (bookmark-maybe-load-default-file) + (let ((completion-ignore-case (if (boundp 'read-file-name-completion-ignore-case) + read-file-name-completion-ignore-case + (memq system-type + '(ms-dos windows-nt darwin cygwin)))) + (icicle-unpropertize-completion-result-flag t)) + (completing-read "File: " (mapcar #'list (bmkp-file-names)) nil t nil 'file-name-history + (and (not no-default-p) + (let ((file (buffer-file-name))) + (if (and file (member file (bmkp-file-names))) + file + bmkp-last-specific-file)))))) + +(defun bmkp-refresh-menu-list (&optional bookmark) + "Refresh (revert) the bookmark list (\"menu list\"). +This brings the displayed list up to date. It does not change the +current filtering or sorting of the displayed list. +Non-nil optional arg BOOKMARK means move cursor to BOOKMARK's line." + (unless (stringp bookmark) (setq bookmark (bookmark-name-from-full-record bookmark))) + (let ((bookmark-alist (if bmkp-bmenu-filter-function + (funcall bmkp-bmenu-filter-function) + bookmark-alist))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp) + (when bookmark + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bookmark) + (let ((bmenu-win (get-buffer-window (current-buffer) 0))) + (when bmenu-win (set-window-point bmenu-win (point)))))))) + +;;;###autoload +(defun bmkp-unomit-all () ; Bound to `O U' in bookmark list + "Remove all bookmarks from the list of omitted bookmarks. +All bookmarks will henceforth be available for display." + (interactive) + (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks to UN-omit")) + (message "UN-omitting ALL omitted bookmarks...") + (let ((count 0)) + (dolist (bmk-name bmkp-bmenu-omitted-bookmarks) + (setq bmkp-bmenu-omitted-bookmarks (bmkp-delete-bookmark-name-from-list + bmk-name bmkp-bmenu-omitted-bookmarks) + count (1+ count))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "UN-omitted %d bookmarks" count)) + (when (equal (buffer-name (current-buffer)) "*Bookmark List*") (bmkp-bmenu-show-all)) + (when (and (fboundp 'fit-frame-if-one-window) + (equal (buffer-name (current-buffer)) "*Bookmark List*")) + (fit-frame-if-one-window))) + +(defun bmkp-omitted-alist-only () + "`bookmark-alist', filtered to retain only the omitted bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-omitted-bookmark-p bookmark-alist)) + +(defun bmkp-omitted-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is an omitted bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (unless (stringp bookmark) (setq bookmark (bookmark-name-from-full-record bookmark))) + (bmkp-bookmark-name-member bookmark bmkp-bmenu-omitted-bookmarks)) + + +;;(@* "Search-and-Replace Locations of Marked Bookmarks") +;; *** Search-and-Replace Locations of Marked Bookmarks *** + +(when (> emacs-major-version 22) + (defvar bmkp-isearch-bookmarks nil + "Bookmarks whose locations are to be incrementally searched.") + + (defun bmkp-isearch-next-bookmark-buffer (&optional bookmark wrap) + "Return the next buffer in a series of bookmark buffers. +Used as a value for `multi-isearch-next-buffer-function', for Isearch +of multiple bookmarks. + +Variable `bmkp-isearch-bookmarks' is a list of bookmarks. Each +bookmark in the list is visited by `bookmark--jump-via', and the +corresponding bookmark buffer is returned." + (let ((bookmarks (if isearch-forward bmkp-isearch-bookmarks (reverse bmkp-isearch-bookmarks)))) + (bookmark--jump-via + (if wrap + (car bookmarks) + (let ((this-bmk (catch 'bmkp-isearch-next-bookmark-buffer + (dolist (bmk bookmarks) + (when (if (bmkp-get-buffer-name bmk) + (equal (bmkp-get-buffer-name bmk) (buffer-name)) + (equal (bookmark-get-filename bmk) (buffer-file-name))) + (throw 'bmkp-isearch-next-bookmark-buffer bmk))) + (car bookmarks)))) + (cadr (member this-bmk bookmarks)))) + 'ignore) + (current-buffer))) + + (defun bmkp-isearch-bookmarks (bookmarks) + "Start multi-bookmark Isearch on BOOKMARKS." + (let ((multi-isearch-next-buffer-function 'bmkp-isearch-next-bookmark-buffer) + (bmkp-isearch-bookmarks bookmarks)) + (bookmark-jump (car bookmarks)) + (goto-char (if isearch-forward (point-min) (point-max))) + (isearch-forward))) + + (defun bmkp-isearch-bookmarks-regexp (bookmarks) + "Start multi-bookmark regexp Isearch on BOOKMARKS." + (let ((multi-isearch-next-buffer-function 'bmkp-isearch-next-bookmark-buffer) + (bmkp-isearch-bookmarks bookmarks)) + (bookmark-jump (car bookmarks)) + (goto-char (if isearch-forward (point-min) (point-max))) + (isearch-forward-regexp)))) + + +;;(@* "Tags") +;; *** Tags *** + +(defun bmkp-get-tags (bookmark) + "Return the `tags' entry for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'tags)) + +(defun bmkp-get-tag-value (bookmark tag &optional msgp) + "Return value of BOOKMARK's tag TAG. +BOOKMARK is a bookmark name or a bookmark record. +TAG is a string. +Return nil if BOOKMARK has no such TAG or if TAG has no value." + (assoc-default tag (bmkp-get-tags bookmark))) + +(defun bmkp-has-tag-p (bookmark tag &optional msgp) + "Return non-nil if BOOKMARK is tagged with TAG. +BOOKMARK is a bookmark name or a bookmark record. +TAG is a string." + (assoc-default tag (bmkp-get-tags bookmark) nil t)) + +;; NOT USED currently - we use `bmkp-read-tags-completing' instead. +(defun bmkp-read-tags () + "Read tags one by one, and return them as a list." + (let ((tag (read-string "Tag (RET for each, empty input to finish): ")) + (btags ())) + (while (not (string= "" tag)) + (push tag btags) + (setq tag (read-string "Tag: "))) + btags)) + +(defun bmkp-read-tag-completing (&optional prompt candidate-tags require-match update-tags-alist-p) + "Read a tag with completion, and return it as a string. +PROMPT is the prompt string. If nil, then use \"Tag: \". +CANDIDATE-TAGS is an alist of tags to use for completion. + If nil, then all tags from all bookmarks are used for completion. + The set of all tags is taken from variable `bmkp-tags-alist'. +REQUIRE-MATCH is passed to `completing-read'. +Non-nil UPDATE-TAGS-ALIST-P means update var `bmkp-tags-alist'." + (bookmark-maybe-load-default-file) + (let ((cand-tags (copy-sequence + (or candidate-tags + (and (not update-tags-alist-p) + bmkp-tags-alist) ; Use cached list. + (bmkp-tags-list)))) ; Update the cache. + (icicle-unpropertize-completion-result-flag t)) + (completing-read (or prompt "Tag: ") cand-tags nil require-match nil 'bmkp-tag-history))) + +(defun bmkp-read-tags-completing (&optional candidate-tags require-match update-tags-alist-p) + "Read tags with completion, and return them as a list of strings. +Reads tags one by one, until you hit `RET' twice consecutively. +CANDIDATE-TAGS is an alist of tags to use for completion. + If nil, then all tags from all bookmarks are used for completion. + The set of all tags is taken from variable `bmkp-tags-alist'. +REQUIRE-MATCH is passed to `completing-read'. +Non-nil UPDATE-TAGS-ALIST-P means update var `bmkp-tags-alist'." + (bookmark-maybe-load-default-file) + (let ((cands ()) + (btags ()) + (prompt1 "Tag (RET for each, empty input to finish): ") + (prompt2 "Tag: ") + (icicle-unpropertize-completion-result-flag t) + tag old-tag) + ;; Make a new candidates alist, with just one entry per tag name. The original cdr is discarded. + (dolist (full-tag (or candidate-tags + (and (not update-tags-alist-p) bmkp-tags-alist) ; Use cached list. + (bmkp-tags-list))) + (add-to-list 'cands (list (if (consp full-tag) (car full-tag) full-tag)))) + (setq tag (completing-read prompt1 cands nil require-match nil 'bmkp-tag-history) + cands (delete (assoc tag cands) cands)) ; Tag read is no longer a candidate. + (while (not (string= "" tag)) + (if (member tag btags) ; User can enter it more than once, if not REQUIRE-MATCH. + (message "Tag `%s' already included" tag) + (push tag btags)) ; But we only add it once. + (setq tag (completing-read prompt2 cands nil require-match nil 'bmkp-tag-history) + cands (delete (assoc tag cands) cands))) + (nreverse btags))) + +;;;###autoload +(defun bmkp-list-all-tags (fullp) ; Bound to `T l' in bookmark list, `C-x p t l' elsewhere + "List all tags used for any bookmarks. +With a prefix argument, list the full alist of tags. +Otherwise, list only the tag names. + +Note that when the full alist is shown, the same tag name will appear +once for each of its different values. + +Show list in minibuffer or, if not enough space, buffer `*All Tags*'." + (interactive "P") + (require 'pp) + (pp-display-expression (bmkp-tags-list (not fullp)) "*All Tags")) + +(defun bmkp-tags-list (&optional names-only-p) + "Current list of all tags, from all bookmarks. +Non-nil NAMES-ONLY-P means return a list of only the tag names. +Otherwise, return an alist of the full tags and set variable +`bmkp-tags-alist' to that alist, as a cache." + (bookmark-maybe-load-default-file) + (let ((tags ()) + bmk-tags) + (dolist (bmk bookmark-alist) + (setq bmk-tags (bmkp-get-tags bmk)) + (dolist (tag bmk-tags) + (add-to-list 'tags (if names-only-p (bmkp-tag-name tag) (bmkp-full-tag tag))))) + (unless names-only-p (setq bmkp-tags-alist tags)) + tags)) + +(defun bmkp-tag-name (tag) + "Name of TAG. If TAG is an atom, then TAG, else (car TAG)." + (if (atom tag) tag (car tag))) + +(defun bmkp-full-tag (tag) + "Full cons entry for TAG. If TAG is a cons, then TAG, else (list TAG)." + (if (consp tag) tag (list tag))) + +;; `T 0' in bookmark list, `C-x p t 0' elsewhere. +;;;###autoload +(defun bmkp-remove-all-tags (bookmark &optional msgp no-cache-update-p) + "Remove all tags from BOOKMARK. +Non-nil optional arg MSGP means display a message about the removal. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'." + (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'msg)) + (when (and msgp (null (bmkp-get-tags bookmark))) (error "Bookmark has no tags to remove")) + (let ((nb-removed (and (interactive-p) (length (bmkp-get-tags bookmark))))) + (bookmark-prop-set bookmark 'tags ()) + (unless no-cache-update-p (bmkp-tags-list)) ; Update the tags cache. + (bmkp-maybe-save-bookmarks) + (when (and msgp nb-removed) (message "%d tags removed" nb-removed))) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bookmark)))) ; So the `t' markers are removed. + +;; `T +' in bookmark list, `C-x p t + b' elsewhere (`b' for bookmark) +;;;###autoload +(defun bmkp-add-tags (bookmark tags &optional msgp no-cache-update-p) + "Add TAGS to BOOKMARK. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag. +Completion for the bookmark name is strict. +Completion for tags is lax: you are not limited to existing tags. + +TAGS is a list of strings. +Non-nil MSGP means display a message about the addition. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags added." + (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) + (bmkp-read-tags-completing) + 'msg)) + (let* ((newtags (copy-alist (bmkp-get-tags bookmark))) + (olen (length newtags))) + (dolist (tag tags) (unless (or (assoc tag newtags) (member tag newtags)) (push tag newtags))) + (bookmark-prop-set bookmark 'tags newtags) + (unless no-cache-update-p (bmkp-tags-list)) ; Update the tags cache. + (bmkp-maybe-save-bookmarks) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bookmark))) ; So the `t' markers are displayed (updated). + (let ((nb-added (- (length newtags) olen))) + (when msgp (message "%d tags added. Now: %S" nb-added ; Echo just the tag names. + (let ((tgs (mapcar #'bmkp-tag-name newtags))) + (setq tgs (sort tgs #'string<))))) + nb-added))) + +;; $$$$$$ NOT YET USED +;;;###autoload +(defun bmkp-set-tag-value-for-navlist (tag value) ; Bound to `C-x p t V' + "Set the value of TAG to VALUE, for each bookmark in the navlist. +If any of the bookmarks has no tag named TAG, then add one with VALUE." + (interactive (list (bmkp-read-tag-completing) (read (read-string "Value: ")) 'msg)) + (bmkp-set-tag-value-for-bookmarks bmkp-nav-alist tag value)) + +;; $$$$$$ NOT YET USED +(defun bmkp-set-tag-value-for-bookmarks (bookmarks tag value) ; Not bound + "Set the value of TAG to VALUE, for each of the BOOKMARKS. +If any of the BOOKMARKS has no tag named TAG, then add one with VALUE." + (dolist (bmk bookmarks) (bmkp-set-tag-value bmk tag value))) + +;;;###autoload +(defun bmkp-set-tag-value (bookmark tag value &optional msgp) ; Bound to `C-x p t v' + "For BOOKMARK's TAG, set the value to VALUE. +If BOOKMARK has no tag named TAG, then add one with value VALUE." + (interactive + (let* ((bmk (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name))) + (tag (bmkp-read-tag-completing "Tag: " (mapcar 'bmkp-full-tag (bmkp-get-tags bmk))))) + (list bmk tag (read (read-string "Value: ")) 'msg))) + (unless (bmkp-has-tag-p bookmark tag) (bmkp-add-tags bookmark (list tag))) + (let* ((newtags (copy-alist (bmkp-get-tags bookmark))) + (assoc-tag (assoc tag newtags)) + (member-tag (and (not assoc-tag) (member tag newtags)))) + (if assoc-tag (setcdr assoc-tag value) (setcar member-tag (cons (car member-tag) value))) + (bookmark-prop-set bookmark 'tags newtags)) + (when msgp "Tag value added")) + +;; `T -' in bookmark list, `C-x p t - b' elsewhere (`b' for bookmark) +;;;###autoload +(defun bmkp-remove-tags (bookmark tags &optional msgp no-cache-update-p) ; `T -' in bookmark list + "Remove TAGS from BOOKMARK. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag. + +TAGS is a list of strings. The corresponding tags are removed. +Non-nil MSGP means display messages. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags removed." + (interactive (let ((bmk (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)))) + (list bmk + (bmkp-read-tags-completing (mapcar 'bmkp-full-tag (bmkp-get-tags bmk)) t) + 'msg))) + (let* ((remtags (copy-alist (bmkp-get-tags bookmark))) + (olen (length remtags))) + (if (null remtags) + (when msgp (message "Bookmark has no tags to remove")) ; Do nothing if bookmark has no tags. + (setq remtags (bmkp-remove-if #'(lambda (tag) + (if (atom tag) (member tag tags) (member (car tag) tags))) + remtags)) + (bookmark-prop-set bookmark 'tags remtags) + (unless no-cache-update-p (bmkp-tags-list)) ; Update the tags cache. + (bmkp-maybe-save-bookmarks) + (when (and (get-buffer "*Bookmark List*") (get-buffer-window (get-buffer "*Bookmark List*") 0)) + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-refresh-menu-list bookmark))) ; So the `t' markers are removed. + (let ((nb-removed (- olen (length remtags)))) + (when msgp (message "%d tags removed. Now: %S" nb-removed ; Echo just the tag names. + (let ((tgs (mapcar #'bmkp-tag-name remtags))) + (setq tgs (sort tgs #'string<))))) + nb-removed)))) + +;;;###autoload +(defun bmkp-remove-tags-from-all (tags &optional msgp) ; Bound to `T d' in bookmark list + "Remove TAGS from all bookmarks. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag. +This affects all bookmarks, even those not showing in bookmark list. + +TAGS is a list of strings. The corresponding tags are removed. +Non-nil optional arg MSGP means display a message about the deletion." + (interactive + (if (not (y-or-n-p "Delete the tags you specify from ALL bookmarks? ")) + (error "Deletion cancelled") + (list (bmkp-read-tags-completing nil t) 'MSG))) + (dolist (bmk (bookmark-all-names)) (bmkp-remove-tags bmk tags nil 'NO-CACHE-UPDATE)) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when msgp (message "Tags removed from all bookmarks: %S" tags))) + +;;;###autoload +(defun bmkp-rename-tag (tag newname &optional msgp) ; Bound to `T r' in bookmark list, `C-x p t r' elsewhere + "Rename TAG to NEWNAME in all bookmarks, even those not showing. +Non-nil optional arg MSGP means display a message about the deletion." + (interactive (list (bmkp-read-tag-completing "Tag (old name): ") + (bmkp-read-tag-completing "New name: ") + 'MSG)) + (let ((tag-exists-p nil)) + (dolist (bmk (bookmark-all-names)) + (let ((newtags (copy-alist (bmkp-get-tags bmk)))) + (when newtags + (let* ((assoc-tag (assoc tag newtags)) + (member-tag (and (not assoc-tag) (member tag newtags)))) + (cond (assoc-tag (setcar assoc-tag newname)) + (member-tag (setcar member-tag newname))) + (when (or assoc-tag member-tag) + (setq tag-exists-p t) + (bookmark-prop-set bmk 'tags newtags)))))) + (if tag-exists-p + (bmkp-tags-list) ; Update the tags cache. + (error "No such tag: `%s'" tag)) + (when msgp (message "Renamed")))) + +;;;###autoload +(defun bmkp-copy-tags (bookmark &optional msgp) ; `C-x p t c', `C-x p t M-w' + "Copy tags from BOOKMARK, so you can paste them to another bookmark. +Note that you can copy from a BOOKMARK that has no tags or has an +empty tags list. In that case, the copied-tags list is empty, so if +you paste it as a replacement then the recipient bookmark will end up +with no tags. + +Non-nil optional arg MSGP means display a message about the number of +tags copied." + (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'msg)) + (let ((btags (bmkp-get-tags bookmark))) + (setq bmkp-copied-tags (copy-alist btags)) + (when msgp (message "%d tags now available for pasting" (length btags))))) + +;;;###autoload +(defun bmkp-paste-add-tags (bookmark &optional msgp no-cache-update-p) ; `C-x p t p', ; `C-x p t C-y' + "Add tags to BOOKMARK that were previously copied from another bookmark. +The tags are copied from `bmkp-copied-tags'. +Non-nil MSGP means display a message about the addition. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags added." + (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'msg)) + (unless (listp bmkp-copied-tags) + (error "`bmkp-paste-add-tags': `bmkp-copied-tags' is not a list")) + (bmkp-add-tags bookmark bmkp-copied-tags msgp no-cache-update-p)) + +;;;###autoload +(defun bmkp-paste-replace-tags (bookmark &optional msgp no-cache-update-p) ; `C-x p t q' + "Replace tags for BOOKMARK with those copied from another bookmark. +The tags are copied from `bmkp-copied-tags'. +Any previously existing tags for BOOKMARK are lost. +Non-nil MSGP means display a message about the addition. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags." + (interactive (list (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name)) 'msg)) + (unless (listp bmkp-copied-tags) + (error "`bmkp-paste-replace-tags': `bmkp-copied-tags' is not a list")) + (when (and (bmkp-get-tags bookmark) msgp) + (y-or-n-p "Existing tags will be lost - really replace them? ")) + (bmkp-remove-all-tags bookmark msgp no-cache-update-p) + (bmkp-add-tags bookmark bmkp-copied-tags msgp no-cache-update-p)) + + +;;(@* "Bookmark Predicates") +;; *** Bookmark Predicates *** + +(defun bmkp-autofile-bookmark-p (bookmark &optional prefix) + "Return non-nil if BOOKMARK is an autofile bookmark. +That means that it is `bmkp-file-bookmark-p' and also its +non-directory file name is the same as the bookmark name. +BOOKMARK is a bookmark name or a bookmark record. + +Non-nil optional arg PREFIX means that the bookmark name is actually +expected to be the file name prefixed by PREFIX (a string)." + (setq bookmark (bookmark-get-bookmark bookmark)) + (and (bmkp-file-bookmark-p bookmark) + (let ((fname (file-name-nondirectory (bookmark-get-filename bookmark)))) + (string= (if prefix (concat prefix fname) fname) + (bookmark-name-from-full-record bookmark))))) + +(defun bmkp-bookmark-file-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a bookmark-file bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-bookmark-file)) + +(defun bmkp-bookmark-image-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is an image-file bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'image-bookmark-jump) + (and (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+). + (bmkp-file-bookmark-p bookmark) + (not (bmkp-dired-bookmark-p bookmark)) + (if (fboundp 'string-match-p) + (string-match-p (image-file-name-regexp) (bookmark-get-filename bookmark)) + (save-match-data + (string-match (image-file-name-regexp) (bookmark-get-filename bookmark))))))) + +(defun bmkp-bookmark-list-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a bookmark-list bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-bookmark-list)) + +(defun bmkp-desktop-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a desktop bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-desktop)) + +;; Note: To avoid remote access, if bookmark does not have the Dired handler, then we insist +;; that it be for a local directory. IOW, we do not include remote directories that were not +;; bookmarked by Bookmark+ (and so do not have the Dired handler). +(defun bmkp-dired-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Dired bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'bmkp-jump-dired) + (bmkp-local-directory-bookmark-p bookmark))) + +(defun bmkp-dired-this-dir-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Dired bookmark for the `default-directory'. +BOOKMARK is a bookmark name or a bookmark record." + (and (bmkp-dired-bookmark-p bookmark) (let ((dir (bookmark-get-filename bookmark))) + (bmkp-same-file-p dir default-directory)))) + +(defun bmkp-file-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks a file or directory. +BOOKMARK is a bookmark name or a bookmark record. +This excludes bookmarks of a more specific kind (e.g. Info, Gnus)." + (let* ((filename (bookmark-get-filename bookmark)) + (nonfile-p (equal filename bmkp-non-file-filename)) + (handler (bookmark-get-handler bookmark))) + (and filename (not nonfile-p) + (or (not handler) + (memq handler bmkp-file-bookmark-handlers) + (equal handler (bmkp-default-handler-for-file filename))) + (not (and (bookmark-prop-get bookmark 'info-node)))))) ; Emacs 20-21 Info: no handler. + +(defun bmkp-file-this-dir-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks file/subdir in `default-directory'. +BOOKMARK is a bookmark name or a bookmark record. +This excludes bookmarks of a more specific kind (e.g. Info, Gnus)." + (and (bmkp-file-bookmark-p bookmark) + (equal (file-name-directory (bookmark-get-filename bookmark)) default-directory))) + +(defun bmkp-function-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a function bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-function)) + +(defun bmkp-gnus-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Gnus bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (memq (bookmark-get-handler bookmark) + '(gnus-summary-bookmark-jump bmkp-jump-gnus bmkext-jump-gnus))) + +(defun bmkp-info-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is an Info bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'Info-bookmark-jump) + (and (not (bookmark-get-handler bookmark)) + (or (string= "*info*" (bmkp-get-buffer-name bookmark)) + (bookmark-prop-get bookmark 'info-node))))) ; Emacs 20-21 - no `buffer-name' entry. + +(defun bmkp-local-directory-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks a local directory. +BOOKMARK is a bookmark name or a bookmark record." + (let ((file (bookmark-get-filename bookmark))) + (and (bmkp-local-file-bookmark-p bookmark) (file-directory-p file)))) + +(defun bmkp-local-file-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks a local file or directory. +BOOKMARK is a bookmark name or a bookmark record. +This excludes bookmarks of a more specific kind (e.g. Info, Gnus)." + (and (bmkp-file-bookmark-p bookmark) (not (bmkp-remote-file-bookmark-p bookmark)))) + +(defun bmkp-man-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a `man' page bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (memq (bookmark-get-handler bookmark) '(bmkp-jump-man bmkp-jump-woman + bmkext-jump-man bmkext-jump-woman))) + +(defun bmkp-marked-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a marked bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (unless (stringp bookmark) (setq bookmark (car bookmark))) + (bmkp-bookmark-name-member bookmark bmkp-bmenu-marked-bookmarks)) + +(defun bmkp-non-file-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a non-file bookmark (e.g *scratch*). +This excludes bookmarks of a more specific kind (e.g. Info, Gnus). +It includes bookmarks to existing buffers, as well as bookmarks +defined for buffers that do not currently exist." + (let* ((filename (bookmark-get-filename bookmark)) + (nonfile-p (equal filename bmkp-non-file-filename))) + (and (bmkp-get-buffer-name bookmark) + (or (not filename) nonfile-p + ;; Ensure not remote before calling `file-exists-p'. (Do not prompt for password.) + (and (not (bmkp-file-remote-p filename)) (not (file-exists-p filename)))) + (not (bookmark-get-handler bookmark))))) + +(defun bmkp-region-bookmark-p (bookmark) + "Return non-nil if BOOKMARK has region information. +BOOKMARK is a bookmark name or a bookmark record." + (and (bmkp-get-end-position bookmark) + (/= (bookmark-get-position bookmark) (bmkp-get-end-position bookmark)))) + +(defun bmkp-remote-file-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks a remote file or directory. +BOOKMARK is a bookmark name or a bookmark record. +This includes remote Dired bookmarks, but otherwise excludes bookmarks +with handlers (e.g. Info, Gnus)." + (let* ((handler (bookmark-get-handler bookmark)) + (file (bookmark-get-filename bookmark)) + (rem-file (and file (bmkp-file-remote-p file)))) + (and rem-file (or (not handler) (eq handler 'bmkp-jump-dired))))) + +(defun bmkp-this-buffer-p (bookmark) + "Return non-nil if BOOKMARK's buffer is the current buffer. +But return nil for bookmarks, such as desktops, that are not really +associated with a buffer, even if they have a `buffer-name' entry. +BOOKMARK is a bookmark name or a bookmark record." + (and (equal (bmkp-get-buffer-name bookmark) (buffer-name)) + (not (bmkp-desktop-bookmark-p bookmark)) + (not (bmkp-bookmark-file-bookmark-p bookmark)) + (not (bmkp-sequence-bookmark-p bookmark)) + (not (bmkp-function-bookmark-p bookmark)) + (not (bmkp-variable-list-bookmark-p bookmark)))) + +(defun bmkp-this-file-p (bookmark) + "Return non-nil if BOOKMARK's filename is the current (absolute) file name. +BOOKMARK is a bookmark name or a bookmark record." + (let ((bmk-file (bookmark-get-filename bookmark)) + (this-file (or (buffer-file-name) (and (eq major-mode 'dired-mode) (if (consp dired-directory) + (car dired-directory) + dired-directory))))) + (and bmk-file (equal bmk-file this-file)))) + +(defun bmkp-last-specific-buffer-p (bookmark) + "Return t if BOOKMARK's `buffer-name' is `bmkp-last-specific-buffer'. +But return nil for bookmarks, such as desktops, that are not really +associated with a buffer, even if they have a `buffer-name' entry. +It does not matter whether the buffer exists. +BOOKMARK is a bookmark name or a bookmark record." + (let ((buf (bmkp-get-buffer-name bookmark))) + (and buf (string= buf bmkp-last-specific-buffer) + (not (bmkp-desktop-bookmark-p bookmark)) + (not (bmkp-bookmark-file-bookmark-p bookmark)) + (not (bmkp-sequence-bookmark-p bookmark)) + (not (bmkp-function-bookmark-p bookmark)) + (not (bmkp-variable-list-bookmark-p bookmark))))) + +(defun bmkp-last-specific-file-p (bookmark) + "Return t if BOOKMARK's `filename' is `bmkp-last-specific-file'. +BOOKMARK is a bookmark name or a bookmark record." + (let ((file (bookmark-get-filename bookmark))) + (and file (string= file bmkp-last-specific-file)))) + +(defun bmkp-sequence-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a sequence bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-sequence)) + +(defun bmkp-url-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a URL bookmark. +That means that it satifies either `bmkp-url-browse-bookmark-p' or +`bmkp-w3m-bookmark-p'. +BOOKMARK is a bookmark name or a bookmark record." + (or (bmkp-url-browse-bookmark-p bookmark) (bmkp-w3m-bookmark-p bookmark))) + +(defun bmkp-url-browse-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a `browse-url' bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-url-browse)) + +(defun bmkp-variable-list-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a variable-list bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'bmkp-jump-variable-list)) + +(defun bmkp-w3m-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a W3M bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (memq (bookmark-get-handler bookmark) '(bmkp-jump-w3m bmkext-jump-w3m))) + + +;;(@* "Filter Functions") +;; *** Filter Functions *** + +(defun bmkp-all-tags-alist-only (tags) + "`bookmark-alist', but with only bookmarks having all their tags in TAGS. +Does not include bookmarks that have no tags. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (member (bmkp-tag-name tag) tags)) bmk-tags)))) + bookmark-alist)) + +(defun bmkp-all-tags-regexp-alist-only (regexp) + "`bookmark-alist', but with only bookmarks having all tags match REGEXP. +Does not include bookmarks that have no tags. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + bmk-tags)))) + bookmark-alist)) + +(defun bmkp-annotated-alist-only () + "`bookmark-alist', but only for bookmarks with non-empty annotations. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) + (let ((annotation (bookmark-get-annotation bmk))) + (and annotation (not (string-equal annotation ""))))) + bookmark-alist)) + +(defun bmkp-autofile-alist-only (&optional prefix) + "`bookmark-alist', filtered to retain only autofile bookmarks. +With non-nil arg PREFIX, the bookmark names must all have that PREFIX." + (bookmark-maybe-load-default-file) + (if (not prefix) + (bmkp-remove-if-not #'bmkp-autofile-bookmark-p bookmark-alist) + (bmkp-remove-if-not #'(lambda (bb) (bmkp-autofile-bookmark-p bb prefix)) bookmark-alist))) + +(defun bmkp-autonamed-alist-only () + "`bookmark-alist', with only autonamed bookmarks (from any buffers). +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-autonamed-bookmark-p bookmark-alist)) + +(defun bmkp-autonamed-this-buffer-alist-only () + "`bookmark-alist', with only autonamed bookmarks for the current buffer. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (bmkp-autonamed-bookmark-for-buffer-p bmk (buffer-name))) + bookmark-alist)) + +(defun bmkp-bookmark-file-alist-only () + "`bookmark-alist', filtered to retain only bookmark-file bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-bookmark-file-bookmark-p bookmark-alist)) + +(defun bmkp-bookmark-list-alist-only () + "`bookmark-alist', filtered to retain only bookmark-list bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-bookmark-list-bookmark-p bookmark-alist)) + +(defun bmkp-desktop-alist-only () + "`bookmark-alist', filtered to retain only desktop bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-desktop-bookmark-p bookmark-alist)) + +(defun bmkp-dired-alist-only () + "`bookmark-alist', filtered to retain only Dired bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-dired-bookmark-p bookmark-alist)) + +(defun bmkp-dired-this-dir-alist-only () + "`bookmark-alist', with only Dired bookmarks for the current directory. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-dired-this-dir-bookmark-p bookmark-alist)) + +(defun bmkp-file-alist-only () + "`bookmark-alist', filtered to retain only file and directory bookmarks. +This excludes bookmarks that might contain file information but are +particular in some way - for example, Info bookmarks or Gnus bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-file-bookmark-p bookmark-alist)) + +(defun bmkp-file-all-tags-alist-only (tags) + "`bookmark-alist', with only file bookmarks having all tags in TAGS. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (and (bmkp-file-bookmark-p bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))) + bookmark-alist)) + +(defun bmkp-file-all-tags-regexp-alist-only (regexp) + "`bookmark-alist', with only file bookmarks having all tags match REGEXP. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (and (bmkp-file-bookmark-p bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + bmk-tags))))) + bookmark-alist)) + +(defun bmkp-file-some-tags-alist-only (tags) + "`bookmark-alist', with only file bookmarks having some tags in TAGS. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) (and (bmkp-file-bookmark-p bmk) + (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))) + bookmark-alist)) + +(defun bmkp-file-some-tags-regexp-alist-only (regexp) + "`bookmark-alist', with only file bookmarks having some tags match REGEXP. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) (and (bmkp-file-bookmark-p bmk) + (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + (bmkp-get-tags bmk)))) + bookmark-alist)) + +(defun bmkp-file-this-dir-alist-only () + "`bookmark-alist', filtered with `bmkp-file-this-dir-bookmark-p'. +Include only files and subdir that are in `default-directory'. +This excludes bookmarks that might contain file information but are +particular in some way - for example, Info bookmarks or Gnus bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-file-this-dir-bookmark-p bookmark-alist)) + +(defun bmkp-file-this-dir-all-tags-alist-only (tags) + "`bookmark-alist', for files in this dir having all tags in TAGS. +Include only files and subdir that are in `default-directory'. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (and (bmkp-file-this-dir-bookmark-p bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))) + bookmark-alist)) + +(defun bmkp-file-this-dir-all-tags-regexp-alist-only (regexp) + "`bookmark-alist', for files in this dir having all tags match REGEXP. +Include only files and subdir that are in `default-directory'. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (and (bmkp-file-this-dir-bookmark-p bmk) + (let ((bmk-tags (bmkp-get-tags bmk))) + (and bmk-tags (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + bmk-tags))))) + bookmark-alist)) + +(defun bmkp-file-this-dir-some-tags-alist-only (tags) + "`bookmark-alist', for files in this dir having some tags in TAGS. +Include only files and subdir that are in `default-directory'. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) (and (bmkp-file-this-dir-bookmark-p bmk) + (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))) + bookmark-alist)) + +(defun bmkp-file-this-dir-some-tags-regexp-alist-only (regexp) + "`bookmark-alist', for files in this dir having some tags match REGEXP. +Include only files and subdir that are in `default-directory'. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) (and (bmkp-file-this-dir-bookmark-p bmk) + (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + (bmkp-get-tags bmk)))) + bookmark-alist)) + +(defun bmkp-gnus-alist-only () + "`bookmark-alist', filtered to retain only Gnus bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-gnus-bookmark-p bookmark-alist)) + +(defun bmkp-info-alist-only () + "`bookmark-alist', filtered to retain only Info bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-info-bookmark-p bookmark-alist)) + +(defun bmkp-last-specific-buffer-alist-only () + "`bookmark-alist', but only for `bmkp-last-specific-buffer'. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-last-specific-buffer-p bookmark-alist)) + +(defun bmkp-last-specific-file-alist-only () + "`bookmark-alist', but only for `bmkp-last-specific-file'. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-last-specific-file-p bookmark-alist)) + +(defun bmkp-man-alist-only () + "`bookmark-alist', filtered to retain only `man' page bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-man-bookmark-p bookmark-alist)) + +(defun bmkp-local-file-alist-only () + "`bookmark-alist', filtered to retain only local-file bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-local-file-bookmark-p bookmark-alist)) + +(defun bmkp-non-autonamed-alist-only () + "`bookmark-alist', with only non-autonamed bookmarks (from any buffers). +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (not (bmkp-autonamed-bookmark-p bmk))) bookmark-alist)) + +(defun bmkp-non-file-alist-only () + "`bookmark-alist', filtered to retain only non-file bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-non-file-bookmark-p bookmark-alist)) + +(defun bmkp-regexp-filtered-annotation-alist-only () + "`bookmark-alist' for annotations matching `bmkp-bmenu-filter-pattern'." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not + #'(lambda (bmk) + (let ((annot (bookmark-get-annotation bmk))) + (and (stringp annot) (not (string= "" annot)) + (string-match bmkp-bmenu-filter-pattern annot)))) + bookmark-alist)) ; (Could use `bmkp-annotated-alist-only' here instead.) + +(defun bmkp-regexp-filtered-bookmark-name-alist-only () + "`bookmark-alist' for bookmarks matching `bmkp-bmenu-filter-pattern'." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not + #'(lambda (bmk) (string-match bmkp-bmenu-filter-pattern (car bmk))) bookmark-alist)) + +(defun bmkp-regexp-filtered-file-name-alist-only () + "`bookmark-alist' for files matching `bmkp-bmenu-filter-pattern'." + (bookmark-maybe-load-default-file) + (let (fname) + (bmkp-remove-if-not #'(lambda (bmk) (and (setq fname (bookmark-get-filename bmk)) + (string-match bmkp-bmenu-filter-pattern fname))) + bookmark-alist))) + +(defun bmkp-regexp-filtered-tags-alist-only () + "`bookmark-alist' for tags matching `bmkp-bmenu-filter-pattern'." + (bookmark-maybe-load-default-file) + (let (tags) + (bmkp-remove-if-not + #'(lambda (bmk) (and (setq tags (bmkp-get-tags bmk)) + (bmkp-some (lambda (tag) + (string-match bmkp-bmenu-filter-pattern (bmkp-tag-name tag))) + tags))) + bookmark-alist))) + +(defun bmkp-region-alist-only () + "`bookmark-alist', filtered to retain only bookmarks that have regions. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-region-bookmark-p bookmark-alist)) + +(defun bmkp-remote-file-alist-only () + "`bookmark-alist', filtered to retain only remote-file bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-remote-file-bookmark-p bookmark-alist)) + +(defun bmkp-some-tags-alist-only (tags) + "`bookmark-alist', but with only bookmarks having some tags in TAGS. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags)) + bookmark-alist)) + +(defun bmkp-some-tags-regexp-alist-only (regexp) + "`bookmark-alist', but with only bookmarks having some tags match REGEXP. +A new list is returned (no side effects)." + (bmkp-remove-if-not + #'(lambda (bmk) + (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) (bmkp-get-tags bmk))) + bookmark-alist)) + +(defun bmkp-specific-buffers-alist-only (&optional buffers) + "`bookmark-alist', filtered to retain only bookmarks to buffers BUFFERS. +BUFFERS is a list of buffer names. +It defaults to a singleton list with the current buffer's name. +A new list is returned (no side effects). + +Note: Bookmarks created by vanilla Emacs do not record the buffer +name. They are therefore excluded from the returned alist." + (unless buffers (setq buffers (list (buffer-name)))) + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (and (not (bmkp-desktop-bookmark-p bmk)) ; Exclude these + (not (bmkp-bookmark-file-bookmark-p bmk)) + (not (bmkp-sequence-bookmark-p bmk)) + (not (bmkp-function-bookmark-p bmk)) + (not (bmkp-variable-list-bookmark-p bmk)) + (member (bmkp-get-buffer-name bmk) buffers))) + bookmark-alist)) + +(defun bmkp-specific-files-alist-only (&optional files) + "`bookmark-alist', filtered to retain only bookmarks to files FILES. +FILES is a list of absolute file names. +It defaults to a singleton list with the current buffer's file name. +A new list is returned (no side effects)." + (unless files (setq files (list (buffer-file-name)))) + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (member (bookmark-get-filename bmk) files)) bookmark-alist)) + +(defun bmkp-this-buffer-alist-only () + "`bookmark-alist', with only bookmarks for the current buffer. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-this-buffer-p bookmark-alist)) + +(defun bmkp-this-file-alist-only () + "`bookmark-alist', with only bookmarks for the current file. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-this-file-p bookmark-alist)) + +(defun bmkp-url-alist-only () + "`bookmark-alist', filtered to retain only URL bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-url-bookmark-p bookmark-alist)) + +(defun bmkp-url-browse-alist-only () + "`bookmark-alist', filtered to retain only non-W3M URL bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-url-browse-bookmark-p bookmark-alist)) + +(defun bmkp-variable-list-alist-only () + "`bookmark-alist', filtered to retain only variable-list bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-variable-list-bookmark-p bookmark-alist)) + +(defun bmkp-w3m-alist-only () + "`bookmark-alist', filtered to retain only W3M bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not #'bmkp-w3m-bookmark-p bookmark-alist)) + + +;;; Marked bookmarks + +(defun bmkp-marked-bookmarks-only () + "Return the list of marked bookmarks." + (bmkp-remove-if-not #'bmkp-marked-bookmark-p bookmark-alist)) + +(defun bmkp-unmarked-bookmarks-only () + "Return the list of unmarked bookmarks." + (bmkp-remove-if #'bmkp-marked-bookmark-p bookmark-alist)) + +(defun bmkp-some-marked-p (alist) + "Return non-nil if ALIST is nonempty and includes a marked bookmark." + (catch 'break (dolist (i alist) (and (bmkp-marked-bookmark-p i) (throw 'break t))))) + +(defun bmkp-some-unmarked-p (alist) + "Return non-nil if ALIST is nonempty and includes an unmarked bookmark." + (catch 'break (dolist (i alist) (and (not (bmkp-marked-bookmark-p i)) (throw 'break t))))) + + +;;(@* "General Utility Functions") +;; *** General Utility Functions *** + +(defun bmkp-remove-dups (list) + "Copy of LIST with duplicate elements removed. Tested with `equal'." + (let ((tail list) + new) + (while tail + (unless (member (car tail) new) (push (car tail) new)) + (pop tail)) + (nreverse new))) + +;; Similar to `bmkp-assoc-delete-all', but compares also property `bmkp-full-record'. +(defun bmkp-delete-bookmark-name-from-list (delname bnames) + "Delete names that represent the same bookmark as DELNAME from BNAMES. +This menas that they are `string=' and have the same value of property +`bmkp-full-record'. +Return the modified list BNAMES." + (let ((delprop (get-text-property 0 'bmkp-full-record delname))) + (if (not delprop) + (delete delname bnames) ; Unpropertized - just use `delete'. + (while (and bnames (string= delname (car bnames)) + (eq delprop (get-text-property 0 'bmkp-full-record (car bnames)))) + (setq bnames (cdr bnames))) + (let ((tail bnames) + tail-cdr) + (while (setq tail-cdr (cdr tail)) + (if (and (car tail-cdr) (string= delname (car tail-cdr)) + (eq delprop (get-text-property 0 'bmkp-full-record (car tail-cdr)))) + (setcdr tail (cdr tail-cdr)) + (setq tail tail-cdr)))) + bnames))) + +(defun bmkp-bookmark-name-member (name names) ; $$$$$$ PUT BACK `eq' instead of `equal'?. + "Like `member', but tests also bookmark NAME's `bmkp-full-record' property. +If NAME has no `bmkp-full-record' property then this is just `member'. + +If NAME has property `bmkp-full-record', then test whether both: + a. NAME is a member of NAMES and + b. NAME has the same `bmkp-full-record' value as an element of NAMES. +Return the tail of NAMES whose car is NAME with the property match." + (let ((prop (get-text-property 0 'bmkp-full-record name))) + (if (not prop) + (member name names) ; Unpropertized - just use `member'. + (while (and names (not (and (string= name (car names)) ; = `bmkp-names-same-bookmark-p'. + (equal prop (get-text-property 0 'bmkp-full-record (car names)))))) + (setq names (cdr names))) + names))) + +(defun bmkp-names-same-bookmark-p (name1 name2) ; $$$$$$ PUT BACK `eq' instead of `equal'?. + "Return non-nil if the two strings name the same bookmark. +The strings are `string=' and their `bmkp-full-record' property values +for the first character are `eq'." + (and (string= name1 name2) + (equal (get-text-property 0 'bmkp-full-record name1) + (get-text-property 0 'bmkp-full-record name2)))) + +(defun bmkp-remove-if (pred xs) + "A copy of list XS with no elements that satisfy predicate PRED." + (let ((result ())) + (dolist (x xs) (unless (funcall pred x) (push x result))) + (nreverse result))) + +(defun bmkp-remove-if-not (pred xs) + "A copy of list XS with only elements that satisfy predicate PRED." + (let ((result ())) + (dolist (x xs) (when (funcall pred x) (push x result))) + (nreverse result))) + +;; Similar to `every' in `cl-extra.el', without non-list sequences and multiple sequences. +(defun bmkp-every (predicate list) + "Return t if PREDICATE is true for all elements of LIST; else nil." + (while (and list (funcall predicate (car list))) (setq list (cdr list))) + (null list)) + +;; Similar to `some' in `cl-extra.el', without non-list sequences and multiple sequences. +(defun bmkp-some (predicate list) + "Return non-nil if PREDICATE is true for some element of LIST; else nil. +Return the first non-nil value returned by PREDICATE." + (let ((res nil)) + (while (and list (not (setq res (funcall predicate (pop list)))))) + res)) + +;; From `cl-seq.el', function `union', without keyword treatment. +;; (Same as `simple-set-union' in `misc-fns.el' and `icicle-set-union' in `icicles-fn.el'.) +(defun bmkp-set-union (list1 list2) + "Combine LIST1 and LIST2 using a set-union operation. +The result list contains all items that appear in either LIST1 or +LIST2. Comparison is done using `equal'. This is a non-destructive +function; it copies the data if necessary." + (cond ((null list1) list2) + ((null list2) list1) + ((equal list1 list2) list1) + (t + (unless (>= (length list1) (length list2)) + (setq list1 (prog1 list2 (setq list2 list1)))) ; Swap them. + (while list2 + (unless (member (car list2) list1) (setq list1 (cons (car list2) list1))) + (setq list2 (cdr list2))) + list1))) + +(defun bmkp-upcase (string) + "`upcase', but in case of error, return original STRING. +This works around an Emacs 20 problem that occurs if STRING contains +binary data (weird chars)." + (condition-case nil (upcase string) (error string))) + +(defun bmkp-same-file-p (file1 file2) + "Return non-nil if FILE1 and FILE2 name the same file. +If either name is not absolute, then it is considered relative to +`default-directory'." + (string= (file-truename (expand-file-name file1)) (file-truename (expand-file-name file2)))) + +(defun bmkp-file-remote-p (file-name) + "Returns non-nil if string FILE-NAME is likely to name a remote file." + (if (fboundp 'file-remote-p) + (file-remote-p file-name) + (and (fboundp 'ffap-file-remote-p) (ffap-file-remote-p file-name)))) + +(defun bmkp-float-time (&optional specified-time) + "Same as `float-time'. (Needed for Emacs 20.)" + (if (fboundp 'float-time) + (float-time specified-time) + (unless specified-time (setq specified-time (current-time))) + (+ (* (float (nth 0 specified-time)) (expt 2 16)) (nth 1 specified-time)))) + +(defun bmkp-face-prop (value) + "Return a list with elements `face' or `font-lock-face' and VALUE. +Starting with Emacs 22, the first element is `font-lock-face'." + (list (if (> emacs-major-version 21) 'font-lock-face 'face) value)) + +(defun bmkp-make-plain-predicate (pred &optional final-pred) + "Return a plain predicate that corresponds to component-predicate PRED. +PRED and FINAL-PRED correspond to their namesakes in +`bmkp-sort-comparer' (which see). + +PRED should return `(t)', `(nil)', or nil. + +Optional arg FINAL-PRED is the final predicate to use if PRED cannot +decide (returns nil). If FINAL-PRED is nil, then `bmkp-alpha-p', the +plain-predicate equivalent of `bmkp-alpha-cp' is used as the final +predicate." + `(lambda (b1 b2) (let ((res (funcall ',pred b1 b2))) + (if res (car res) (funcall ',(or final-pred 'bmkp-alpha-p) b1 b2))))) + +(defun bmkp-repeat-command (command) + "Repeat COMMAND." + (let ((repeat-message-function 'ignore)) + (setq last-repeatable-command command) + (repeat nil))) + + +;;; If you need this for some reason, uncomment it. +;;; (defun bmkp-fix-bookmark-alist-and-save () +;;; "Update format of `bookmark-default-file' created in summer of 2009. +;;; You DO NOT NEED THIS, unless you happen to have used `bookmark+.el' in +;;; the summer of 2009 to create non-file bookmarks. If you did that, +;;; then some of those bookmarks might cause vanilla Emacs (emacs -Q) to +;;; raise an error. You can use this command to fix that problem: it +;;; modifies your existing `bookmark-default-file' (`.emacs.bmk'), after +;;; backing up that file (suffixing the name with \"_saveNUMBER\")." +;;; (interactive) +;;; (require 'cl) ; For `gensym' +;;; (if (not (yes-or-no-p +;;; "This will modify your bookmark file, after backing it up. OK? ")) +;;; (message "OK, nothing done") +;;; (bookmark-maybe-load-default-file) +;;; (let ((bkup-file (concat bookmark-default-file "_" (symbol-name (gensym "save"))))) +;;; (when (condition-case err +;;; (progn +;;; (with-current-buffer (find-file-noselect bookmark-default-file) +;;; (write-file bkup-file)) +;;; (dolist (bmk bookmark-alist) +;;; (let ((fn-tail (member '(filename) bmk)) +;;; (hdlr (bookmark-get-handler (car bmk)))) +;;; (cond (fn-tail +;;; (setcar fn-tail (cons 'filename bmkp-non-file-filename))) +;;; ((and (eq hdlr 'bmkp-jump-gnus) +;;; (not (assoc 'filename bmk))) +;;; (setcdr bmk (cons (cons 'filename bmkp-non-file-filename) +;;; (cdr bmk))))))) +;;; t) ; Be sure `dolist' exit with t to allow saving. +;;; (error (error "No changes made. %s" (error-message-string err)))) +;;; (bookmark-save) +;;; (message "Bookmarks file fixed. Old version is `%s'" bkup-file))))) + + +;;(@* "Bookmark Entry Access Functions") +;; *** Bookmark Entry Access Functions *** + +(defun bmkp-get-buffer-name (bookmark) + "Return the `buffer-name' value for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'buffer-name)) + +(defun bmkp-get-end-position (bookmark) + "Return the `end-position' value for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'end-position)) + +(defun bmkp-get-visits-count (bookmark) + "Return the `visits' count for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'visits)) + +(defun bmkp-get-visit-time (bookmark) + "Return the `time' value for BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + ;; Should just be a prop-get, but when first implemented, we used a float + ;; instead of a time cons, so we need to convert any such obsolete recorded times. + (let ((vt (bookmark-prop-get bookmark 'time))) + (when (numberp vt) ; Convert mid-2009 time values (floats) to cons form. + (setq vt (if (boundp 'seconds-to-time) + (seconds-to-time vt) + (list (floor vt 65536) ; Inlined `seconds-to-time', for Emacs 20-21. + (floor (mod vt 65536)) + (floor (* (- vt (ffloor vt)) 1000000)))))) + vt)) + + +;;(@* "Sorting - General Functions") +;; *** Sorting - General Functions *** + +(defun bmkp-sort-omit (alist &optional omit) + "Sort a copy of ALIST, omitting any elements whose keys are in OMIT. +Return the copy. +Do not sort if `bmkp-sort-comparer' is nil. +This is a non-destructive operation: ALIST is not modified. + +Sorting is done using using `bmkp-sort-comparer'. +If `bmkp-reverse-sort-p' is non-nil, then reverse the sort order. +Keys are compared for sorting using `equal'. + +If optional arg OMIT is non-nil, then it is a list of keys. Omit from +the return value any elements with keys in the list." + (let ((new-alist (bmkp-remove-omitted alist omit)) + (sort-fn (and bmkp-sort-comparer (if (and (not (functionp bmkp-sort-comparer)) + (consp bmkp-sort-comparer)) + 'bmkp-multi-sort + bmkp-sort-comparer)))) + (when sort-fn + (setq new-alist (sort new-alist (if bmkp-reverse-sort-p + (lambda (a b) (not (funcall sort-fn a b))) + sort-fn)))) + new-alist)) + +(defun bmkp-remove-omitted (alist &optional omit) + "Copy of bookmark ALIST without bookmarks whose names are in list OMIT. +Name comparison is done using `bmkp-bookmark-name-member'. +If optional arg OMIT is non-nil, then omit from the return value any +elements with keys in list OMIT." + (let ((new ())) + (dolist (ii alist) (unless (bmkp-bookmark-name-member (car ii) omit) (push ii new))) + (nreverse new))) + +;;; $$$$$$ No longer used. +;;; (defun bmkp-sort-and-remove-dups (alist &optional omit) +;;; "Remove duplicates from a copy of ALIST, then sort it and return it. +;;; Do not sort if `bmkp-sort-comparer' is nil. +;;; Always remove duplicates. Keep only the first element with a given +;;; key. This is a non-destructive operation: ALIST is not modified. + +;;; Sorting is done using using `bmkp-sort-comparer'. +;;; If `bmkp-reverse-sort-p' is non-nil, then reverse the sort order. +;;; Keys are compared for sorting using `equal'. +;;; If optional arg OMIT is non-nil, then omit from the return value any +;;; elements with keys in list OMIT." +;;; (let ((new-alist (bmkp-remove-assoc-dups alist omit)) +;;; (sort-fn (and bmkp-sort-comparer (if (and (not (functionp bmkp-sort-comparer)) +;;; (consp bmkp-sort-comparer)) +;;; 'bmkp-multi-sort +;;; bmkp-sort-comparer)))) +;;; (when sort-fn +;;; (setq new-alist (sort new-alist (if bmkp-reverse-sort-p +;;; (lambda (a b) (not (funcall sort-fn a b))) +;;; sort-fn)))) +;;; new-alist)) + +;;; KEEP this simpler version also. This uses `run-hook-with-args-until-success', but it +;;; does not respect `bmkp-reverse-multi-sort-p'. +;;; (defun bmkp-multi-sort (b1 b2) +;;; "Try predicates in `bmkp-sort-comparer', in order, until one decides. +;;; See the description of `bmkp-sort-comparer'." +;;; (let* ((preds (append (car bmkp-sort-comparer) (cdr bmkp-sort-comparer))) +;;; (result (run-hook-with-args-until-success 'preds b1 b2))) +;;; (if (consp result) +;;; (car result) +;;; result))) + +;;; $$$$$$ No longer used. +;;; (defun bmkp-remove-assoc-dups (alist &optional omit) +;;; "Shallow copy of ALIST without elements that have duplicate keys. +;;; Only the first element of those with the same key is kept. +;;; Keys are compared using `equal'. +;;; If optional arg OMIT is non-nil, then omit from the return value any +;;; elements with keys in list OMIT." +;;; (let ((new ())) +;;; (dolist (ii alist) (unless (or (assoc (car ii) new) (member (car ii) omit)) (push ii new))) +;;; (nreverse new))) + + +;; This Lisp definition respects `bmkp-reverse-multi-sort-p', and can be extended. +(defun bmkp-multi-sort (b1 b2) + "Try predicates in `bmkp-sort-comparer', in order, until one decides. +See the description of `bmkp-sort-comparer'. +If `bmkp-reverse-multi-sort-p' is non-nil, then reverse the order for +using multi-sorting predicates." + (let ((preds (car bmkp-sort-comparer)) + (final-pred (cadr bmkp-sort-comparer)) + (result nil)) + (when bmkp-reverse-multi-sort-p (setq preds (reverse preds))) + (catch 'bmkp-multi-sort + (dolist (pred preds) + (setq result (funcall pred b1 b2)) + (when (consp result) + (when bmkp-reverse-multi-sort-p (setq result (list (not (car result))))) + (throw 'bmkp-multi-sort (car result)))) + (and final-pred (if bmkp-reverse-multi-sort-p + (not (funcall final-pred b1 b2)) + (funcall final-pred b1 b2)))))) + +;; The message is only approximate. The effect of `bmkp-reverse-multi-sort-p' is not +;; always intuitive, but it can often be useful. What's not always intuitive is the placement +;; (the order) of bookmarks that are not sorted by the PREDs. +;; +(defun bmkp-msg-about-sort-order (order &optional prefix-msg suffix-msg) + "Display a message mentioning the current sort ORDER and direction. +Optional arg PREFIX-MSG is prepended to the constructed message, and +terminated with a period. +Similarly, SUFFIX-MSG is appended, after appending \". \"." + (let ((msg (if (not bmkp-sort-comparer) + "Bookmarks NOT sorted" + (format "%s%s" (concat "Sorted " order) + (if (not (and (consp bmkp-sort-comparer) ; Ordinary single predicate. + (consp (car bmkp-sort-comparer)))) + (if bmkp-reverse-sort-p "; REVERSED" "") + (if (not (cadr (car bmkp-sort-comparer))) + ;; Single PRED. + (if (or (and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + (and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p))) + "; REVERSED" + "") + + ;; In case we want to distinguish: + ;; (if (and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + ;; "; reversed" + ;; (if (and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p)) + ;; "; reversed +" + ;; "")) + + ;; At least two PREDs. + (cond ((and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + "; REVERSED") + ((and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p)) + "; each predicate group reversed") + ((and bmkp-reverse-multi-sort-p bmkp-reverse-sort-p) + "; order of predicate groups reversed") + (t "")))))))) + (when prefix-msg (setq msg (concat prefix-msg ". " msg))) + (when suffix-msg (setq msg (concat msg ". " suffix-msg))) + (message msg))) + + +;;(@* "Sorting - Commands") +;; *** Sorting - Commands *** + +(defun bmkp-current-sort-order () + "Current sort order or sort function, as a string suitable in a message." + (or (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist)) (format "%s" bmkp-sort-comparer))) + + +;;(@* "Sorting - General Predicates") +;; *** Sorting - General Predicates *** + +(defun bmkp-marked-cp (b1 b2) + "True if bookmark B1 is marked and bookmark B2 is not. +B1 and B2 are bookmarks or bookmark names. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if incomparable as described." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((m1 (bmkp-marked-bookmark-p b1)) + (m2 (bmkp-marked-bookmark-p b2))) + (cond ((and m1 m2) nil) + (m1 '(t)) + (m2 '(nil)) + (t nil)))) + +(defun bmkp-visited-more-cp (b1 b2) + "True if bookmark B1 was visited more often than B2. +B1 and B2 are bookmarks or bookmark names. +True also if B1 was visited but B2 was not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if incomparable as described." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((v1 (bmkp-get-visits-count b1)) + (v2 (bmkp-get-visits-count b2))) + (cond ((and v1 v2) + (cond ((> v1 v2) '(t)) + ((> v2 v1) '(nil)) + (t nil))) + (v1 '(t)) + (v2 '(nil)) + (t nil)))) + +(defun bmkp-bookmark-creation-cp (b1 b2) + "True if bookmark B1 was created more recently than B2. +B1 and B2 are bookmarks or bookmark names. +True also if B1 has a `created' entry but B2 has none. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if incomparable as described." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((t1 (bookmark-prop-get b1 'created)) + (t2 (bookmark-prop-get b2 'created))) + (cond ((and t1 t2) + (setq t1 (bmkp-float-time t1) + t2 (bmkp-float-time t2)) + (cond ((> t1 t2) '(t)) + ((> t2 t1) '(nil)) + (t nil))) + (t1 '(t)) + (t2 '(nil)) + (t nil)))) + +;; Not used currently. +(defun bmkp-same-creation-time-p (b1 b2) + "Return non-nil if `B1 and B2 have same `created' entry. +B1 and B2 are bookmarks or bookmark names. +If neither has a `created' entry (vanilla bookmarks), then return +non-nil if the full bookmarks are `equal'." + (let ((time1 (bookmark-prop-get b1 'created)) + (time2 (bookmark-prop-get b2 'created))) + (if (or time1 time2) + (equal time1 time2) + (equal b1 b2)))) + +(defun bmkp-bookmark-last-access-cp (b1 b2) + "True if bookmark B1 was visited more recently than B2. +B1 and B2 are bookmarks or bookmark names. +True also if B1 was visited but B2 was not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if incomparable as described." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((t1 (bmkp-get-visit-time b1)) + (t2 (bmkp-get-visit-time b2))) + (cond ((and t1 t2) + (setq t1 (bmkp-float-time t1) + t2 (bmkp-float-time t2)) + (cond ((> t1 t2) '(t)) + ((> t2 t1) '(nil)) + (t nil))) + (t1 '(t)) + (t2 '(nil)) + (t nil)))) + +(defun bmkp-buffer-last-access-cp (b1 b2) + "True if bookmark B1's buffer or file was visited more recently than B2's. +B1 and B2 are bookmarks or bookmark names. +A bookmark to an existing buffer sorts before a file bookmark, even if +the buffer has not been visited during this session. + +True also if B1 has a buffer but B2 does not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if incomparable as described." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((buf1 (bmkp-get-buffer-name b1)) + (buf2 (bmkp-get-buffer-name b2)) + f1 f2 t1 t2) + (setq buf1 (and buf1 (get-buffer buf1)) + buf2 (and buf2 (get-buffer buf2))) + (cond ((and buf1 buf2) ; Both buffers exist. See whether they were accessed. + (when buf1 (setq buf1 (member buf1 (buffer-list)) + buf1 (length buf1))) + (when buf2 (setq buf2 (member buf2 (buffer-list)) + buf2 (length buf2))) + (cond ((and buf1 buf2) ; Both were accessed. Priority to most recent access. + (cond ((< buf1 buf2) '(t)) + ((< buf2 buf1) '(nil)) + (t nil))) + (buf1 '(t)) ; Only buf1 was accessed. + (buf2 '(nil)) ; Only buf2 was accessed. + (t nil))) ; Neither was accessed. + + (buf1 '(t)) ; Only buf1 exists. + (buf2 '(nil)) ; Only buf2 exists. + (t nil)))) ; Neither buffer exists + +(defun bmkp-handler-cp (b1 b2) + "True if bookmark B1's handler name sorts alphabetically before B2's. +B1 and B2 are bookmarks or bookmark names. +Two bookmarks with handlers are compared alphabetically, by their +handler-function names, respecting `case-fold-search'. +True also if B1 has a handler but B2 has not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((h1 (bookmark-get-handler b1)) + (h2 (bookmark-get-handler b2))) + (cond ((and h1 h2 (symbolp h1) (symbolp h2)) + ;; Pretend woman bookmarks are man bookmarks, to keep them together. + (when (eq h1 'bmkp-jump-woman) (setq h1 'bmkp-jump-man)) + (when (eq h2 'bmkp-jump-woman) (setq h2 'bmkp-jump-man)) + (setq h1 (symbol-name h1) + h2 (symbol-name h2)) + (when case-fold-search (setq h1 (bmkp-upcase h1) + h2 (bmkp-upcase h2))) + (cond ((string-lessp h1 h2) '(t)) + ((string-lessp h2 h1) '(nil)) + (t nil))) + (h1 '(t)) + (h2 '(nil)) + (t nil)))) + +(defun bmkp-info-cp (b1 b2) + "True if bookmark B1 sorts as an Info bookmark before B2. +B1 and B2 are bookmarks or bookmark names. +Two Info bookmarks are compared first by file name (corresponding to +the manual), then by node name, then by position. +True also if B1 is an Info bookmark but B2 is not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((i1 (bmkp-info-bookmark-p b1)) + (i2 (bmkp-info-bookmark-p b2))) + (cond ((and i1 i2) + (setq i1 (abbreviate-file-name (bookmark-get-filename b1)) + i2 (abbreviate-file-name (bookmark-get-filename b2))) + (when case-fold-search (setq i1 (bmkp-upcase i1) + i2 (bmkp-upcase i2))) + (cond ((string-lessp i1 i2) '(t)) ; Compare manuals (file names). + ((string-lessp i2 i1) '(nil)) + (t ; Compare node names. + (setq i1 (bookmark-prop-get b1 'info-node) + i2 (bookmark-prop-get b2 'info-node)) + (cond ((string-lessp i1 i2) '(t)) + ((string-lessp i2 i1) '(nil)) + (t + (setq i1 (bookmark-get-position b1) + i2 (bookmark-get-position b2)) + (cond ((or (not i1) (not i2)) '(t)) ; Fallback if no `position' entry. + ((<= i1 i2) '(t)) + ((< i2 i1) '(nil)))))))) + (i1 '(t)) + (i2 '(nil)) + (t nil)))) + +(defun bmkp-gnus-cp (b1 b2) + "True if bookmark B1 sorts as a Gnus bookmark before B2. +B1 and B2 are bookmarks or bookmark names. +Two Gnus bookmarks are compared first by Gnus group name, then by +article number, then by message ID. +True also if B1 is a Gnus bookmark but B2 is not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((g1 (bmkp-gnus-bookmark-p b1)) + (g2 (bmkp-gnus-bookmark-p b2))) + (cond ((and g1 g2) + (setq g1 (bookmark-prop-get b1 'group) + g2 (bookmark-prop-get b2 'group)) + (cond ((string-lessp g1 g2) '(t)) ; Compare groups. + ((string-lessp g2 g1) '(nil)) + (t ; Compare article numbers. + (setq g1 (bookmark-prop-get b1 'article) + g2 (bookmark-prop-get b2 'article)) + (cond ((< g1 g2) '(t)) + ((< g2 g1) '(nil)) + (t + (setq g1 (bookmark-prop-get b1 'message-id) + g2 (bookmark-prop-get b2 'message-id)) + (cond ((string-lessp g1 g2) '(t)) ; Compare message IDs. + ((string-lessp g2 g1) '(nil)) + (t nil))))))) + (g1 '(t)) + (g2 '(nil)) + (t nil)))) + +(defun bmkp-url-cp (b1 b2) + "True if bookmark B1 sorts as a URL bookmark before B2. +B1 and B2 are bookmarks or bookmark names. +Two URL bookmarks are compared alphabetically, by their URLs. +True also if B1 is a URL bookmark but B2 is not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((u1 (bmkp-url-bookmark-p b1)) + (u2 (bmkp-url-bookmark-p b2))) + (cond ((and u1 u2) + (setq u1 (or (bookmark-prop-get b1 'location) (bookmark-get-filename b1)) + u2 (or (bookmark-prop-get b2 'location) (bookmark-get-filename b2))) + (cond ((string-lessp u1 u2) '(t)) + ((string-lessp u2 u1) '(nil)) + (t nil))) + (u1 '(t)) + (u2 '(nil)) + (t nil)))) + +;; Not used now. +(defun bmkp-w3m-cp (b1 b2) + "True if bookmark B1 sorts as a W3M URL bookmark before B2. +B1 and B2 are bookmarks or bookmark names. +Two W3M URL bookmarks are compared alphabetically, by their URLs. +True also if B1 is a W3M bookmark but B2 is not. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((w1 (bmkp-w3m-bookmark-p b1)) + (w2 (bmkp-w3m-bookmark-p b2))) + (cond ((and w1 w2) + (setq w1 (bookmark-get-filename b1) + w2 (bookmark-get-filename b2)) + (cond ((string-lessp w1 w2) '(t)) + ((string-lessp w2 w1) '(nil)) + (t nil))) + (w1 '(t)) + (w2 '(nil)) + (t nil)))) + +(defun bmkp-position-cp (b1 b2) + "True if the `position' of B1 is not greater than that of B2. +B1 and B2 are bookmarks or bookmark names. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if B1 and B2 do not bookmark the same buffer or they have +the same `position' value." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((buf1 (bmkp-get-buffer-name b1)) + (buf2 (bmkp-get-buffer-name b2))) + (and buf1 buf2 (equal buf1 buf2) + (let ((i1 (bookmark-get-position b1)) + (i2 (bookmark-get-position b2))) + (cond ((or (not i1) (not i2)) '(t)) ; Fallback if no `position' entry. + ((<= i1 i2) '(t)) + ((< i2 i1) '(nil))))))) + +(defun bmkp-alpha-cp (b1 b2) + "True if bookmark B1's name sorts alphabetically before B2's. +B1 and B2 are bookmarks or bookmark names. +The bookmark names are compared, respecting `case-fold-search'. +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((s1 (car b1)) + (s2 (car b2))) + (when case-fold-search (setq s1 (bmkp-upcase s1) + s2 (bmkp-upcase s2))) + (cond ((string-lessp s1 s2) '(t)) + ((string-lessp s2 s1) '(nil)) + (t nil)))) + +;; Do not use `bmkp-make-plain-predicate', because it falls back on `bookmark-alpha-p'. +;; Return nil if `bookmark-alpha-cp' cannot decide. +(defun bmkp-alpha-p (b1 b2) + "True if bookmark B1's name sorts alphabetically before B2's. +B1 and B2 are bookmarks or bookmark names. +The bookmark names are compared, respecting `case-fold-search'." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (car (bmkp-alpha-cp b1 b2))) + + +;;(@* "Sorting - File-Name Predicates") +;; *** Sorting - File-Name Predicates *** + +(defun bmkp-file-alpha-cp (b1 b2) + "True if bookmark B1's file name sorts alphabetically before B2's. +B1 and B2 are bookmarks or bookmark names. +The file names are shortened using `abbreviate-file-name', then they +are compared respecting `case-fold-search'. + +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (let ((f1 (bmkp-file-bookmark-p b1)) + (f2 (bmkp-file-bookmark-p b2))) + (cond ((and f1 f2) + ;; Call `abbreviate-file-name' mainly to get letter case right per platform. + (setq f1 (abbreviate-file-name (bookmark-get-filename b1)) + f2 (abbreviate-file-name (bookmark-get-filename b2))) + (when case-fold-search (setq f1 (bmkp-upcase f1) + f2 (bmkp-upcase f2))) + (cond ((string-lessp f1 f2) '(t)) + ((string-lessp f2 f1) '(nil)) + (t nil))) + (f1 '(t)) + (f2 '(nil)) + (t nil)))) + +;; We define all file-attribute predicates, in case you want to use them. +;; +;; `bmkp-file-attribute-0-cp' - type +;; `bmkp-file-attribute-1-cp' - links +;; `bmkp-file-attribute-2-cp' - uid +;; `bmkp-file-attribute-3-cp' - gid +;; `bmkp-file-attribute-4-cp' - last access time +;; `bmkp-file-attribute-5-cp' - last update time +;; `bmkp-file-attribute-6-cp' - last status change +;; `bmkp-file-attribute-7-cp' - size +;; `bmkp-file-attribute-8-cp' - modes +;; `bmkp-file-attribute-9-cp' - gid change +;; `bmkp-file-attribute-10-cp' - inode +;; `bmkp-file-attribute-11-cp' - device +;; +(bmkp-define-file-sort-predicate 0) ; Type: file, symlink, dir +(bmkp-define-file-sort-predicate 1) ; Links +(bmkp-define-file-sort-predicate 2) ; Uid +(bmkp-define-file-sort-predicate 3) ; Gid +(bmkp-define-file-sort-predicate 4) ; Last access time +(bmkp-define-file-sort-predicate 5) ; Last modification time +(bmkp-define-file-sort-predicate 6) ; Last status-change time +(bmkp-define-file-sort-predicate 7) ; Size +(bmkp-define-file-sort-predicate 8) ; Modes +(bmkp-define-file-sort-predicate 9) ; Gid would change if re-created +(bmkp-define-file-sort-predicate 10) ; Inode +(bmkp-define-file-sort-predicate 11) ; Device + +(defun bmkp-local-file-accessed-more-recently-cp (b1 b2) + "True if bookmark B1's local file was accessed more recently than B2's. +B1 and B2 are bookmarks or bookmark names. +A local file sorts before a remote file, which sorts before other +bookmarks. Two remote files are considered incomparable - their +access times are not examined. + +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (cond ((and (bmkp-local-file-bookmark-p b1) (bmkp-local-file-bookmark-p b2)) + (bmkp-cp-not (bmkp-file-attribute-4-cp b1 b2))) + ((bmkp-local-file-bookmark-p b1) '(t)) + ((bmkp-local-file-bookmark-p b2) '(nil)) + ((and (bmkp-remote-file-bookmark-p b1) + (bmkp-remote-file-bookmark-p b2)) nil) + ((bmkp-remote-file-bookmark-p b1) '(t)) + ((bmkp-remote-file-bookmark-p b2) '(nil)) + (t nil))) + +(defun bmkp-local-file-updated-more-recently-cp (b1 b2) + "True if bookmark B1's local file was updated more recently than B2's. +B1 and B2 are bookmarks or bookmark names. +A local file sorts before a remote file, which sorts before other +bookmarks. Two remote files are considered incomparable - their +update times are not examined. + +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (cond ((and (bmkp-local-file-bookmark-p b1) (bmkp-local-file-bookmark-p b2)) + (bmkp-cp-not (bmkp-file-attribute-5-cp b1 b2))) + ((bmkp-local-file-bookmark-p b1) '(t)) + ((bmkp-local-file-bookmark-p b2) '(nil)) + ((and (bmkp-remote-file-bookmark-p b1) + (bmkp-remote-file-bookmark-p b2)) nil) + ((bmkp-remote-file-bookmark-p b1) '(t)) + ((bmkp-remote-file-bookmark-p b2) '(nil)) + (t nil))) + +(defun bmkp-local-file-size-cp (b1 b2) + "True if bookmark B1's local file is larger than B2's. +B1 and B2 are bookmarks or bookmark names. +A local file sorts before a remote file, which sorts before other +bookmarks. Two remote files are considered incomparable - their +sizes are not examined. + +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (cond ((and (bmkp-local-file-bookmark-p b1) (bmkp-local-file-bookmark-p b2)) + (bmkp-cp-not (bmkp-file-attribute-7-cp b1 b2))) + ((bmkp-local-file-bookmark-p b1) '(t)) + ((bmkp-local-file-bookmark-p b2) '(nil)) + ((and (bmkp-remote-file-bookmark-p b1) + (bmkp-remote-file-bookmark-p b2)) nil) + ((bmkp-remote-file-bookmark-p b1) '(t)) + ((bmkp-remote-file-bookmark-p b2) '(nil)) + (t nil))) + +(defun bmkp-local-file-type-cp (b1 b2) + "True if bookmark B1 sorts by local file type before B2. +B1 and B2 are bookmarks or bookmark names. +For two local files, a file sorts before a symlink, which sorts before +a directory. + +A local file sorts before a remote file, which sorts before other +bookmarks. Two remote files are considered incomparable - their file +types are not examined. + +Reverse the roles of B1 and B2 for a false value. +A true value is returned as `(t)', a false value as `(nil)'. +Return nil if neither sorts before the other." + (setq b1 (bookmark-get-bookmark b1) + b2 (bookmark-get-bookmark b2)) + (cond ((and (bmkp-local-file-bookmark-p b1) (bmkp-local-file-bookmark-p b2)) + (bmkp-file-attribute-0-cp b1 b2)) + ((bmkp-local-file-bookmark-p b1) '(t)) + ((bmkp-local-file-bookmark-p b2) '(nil)) + ((and (bmkp-remote-file-bookmark-p b1) + (bmkp-remote-file-bookmark-p b2)) nil) + ((bmkp-remote-file-bookmark-p b1) '(t)) + ((bmkp-remote-file-bookmark-p b2) '(nil)) + (t nil))) + +(defun bmkp-cp-not (truth) + "Return the negation of boolean value TRUTH. +If TRUTH is (t), return (nil), and vice versa. +If TRUTH is nil, return nil." + (and truth (if (car truth) '(nil) '(t)))) + + +;;(@* "Indirect Bookmarking Functions") +;; *** Indirect Bookmarking Functions *** + +;;;###autoload +(defun bmkp-url-target-set (url &optional prefix-only-p name/prefix) ; `C-x p c u' + "Set a bookmark for a URL. Return the bookmark. +Interactively you are prompted for the URL. Completion is available. +Use `M-n' to pick up the url at point as the default. + +You are also prompted for the bookmark name. But with a prefix arg, +you are prompted only for a bookmark-name prefix. In that case, the +bookmark name is the prefix followed by the URL." + (interactive + (list (if (require 'ffap nil t) + (ffap-read-file-or-url "URL: " (or (thing-at-point 'url) (and (fboundp 'url-get-url-at-point) + (url-get-url-at-point)))) + (read-file-name "URL: " nil (or (thing-at-point 'url) (and (fboundp 'url-get-url-at-point) + (url-get-url-at-point))))) + current-prefix-arg + (if current-prefix-arg + (read-string "Prefix for bookmark name: ") + (bmkp-completing-read-lax "Bookmark name")))) + (unless name/prefix (setq name/prefix "")) + (let ((bookmark-make-record-function (if (eq major-mode 'w3m-mode) + 'bmkp-make-w3m-record + (lambda () (bmkp-make-url-browse-record url)))) + bmk failure) + (condition-case err + (setq bmk (bookmark-store (if prefix-only-p (concat name/prefix url) name/prefix) + (cdr (bookmark-make-record)) nil)) + (error (setq failure err))) + (if (not failure) + bmk ; Return the bookmark. + (error "Failed to create bookmark for `%s':\n%s\n" url failure)))) + +;;; Bound to `C-x p c f' +;;;###autoload +(defun bmkp-file-target-set (file &optional prefix-only-p name/prefix no-overwrite msgp) + "Set a bookmark for FILE. Return the bookmark. +The bookmarked position is the beginning of the file. +Interactively you are prompted for FILE. Completion is available. +You can use `M-n' to pick up the file name at point, or if none then +the visited file. + +You are also prompted for the bookmark name. But with a prefix arg, +you are prompted only for a bookmark-name prefix. In that case, the +bookmark name is the prefix followed by the non-directory part of +FILE. + +From Lisp code, optional arg NO-OVERWRITE is passed to +`bookmark-store': non-nil means do not overwrite an existing bookmark +that has the same name." + (interactive + (list (read-file-name "File: " nil + (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+. + (run-hook-with-args-until-success 'file-name-at-point-functions) + (ffap-guesser)) + (thing-at-point 'filename) + (buffer-file-name))) + current-prefix-arg + (if current-prefix-arg + (read-string "Prefix for bookmark name: ") + (bmkp-completing-read-lax "Bookmark name")) + 'MSG)) + (unless name/prefix (setq name/prefix "")) + (let ((bookmark-make-record-function (bmkp-make-record-for-target-file file)) + bmk failure) + (condition-case err + (setq bmk (bookmark-store + (if prefix-only-p (concat name/prefix (file-name-nondirectory file)) name/prefix) + (cdr (bookmark-make-record)) no-overwrite)) + (error (setq failure (error-message-string err)))) + (if (not failure) + (prog1 bmk ; Return the bookmark. + (when (and msgp (not (file-exists-p file))) + (message "File name is now bookmarked, but no such file yet: `%s'" + (expand-file-name file)))) + (error "Failed to create bookmark for `%s':\n%s\n" file failure)))) + +(defun bmkp-make-record-for-target-file (file) + "Return a function that creates a bookmark record for FILE. +The bookmarked position will be the beginning of the file." + ;; $$$$$$ Maybe need a way to bypass default handler, at least for autofiles. + ;; Doesn't seem to make much sense to use a handler such as a shell cmd in this context. (?) + (let ((default-handler (condition-case nil (bmkp-default-handler-for-file file) (error nil)))) + (cond (default-handler ; User default handler + `(lambda () '((filename . ,file) (position . 0) (handler . ,default-handler)))) + ;; Non-user defaults. + ((and (require 'image nil t) (require 'image-mode nil t) ; Image + (condition-case nil (image-type file) (error nil))) + ;; Last two lines of function are from `image-bookmark-make-record'. + ;; But don't use that directly, because it uses + ;; `bookmark-make-record-default', which gets nil for `filename'. + + ;; NEED to keep this code sync'd with `diredp-bookmark'. + (lambda () + `((filename . ,file) + (position . 0) + (image-type . ,(image-type file)) + (handler . image-bookmark-jump)))) + ((let ((case-fold-search t)) (string-match "\\([.]au$\\|[.]wav$\\)" file)) ; Sound + `(lambda () '((filename . ,file) (handler . bmkp-sound-jump)))) + (t + `(lambda () '((filename . ,file) (position . 0))))))) + +;;;###autoload +(defalias 'bmkp-bookmark-a-file 'bmkp-autofile-set) +;;;###autoload +(defun bmkp-autofile-set (file &optional dir prefix msgp) ; Bound to `C-x p c a' + "Set a bookmark for FILE, autonaming the bookmark for the file. +Return the bookmark. +Interactively, you are prompted for FILE. You can use `M-n' to pick +up the file name at point, or if none then the visited file. + +The bookmark name is the non-directory part of FILE, but with a prefix +arg you are also prompted for a PREFIX string to prepend to the +bookmark name. The bookmarked position is the beginning of the file. + +Note that if you provide PREFIX then the bookmark will not satisfy +`bmkp-autofile-bookmark-p' unless you provide the same PREFIX to that +predicate. + +The bookmark's file name is FILE if absolute. If relative then it is +FILE expanded in DIR, if non-nil, or in the current directory +\(`default-directory'). + +If a bookmark with the same name already exists for the same file name +then do nothing. + +Otherwise, create a new bookmark for the file, even if a bookmark with +the same name already exists. This means that you can have more than +one autofile bookmark with the same bookmark name and the same +relative file name (non-directory part), but with different absolute +file names." + (interactive + (list (read-file-name "File: " nil + (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+. + (run-hook-with-args-until-success 'file-name-at-point-functions) + (ffap-guesser)) + (thing-at-point 'filename) + (buffer-file-name))) + nil + (and current-prefix-arg (read-string "Prefix for bookmark name: ")) + 'MSG)) + (let* ((dir-to-use (if (file-name-absolute-p file) + (file-name-directory file) + (or dir default-directory))) + ;; Look for existing bookmark with same name, same file, in `dir-to-use'. + (bmk (bmkp-get-autofile-bookmark file dir-to-use prefix))) + ;; If BMK was found, then instead of doing nothing we could replace the existing BMK with a new + ;; one, as follows: + ;; (let ((bookmark-make-record-function (bmkp-make-record-for-target-file file))) + ;; (bmkp-replace-existing-bookmark bmk)) ; Update the existing bookmark. + (or bmk ; Do nothing, and return the bookmark. + ;; Create a new bookmark, and return it. + (bmkp-file-target-set (expand-file-name file dir-to-use) t prefix 'NO-OVERWRITE msgp)))) + +(defun bmkp-get-autofile-bookmark (file &optional dir prefix) + "Return an existing autofile bookmark for FILE, or nil if there is none. +The bookmark name is the non-directory part of FILE, but if PREFIX is +non-nil then it is PREFIX prepended to the non-directory part of FILE. + +The directory part of property `filename' is the directory part of +FILE, if FILE is absolute. Otherwise, it is DIR, if non-nil, or +`default-directory' otherwise. + +FILE and the `filename' property of the bookmark returned are the +same, except possibly for their directory parts (see previous)." + (let* ((fname (file-name-nondirectory file)) + (bname (if prefix (concat prefix fname) fname)) + (dir-to-use (if (file-name-absolute-p file) + (file-name-directory file) + (or dir default-directory)))) + ;; Look for existing bookmark with same name, same file, in `dir-to-use'. + (catch 'bmkp-get-autofile-bookmark + (dolist (bmk bookmark-alist) + (when (string= bname (bookmark-name-from-full-record bmk)) + (let* ((bfil (bookmark-get-filename bmk)) + (bdir (and bfil (file-name-directory bfil)))) + (when (and bfil + (bmkp-same-file-p fname (file-name-nondirectory bfil)) + (bmkp-same-file-p bdir dir-to-use)) + (throw 'bmkp-get-autofile-bookmark bmk))))) ; Return the bookmark. + nil))) + +;;;###autoload +(defalias 'bmkp-tag-a-file 'bmkp-autofile-add-tags) ; Bound to `C-x p t + a' +;;;###autoload +(defun bmkp-autofile-add-tags (file tags &optional dir prefix msgp no-cache-update-p) + "Add TAGS to autofile bookmark for FILE. +Interactively, you are prompted for FILE and then TAGS. +When prompted for FILE you can use `M-n' to pick up the file name at +point, or if none then the visited file. + +When prompted for tags, hit `RET' to enter each tag, then hit `RET' +again after the last tag. You can use completion to enter each tag. +Completion is lax: you are not limited to existing tags. + +TAGS is a list of strings. DIR, PREFIX are as for `bmkp-autofile-set'. +Non-nil MSGP means display a message about the addition. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags added." + (interactive + (list (read-file-name "File: " nil + (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+. + (run-hook-with-args-until-success 'file-name-at-point-functions) + (ffap-guesser)) + (thing-at-point 'filename) + (buffer-file-name))) + (bmkp-read-tags-completing) + nil + (and current-prefix-arg (read-string "Prefix for bookmark name: ")) + 'msg)) + (bmkp-add-tags (bmkp-autofile-set file dir prefix) tags msgp no-cache-update-p)) + +;;;###autoload +(defalias 'bmkp-untag-a-file 'bmkp-autofile-remove-tags) ; Bound to `C-x p t - a' +;;;###autoload +(defun bmkp-autofile-remove-tags (file tags &optional dir prefix msgp no-cache-update-p) + "Remove TAGS from autofile bookmark for FILE. +Interactively, you are prompted for TAGS and then FILE. +With Emacs 22 and later, only files with at least one of the given +tags are candidates. + +When prompted for tags, hit `RET' to enter each tag to be removed, +then hit `RET' again after the last tag. You can use completion to +enter each tag. + +When prompted for FILE you can use `M-n' to pick up the file name at +point, or if none then the visited file. + +TAGS is a list of strings. DIR, PREFIX are as for `bmkp-autofile-set'. +Non-nil MSGP means display a message about the addition. +Non-nil NO-CACHE-UPDATE-P means do not update `bmkp-tags-alist'. +Return the number of tags removed." + (interactive + (let* ((pref (and current-prefix-arg (read-string "Prefix for bookmark name: "))) + (tgs (bmkp-read-tags-completing)) + (fil (condition-case nil + (read-file-name + "File: " nil + (or (if (boundp 'file-name-at-point-functions) ; In `files.el', Emacs 23.2+. + (run-hook-with-args-until-success 'file-name-at-point-functions) + (ffap-guesser)) + (thing-at-point 'filename) + (buffer-file-name)) + t nil + (lambda (ff) ; PREDICATE - only for Emacs 22+. + (let* ((bmk (bmkp-get-autofile-bookmark ff nil pref)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (catch 'bmkp-autofile-remove-tags + (dolist (tag tgs) + (when (not (member tag btgs)) + (throw 'bmkp-autofile-remove-tags nil))) + t))))) + (error (read-file-name + "File: " nil + (or (ffap-guesser) + (thing-at-point 'filename) + (buffer-file-name))))))) + (list fil tgs nil pref 'MSG))) + (bmkp-remove-tags (bmkp-autofile-set file dir prefix) tags msgp no-cache-update-p)) + +;;;###autoload +(defun bmkp-purge-notags-autofiles (&optional prefix) ; Not bound + "Delete all autofile bookmarks that have no tags. +With a prefix arg, you are prompted for a PREFIX for the bookmark name." + (interactive (if (not (y-or-n-p "Delete all autofile bookmarks that do not have tags? ")) + (error "Deletion cancelled") + (list (and current-prefix-arg (read-string "Prefix for bookmark name: "))))) + (let ((bmks (bmkp-autofile-alist-only prefix)) + record tags) + ;; Needs Bookmark+ version of `bookmark-delete', which accepts a bookmark, not just its name. + (dolist (bmk bmks) + (when (and (setq tags (assq 'tags (bookmark-get-bookmark-record bmk))) + (or (not tags) (null (cdr tags)))) + (bookmark-delete bmk))) + (bmkp-tags-list))) ; Update the tags cache. + +;; $$$$$$ Not used currently. +(defun bmkp-replace-existing-bookmark (bookmark) + "Replace existing BOOKMARK with a new one of the same name. +Return the new bookmark. +BOOKMARK is a full bookmark record, not a bookmark name. +This just replaces the existing bookmark data with the data for a new +bookmark, based on `bookmark-make-record-function'. The bookmark name +is unchanged." + (let (failure) + (condition-case err + (progn ; Code similar to `bookmark-store'. + (setcdr bookmark (cdr (bookmark-make-record))) + (bmkp-maybe-save-bookmarks) + (setq bookmark-current-bookmark (bookmark-name-from-full-record bookmark)) + (bookmark-bmenu-surreptitiously-rebuild-list)) + (error (setq failure (error-message-string err)))) + (if (not failure) + bookmark ; Return the bookmark. + (error "Failed to update bookmark `%s':\n%s\n" + (bookmark-name-from-full-record bookmark) failure)))) + +(defun bmkp-default-handler-for-file (filename) + "Return a default bookmark handler for FILENAME, or nil. +If non-nil, it is a Lisp function, determined as follows: + +1. Match FILENAME against `bmkp-default-handler-associations'. If it +matches a Lisp function, return that function. If it matches a shell +command, return a Lisp function that invokes that command. + +2. If no match is found and `bmkp-guess-default-handler-for-file-flag' +is non-nil, then try to find an appropriate shell command using, in +order, `dired-guess-default' and (Emacs 23+ only) +`mailcap-file-default-commands'. If a match is found then return a +Lisp function that invokes that shell command." + (let* ((bmkp-user (bmkp-default-handler-user filename)) + (shell-cmd (if (stringp bmkp-user) + bmkp-user + (and (not bmkp-user) + bmkp-guess-default-handler-for-file-flag + (or (and (require 'dired-x nil t) + (let* ((case-fold-search + (or (and (boundp 'dired-guess-shell-case-fold-search) + dired-guess-shell-case-fold-search) + case-fold-search)) + (default (dired-guess-default (list filename)))) + (if (consp default) (car default) default))) + (and (require 'mailcap nil t) ; Emacs 23+ + (car (mailcap-file-default-commands (list filename))))))))) + (cond ((stringp shell-cmd) `(lambda (bmk) (dired-do-shell-command ,shell-cmd nil ',(list filename)))) + ((or (functionp bmkp-user) (and bmkp-user (symbolp bmkp-user))) + `(lambda (bmk) (funcall #',bmkp-user ,filename))) + (t nil)))) + +(defun bmkp-default-handler-user (filename) + "Return default handler for FILENAME. +The value is based on `bmkp-default-handler-associations'." + (catch 'bmkp-default-handler-user + (dolist (assn bmkp-default-handler-associations) + (when (string-match (car assn) filename) + (throw 'bmkp-default-handler-user (cdr assn)))) + nil)) + +(defun bmkp-sound-jump (bookmark) + "Handler for sound files: play the sound file that is BOOKMARK's file." + (play-sound-file (bookmark-get-filename bookmark))) + +(when (> emacs-major-version 21) + (defun bmkp-compilation-target-set (&optional prefix) ; `C-c C-b' + "Set a bookmark at the start of the line for this compilation hit. +You are prompted for the bookmark name. But with a prefix arg, you +are prompted only for a PREFIX string. In that case, and in Lisp +code, the bookmark name is PREFIX followed by the (relative) file name +of the hit, followed by the line number of the hit." + (interactive "P") + (let* ((file+line (bmkp-compilation-file+line-at (line-beginning-position))) + (file (car file+line)) + (line (cdr file+line))) + (unless (and file line) (error "Cursor is not on a compilation hit")) + (save-excursion + (with-current-buffer (find-file-noselect file) + (goto-char (point-min)) (forward-line (1- line)) + (if (not prefix) + (call-interactively #'bookmark-set) + (when (interactive-p) + (setq prefix (read-string "Prefix for bookmark name: "))) + (unless (stringp prefix) (setq prefix "")) + (bookmark-set (format "%s%s, line %s" prefix (file-name-nondirectory file) line) + 99 'INTERACTIVEP)))))) + + (defun bmkp-compilation-file+line-at (&optional pos) + "Return the file and position indicated by this compilation message. +These are returned as a cons: (FILE . POSITION). +POSITION is the beginning of the line indicated by the message." + (unless pos (setq pos (point))) + (let* ((loc (car (get-text-property pos 'message))) + (line (cadr loc)) + (filename (caar (nth 2 loc))) + (directory (cadr (car (nth 2 loc)))) + (spec-dir (if directory (expand-file-name directory) default-directory))) + (cons (expand-file-name filename spec-dir) line)))) + +(when (> emacs-major-version 21) + (defun bmkp-compilation-target-set-all (prefix &optional msgp) ; `C-c C-M-b' + "Set a bookmark for each hit of a compilation buffer. +NOTE: You can use `C-x C-q' to make the buffer writable and then + remove any hits that you do not want to bookmark. Only the hits + remaining in the buffer are bookmarked. + +You are prompted for a PREFIX string to prepend to each bookmark name, +the rest of which is the file name of the hit followed by its line +number." + (interactive (list (read-string "Prefix for bookmark name: ") 'MSGP)) + (if (y-or-n-p "This will bookmark *EACH* hit in the buffer. Continue? ") + (let ((count 0)) + (save-excursion + (goto-char (point-min)) + (when (get-text-property (point) 'message) ; Visible part of buffer starts with a hit + (condition-case nil ; because buffer is narrowed or header text otherwise removed. + (bmkp-compilation-target-set prefix) ; Ignore error here (e.g. killed buffer). + (error nil)) + (setq count (1+ count))) + (while (and (condition-case nil (progn (compilation-next-error 1) t) (error nil)) + (not (eobp))) + (condition-case nil + (bmkp-compilation-target-set prefix) ; Ignore error here (e.g. killed buffer). + (error nil)) + (setq count (1+ count))) + (when msgp (message "Set %d bookmarks" count)))) + (message "OK - canceled")))) + + +;; We could make the `occur' code work for Emacs 20 & 21 also, but you would not be able to +;; delete some occurrences and bookmark only the remaining ones. + +(when (> emacs-major-version 21) + (defun bmkp-occur-target-set (&optional prefix) ; `C-c C-b' + "Set a bookmark at the start of the line for this `(multi-)occur' hit. +You are prompted for the bookmark name. But with a prefix arg, you +are prompted only for a PREFIX string. In that case, and in Lisp +code, the bookmark name is PREFIX followed by the buffer name of the +hit, followed by the line number of the hit. + +You can use this only in `Occur' mode (commands such as `occur' and +`multi-occur')." + (interactive "P") + (unless (eq major-mode 'occur-mode) (error "You must be in `occur-mode'")) + (let* ((line (and prefix + (save-excursion + (forward-line 0) + ;; We could use [: ] here, to handle `moccur', but that loses anyway for + ;; `occur-mode-find-occurrence', so we would need other hoops too. + (re-search-forward "^\\s-+\\([0-9]+\\):" (line-end-position) 'NOERROR) + (or (format "%5d" (string-to-number (match-string 1))) "")))) + (mkr (occur-mode-find-occurrence)) + (buf (marker-buffer mkr)) + (file (or (buffer-file-name buf) bmkp-non-file-filename))) + (save-excursion (with-current-buffer buf + (goto-char mkr) + (if (not prefix) + (call-interactively #'bookmark-set) + (when (interactive-p) + (setq prefix (read-string "Prefix for bookmark name: "))) + (unless (stringp prefix) (setq prefix "")) + (bookmark-set (format "%s%s, line %s" prefix buf line) 99 'INTERACTIVEP))))))) + +(when (> emacs-major-version 21) + (defun bmkp-occur-target-set-all (&optional prefix msgp) ; `C-c C-M-b' + "Set a bookmark for each hit of a `(multi-)occur' buffer. +NOTE: You can use `C-x C-q' to make the buffer writable and then + remove any hits that you do not want to bookmark. Only the hits + remaining in the buffer are bookmarked. + +You are prompted for a PREFIX string to prepend to each bookmark name, +the rest of which is the buffer name of the hit followed by its line +number. + +You can use this only in `Occur' mode (commands such as `occur' and +`multi-occur'). + +See also command `bmkp-occur-create-autonamed-bookmarks', which +creates autonamed bookmarks to all `occur' and `multi-occur' hits." + (interactive (list (read-string "Prefix for bookmark name: ") 'MSGP)) + (if (y-or-n-p "This will bookmark *EACH* hit in the buffer. Continue? ") + (let ((count 0)) + (save-excursion + (goto-char (point-min)) + (while (condition-case nil + (progn (occur-next) t) ; "No more matches" ends loop. + (error nil)) + (condition-case nil + (bmkp-occur-target-set prefix) ; Ignore error here (e.g. killed buffer). + (error nil)) + (setq count (1+ count))) + (when msgp (message "Set %d bookmarks" count)))) + (message "OK - canceled")))) + + +;;(@* "Other Bookmark+ Functions (`bmkp-*')") +;; *** Other Bookmark+ Functions (`bmkp-*') *** + +;;;###autoload +(defun bmkp-describe-bookmark (bookmark &optional defn) + "Describe BOOKMARK. +With a prefix argument, show the internal definition of the bookmark. +BOOKMARK is a bookmark name or a bookmark record. + +Starting with Emacs 22, if the file is an image file then: +* Show a thumbnail of the image as well. +* If you have command-line tool `exiftool' installed and in your + `$PATH' or `exec-path', then show EXIF data (metadata) about the + image. See standard Emacs library `image-dired.el' for more + information about `exiftool'" + (interactive (list (bookmark-completing-read + "Describe bookmark" + (or (and (fboundp 'bmkp-default-lighted) (bmkp-default-lighted)) + (bmkp-default-bookmark-name))) + current-prefix-arg)) + (if defn + (bmkp-describe-bookmark-internals bookmark) + (setq bookmark (bookmark-get-bookmark bookmark)) + (help-setup-xref (list #'bmkp-describe-bookmark bookmark) (interactive-p)) + (let ((help-text (bmkp-bookmark-description bookmark))) + (with-output-to-temp-buffer "*Help*" (princ help-text)) + (with-current-buffer "*Help*" + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "@#%&()_IMAGE-HERE_()&%#@\\(.+\\)" nil t) + (let* ((image-file (match-string 1)) + (image-string (save-match-data + (apply #'propertize "X" + `(display + ,(append (image-dired-get-thumbnail-image image-file) + '(:margin 10)) + rear-nonsticky (display) + mouse-face highlight + follow-link t + help-echo "`mouse-2' or `RET': Show full image" + keymap + (keymap + (mouse-2 + . (lambda (e) (interactive "e") + (find-file ,image-file))) + (13 + . (lambda () (interactive) + (find-file ,image-file)))))))) + (buffer-read-only nil)) + (replace-match image-string))))) + help-text))) + +(defun bmkp-bookmark-description (bookmark &optional no-image) + "Help-text description of BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Starting with Emacs 22 and unless optional arg NO-IMAGE is non-nil, if +the file is an image file then the description includes the following: +* A placeholder for a thumbnail image: \"@#%&()_IMAGE-HERE_()&%#@\" +* EXIF data (metadata) about the image, provided you have command-line + tool `exiftool' installed and in your `$PATH' or `exec-path'. See + standard Emacs library `image-dired.el' for more information about + `exiftool'." + (setq bookmark (bookmark-get-bookmark bookmark)) + (let ((bname (bookmark-name-from-full-record bookmark)) + (buf (bmkp-get-buffer-name bookmark)) + (file (bookmark-get-filename bookmark)) + (image-p (bmkp-bookmark-image-bookmark-p bookmark)) + (location (bookmark-prop-get bookmark 'location)) + (start (bookmark-get-position bookmark)) + (end (bmkp-get-end-position bookmark)) + (created (bookmark-prop-get bookmark 'created)) + (time (bmkp-get-visit-time bookmark)) + (visits (bmkp-get-visits-count bookmark)) + (tags (mapcar #'bmkp-tag-name (bmkp-get-tags bookmark))) + (sequence-p (bmkp-sequence-bookmark-p bookmark)) + (function-p (bmkp-function-bookmark-p bookmark)) + (variable-list-p (bmkp-variable-list-bookmark-p bookmark)) + (desktop-p (bmkp-desktop-bookmark-p bookmark)) + (bookmark-file-p (bmkp-bookmark-file-bookmark-p bookmark)) + (dired-p (bmkp-dired-bookmark-p bookmark)) + (gnus-p (bmkp-gnus-bookmark-p bookmark)) + (info-p (bmkp-info-bookmark-p bookmark)) + (man-p (bmkp-man-bookmark-p bookmark)) + (url-p (bmkp-url-bookmark-p bookmark)) + (w3m-p (bmkp-w3m-bookmark-p bookmark)) + (annot (bookmark-get-annotation bookmark)) + no-position-p) + (setq no-position-p (not start)) + (when (or sequence-p function-p variable-list-p) (setq no-position-p t)) + (let* ((help-text + (concat + (format "Bookmark `%s'\n%s\n\n" bname (make-string (+ 11 (length bname)) ?-)) + (cond (sequence-p (format "Sequence:\n%s\n" + (pp-to-string + (bookmark-prop-get bookmark 'sequence)))) + (function-p (let ((fn (bookmark-prop-get bookmark 'function))) + (if (symbolp fn) + (format "Function:\t\t%s\n" fn) + (format "Function:\n%s\n" + (pp-to-string + (bookmark-prop-get bookmark 'function)))))) + (variable-list-p (format "Variable list:\n%s\n" + (pp-to-string (bookmark-prop-get bookmark 'variables)))) + (gnus-p (format "Gnus, group:\t\t%s, article: %s, message-id: %s\n" + (bookmark-prop-get bookmark 'group) + (bookmark-prop-get bookmark 'article) + (bookmark-prop-get bookmark 'message-id))) + (man-p (format "UNIX `man' page for:\t`%s'\n" + (or (bookmark-prop-get bookmark 'man-args) + ;; WoMan has no variable for the cmd name. + (bookmark-prop-get bookmark 'buffer-name)))) + (info-p (format "Info node:\t\t(%s) %s\n" + (file-name-nondirectory file) + (bookmark-prop-get bookmark 'info-node))) + (w3m-p (format "W3m URL:\t\t%s\n" file)) + (url-p (format "URL:\t\t%s\n" location)) + (desktop-p (format "Desktop file:\t\t%s\n" + (bookmark-prop-get bookmark 'desktop-file))) + (bookmark-file-p (format "Bookmark file:\t\t%s\n" + (bookmark-prop-get bookmark 'bookmark-file))) + (dired-p (let ((switches (bookmark-prop-get bookmark 'dired-switches)) + (marked (length (bookmark-prop-get bookmark + 'dired-marked))) + (inserted (length (bookmark-prop-get bookmark + 'dired-subdirs))) + (hidden (length + (bookmark-prop-get bookmark + 'dired-hidden-dirs)))) + (format "Dired%s:%s\t\t%s\nMarked:\t\t\t%s\n\ +Inserted subdirs:\t%s\nHidden subdirs:\t\t%s\n" + (if switches (format " `%s'" switches) "") + (if switches "" (format "\t")) + (expand-file-name file) + marked inserted hidden))) + ((equal file bmkp-non-file-filename) + (format "Buffer:\t\t\t%s\n" (bmkp-get-buffer-name bookmark))) + (file (concat (format "File:\t\t\t%s\n" (file-name-nondirectory file)) + (let ((dir (file-name-directory (expand-file-name file)))) + (and dir (format "Directory:\t\t%s\n" dir))))) + (t "Unknown\n")) + (unless no-position-p + (if (bmkp-region-bookmark-p bookmark) + (format "Region:\t\t\t%d to %d (%d chars)\n" start end (- end start)) + (format "Position:\t\t%d\n" start))) + (and visits (format "Visits:\t\t\t%d\n" visits)) + (and time (format "Last visit:\t\t%s\n" (format-time-string "%c" time))) + (and created (format "Creation:\t\t%s\n" (format-time-string "%c" created))) + (and tags (format "Tags:\t\t\t%S\n" tags)) + (and annot (format "\nAnnotation:\n%s" annot)) + (and (not no-image) + (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+). + (if (fboundp 'string-match-p) + (string-match-p (image-file-name-regexp) file) + (save-match-data + (string-match (image-file-name-regexp) file))) + (if (fboundp 'display-graphic-p) (display-graphic-p) window-system) + (require 'image-dired nil t) + (image-dired-get-thumbnail-image file) + (concat "\n@#%&()_IMAGE-HERE_()&%#@" file "\n")) + (and (not no-image) + (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+). + (if (fboundp 'string-match-p) + (string-match-p (image-file-name-regexp) file) + (save-match-data + (string-match (image-file-name-regexp) file))) + (progn (message "Gathering image data...") t) + (condition-case nil + (let ((all (bmkp-all-exif-data (expand-file-name file)))) + (concat + (and all (not (zerop (length all))) + (format "\nImage Data (EXIF)\n-----------------\n%s" + all)))) + (error nil)))))) + help-text))) + +;; This is the same as `help-all-exif-data' in `help-fns+.el', but we avoid requiring that library. +(defun bmkp-all-exif-data (file) + "Return all EXIF data from FILE, using command-line tool `exiftool'." + (with-temp-buffer + (delete-region (point-min) (point-max)) + (unless (eq 0 (call-process shell-file-name nil t nil shell-command-switch + (format "exiftool -All \"%s\"" file))) + (error "Could not get EXIF data")) + (buffer-substring (point-min) (point-max)))) + + +;;;###autoload +(defun bmkp-describe-bookmark-internals (bookmark) + "Show the internal definition of the bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (interactive (list (bookmark-completing-read "Describe bookmark" (bmkp-default-bookmark-name)))) + (setq bookmark (bookmark-get-bookmark bookmark)) + (help-setup-xref (list #'bmkp-describe-bookmark-internals bookmark) (interactive-p)) + (let* ((bname (bookmark-name-from-full-record bookmark)) + (help-text (format "Bookmark `%s'\n%s\n\n%s" bname (make-string (+ 11 (length bname)) ?-) + (pp-to-string bookmark)))) + (with-output-to-temp-buffer "*Help*" (princ help-text)) + help-text)) + +;;;###autoload +(defun bmkp-list-defuns-in-commands-file () + "List the functions defined in `bmkp-bmenu-commands-file'. +Typically, these are all commands." + (interactive) + (when (and bmkp-bmenu-commands-file (file-readable-p bmkp-bmenu-commands-file)) + (let ((fns ()) + (buf (let ((enable-local-variables nil)) + (find-file-noselect bmkp-bmenu-commands-file)))) + (help-setup-xref (list #'bmkp-list-defuns-in-commands-file) (interactive-p)) + (with-current-buffer buf + (goto-char (point-min)) + (while (not (eobp)) + (when (re-search-forward "\\s-*(defun \\([^ \t\n(\"]+\\)[ \t\n(]" nil 'move) + (push (match-string 1) fns))) + (setq fns (nreverse fns) + fns (sort fns 'string-lessp))) + (when (buffer-live-p buf) (kill-buffer buf)) + (with-output-to-temp-buffer "*Help*" + (princ "Bookmark Commands You Defined (in `bmkp-bmenu-commands-file')") (terpri) + (princ "------------------------------------------------------------------") (terpri) + (terpri) + (let ((non-dups (bmkp-remove-dups fns))) + (dolist (fn non-dups) + (if (and (fboundp (intern fn)) (fboundp 'help-insert-xref-button)) + (with-current-buffer "*Help*" + (goto-char (point-max)) + (help-insert-xref-button fn 'help-function (intern fn) (commandp (intern fn)))) + (princ fn)) + (let ((dups (member fn fns)) ; Sorted, so all dups are together. + (count 0)) + (while (equal fn (car dups)) + (setq count (1+ count) + dups (cdr dups))) + (when (> count 1) (princ (format " (%d times)" count)))) + (terpri))) + (help-make-xrefs (current-buffer))) + fns))) + +(defun bmkp-root-or-sudo-logged-p () + "Return t if the user logged in using Tramp as `root' or `sudo'. +Otherwise, return nil." + (catch 'break + (dolist (ii (mapcar #'buffer-name (buffer-list))) + (when (string-match "*tramp/\\(su\\|sudo\\) ." ii) (throw 'break t))))) + +(defun bmkp-position-post-context (breg) + "Return `bookmark-search-size' chars, starting at position BREG. +Return nil if there are not that many chars. +This is text that follows the bookmark's `position'. +This is used for a non-region bookmark." + (and (>= (- (point-max) breg) bookmark-search-size) + (buffer-substring-no-properties breg (+ breg bookmark-search-size)))) + +(defun bmkp-position-post-context-region (breg ereg) + "Return the region prefix, at BREG. +Return at most `bmkp-region-search-size' or (- EREG BREG) chars. +This is text that follows the bookmark's `position'. +This is used for a region bookmark." + (buffer-substring-no-properties breg (+ breg (min bmkp-region-search-size (- ereg breg))))) + +(defun bmkp-position-pre-context (breg) + "Return `bookmark-search-size' chars that precede BREG. +Return nil if there are not that many chars. +This is text that precedes the bookmark's `position'. +This is used for a non-region bookmark." + (and (>= (- breg (point-min)) bookmark-search-size) + (buffer-substring-no-properties breg (- breg bookmark-search-size)))) + +(defun bmkp-position-pre-context-region (breg) + "Return the text preceding the region beginning, BREG. +Return at most `bmkp-region-search-size' chars. +This is text that precedes the bookmark's `position'. +This is used for a region bookmark." + (buffer-substring-no-properties (max (- breg bmkp-region-search-size) (point-min)) breg)) + +(defun bmkp-end-position-pre-context (breg ereg) + "Return the region suffix, ending at EREG. +Return at most `bmkp-region-search-size' or (- EREG BREG) chars. +This is text that precedes the bookmark's `end-position'." + (buffer-substring-no-properties (- ereg (min bmkp-region-search-size (- ereg breg))) ereg)) + +(defun bmkp-end-position-post-context (ereg) + "Return the text following the region end, EREG. +Return at most `bmkp-region-search-size' chars. +This is text that follows the bookmark's `end-position'." + (buffer-substring-no-properties ereg + (+ ereg (min bmkp-region-search-size (- (point-max) (point)))))) + +(defun bmkp-position-after-whitespace (position) + "Move forward from POSITION, skipping over whitespace. Return point." + (goto-char position) (skip-chars-forward " \n\t" (point-max)) (point)) + +(defun bmkp-position-before-whitespace (position) + "Move backward from POSITION, skipping over whitespace. Return point." + (goto-char position) (skip-chars-backward " \n\t" (point-min)) (point)) + +(defun bmkp-save-new-region-location (bookmark beg end) + "Update and save `bookmark-alist' for BOOKMARK, relocating its region. +BOOKMARK is a bookmark record. +BEG and END are the new region limits for BOOKMARK. +Do nothing and return nil if `bmkp-save-new-location-flag' is nil. +Otherwise, return non-nil if region was relocated." + (and bmkp-save-new-location-flag + (y-or-n-p "Region relocated. Do you want to save new region limits? ") + (progn + (bookmark-prop-set bookmark 'front-context-string (bmkp-position-post-context-region + beg end)) + (bookmark-prop-set bookmark 'rear-context-string (bmkp-position-pre-context-region beg)) + (bookmark-prop-set bookmark 'front-context-region-string (bmkp-end-position-pre-context + beg end)) + (bookmark-prop-set bookmark 'rear-context-region-string (bmkp-end-position-post-context end)) + (bookmark-prop-set bookmark 'position beg) + (bookmark-prop-set bookmark 'end-position end) + (bmkp-maybe-save-bookmarks) + t))) + +(defun bmkp-handle-region-default (bookmark) + "Default function to handle BOOKMARK's region. +BOOKMARK is a bookmark name or a bookmark record. +Relocate the region if necessary, then activate it. +If region was relocated, save it if user confirms saving." + ;; Relocate by searching from the beginning (and possibly the end) of the buffer. + (let* (;; Get bookmark object once and for all. + ;; Actually, we know BOOKMARK is a bookmark object (not a name), but play safe. + (bmk (bookmark-get-bookmark bookmark)) + (bor-str (bookmark-get-front-context-string bmk)) + (eor-str (bookmark-prop-get bmk 'front-context-region-string)) + (br-str (bookmark-get-rear-context-string bmk)) + (ar-str (bookmark-prop-get bookmark 'rear-context-region-string)) + (pos (bookmark-get-position bmk)) + (end-pos (bmkp-get-end-position bmk)) + (reg-retrieved-p t) + (reg-relocated-p nil)) + (unless (and (string= bor-str (buffer-substring-no-properties (point) (+ (point) + (length bor-str)))) + (save-excursion + (goto-char end-pos) + (string= eor-str (buffer-substring-no-properties (point) (- (point) + (length bor-str)))))) + ;; Relocate region by searching from beginning (and possibly from end) of buffer. + (let ((beg nil) + (end nil)) + ;; Go to bob and search forward for END. + (goto-char (point-min)) + (if (search-forward eor-str (point-max) t) ; Find END, using `eor-str'. + (setq end (point)) + ;; Verify that region is not before context. + (unless (search-forward br-str (point-max) t) + (when (search-forward ar-str (point-max) t) ; Find END, using `ar-str'. + (setq end (match-beginning 0) + end (and end (bmkp-position-before-whitespace end)))))) + ;; If failed to find END, go to eob and search backward for BEG. + (unless end (goto-char (point-max))) + (if (search-backward bor-str (point-min) t) ; Find BEG, using `bor-str'. + (setq beg (point)) + ;; Verify that region is not after context. + (unless (search-backward ar-str (point-min) t) + (when (search-backward br-str (point-min) t) ; Find BEG, using `br-str'. + (setq beg (match-end 0) + beg (and beg (bmkp-position-after-whitespace beg)))))) + (setq reg-retrieved-p (or beg end) + reg-relocated-p reg-retrieved-p + ;; If only one of BEG or END was found, the relocated region is only + ;; approximate (keep the same length). If both were found, it is exact. + pos (or beg (and end (- end (- end-pos pos))) pos) + end-pos (or end (and beg (+ pos (- end-pos pos))) end-pos)))) + ;; Region is available. Activate it and maybe save it. + (cond (reg-retrieved-p + (goto-char pos) + (push-mark end-pos 'nomsg 'activate) + (setq deactivate-mark nil) + (when bmkp-show-end-of-region + (let ((end-win (save-excursion (forward-line (window-height)) (end-of-line) (point)))) + ;; Bounce point and mark. + (save-excursion (sit-for 0.6) (exchange-point-and-mark) (sit-for 1)) + ;; Recenter if region end is not visible. + (when (> end-pos end-win) (recenter 1)))) + ;; Maybe save region. + (if (and reg-relocated-p (bmkp-save-new-region-location bmk pos end-pos)) + (message "Saved relocated region (from %d to %d)" pos end-pos) + (message "Region is from %d to %d" pos end-pos))) + (t ; No region. Go to old start. Don't push-mark. + (goto-char pos) (forward-line 0) + (message "No region from %d to %d" pos end-pos))))) + +;; Same as `line-number-at-pos', which is not available until Emacs 22. +(defun bmkp-line-number-at-pos (&optional pos) + "Buffer line number at position POS. Current line number if POS is nil. +Counting starts at (point-min), so any narrowing restriction applies." + (1+ (count-lines (point-min) (save-excursion (when pos (goto-char pos)) (forward-line 0) (point))))) + +(defun bmkp-goto-position (bookmark file buf bufname pos forward-str behind-str) + "Go to a bookmark that has no region. +Update the recorded position if `bmkp-save-new-location-flag'. +Arguments are respectively the bookmark, its file, buffer, buffer +name, recorded position, and the context strings for the position." + (if (and file (file-readable-p file) (not (buffer-live-p buf))) + (with-current-buffer (find-file-noselect file) (setq buf (buffer-name))) + ;; No file found. See if a non-file buffer exists for this. If not, raise error. + (unless (or (and buf (get-buffer buf)) + (and bufname (get-buffer bufname) (not (string= buf bufname)))) + (signal 'file-error `("Jumping to bookmark" "No such file or directory" ,file)))) + (set-buffer (or buf bufname)) + (when bmkp-jump-display-function + (save-current-buffer (funcall bmkp-jump-display-function (current-buffer)))) + (setq deactivate-mark t) + (raise-frame) + (goto-char pos) + ;; Try to relocate position. + ;; Search forward first. Then, if FORWARD-STR exists and was found in the file, search + ;; backward for BEHIND-STR. The rationale is that if text was inserted between the two + ;; in the file, then it's better to end up before point, so you can see the text, rather + ;; than after it and not see it. + (when (and forward-str (search-forward forward-str (point-max) t)) + (goto-char (match-beginning 0))) + (when (and behind-str (search-backward behind-str (point-min) t)) (goto-char (match-end 0))) + (when (and (/= pos (point)) bmkp-save-new-location-flag) + (bookmark-prop-set bookmark 'position (point)) + (bookmark-prop-set bookmark 'end-position (point)) + (bmkp-maybe-save-bookmarks)) + (/= pos (point))) ; Return value indicates whether POS was accurate. + +(defun bmkp-jump-sequence (bookmark) + "Handle a sequence bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for sequence bookmarks." + (dolist (bmk (bookmark-prop-get bookmark 'sequence)) + (bookmark--jump-via bmk bmkp-sequence-jump-display-function)) + (message "Done invoking bookmarks in sequence `%s'" + (if (stringp bookmark) bookmark (bookmark-name-from-full-record bookmark)))) + +(defun bmkp-jump-function (bookmark) + "Handle a function bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for function bookmarks." + (funcall (bookmark-prop-get bookmark 'function))) + +(defun bmkp-make-bookmark-list-record () + "Create and return a bookmark-list bookmark record. +This records the current state of buffer `*Bookmark List*': the sort +order, filter function, regexp pattern, title, and omit list." + (let ((state `((last-sort-comparer . ,bmkp-sort-comparer) + (last-reverse-sort-p . ,bmkp-reverse-sort-p) + (last-reverse-multi-sort-p . ,bmkp-reverse-multi-sort-p) + (last-bmenu-filter-function . ,bmkp-bmenu-filter-function) + (last-bmenu-filter-pattern . ,bmkp-bmenu-filter-pattern) + (last-bmenu-omitted-bookmarks . ,(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks)) + (last-bmenu-title . ,bmkp-bmenu-title) + (last-bmenu-toggle-filenames . ,bookmark-bmenu-toggle-filenames)))) + `(,@(bookmark-make-record-default 'no-file 'no-context) + (filename . ,bmkp-non-file-filename) + (bookmark-list . ,state) + (handler . bmkp-jump-bookmark-list)))) + +(add-hook 'bookmark-bmenu-mode-hook + #'(lambda () (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-bookmark-list-record))) + +(defun bmkp-jump-bookmark-list (bookmark) + "Jump to bookmark-list bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for record returned by `bmkp-make-bookmark-list-record'." + (let ((state (bookmark-prop-get bookmark 'bookmark-list))) + (setq bmkp-sort-comparer (cdr (assq 'last-sort-comparer state)) + bmkp-reverse-sort-p (cdr (assq 'last-reverse-sort-p state)) + bmkp-reverse-multi-sort-p (cdr (assq 'last-reverse-multi-sort-p state)) + bmkp-bmenu-filter-function (cdr (assq 'last-bmenu-filter-function state)) + bmkp-bmenu-filter-pattern (or (cdr (assq 'last-bmenu-filter-pattern state)) "") + bmkp-bmenu-omitted-bookmarks (cdr (assq 'last-bmenu-omitted-bookmarks state)) + bmkp-bmenu-title (cdr (assq 'last-bmenu-title state)) + bookmark-bmenu-toggle-filenames (cdr (assq 'last-bmenu-toggle-filenames state)))) + (let ((bookmark-alist (if bmkp-bmenu-filter-function + (funcall bmkp-bmenu-filter-function) + bookmark-alist))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp) + (when (get-buffer "*Bookmark List*") (pop-to-buffer "*Bookmark List*")))) + +;; Bookmark-file bookmarks. +;;;###autoload +(defun bmkp-set-bookmark-file-bookmark (file &optional msgp) ; Bound to `C-x p x' + "Create a bookmark that loads bookmark-file FILE when \"jumped\" to. +You are prompted for the names of the bookmark file and the bookmark." + (interactive (list (let ((insert-default-directory t)) + (read-file-name + "Create bookmark to load bookmark file: " "~/" + ;; Default file as default choice, unless it's already current. + (and (not (bmkp-same-file-p bookmark-default-file bmkp-current-bookmark-file)) + bookmark-default-file) + 'confirm)) + 'MSG)) + (setq file (expand-file-name file)) + (unless (file-readable-p file) (error "Unreadable bookmark file `%s'" file)) + (with-current-buffer (let ((enable-local-variables ())) (find-file-noselect file)) + (goto-char (point-min)) + (condition-case nil ; Check whether it's a valid bookmark file. + (progn (bookmark-maybe-upgrade-file-format) + (unless (listp (bookmark-alist-from-buffer)) (error ""))) + (error (error "Not a valid bookmark file: `%s'" file)))) + (let ((bookmark-make-record-function #'(lambda () (bmkp-make-bookmark-file-record file)))) + (call-interactively #'bookmark-set)) + (when msgp (message "Set bookmark-file bookmark"))) + +(defun bmkp-make-bookmark-file-record (bookmark-file) + "Create and return a bookmark-file bookmark record. +Records the BOOKMARK-FILE name. +Adds a handler that tests the prefix arg and loads the bookmark file +either as a replacement for the current bookmark file or as a +supplement to it." + `(,@(bookmark-make-record-default 'no-file 'no-context) + (filename . ,bookmark-file) + (bookmark-file . ,bookmark-file) + (handler . bmkp-jump-bookmark-file))) + +(defun bmkp-jump-bookmark-file (bookmark &optional switchp no-msg) + "Jump to bookmark-file bookmark BOOKMARK, which loads the bookmark file. +BOOKMARK is a bookmark name or a bookmark record. +Non-nil SWITCHP means overwrite the current bookmark list. +Handler function for record returned by `bmkp-make-bookmark-file-record'." + (let ((file (bookmark-prop-get bookmark 'bookmark-file)) + (overwritep (and (or switchp current-prefix-arg) + (y-or-n-p "Switch to new bookmark file, instead of just adding it? ")))) + (bookmark-load file overwritep)) + ;; This `throw' is only for the case where this handler is is called from `bookmark--jump-via'. + ;; It just tells `bookmark--jump-via' to skip the rest of what it does after calling the handler. + (condition-case nil + (throw 'bookmark--jump-via 'BOOKMARK-FILE-JUMP) + (no-catch nil))) + +;;;###autoload +(defun bmkp-bookmark-file-jump (bookmark-name &optional switchp no-msg) ; `C-x j x' + "Jump to a bookmark-file bookmark, which means load its bookmark file. +With a prefix argument, switch to the new bookmark file. +Otherwise, load it to supplement the current bookmark list." + (interactive + (let ((alist (bmkp-bookmark-file-alist-only))) + (list (bmkp-read-bookmark-for-type "bookmark-file " alist nil nil 'bmkp-bookmark-file-history) + current-prefix-arg))) + (bmkp-jump-bookmark-file bookmark-name switchp no-msg)) + +;; Desktop bookmarks +;;;###autoload +(defun bmkp-set-desktop-bookmark (desktop-file) ; Bound globally to `C-x p K', `C-x r K', `C-x p c K' + "Save the desktop as a bookmark. +You are prompted for the desktop-file location and the bookmark name." + (interactive (list (read-file-name "Save desktop in file: "))) + (set-text-properties 0 (length desktop-file) nil desktop-file) + (unless (file-name-absolute-p desktop-file) (setq desktop-file (expand-file-name desktop-file))) + (unless (condition-case nil (require 'desktop nil t) (error nil)) + (error "You must have library `desktop.el' to use this command")) + (let ((desktop-basefilename (file-name-nondirectory desktop-file)) ; Emacs < 22 + (desktop-base-file-name (file-name-nondirectory desktop-file)) ; Emacs 23+ + (desktop-dir (file-name-directory desktop-file)) + (desktop-restore-eager t) ; Don't bother with lazy restore. + (desktop-globals-to-save (bmkp-remove-if #'(lambda (elt) + (memq elt bmkp-desktop-no-save-vars)) + desktop-globals-to-save))) + (if (< emacs-major-version 22) + (desktop-save desktop-dir) ; Emacs < 22 has no locking. + (desktop-save desktop-dir 'RELEASE)) + (message "Desktop saved in `%s'" desktop-file) + (let ((bookmark-make-record-function #'(lambda () (bmkp-make-desktop-record desktop-file)))) + (call-interactively #'bookmark-set)))) + +(defun bmkp-make-desktop-record (desktop-file) + "Create and return a desktop bookmark record. +DESKTOP-FILE is the absolute file name of the desktop file to use." + `(,@(bookmark-make-record-default 'no-file 'no-context) + (filename . ,bmkp-non-file-filename) + (desktop-file . ,desktop-file) + (handler . bmkp-jump-desktop))) + +(defun bmkp-jump-desktop (bookmark) + "Jump to desktop bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for record returned by `bmkp-make-desktop-record'." + (let ((desktop-file (bookmark-prop-get bookmark 'desktop-file))) + (unless (condition-case nil (require 'desktop nil t) (error nil)) + (error "You must have library `desktop.el' to use this command")) + ;; (unless desktop-file (error "Not a desktop-bookmark: %S" bookmark)) ; Shouldn't happen. + (bmkp-desktop-change-dir desktop-file) + (unless (bmkp-desktop-read desktop-file) (error "Could not load desktop file")))) + +;; Derived from code in `desktop-change-dir'. +;;;###autoload +(defun bmkp-desktop-change-dir (desktop-file) + "Change to desktop saved in DESKTOP-FILE. +Kill the desktop as specified by variables `desktop-save-mode' and + `desktop-save' (starting with Emacs 22). +Clear the desktop and load DESKTOP-FILE DIRNAME." + (interactive (list (read-file-name "Change to desktop file: "))) + (set-text-properties 0 (length desktop-file) nil desktop-file) + (unless (file-name-absolute-p desktop-file) (setq desktop-file (expand-file-name desktop-file))) + (unless (condition-case nil (require 'desktop nil t) (error nil)) + (error "You must have library `desktop.el' to use this command")) + (let ((desktop-basefilename (file-name-nondirectory desktop-file)) ; Emacs < 22 + (desktop-base-file-name (file-name-nondirectory desktop-file)) ; Emacs 23+ + (desktop-dir (file-name-directory desktop-file)) + (desktop-restore-eager t) ; Don't bother with lazy restore. + (desktop-globals-to-save (bmkp-remove-if #'(lambda (elt) + (memq elt bmkp-desktop-no-save-vars)) + desktop-globals-to-save))) + (bmkp-desktop-kill) + (desktop-clear) + (if (< emacs-major-version 22) (desktop-read) (desktop-read desktop-dir)))) + +;; Derived from code in `desktop-kill'. +(defun bmkp-desktop-kill () + "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do. +This does nothing in Emacs versions prior to Emacs 22." + ;; We assume here: `desktop.el' has been loaded and `desktop-dirname' is defined. + (when (and (and (boundp 'desktop-save-mode) desktop-save-mode) ; Not defined in Emacs 20-21. + (let ((exists (file-exists-p (desktop-full-file-name)))) + (or (eq desktop-save t) + (and exists (memq desktop-save '(ask-if-new if-exists))) + (and (or (memq desktop-save '(ask ask-if-new)) + (and exists (eq desktop-save 'ask-if-exists))) + (y-or-n-p "Save current desktop? "))))) + (condition-case err + (if (< emacs-major-version 22) + (desktop-save desktop-dirname) ; Emacs < 22 has no locking. + (desktop-save desktop-dirname 'RELEASE)) + (file-error (unless (yes-or-no-p "Error while saving the desktop. Ignore? ") + (signal (car err) (cdr err)))))) + ;; Just release lock, regardless of whether this Emacs process is the owner. + (when (fboundp 'desktop-release-lock) (desktop-release-lock))) ; Not defined for Emacs 20. + +;; Derived from code in `desktop-read'. +;;;###autoload +(defun bmkp-desktop-read (file) + "Load desktop-file FILE, then run `desktop-after-read-hook'. +Return t if FILE was loaded, nil otherwise." + (interactive) + (unless (file-name-absolute-p file) (setq file (expand-file-name file))) ; Shouldn't happen. + (setq desktop-dirname (file-name-directory file)) + (if (not (file-readable-p file)) + nil ; Return nil, meaning not loaded. + (let ((desktop-restore-eager t) ; Don't bother with lazy restore. + (desktop-first-buffer nil) + (desktop-buffer-ok-count 0) + (desktop-buffer-fail-count 0) + (desktop-save nil)) ; Prevent desktop saving during eval of desktop buffer. + (when (fboundp 'desktop-lazy-abort) (desktop-lazy-abort)) ; Emacs 22+. + (load file t t t) + (when (boundp 'desktop-file-modtime) ; Emacs 22+ + (setq desktop-file-modtime (nth 5 (file-attributes file)))) + ;; `desktop-create-buffer' puts buffers at end of the buffer list. + ;; We want buffers existing prior to evaluating the desktop (and not reused) to be placed + ;; at the end of the buffer list, so we move them here. + (mapc 'bury-buffer (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list)))))) + (switch-to-buffer (car (buffer-list))) + (run-hooks 'desktop-delay-hook) + (setq desktop-delay-hook ()) + (run-hooks 'desktop-after-read-hook) + (when (boundp 'desktop-buffer-ok-count) ; Emacs 22+ + (message "Desktop: %d buffer%s restored%s%s." desktop-buffer-ok-count + (if (= 1 desktop-buffer-ok-count) "" "s") + (if (< 0 desktop-buffer-fail-count) + (format ", %d failed to restore" desktop-buffer-fail-count) + "") + (if (and (boundp 'desktop-buffer-args-list) desktop-buffer-args-list) + (format ", %d to be restored lazily" (length desktop-buffer-args-list)) + ""))) + t))) ; Return t, meaning successfully loaded. + +;;;###autoload +(defun bmkp-desktop-delete (bookmark-name) + "Delete desktop bookmark BOOKMARK-NAME, and delete its desktop file. +Release the lock file in that desktop's directory. +\(This means that if you currently have locked a different desktop +in the same directory, then you will need to relock it.)" + (interactive (let ((alist (bmkp-desktop-alist-only))) + (list (bmkp-read-bookmark-for-type "desktop " alist nil nil 'bmkp-desktop-history + "Delete ")))) + (let ((desktop-file (bookmark-prop-get bookmark-name 'desktop-file))) + (unless desktop-file (error "Not a desktop-bookmark: `%s'" bookmark-name)) + ;; Release the desktop lock file in the same directory as DESKTOP-FILE. + ;; This will NOT be the right thing to do if a desktop file different from DESKTOP-FILE + ;; is currently locked in the same directory. + (let ((desktop-dir (file-name-directory desktop-file))) + (when (fboundp 'desktop-release-lock) (desktop-release-lock))) ; Not defined for Emacs 20. + (when (file-exists-p desktop-file) (delete-file desktop-file))) + (bookmark-delete bookmark-name)) + +;; Variable-list bookmarks +(when (boundp 'wide-n-restrictions) + (defun bmkp-set-restrictions-bookmark () + "Save the ring of restrictions for the current buffer as a bookmark. +You need library `wide-n.el' to use the bookmark created." + (interactive) + (let ((bookmark-make-record-function + (lambda () (bmkp-make-variable-list-record + `((wide-n-restrictions + . ,(mapcar (lambda (x) + (if (eq x 'all) + 'all + (let ((beg (car x)) ; Convert markers to number positions. + (end (cdr x))) + (cons (if (markerp beg) (marker-position beg) beg) + (if (markerp end) (marker-position end) end))))) + wide-n-restrictions))))))) + (call-interactively #'bookmark-set) + (unless (featurep 'wide-n) (message "Bookmark created, but you need `wide-n.el' to use it"))))) + +;;;###autoload +(defun bmkp-set-variable-list-bookmark (variables) + "Save a list of variables as a bookmark. +Interactively, read the variables to save, using +`bmkp-read-variables-completing'." + (interactive (list (bmkp-read-variables-completing))) + (let ((bookmark-make-record-function #'(lambda () (bmkp-make-variable-list-record variables)))) + (call-interactively #'bookmark-set))) + +(defun bmkp-create-variable-list-bookmark (bookmark-name vars vals &optional buffer-name) + "Create a variable-list bookmark named BOOKMARK-NAME from VARS and VALS. +VARS and VALS are corresponding lists of variables and their values. + +Optional arg BUFFER-NAME is the buffer name to use for the bookmark (a +string). This is useful if some of the variables are buffer-local. +If BUFFER-NAME is nil, the current buffer name is recorded." + (eval `(multiple-value-bind ,vars ',vals + (let ((bookmark-make-record-function + (lambda () (bmkp-make-variable-list-record ',vars ,buffer-name)))) + (bookmark-set ,bookmark-name nil t))))) + +(defun bmkp-read-variables-completing (&optional option) + "Read variable names with completion, and return them as a list of symbols. +Reads names one by one, until you hit `RET' twice consecutively. +Non-nil argument OPTION means read only user option names." + (bookmark-maybe-load-default-file) + (let ((var (bmkp-read-variable "Variable (RET for each, empty input to finish): " option)) + (vars ()) + old-var) + (while (not (string= "" var)) + (add-to-list 'vars var) + (setq var (bmkp-read-variable "Variable: " option))) + (nreverse vars))) + +(defun bmkp-read-variable (prompt &optional option default-value) + "Read name of a variable and return it as a symbol. +Prompt with string PROMPT. +With non-nil OPTION, read the name of a user option. +The default value is DEFAULT-VALUE if non-nil, or the nearest symbol +to the cursor if it is a variable." + (setq option (if option 'user-variable-p 'boundp)) + (let ((symb (cond ((fboundp 'symbol-nearest-point) + (symbol-nearest-point)) + ((fboundp 'symbol-at-point) (symbol-at-point)) + (t nil))) + (enable-recursive-minibuffers t) + (icicle-unpropertize-completion-result-flag t)) + (when (and default-value (symbolp default-value)) + (setq default-value (symbol-name default-value))) + (intern (completing-read prompt obarray option t nil 'minibuffer-history + (or default-value (and (funcall option symb) (symbol-name symb))) + t)))) + +(defun bmkp-make-variable-list-record (variables &optional buffer-name) + "Create and return a variable-list bookmark record. +VARIABLES is the list of variables to save. +Each entry in VARIABLES is either a variable (a symbol) or a cons + whose car is a variable and whose cdr is the variable's value. + +Optional arg BUFFER-NAME is the buffer to use for the bookmark. This +is useful if some of the variables are buffer-local. If BUFFER-NAME +is nil, the current buffer is used." + (let ((record `(,@(bookmark-make-record-default 'no-file 'no-context) + (filename . ,bmkp-non-file-filename) + (variables . ,(or (bmkp-printable-vars+vals variables) + (error "No variables to bookmark"))) + (handler . bmkp-jump-variable-list)))) + (when buffer-name (let ((bname (assq 'buffer-name record))) (setcdr bname buffer-name))) + record)) + +(defun bmkp-printable-vars+vals (variables) + "Return an alist of printable VARIABLES paired with their values. +Display a message for any variables that are not printable. +VARIABLES is the list of variables. Each entry in VARIABLES is either + a variable (a symbol) or a cons whose car is a variable and whose cdr + is the variable's value." + (let ((vars+vals ()) + (unprintables ())) + (dolist (var variables) + (let ((val (if (consp var) (cdr var) (symbol-value var)))) + (if (bmkp-printable-p val) + (add-to-list 'vars+vals (if (consp var) var (cons var val))) + (add-to-list 'unprintables var)))) + (when unprintables (message "Unsavable (unreadable) vars: %S" unprintables) (sit-for 3)) + vars+vals)) + +;; Same as `savehist-printable', except added `print-circle' binding. +(defun bmkp-printable-p (value) + "Return non-nil if VALUE would be Lisp-readable if printed using `prin1'." + (or (stringp value) (numberp value) (symbolp value) + (with-temp-buffer ; Print and try to read. + (condition-case nil + (let ((print-readably t) + (print-level nil) + (print-circle t)) + (prin1 value (current-buffer)) + (read (point-min-marker)) + t) + (error nil))))) + +(defun bmkp-jump-variable-list (bookmark) + "Jump to variable-list bookmark BOOKMARK, restoring the recorded values. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for record returned by `bmkp-make-variable-list-record'." + (let ((buf (bmkp-get-buffer-name bookmark)) + (vars+vals (bookmark-prop-get bookmark 'variables))) + (unless (get-buffer buf) + (message "Bookmarked for non-existent buffer `%s', so using current buffer" buf) (sit-for 3) + (setq buf (current-buffer))) + (with-current-buffer buf + (dolist (var+val vars+vals) + (set (car var+val) (cdr var+val)))) + (message "Variables restored in buffer `%s': %S" buf (mapcar #'car vars+vals)) + (sit-for 3))) + +;; URL browse support +(defun bmkp-make-url-browse-record (url) + "Create and return a url bookmark for `browse-url' to visit URL. +The handler is `bmkp-jump-url-browse'." + (require 'browse-url) + (let ((url-0 (copy-sequence url))) + (set-text-properties 0 (length url) () url-0) + `((filename . ,bmkp-non-file-filename) + (location . ,url-0) + (handler . bmkp-jump-url-browse)))) + +(defun bmkp-jump-url-browse (bookmark) + "Handler function for record returned by `bmkp-make-url-browse-record'. +BOOKMARK is a bookmark name or a bookmark record." + (require 'browse-url) + (let ((url (bookmark-prop-get bookmark 'location))) + (browse-url url))) + +;; W3M support +(defun bmkp-make-w3m-record () + "Make a special entry for w3m buffers." + (require 'w3m) ; For `w3m-current-url'. + `(,w3m-current-title + ,@(bookmark-make-record-default 'no-file) + (filename . ,w3m-current-url) + (handler . bmkp-jump-w3m))) + +(add-hook 'w3m-mode-hook #'(lambda () (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-w3m-record))) + +(defun bmkp-w3m-set-new-buffer-name () + "Set the w3m buffer name according to the number of w3m buffers already open." + (require 'w3m) ; For `w3m-list-buffers'. + (let ((len (length (w3m-list-buffers 'nosort)))) + (if (eq len 0) "*w3m*" (format "*w3m*<%d>" (1+ len))))) + +(defun bmkp-jump-w3m-new-session (bookmark) + "Jump to W3M bookmark BOOKMARK, setting a new tab." + (require 'w3m) + (let ((buf (bmkp-w3m-set-new-buffer-name))) + (w3m-browse-url (bookmark-prop-get bookmark 'filename) 'newsession) + (while (not (get-buffer buf)) (sit-for 1)) ; Be sure we have the W3M buffer. + (with-current-buffer buf + (goto-char (point-min)) + ;; Wait until data arrives in buffer, before setting region. + (while (eq (line-beginning-position) (line-end-position)) (sit-for 1))) + (bookmark-default-handler + `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark))))) + +(defun bmkp-jump-w3m-only-one-tab (bookmark) + "Close all W3M sessions and jump to BOOKMARK in a new W3M buffer." + (require 'w3m) + (w3m-quit 'force) ; Be sure we start with an empty W3M buffer. + (w3m-browse-url (bookmark-prop-get bookmark 'filename)) + (with-current-buffer "*w3m*" (while (eq (point-min) (point-max)) (sit-for 1))) + (bookmark-default-handler + `("" (buffer . ,(buffer-name (current-buffer))) . ,(bookmark-get-bookmark-record bookmark)))) + +(defalias 'bmkext-jump-w3m 'bmkp-jump-w3m) +(defun bmkp-jump-w3m (bookmark) + "Handler function for record returned by `bmkp-make-w3m-record'. +BOOKMARK is a bookmark name or a bookmark record. +Use multi-tabs in W3M if `bmkp-w3m-allow-multi-tabs' is non-nil." + (require 'w3m) + (if bmkp-w3m-allow-multi-tabs + (bmkp-jump-w3m-new-session bookmark) + (bmkp-jump-w3m-only-one-tab bookmark))) + + +;; GNUS support for Emacs < 24. + +(defun bmkp-make-gnus-record () + "Make a bookmark entry for a Gnus summary buffer." + (require 'gnus) + (unless (and (eq major-mode 'gnus-summary-mode) gnus-article-current) + (error "Try again, from the Gnus summary buffer")) + (let* ((grp (car gnus-article-current)) + (art (cdr gnus-article-current)) + (head (gnus-summary-article-header art)) + (id (mail-header-id head))) + `((elt (gnus-summary-article-header) 1) + ,@(bookmark-make-record-default 'no-file) + (filename . ,bmkp-non-file-filename) (group . ,grp) (article . ,art) (message-id . ,id) + (handler . bmkp-jump-gnus)))) + +(unless (> emacs-major-version 23) ; Emacs 24 has `gnus-summary-bookmark-make-record'. + (add-hook 'gnus-summary-mode-hook #'(lambda () + (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-gnus-record)))) + +(unless (> emacs-major-version 23) ; Emacs 24 has `gnus-summary-bookmark-make-record'. + (add-hook 'gnus-article-mode-hook #'(lambda () + (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-gnus-record)))) + +(defun bmkext-jump-gnus (bookmark) ; Compatibility code. + "`gnus-summary-bookmark-jump' if defined, else `bmkp-jump-gnus'." + (if (fboundp 'gnus-summary-bookmark-jump) + (gnus-summary-bookmark-jump bookmark) ; Emacs 24 + (bmkp-jump-gnus bookmark))) + +(defun bmkp-jump-gnus (bookmark) + "Handler function for record returned by `bmkp-make-gnus-record'. +BOOKMARK is a bookmark name or a bookmark record." + (let ((group (bookmark-prop-get bookmark 'group)) + (article (bookmark-prop-get bookmark 'article)) + (id (bookmark-prop-get bookmark 'message-id)) + (buf (bookmark-prop-get bookmark 'buffer))) + (if (< emacs-major-version 22) (gnus-fetch-group group) (gnus-fetch-group group (list article))) + (gnus-summary-insert-cached-articles) + (gnus-summary-goto-article id nil 'force) + (bookmark-default-handler `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark))))) + + +;; `man' and `woman' support for Emacs < 24. + +(when (> emacs-major-version 20) + (defun bmkp-make-woman-record () + "Create bookmark record for `man' page bookmark created by `woman'." + `(,@(bookmark-make-record-default 'no-file) + (filename . ,woman-last-file-name) (handler . bmkp-jump-woman))) + + (unless (> emacs-major-version 23) + (add-hook 'woman-mode-hook #'(lambda () + (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-woman-record))))) + +(defun bmkp-make-man-record () + "Create bookmark record for `man' page bookmark created by `man'." + `(,@(bookmark-make-record-default 'no-file) + (filename . ,bmkp-non-file-filename) + (man-args . ,Man-arguments) (handler . bmkp-jump-man))) + +(unless (> emacs-major-version 23) + (add-hook 'Man-mode-hook #'(lambda () (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-man-record)))) + +(defun bmkext-jump-woman (bookmark) ; Compatibility code. + "`woman-bookmark-jump' if defined, else `bmkp-jump-woman'." + (if (fboundp 'woman-bookmark-jump) + (woman-bookmark-jump bookmark) ; Emacs 24 + (bmkp-jump-woman bookmark))) + +(defun bmkp-jump-woman (bookmark) + "Handler function for `man' page bookmark created by `woman'." + (unless (> emacs-major-version 20) + (error "`woman' bookmarks are not supported in Emacs prior to Emacs 21")) + (bookmark-default-handler + `("" (buffer . ,(save-window-excursion (woman-find-file (bookmark-get-filename bookmark)) + (current-buffer))) + . ,(bookmark-get-bookmark-record bookmark)))) + +(defun bmkext-jump-man (bookmark) ; Compatibility code. + "`Man-bookmark-jump' if defined, else `bmkp-jump-man'." + (if (fboundp 'Man-bookmark-jump) + (Man-bookmark-jump bookmark) ; Emacs 24 + (bmkp-jump-man bookmark))) + +(defun bmkp-jump-man (bookmark) + "Handler function for `man' page bookmark created by `man'." + (require 'man) + (let ((Man-notify-method (case bmkp-jump-display-function + ((nil display-buffer) 'quiet) + (switch-to-buffer 'pushy) + ((switch-to-buffer-other-window pop-to-buffer) 'friendly) + (t 'quiet)))) + (Man-getpage-in-background (bookmark-prop-get bookmark 'man-args)) + (while (get-process "man") (sit-for 0.2)) + (bookmark-default-handler (bookmark-get-bookmark bookmark)))) + +(defun bmkp-make-dired-record () + "Create and return a Dired bookmark record." + (let ((hidden-dirs (save-excursion (dired-remember-hidden)))) + (unwind-protect + (let ((dir (expand-file-name (if (consp dired-directory) + (file-name-directory (car dired-directory)) + dired-directory))) + (subdirs (bmkp-dired-subdirs)) + (mfiles (mapcar #'(lambda (mm) (car mm)) + (dired-remember-marks (point-min) (point-max))))) + `(,dir + ,@(bookmark-make-record-default 'no-file) + (filename . ,dir) (dired-directory . ,dired-directory) + (dired-marked . ,mfiles) (dired-switches . ,dired-actual-switches) + (dired-subdirs . ,subdirs) (dired-hidden-dirs . ,hidden-dirs) + (handler . bmkp-jump-dired))) + (save-excursion ; Hide subdirs that were hidden. + (dolist (dir hidden-dirs) (when (dired-goto-subdir dir) (dired-hide-subdir 1))))))) + +;;;###autoload +(defun bmkp-dired-subdirs () + "Alist of inserted subdirectories, without their positions (markers). +This is like `dired-subdir-alist' but without the top-level dir and +without subdir positions (markers)." + (interactive) + (let ((subdir-alist (cdr (reverse dired-subdir-alist))) ; Remove top. + (subdirs-wo-posns ())) + (dolist (sub subdir-alist) (push (list (car sub)) subdirs-wo-posns)) + subdirs-wo-posns)) + +(add-hook 'dired-mode-hook #'(lambda () (set (make-local-variable 'bookmark-make-record-function) + 'bmkp-make-dired-record))) + +(defun bmkp-jump-dired (bookmark) + "Jump to Dired bookmark BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Handler function for record returned by `bmkp-make-dired-record'." + (let ((dir (bookmark-prop-get bookmark 'dired-directory)) + (mfiles (bookmark-prop-get bookmark 'dired-marked)) + (switches (bookmark-prop-get bookmark 'dired-switches)) + (subdirs (bookmark-prop-get bookmark 'dired-subdirs)) + (hidden-dirs (bookmark-prop-get bookmark 'dired-hidden-dirs))) + (case bmkp-jump-display-function + ((nil switch-to-buffer display-buffer) (dired dir switches)) + ((pop-to-buffer switch-to-buffer-other-window) (dired-other-window dir switches)) + (t (dired dir switches))) + (let ((inhibit-read-only t)) + (dired-insert-old-subdirs subdirs) + (dired-mark-remembered (mapcar #'(lambda (mf) (cons (expand-file-name mf dir) 42)) mfiles)) + (save-excursion + (dolist (dir hidden-dirs) (when (dired-goto-subdir dir) (dired-hide-subdir 1))))) + (goto-char (bookmark-get-position bookmark)))) + + +(defun bmkp-read-bookmark-for-type (type alist &optional other-win pred hist action) + "Read name of a bookmark of type TYPE. +TYPE is a string used only in the prompt: \"Jump to TYPE bookmark: \". +ALIST is the alist used for completion - nil means `bookmark-alist'. +Non-nil OTHER-WIN means append \" in another window\" to the prompt. +Non-nil PRED is a predicate used for completion. +Non-nil HIST is a history symbol. Default is `bookmark-history'. +ACTION is the action to mention in the prompt. `Jump to ', if nil." + (unless alist (error "No bookmarks of type %s" type)) + (bookmark-completing-read + (concat (or action "Jump to ") type "bookmark" (and other-win " in another window")) + (bmkp-default-bookmark-name alist) + alist pred hist)) + +;;;###autoload +(defun bmkp-jump-to-type (bookmark-name &optional use-region-p) ; `C-x j :' + "Jump to a bookmark of a given type. You are prompted for the type. +Otherwise, this is the same as `bookmark-jump' - see that, in +particular, for info about using a prefix argument." + (interactive + (let* ((completion-ignore-case t) + (type-cands bmkp-types-alist) + (icicle-unpropertize-completion-result-flag t) + (type (completing-read "Type of bookmark: " + type-cands nil t)) + (alist (funcall (intern + (format "bmkp-%s-alist-only" type)))) + (history (assoc-default type type-cands)) + (bmk-name (bmkp-read-bookmark-for-type (concat type " ") + alist nil nil history))) + (list bmk-name (or (equal type "Region") current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-jump-to-type-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j :' + "`bmkp-jump-to-type', but in another window." + (interactive + (let* ((completion-ignore-case t) + (type-cands bmkp-types-alist) + (icicle-unpropertize-completion-result-flag t) + (type (completing-read "Type of bookmark: " + type-cands nil t)) + (alist (funcall (intern + (format "bmkp-%s-alist-only" type)))) + (history (assoc-default type type-cands)) + (bmk-name (bmkp-read-bookmark-for-type (concat type " ") + alist t nil history))) + (list bmk-name (or (equal type "Region") current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-autonamed-jump (bookmark-name) ; `C-x j # #' + "Jump to an autonamed bookmark. +This is a specialization of `bookmark-jump'." + (interactive + (let ((alist (bmkp-autonamed-alist-only))) + (list (bmkp-read-bookmark-for-type "autonamed " alist nil nil 'bmkp-autonamed-history)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer nil)) + +;;;###autoload +(defun bmkp-autonamed-jump-other-window (bookmark-name) ; `C-x 4 j # #' + "`bmkp-autonamed-jump', but in another window." + (interactive + (let ((alist (bmkp-autonamed-alist-only))) + (list (bmkp-read-bookmark-for-type "autonamed " alist t nil 'bmkp-autonamed-history)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window nil)) + +;;;###autoload +(defun bmkp-autonamed-this-buffer-jump (bookmark-name) ; `C-x j # .' + "Jump to an autonamed bookmark in the current buffer. +This is a specialization of `bookmark-jump'." + (interactive + (let ((alist (bmkp-autonamed-this-buffer-alist-only))) + (list (bmkp-read-bookmark-for-type "autonamed " alist nil nil 'bmkp-autonamed-history)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer nil)) + +;;;###autoload +(defun bmkp-autonamed-this-buffer-jump-other-window (bookmark-name) ; `C-x 4 j # .' + "`bmkp-autonamed-this-buffer-jump', but in another window." + (interactive + (let ((alist (bmkp-autonamed-this-buffer-alist-only))) + (list (bmkp-read-bookmark-for-type "autonamed " alist t nil 'bmkp-autonamed-history)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window nil)) + +;;;###autoload +(defun bmkp-bookmark-list-jump (bookmark-name &optional use-region-p) ; `C-x j B' + "Jump to a bookmark-list bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-bookmark-list-alist-only))) + (list (bmkp-read-bookmark-for-type "bookmark-list " alist nil nil 'bmkp-bookmark-list-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-desktop-jump (bookmark-name &optional use-region-p) ; `C-x j K' + "Jump to a desktop bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-desktop-alist-only))) + (list (bmkp-read-bookmark-for-type "desktop " alist nil nil 'bmkp-desktop-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-dired-jump (bookmark-name &optional use-region-p) ; `C-x j d' + "Jump to a Dired bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-dired-alist-only))) + (list (bmkp-read-bookmark-for-type "Dired " alist nil nil 'bmkp-dired-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-dired-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j d' + "`bmkp-dired-jump', but in another window." + (interactive + (let ((alist (bmkp-dired-alist-only))) + (list (bmkp-read-bookmark-for-type "Dired " alist t nil 'bmkp-dired-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-dired-this-dir-jump (bookmark-name &optional use-region-p) ; `C-x j C-d' + "Jump to a Dired bookmark for the `default-directory'. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-dired-this-dir-alist-only))) + (list (bmkp-read-bookmark-for-type "Dired-for-this-dir " alist nil nil 'bmkp-dired-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-dired-this-dir-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j C-d' + "`bmkp-dired-this-dir-jump', but in another window." + (interactive + (let ((alist (bmkp-dired-this-dir-alist-only))) + (list (bmkp-read-bookmark-for-type "Dired-for-this-dir " alist t nil 'bmkp-dired-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-file-jump (bookmark-name &optional use-region-p) ; `C-x j f' + "Jump to a file or directory bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-file-alist-only))) + (list (bmkp-read-bookmark-for-type "file " alist nil nil 'bmkp-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-file-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j f' + "`bmkp-file-jump', but in another window." + (interactive + (let ((alist (bmkp-file-alist-only))) + (list (bmkp-read-bookmark-for-type "file " alist t nil 'bmkp-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-file-this-dir-jump (bookmark-name &optional use-region-p) ; `C-x j C-f' + "Jump to a bookmark for a file or subdir in the `default-directory'. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-file-this-dir-alist-only))) + (list (bmkp-read-bookmark-for-type "file-in-this-dir " alist nil nil 'bmkp-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-file-this-dir-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j C-f' + "`bmkp-file-this-dir-jump', but in another window." + (interactive + (let ((alist (bmkp-file-this-dir-alist-only))) + (list (bmkp-read-bookmark-for-type "file-in-this-dir " alist t nil 'bmkp-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-gnus-jump (bookmark-name &optional use-region-p) ; `C-x j g' + "Jump to a Gnus bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-gnus-alist-only))) + (list (bmkp-read-bookmark-for-type "Gnus " alist nil nil 'bmkp-gnus-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-gnus-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j g' + "`bmkp-gnus-jump', but in another window." + (interactive + (let ((alist (bmkp-gnus-alist-only))) + (list (bmkp-read-bookmark-for-type "Gnus " alist t nil 'bmkp-gnus-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-info-jump (bookmark-name &optional use-region-p) ; `C-x j i' + "Jump to an Info bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-info-alist-only))) + (list (bmkp-read-bookmark-for-type "Info " alist nil nil 'bmkp-info-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-info-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j i' + "`bmkp-info-jump', but in another window." + (interactive + (let ((alist (bmkp-info-alist-only))) + (list (bmkp-read-bookmark-for-type "Info " alist t nil 'bmkp-info-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-local-file-jump (bookmark-name &optional use-region-p) ; `C-x j l' + "Jump to a local file or directory bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-local-file-alist-only))) + (list (bmkp-read-bookmark-for-type "local file " alist nil nil 'bmkp-local-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-local-file-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j l' + "`bmkp-local-file-jump', but in another window." + (interactive + (let ((alist (bmkp-local-file-alist-only))) + (list (bmkp-read-bookmark-for-type "local file " alist t nil 'bmkp-local-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-man-jump (bookmark-name &optional use-region-p) ; `C-x j m' + "Jump to a `man'-page bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-man-alist-only))) + (list (bmkp-read-bookmark-for-type "`man' " alist nil nil 'bmkp-man-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-man-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j m' + "`bmkp-man-jump', but in another window." + (interactive + (let ((alist (bmkp-man-alist-only))) + (list (bmkp-read-bookmark-for-type "`man' " alist t nil 'bmkp-man-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-non-file-jump (bookmark-name &optional use-region-p) ; `C-x j b' + "Jump to a non-file (buffer) bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-non-file-alist-only))) + (list (bmkp-read-bookmark-for-type "non-file (buffer) " alist nil nil 'bmkp-non-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-non-file-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j b' + "`bmkp-non-file-jump', but in another window." + (interactive + (let ((alist (bmkp-non-file-alist-only))) + (list (bmkp-read-bookmark-for-type "non-file (buffer) " alist t nil 'bmkp-non-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-region-jump (bookmark-name) ; `C-x j r' + "Jump to a region bookmark. +This is a specialization of `bookmark-jump', but without a prefix arg." + (interactive (list (bmkp-read-bookmark-for-type "region " (bmkp-region-alist-only) nil nil + 'bmkp-region-history))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer t)) + +;;;###autoload +(defun bmkp-region-jump-other-window (bookmark-name) ; `C-x 4 j r' + "`bmkp-region-jump', but in another window." + (interactive (list (bmkp-read-bookmark-for-type "region " (bmkp-region-alist-only) t nil + 'bmkp-region-history))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window t)) + +;;;###autoload +(defun bmkp-remote-file-jump (bookmark-name &optional use-region-p) ; `C-x j n' + "Jump to a remote file or directory bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-remote-file-alist-only))) + (list (bmkp-read-bookmark-for-type "remote file " alist nil nil 'bmkp-remote-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-remote-file-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j n' + "`bmkp-remote-file-jump', but in another window." + (interactive + (let ((alist (bmkp-remote-file-alist-only))) + (list (bmkp-read-bookmark-for-type "remote file " alist t nil 'bmkp-remote-file-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-specific-buffers-jump (buffers bookmark-name &optional use-region-p) ; `C-x j = b' + "Jump to a bookmark for a buffer in list BUFFERS. +Interactively, read buffer names and bookmark name, with completion. + +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((buffs ()) + buff) + (while (and (setq buff (bmkp-completing-read-buffer-name 'ALLOW-EMPTY)) (not (string= "" buff))) + (add-to-list 'buffs buff)) + (let ((alist (bmkp-specific-buffers-alist-only buffs))) + (list buffs (bmkp-read-bookmark-for-type "specific-buffers " alist) current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-specific-buffers-jump-other-window (buffers bookmark-name + &optional use-region-p) ; `C-x 4 j = b' + "`bmkp-specific-buffers-jump', but in another window." + (interactive + (let ((buffs ()) + buff) + (while (and (setq buff (bmkp-completing-read-buffer-name 'ALLOW-EMPTY)) (not (string= "" buff))) + (add-to-list 'buffs buff)) + (let ((alist (bmkp-specific-buffers-alist-only buffs))) + (list buffs (bmkp-read-bookmark-for-type "specific-buffers " alist) current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-specific-files-jump (files bookmark-name &optional use-region-p) ; `C-x j = f' + "Jump to a bookmark for a file in list FILES. +Interactively, read file names and bookmark name, with completion. + +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((use-file-dialog nil) + (files ()) + file) + (while (and (setq file (bmkp-completing-read-file-name 'ALLOW-EMPTY)) (not (string= "" file))) + (add-to-list 'files file)) + (let ((alist (bmkp-specific-files-alist-only files))) + (list files (bmkp-read-bookmark-for-type "specific-files " alist) current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-specific-files-jump-other-window (files bookmark-name + &optional use-region-p) ; `C-x 4 j = f' + "`bmkp-specific-files-jump', but in another window." + (interactive + (let ((use-file-dialog nil) + (files ()) + file) + (while (and (setq file (bmkp-completing-read-file-name 'ALLOW-EMPTY)) (not (string= "" file))) + (add-to-list 'files file)) + (let ((alist (bmkp-specific-files-alist-only files))) + (list files (bmkp-read-bookmark-for-type "specific-files " alist) current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-this-buffer-jump (bookmark-name &optional use-region-p) ; `C-x j .' + "Jump to a bookmark for the current buffer. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-this-buffer-alist-only))) + (unless alist (error "No bookmarks for this buffer")) + (list (bookmark-completing-read "Jump to bookmark for this buffer" + (bmkp-default-bookmark-name alist) alist) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-this-buffer-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j .' + "`bmkp-this-buffer-jump', but in another window." + (interactive + (let ((alist (bmkp-this-buffer-alist-only))) + (unless alist (error "No bookmarks for this buffer")) + (list (bookmark-completing-read "Jump to bookmark for this buffer in another window" + (bmkp-default-bookmark-name alist) alist) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;; ;;;###autoload +;;; (defun bmkp-this-file-jump (bookmark-name &optional use-region-p) +;;; "Jump to a bookmark for the current file (absolute file name). +;;; This is a specialization of `bookmark-jump' - see that, in particular +;;; for info about using a prefix argument." +;;; (interactive +;;; (progn (unless (or (buffer-file-name) (and (eq major-mode 'dired-mode) +;;; (if (consp dired-directory) +;;; (car dired-directory) +;;; dired-directory))) +;;; (error "This buffer is not associated with a file")) +;;; (let ((alist (bmkp-this-file-alist-only))) +;;; (unless alist (error "No bookmarks for this file")) +;;; (list (bookmark-completing-read "Jump to bookmark for this file" +;;; (bmkp-default-bookmark-name alist) alist) +;;; current-prefix-arg)))) +;;; (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;; ;;;###autoload +;;; (defun bmkp-this-file-jump-other-window (bookmark-name &optional use-region-p) +;;; "`bmkp-this-file-jump', but in another window." +;;; (interactive +;;; (progn (unless (or (buffer-file-name) (and (eq major-mode 'dired-mode) +;;; (if (consp dired-directory) +;;; (car dired-directory) +;;; dired-directory))) +;;; (error "This buffer is not associated with a file")) +;;; (let ((alist (bmkp-this-file-alist-only))) +;;; (unless alist (error "No bookmarks for this file")) +;;; (list (bookmark-completing-read "Jump to bookmark for this file in another window" +;;; (bmkp-default-bookmark-name alist) alist) +;;; current-prefix-arg)))) +;;; (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-variable-list-jump (bookmark-name) ; `C-x j v' + "Jump to a variable-list bookmark. +This is a specialization of `bookmark-jump'." + (interactive + (let ((alist (bmkp-variable-list-alist-only))) + (list (bmkp-read-bookmark-for-type "variable-list " alist nil nil 'bmkp-variable-list-history)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer nil)) + +;;;###autoload +(defun bmkp-url-jump (bookmark-name &optional use-region-p) ; `C-x j u' + "Jump to a URL bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (if (fboundp 'w3m-list-buffers) + (bmkp-url-alist-only) + (bmkp-url-browse-alist-only)))) + (list (bmkp-read-bookmark-for-type "URL " alist nil nil 'bmkp-url-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-url-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j u' + "`bmkp-url-jump', but in another window." + (interactive + (let ((alist (if (fboundp 'w3m-list-buffers) + (bmkp-url-alist-only) + (bmkp-url-browse-alist-only)))) + (list (bmkp-read-bookmark-for-type "URL " alist t nil 'bmkp-url-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-w3m-jump (bookmark-name &optional use-region-p) ; `C-x j w' + "Jump to a W3M bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-w3m-alist-only))) + (list (bmkp-read-bookmark-for-type "W3M " alist nil nil 'bmkp-w3m-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-w3m-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j w' + "`bmkp-w3m-jump', but in another window." + (interactive + (let ((alist (bmkp-w3m-alist-only))) + (list (bmkp-read-bookmark-for-type "W3M " alist t nil 'bmkp-w3m-history) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-all-tags-jump (tags bookmark) ; `C-x j t *' + "Jump to a BOOKMARK that has all of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag. +If you specify no tags, then every bookmark that has some tags is a +candidate." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-all-tags-alist-only tgs))) + (unless alist (error "No bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t *' + "`bmkp-all-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-all-tags-alist-only tgs))) + (unless alist (error "No bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-all-tags-regexp-jump (regexp bookmark) ; `C-x j t % *' + "Jump to a BOOKMARK that has each tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for all tags: ")) + (alist (bmkp-all-tags-regexp-alist-only rgx))) + (unless alist (error "No bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t % *' + "`bmkp-all-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for all tags: ")) + (alist (bmkp-all-tags-regexp-alist-only rgx))) + (unless alist (error "No bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-some-tags-jump (tags bookmark) ; `C-x j t +' + "Jump to a BOOKMARK that has at least one of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t +' + "`bmkp-some-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-some-tags-regexp-jump (regexp bookmark) ; `C-x j t % +' + "Jump to a BOOKMARK that has a tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-some-tags-regexp-alist-only rgx))) + (unless alist (error "No bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t % +' + "`bmkp-some-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-some-tags-regexp-alist-only rgx))) + (unless alist (error "No bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "Bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-all-tags-jump (tags bookmark) ; `C-x j t f *' + "Jump to a file or directory BOOKMARK that has all of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag. +If you specify no tags, then every bookmark that has some tags is a +candidate." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-all-tags-alist-only tgs))) + (unless alist (error "No file or dir bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t f *' + "`bmkp-file-all-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-all-tags-alist-only tgs))) + (unless alist (error "No file or dir bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-all-tags-regexp-jump (regexp bookmark) ; `C-x j t f % *' + "Jump to a file or directory BOOKMARK that has each tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-all-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t f % *' + "`bmkp-file-all-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-all-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-some-tags-jump (tags bookmark) ; `C-x j t f +' + "Jump to a file or directory BOOKMARK that has at least one of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No file or dir bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t f +' + "`bmkp-file-some-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No file or dir bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-some-tags-regexp-jump (regexp bookmark) ; `C-x j t f % +' + "Jump to a file or directory BOOKMARK that has a tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-some-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t f % +' + "`bmkp-file-some-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-some-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-all-tags-jump (tags bookmark) ; `C-x j t C-f *' + "Jump to a file BOOKMARK in this dir that has all of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag. +If you specify no tags, then every bookmark that has some tags is a +candidate." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-this-dir-all-tags-alist-only tgs))) + (unless alist (error "No file or dir bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-all-tags-jump-other-window (tags bookmark) ; `C-x 4 j t C-f *' + "`bmkp-file-this-dir-all-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-this-dir-all-tags-alist-only tgs))) + (unless alist (error "No file or dir bookmarks have all of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-all-tags-regexp-jump (regexp bookmark) ; `C-x j t C-f % *' + "Jump to a file BOOKMARK in this dir that has each tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-this-dir-all-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-all-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t C-f % *' + "`bmkp-file-this-dir-all-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-this-dir-all-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-some-tags-jump (tags bookmark) ; `C-x j t C-f +' + "Jump to a file BOOKMARK in this dir that has at least one of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter the bookmark name and each tag." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-this-dir-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No file or dir bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-some-tags-jump-other-window (tags bookmark) ; `C-x 4 j t C-f +' + "`bmkp-file-this-dir-some-tags-jump', but in another window." + (interactive + (let* ((tgs (bmkp-read-tags-completing)) + (alist (bmkp-file-this-dir-some-tags-alist-only tgs))) + (unless tgs (error "You did not specify any tags")) + (unless alist (error "No file or dir bookmarks have any of the specified tags")) + (list tgs (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-some-tags-regexp-jump (regexp bookmark) ; `C-x j t C-f % +' + "Jump to a file BOOKMARK in this dir that has a tag matching REGEXP. +You are prompted for the REGEXP. +Then you are prompted for the BOOKMARK (with completion)." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-this-dir-some-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump bookmark)) + +;;;###autoload +(defun bmkp-file-this-dir-some-tags-regexp-jump-other-window (regexp bookmark) ; `C-x 4 j t C-f % +' + "`bmkp-file-this-dir-some-tags-regexp-jump', but in another window." + (interactive + (let* ((rgx (read-string "Regexp for tags: ")) + (alist (bmkp-file-this-dir-some-tags-regexp-alist-only rgx))) + (unless alist (error "No file or dir bookmarks have tags that match `%s'" rgx)) + (list rgx (bookmark-completing-read "File bookmark" (bmkp-default-bookmark-name alist) alist)))) + (bookmark-jump-other-window bookmark)) + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defalias 'bmkp-autofile-jump 'bmkp-find-file) + (defun bmkp-find-file () ; `C-x j a' + "Visit a file or directory that has an autofile bookmark." + (interactive) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) (bmkp-get-autofile-bookmark ff)))) + (find-file (read-file-name "Find file: " nil nil t nil pred))))) + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defalias 'bmkp-autofile-jump-other-window 'bmkp-find-file) + (defun bmkp-find-file-other-window () ; `C-x 4 j a' + "`bmkp-find-file', but in another window." + (interactive) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) (bmkp-get-autofile-bookmark ff)))) + (find-file-other-window (read-file-name "Find file: " nil nil t nil pred))))) + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-all-tags (tags) ; `C-x j t a *' + "Visit a file or directory that has all of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion. +If you specify no tags, then every file that has some tags is a +candidate." + (interactive (list (bmkp-read-tags-completing))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) + tags)))))) + (find-file (read-file-name "Find file: " nil nil t nil pred))))) + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-all-tags-other-window (tags) ; `C-x 4 j t a *' + "`bmkp-find-file-all-tags', but in another window." + (interactive (list (bmkp-read-tags-completing))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) + tags)))))) + (find-file-other-window (read-file-name "Find file: " nil nil t nil pred))))) + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-all-tags-regexp (regexp) ; `C-x j t a % *' + "Visit a file or directory that has each tag matching REGEXP. +You are prompted for the REGEXP." + (interactive (list (read-string "Regexp for tags: "))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-every + #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + btgs)))))) + (find-file (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-all-tags-regexp-other-window (regexp) ; `C-x 4 j t a % *' + "`bmkp-find-file-all-tags-regexp', but in another window." + (interactive (list (read-string "Regexp for tags: "))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-every + #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + btgs)))))) + (find-file-other-window (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-some-tags (tags) ; `C-x j t a +' + "Visit a file or directory that has at least one of the TAGS. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion." + (interactive (list (bmkp-read-tags-completing))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags)))))) + (find-file (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-some-tags-other-window (tags) ; `C-x 4 j t a +' + "`bmkp-find-file-some-tags', but in another window." + (interactive (list (bmkp-read-tags-completing))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags)))))) + (find-file-other-window (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-some-tags-regexp (regexp) ; `C-x j t a % +' + "Visit a file or directory that has a tag matching REGEXP. +You are prompted for the REGEXP." + (interactive (list (read-string "Regexp for tags: "))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-some + #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + btgs)))))) + (find-file (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (defun bmkp-find-file-some-tags-regexp-other-window (regexp) ; `C-x 4 j t a % +' + "`bmkp-find-file-some-tags-regexp', but in another window." + (interactive (list (read-string "Regexp for tags: "))) + (let ((use-file-dialog nil) + (pred #'(lambda (ff) + (let* ((bmk (bmkp-get-autofile-bookmark ff)) + (btgs (and bmk (bmkp-get-tags bmk)))) + (and btgs (bmkp-some + #'(lambda (tag) (string-match regexp (bmkp-tag-name tag))) + btgs)))))) + (find-file-other-window (read-file-name "Find file: " nil nil t nil pred))))) + +;;;###autoload +(defun bmkp-jump-in-navlist (bookmark-name &optional use-region-p) ; `C-x j N' + "Jump to a bookmark, choosing from those in the navigation list." + (interactive + (progn (unless bmkp-nav-alist + (bookmark-maybe-load-default-file) + (setq bmkp-nav-alist bookmark-alist) + (unless bmkp-nav-alist (error "No bookmarks")) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist)) + (message "Bookmark navigation list is now the global bookmark list") (sit-for 2)) + (let ((bookmark-alist bmkp-nav-alist)) + (list (bookmark-completing-read "Jump to bookmark (in another window)" + (bmkp-default-bookmark-name)) + current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-jump-in-navlist-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j N' + "Same as `bmkp-jump-in-navlist', but use another window." + (interactive + (progn (unless bmkp-nav-alist + (bookmark-maybe-load-default-file) + (setq bmkp-nav-alist bookmark-alist) + (unless bmkp-nav-alist (error "No bookmarks")) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist)) + (message "Bookmark navigation list is now the global bookmark list") (sit-for 2)) + (let ((bookmark-alist bmkp-nav-alist)) + (list (bookmark-completing-read "Jump to bookmark (in another window)" + (bmkp-default-bookmark-name)) + current-prefix-arg)))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-cycle (increment &optional other-window startoverp) + "Cycle through bookmarks in the navlist by INCREMENT (default: 1). +Positive INCREMENT cycles forward. Negative INCREMENT cycles backward. +Interactively, the prefix arg determines INCREMENT: + Plain `C-u': 1 + otherwise: the numeric prefix arg value + +Plain `C-u' also means start over at first bookmark. + +You can set the navigation list using commands + `bmkp-choose-navlist-from-bookmark-list' and + `bmkp-choose-navlist-of-type'. + +You can cycle among bookmarks in the current buffer using + `bmkp-cycle-this-buffer' and + `bmkp-cycle-this-buffer-other-window.' + +In Lisp code: + Non-nil OTHER-WINDOW means jump to the bookmark in another window. + Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the + first bookmark in the navlist." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr))) + (unless bmkp-nav-alist + (bookmark-maybe-load-default-file) + (setq bmkp-nav-alist bookmark-alist) + (unless bmkp-nav-alist (error "No bookmarks")) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist)) + (message "Bookmark navigation list is now the global bookmark list") (sit-for 2)) + (unless (and bmkp-current-nav-bookmark (not startoverp) + (bookmark-get-bookmark bmkp-current-nav-bookmark 'NOERROR)) + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist))) + (if (bmkp-cycle-1 increment other-window startoverp) + (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark) + (bmkp-function-bookmark-p bmkp-current-nav-bookmark)) + (message "Position: %9d, Bookmark: `%s'" + (point) (bookmark-name-from-full-record bmkp-current-nav-bookmark))) + (message "Invalid bookmark: `%s'" (bookmark-name-from-full-record bmkp-current-nav-bookmark)))) + +;;;###autoload +(defun bmkp-cycle-other-window (increment &optional startoverp) + "Same as `bmkp-cycle' but uses another window." + (interactive "p") + (bmkp-cycle increment 'OTHER-WINDOW startoverp)) + +;;;###autoload +(defun bmkp-cycle-this-buffer (increment &optional other-window startoverp) + "Cycle through bookmarks in this buffer by INCREMENT (default: 1). +Positive INCREMENT cycles forward. Negative INCREMENT cycles backward. +Interactively, the prefix arg determines INCREMENT: + Plain `C-u': 1 + otherwise: the numeric prefix arg value + +Plain `C-u' also means start over at first bookmark. + +You can cycle among bookmarks beyond the current buffer using +`bmkp-cycle' and `bmkp-cycle-other-window.' + +You can set your preferred sort order for this-buffer bookmarks by +customizing option `bmkp-this-buffer-cycle-sort-comparer'. + +To change the sort order without customizing, you can use \ +`\\[bmkp-this-buffer-bmenu-list]' to +show the `*Bookmark List*' with only this buffer's bookmarks, sort +them there, and use `\\[bmkp-choose-navlist-from-bookmark-list]', choosing \ +`CURRENT *Bookmark List*' as +the navigation list. + +Then you can cycle the bookmarks using `bmkp-cycle' +\(`\\[bmkp-next-bookmark-repeat]' etc.), instead of `bmkp-cycle-this-buffer'. + +In Lisp code: + Non-nil OTHER-WINDOW means jump to the bookmark in another window. + Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the + first bookmark in the navlist." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr))) + (bookmark-maybe-load-default-file) + (let ((bmkp-sort-comparer bmkp-this-buffer-cycle-sort-comparer)) + (setq bmkp-nav-alist (bmkp-sort-omit (bmkp-this-buffer-alist-only)))) + (unless bmkp-nav-alist (error "No bookmarks in this buffer")) + (unless (and bmkp-current-nav-bookmark (not startoverp) + (bookmark-get-bookmark bmkp-current-nav-bookmark 'NOERROR) + (bmkp-this-buffer-p bmkp-current-nav-bookmark)) ; Exclude desktops etc. + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist))) + (if (bmkp-cycle-1 increment other-window startoverp) + (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark) + (bmkp-function-bookmark-p bmkp-current-nav-bookmark)) + (message "Position: %9d, Bookmark: `%s'" + (point) (bookmark-name-from-full-record bmkp-current-nav-bookmark))) + (message "Invalid bookmark: `%s'" (bookmark-name-from-full-record bmkp-current-nav-bookmark)))) + +;;;###autoload +(defun bmkp-cycle-this-buffer-other-window (increment &optional startoverp) + "Same as `bmkp-cycle-this-buffer' but use other window." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-this-buffer increment 'OTHER-WINDOW startoverp)) + +(defun bmkp-cycle-1 (increment &optional other-window startoverp) + "Helper for `bmkp-cycle' and `bmkp-cycle-this-buffer'. +Do nothing if `bmkp-current-nav-bookmark' is an invalid bookmark. +Return `bmkp-current-nav-bookmark', or nil if invalid. + +NOTE: If `pop-up-frames' is non-nil, then cycling inhibits automatic +showing of annotations (`bookmark-automatically-show-annotations'). +This is to prevent change of frame focus, so cycling can continue +properly. + +See `bmkp-cycle' for descriptions of the arguments." + (let ((bookmark-alist bmkp-nav-alist) + (bookmark (bookmark-get-bookmark bmkp-current-nav-bookmark 'no-error)) + (bmkp-use-region (eq 'cycling-too bmkp-use-region))) + (unless bookmark-alist (error "No bookmarks for cycling")) + (when bookmark ; Skip bookmarks with bad names. + (setq bmkp-current-nav-bookmark + (if startoverp + (car bookmark-alist) + (let ((index (bmkp-list-position bookmark bookmark-alist #'eq))) + (if index + (nth (mod (+ increment index) (length bookmark-alist)) bookmark-alist) + (message "bmkp-cycle-1: Bookmark `%s' is not in navlist" + (bookmark-name-from-full-record bmkp-current-nav-bookmark)) + (car bookmark-alist))))) + (let ((bookmark-automatically-show-annotations ; Prevent possible frame focus change. + (and bookmark-automatically-show-annotations (not pop-up-frames)))) + (if other-window + (bookmark-jump-other-window (bookmark-name-from-full-record bmkp-current-nav-bookmark)) + (save-selected-window (bookmark-name-from-full-record + (bookmark-jump bmkp-current-nav-bookmark)))))) + (and bookmark bmkp-current-nav-bookmark))) ; Return nil if not a valid bookmark. + +(defun bmkp-list-position (item items &optional test) + "Find the first occurrence of ITEM in list ITEMS. +Return the index of the matching item, or nil if not found. +Items are compared using binary predicate TEST, or `equal' if TEST is +nil." + (unless test (setq test 'equal)) + (let ((pos 0)) + (catch 'bmkp-list-position + (dolist (itm items) + (when (funcall test item itm) (throw 'bmkp-list-position pos)) + (setq pos (1+ pos))) + nil))) + +;;;###autoload +(defun bmkp-next-bookmark (n &optional startoverp) ; You can bind this to a repeatable key + "Jump to the Nth next bookmark in the bookmark navigation list. +N defaults to 1, meaning the next bookmark. +Plain `C-u' means start over at first bookmark. +See also `bmkp-cycle'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle n nil startoverp)) + +;;;###autoload +(defun bmkp-previous-bookmark (n &optional startoverp) ; You can bind this to a repeatable key + "Jump to the Nth previous bookmark in the bookmark navigation list. +See `bmkp-next-bookmark'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle (- n) nil startoverp)) + +;;;###autoload +(defun bmkp-next-bookmark-repeat (arg) ; `C-x p right', `C-x p f', `C-x p C-f' + "Jump to the Nth-next bookmark in the bookmark navigation list. +This is a repeatable version of `bmkp-next-bookmark'. +N defaults to 1, meaning the next bookmark. +Plain `C-u' means start over at the first bookmark (and no repeat)." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-next-bookmark)) + +;;;###autoload +(defun bmkp-previous-bookmark-repeat (arg) ; `C-x p left', `C-x p b', `C-x p C-b' + "Jump to the Nth-previous bookmark in the bookmark navigation list. +See `bmkp-next-bookmark-repeat'." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-previous-bookmark)) + +;;;###autoload +(defun bmkp-next-bookmark-this-buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `S-f2' + "Jump to the Nth-next bookmark in the current buffer. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one. +See also `bmkp-cycle-this-buffer'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-this-buffer n nil startoverp)) + +;;;###autoload +(defun bmkp-previous-bookmark-this-buffer (n &optional startoverp) ; Bind to repeatable key, e.g. `f2' + "Jump to the Nth-previous bookmark in the current buffer. +See `bmkp-next-bookmark-this-buffer'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-this-buffer (- n) nil startoverp)) + +;;;###autoload +(defun bmkp-next-bookmark-this-buffer-repeat (arg) ; `C-x p down', `C-x p n', `C-x p C-n' + "Jump to the Nth next bookmark in the current buffer. +This is a repeatable version of `bmkp-next-bookmark-this-buffer'. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one (and no repeat)." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-next-bookmark-this-buffer)) + +;;;###autoload +(defun bmkp-previous-bookmark-this-buffer-repeat (arg) ; `C-x p up', `C-x p p', `C-x p C-p' + "Jump to the Nth previous bookmark in the current buffer. +See `bmkp-next-bookmark-this-buffer-repeat'." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-previous-bookmark-this-buffer)) + +;;;###autoload +(defun bmkp-next-bookmark-w32 (n &optional startoverp) ; You can bind this to a repeatable key + "Windows `Open' the Nth next bookmark in the bookmark navigation list. +MS Windows only. Invokes the program associated with the file type. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one. +See also `bmkp-cycle'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (let ((bmkp-use-w32-browser-p t)) (bmkp-cycle n nil startoverp))) + +;;;###autoload +(defun bmkp-previous-bookmark-w32 (n &optional startoverp) ; You can bind this to a repeatable key + "Windows `Open' the Nth previous bookmark in the bookmark navlist. +See `bmkp-next-bookmark-w32'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (let ((bmkp-use-w32-browser-p t)) (bmkp-cycle (- n) nil startoverp))) + +;;;###autoload +(defun bmkp-next-bookmark-w32-repeat (arg) ; `C-x p next' + "Windows `Open' the Nth next bookmark in the bookmark navigation list. +This is a repeatable version of `bmkp-next-bookmark'. +N defaults to 1, meaning the next bookmark. +Plain `C-u' means start over at the first one (and no repeat)." + (interactive "P") + (require 'repeat) + (let ((bmkp-use-w32-browser-p t)) (bmkp-repeat-command 'bmkp-next-bookmark))) + +;;;###autoload +(defun bmkp-previous-bookmark-w32-repeat (arg) ; `C-x p prior' + "Windows `Open' the Nth previous bookmark in the bookmark navlist. +See `bmkp-next-bookmark-w32-repeat'." + (interactive "P") + (require 'repeat) + (let ((bmkp-use-w32-browser-p t)) (bmkp-repeat-command 'bmkp-previous-bookmark))) + +;; In spite of their names, `bmkp-cycle-specific-(buffers|files)*' just cycle bookmarks in the +;; current buffer or file. There is no way to choose multiple buffers or files. +;; +;; `bmkp-cycle-autonamed', `bmkp-cycle-autonamed-other-window', +;; `bmkp-cycle-bookmark-list', `bmkp-cycle-bookmark-list-other-window', +;; `bmkp-cycle-desktop', +;; `bmkp-cycle-dired', `bmkp-cycle-dired-other-window', +;; `bmkp-cycle-file', `bmkp-cycle-file-other-window', +;; `bmkp-cycle-gnus', `bmkp-cycle-gnus-other-window', +;; `bmkp-cycle-info', `bmkp-cycle-info-other-window', +;; `bmkp-cycle-lighted', `bmkp-cycle-lighted-other-window', +;; `bmkp-cycle-local-file', `bmkp-cycle-local-file-other-window', +;; `bmkp-cycle-man', `bmkp-cycle-man-other-window', +;; `bmkp-cycle-non-file', `bmkp-cycle-non-file-other-window', +;; `bmkp-cycle-remote-file', `bmkp-cycle-remote-file-other-window', +;; `bmkp-cycle-specific-buffers', `bmkp-cycle-specific-buffers-other-window', +;; `bmkp-cycle-specific-files', `bmkp-cycle-specific-files-other-window', +;; `bmkp-cycle-variable-list', +;; `bmkp-cycle-url', `bmkp-cycle-url-other-window', +;; `bmkp-next-autonamed-bookmark', `bmkp-next-autonamed-bookmark-repeat', +;; `bmkp-next-bookmark-list-bookmark', `bmkp-next-bookmark-list-bookmark-repeat', +;; `bmkp-next-desktop-bookmark', `bmkp-next-desktop-bookmark-repeat', +;; `bmkp-next-dired-bookmark', `bmkp-next-dired-bookmark-repeat', +;; `bmkp-next-file-bookmark', `bmkp-next-file-bookmark-repeat', +;; `bmkp-next-gnus-bookmark', `bmkp-next-gnus-bookmark-repeat', +;; `bmkp-next-info-bookmark', `bmkp-next-info-bookmark-repeat', +;; `bmkp-next-lighted-bookmark', `bmkp-next-lighted-bookmark-repeat', +;; `bmkp-next-local-file-bookmark', `bmkp-next-local-file-bookmark-repeat', +;; `bmkp-next-man-bookmark', `bmkp-next-man-bookmark-repeat', +;; `bmkp-next-non-file-bookmark', `bmkp-next-non-file-bookmark-repeat', +;; `bmkp-next-remote-file-bookmark', `bmkp-next-remote-file-bookmark-repeat', +;; `bmkp-next-specific-buffers-bookmark', `bmkp-next-specific-buffers-bookmark-repeat', +;; `bmkp-next-specific-files-bookmark', `bmkp-next-specific-files-bookmark-repeat', +;; `bmkp-next-variable-list-bookmark', `bmkp-next-variable-list-bookmark-repeat', +;; `bmkp-next-url-bookmark', `bmkp-next-url-bookmark-repeat'. +;; +(bmkp-define-cycle-command "autonamed") +(bmkp-define-cycle-command "autonamed" 'OTHER-WINDOW) +(bmkp-define-cycle-command "bookmark-list") ; No other-window version needed +(bmkp-define-cycle-command "desktop") ; No other-window version needed +(bmkp-define-cycle-command "dired") +(bmkp-define-cycle-command "dired" 'OTHER-WINDOW) +(bmkp-define-cycle-command "file") +(bmkp-define-cycle-command "file" 'OTHER-WINDOW) +(bmkp-define-cycle-command "gnus") +(bmkp-define-cycle-command "gnus" 'OTHER-WINDOW) +(bmkp-define-cycle-command "info") +(bmkp-define-cycle-command "info" 'OTHER-WINDOW) +(when (featurep 'bookmark+-lit) + (bmkp-define-cycle-command "lighted") + (bmkp-define-cycle-command "lighted" 'OTHER-WINDOW)) +(bmkp-define-cycle-command "local-file") +(bmkp-define-cycle-command "local-file" 'OTHER-WINDOW) +(bmkp-define-cycle-command "man") +(bmkp-define-cycle-command "man" 'OTHER-WINDOW) +(bmkp-define-cycle-command "non-file") +(bmkp-define-cycle-command "non-file" 'OTHER-WINDOW) +(bmkp-define-cycle-command "remote-file") +(bmkp-define-cycle-command "remote-file" 'OTHER-WINDOW) +(bmkp-define-cycle-command "specific-buffers") +(bmkp-define-cycle-command "specific-buffers" 'OTHER-WINDOW) +(bmkp-define-cycle-command "specific-files") +(bmkp-define-cycle-command "specific-files" 'OTHER-WINDOW) +(bmkp-define-cycle-command "variable-list") ; No other-window version needed +(bmkp-define-cycle-command "url") +(bmkp-define-cycle-command "url" 'OTHER-WINDOW) + +(bmkp-define-next+prev-cycle-commands "autonamed") +(bmkp-define-next+prev-cycle-commands "bookmark-list") +(bmkp-define-next+prev-cycle-commands "desktop") +(bmkp-define-next+prev-cycle-commands "dired") +(bmkp-define-next+prev-cycle-commands "file") +(bmkp-define-next+prev-cycle-commands "gnus") +(bmkp-define-next+prev-cycle-commands "info") +(bmkp-define-next+prev-cycle-commands "lighted") +(bmkp-define-next+prev-cycle-commands "local-file") +(bmkp-define-next+prev-cycle-commands "man") +(bmkp-define-next+prev-cycle-commands "non-file") +(bmkp-define-next+prev-cycle-commands "remote-file") +(bmkp-define-next+prev-cycle-commands "specific-buffers") +(bmkp-define-next+prev-cycle-commands "specific-files") +(bmkp-define-next+prev-cycle-commands "variable-list") +(bmkp-define-next+prev-cycle-commands "url") + +;;;###autoload +(defun bmkp-toggle-autonamed-bookmark-set/delete (position &optional allp) ; Bound to `C-x p RET' + "If there is an autonamed bookmark at point, delete it, else create one. +The bookmark created has no region. Its name is formatted according +to option `bmkp-autoname-bookmark-function'. + +With a prefix arg, delete *ALL* autonamed bookmarks for this buffer. + +Non-interactively, act at POSITION, not point." + (interactive "d\nP") + (if allp + (bmkp-delete-all-autonamed-for-this-buffer) + (let ((bmk-name (funcall bmkp-autoname-bookmark-function position))) + (if (not (bookmark-get-bookmark bmk-name 'noerror)) + (let ((mark-active nil)) ; Do not set a region bookmark. + (bookmark-set bmk-name) + (message "Set bookmark `%s'" bmk-name)) + (bookmark-delete bmk-name) + (message "Deleted bookmark `%s'" bmk-name))))) + +;;;###autoload +(defun bmkp-set-autonamed-bookmark (position &optional msgp) + "Set an autonamed bookmark at point. +The bookmark created has no region. Its name is formatted according +to option `bmkp-autoname-bookmark-function'. +Non-interactively, act at POSITION, not point." + (interactive (list (point) t)) + (let ((bmk-name (funcall bmkp-autoname-bookmark-function position)) + (mark-active nil)) ; Do not set a region bookmark. + (bookmark-set bmk-name) + (when msgp (message "Set bookmark `%s'" bmk-name)))) + +;;;###autoload +(defun bmkp-set-autonamed-bookmark-at-line (number) + "Set an autonamed bookmark at the beginning of the given line NUMBER." + (interactive "nSet bookmark on line: ") + (save-excursion + (goto-char (point-min)) + (unless (zerop (forward-line (1- number))) + (error "No such line: %d (%d lines total)" number (1+ (count-lines (point-min) (point-max))))) + (bmkp-set-autonamed-bookmark (point)))) + +(when (> emacs-major-version 21) + (defun bmkp-occur-create-autonamed-bookmarks ( &optional msgp) + "Create an autonamed bookmark for each `occur' hit. +You can use this only in `Occur' mode (commands such as `occur' and +`multi-occur')." + (interactive (list 'MSG)) + (unless (eq major-mode 'occur-mode) (error "You must be in `occur-mode'")) + (let ((count 0)) + (save-excursion + (goto-char (point-min)) + (while (condition-case nil (progn (occur-next) t) (error nil)) + (let* ((pos (get-text-property (point) 'occur-target)) + (buf (and pos (marker-buffer pos)))) + (when buf + (with-current-buffer buf + (goto-char pos) + (bmkp-set-autonamed-bookmark (point))) + (setq count (1+ count)))))) + (when msgp (message "Created %d autonamed bookmarks" count))))) + +;;;###autoload +(defun bmkp-set-autonamed-regexp-buffer (regexp &optional msgp) + "Set autonamed bookmarks at matches for REGEXP in the buffer." + (interactive (list (read-string "Regexp: " nil 'regexp-history) + t)) + (bmkp-set-autonamed-regexp-region regexp (point-min) (point-max) 'MSG)) + +;;;###autoload +(defun bmkp-set-autonamed-regexp-region (regexp beg end &optional msgp) + "Set autonamed bookmarks at matches for REGEXP in the region." + (interactive (list (read-string "Regexp: " nil 'regexp-history) + (region-beginning) (region-end) + t)) + (let ((count 0)) + (save-excursion + (goto-char beg) + (while (re-search-forward regexp end t) + (bmkp-set-autonamed-bookmark (point)) + (setq count (1+ count)) + (forward-line 1))) + (when msgp (message "Set %d autonamed bookmarks" count)))) + +(defun bmkp-autoname-bookmark (position) + "Return a bookmark name using POSITION and the current buffer name. +The name is composed as follows: + POSITION followed by a space and then the buffer name. + The position value is prefixed with zeros to comprise 9 characters. + For example, for POSITION value 31416 and current buffer `my-buffer', + the name returned would be `000031416 my-buffer'" + (format "%09d %s" (abs position) (buffer-name))) + +;;;###autoload +(defun bmkp-delete-all-autonamed-for-this-buffer () + "Delete all autonamed bookmarks for the current buffer. +To be deleted, a bookmark name must be an autonamed bookmark whose +buffer part names the current buffer." + (interactive) + (let ((bmks-to-delete (mapcar #'bookmark-name-from-full-record + (bmkp-autonamed-this-buffer-alist-only)))) + (if (null bmks-to-delete) + (message "No autonamed bookmarks for buffer `%s'" (buffer-name)) + (when (y-or-n-p (format "Delete ALL autonamed bookmarks for buffer `%s'? " (buffer-name))) + (dolist (bmk bmks-to-delete) (bookmark-delete bmk)) + (message "Deleted all bookmarks for buffer `%s'" (buffer-name)))))) + +;; You can use this in `kill-buffer-hook'. +(defun bmkp-delete-autonamed-this-buffer-no-confirm () + "Delete all autonamed bookmarks for this buffer, without confirmation." + (when (and bookmarks-already-loaded bookmark-alist) + (let ((bmks-to-delete (mapcar #'bookmark-name-from-full-record + (bmkp-autonamed-this-buffer-alist-only)))) + (dolist (bmk bmks-to-delete) (bookmark-delete bmk))))) + +;; You can use this in `kill-emacs-hook'. +(defun bmkp-delete-autonamed-no-confirm () + "Delete all autonamed bookmarks for all buffers, without confirmation." + (when (and bookmarks-already-loaded bookmark-alist) + (dolist (buf (buffer-list)) + (with-current-buffer buf (bmkp-delete-autonamed-this-buffer-no-confirm))))) + +;;;###autoload +(defun bmkp-delete-bookmarks (position allp &optional alist) ; Bound to `C-x p delete' + "Delete some bookmarks at point or all bookmarks in the buffer. +With no prefix argument, delete some bookmarks at point. +If there is more than one, require confirmation for each. + +With a prefix argument, delete *ALL* bookmarks in the current buffer. + +Non-interactively, delete at POSITION. +Optional arg ALIST is the alist of bookmarks. It defaults to +`bookmark-alist'." + (interactive "d\nP") + (let ((bmks-to-delete (and allp (mapcar #'bookmark-name-from-full-record + (bmkp-this-buffer-alist-only)))) + (bmks-deleted ()) + bmk-pos) + (cond ((and bmks-to-delete (y-or-n-p (format "Delete ALL bookmarks in buffer `%s'? " + (buffer-name)))) + (dolist (bmk bmks-to-delete) (bookmark-delete bmk)) + (message "Deleted all bookmarks in buffer `%s'" (buffer-name))) + (bmks-to-delete (message "Canceled - nothing deleted")) + (allp (message "No bookmarks in buffer `%s' to delete" (buffer-name))) + (t + (dolist (bmk (or alist bookmark-alist)) + (when (eq (setq bmk-pos (bookmark-get-position bmk)) position) + (add-to-list 'bmks-to-delete (bookmark-name-from-full-record bmk)))) + (if bmks-to-delete + (cond ((cadr bmks-to-delete) + (dolist (bmk bmks-to-delete) + (when (y-or-n-p (format "Delete bookmark `%s'? " bmk)) + (bookmark-delete bmk) + (add-to-list 'bmks-deleted bmk))) + (message (if bmks-deleted + (format "Deleted bookmarks: %s" bmks-deleted) + "No bookmarks deleted"))) + (t + (bookmark-delete (car bmks-to-delete)) + (message "Deleted bookmark `%s'" (car bmks-to-delete)))) + (when (interactive-p) (message "No bookmarks at point to delete"))))))) + + +;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-1) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-1.el ends here diff --git a/auto-install/bookmark+-bmu.el b/auto-install/bookmark+-bmu.el new file mode 100644 index 0000000..5ccdb40 --- /dev/null +++ b/auto-install/bookmark+-bmu.el @@ -0,0 +1,4377 @@ + +;;; bookmark+-bmu.el --- Bookmark+ code for the `*Bookmark List*' (bmenu). +;; +;; Filename: bookmark+-bmu.el +;; Description: Bookmark+ code for the `*Bookmark List*' (bmenu). +;; Author: Drew Adams, Thierry Volpiatto +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved. +;; Created: Mon Jul 12 09:05:21 2010 (-0700) +;; Last-Updated: Fri Jul 1 14:51:29 2011 (-0700) +;; By: dradams +;; Update #: 771 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-bmu.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `bookmark+-mac', `pp'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library contains code for buffer `*Bookmark List*' (mode +;; `bookmark-bmenu-mode'). +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (this file) +;; `bookmark+-1.el' - other required code (non-bmenu) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) + +;;(@> "Index") +;; +;; Index +;; ----- +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Things Defined Here") +;; (@> "Faces (Customizable)") +;; (@> "User Options (Customizable)") +;; (@> "Internal Variables") +;; (@> "Compatibility Code for Older Emacs Versions") +;; (@> "Menu List Replacements (`bookmark-bmenu-*')") +;; (@> "Bookmark+ Functions (`bmkp-*')") +;; (@> "Menu-List (`*-bmenu-*') Filter Commands") +;; (@> "Menu-List (`*-bmenu-*') Commands Involving Marks") +;; (@> "Omitted Bookmarks") +;; (@> "Search-and-Replace Locations of Marked Bookmarks") +;; (@> "Tags") +;; (@> "General Menu-List (`-*bmenu-*') Commands and Functions") +;; (@> "Sorting - Commands") +;; (@> "Other Bookmark+ Functions (`bmkp-*')") +;; (@> "Keymaps") + +;;(@* "Things Defined Here") +;; +;; Things Defined Here +;; ------------------- +;; +;; Commands defined here: +;; +;; `bmkp-bmenu-add-tags', `bmkp-bmenu-add-tags-to-marked', +;; `bmkp-bmenu-change-sort-order', +;; `bmkp-bmenu-change-sort-order-repeat', `bmkp-bmenu-copy-tags', +;; `bmkp-bmenu-define-command', +;; `bmkp-bmenu-define-full-snapshot-command', +;; `bmkp-bmenu-define-jump-marked-command', +;; `bmkp-bmenu-delete-marked', `bmkp-bmenu-describe-marked', +;; `bmkp-bmenu-describe-this+move-down', +;; `bmkp-bmenu-describe-this+move-up', +;; `bmkp-bmenu-describe-this-bookmark',`bmkp-bmenu-dired-marked', +;; `bmkp-bmenu-edit-bookmark', `bmkp-edit-tags-send', +;; `bmkp-bmenu-filter-annotation-incrementally', +;; `bmkp-bmenu-filter-bookmark-name-incrementally', +;; `bmkp-bmenu-filter-file-name-incrementally', +;; `bmkp-bmenu-filter-tags-incrementally', +;; `bmkp-bmenu-isearch-marked-bookmarks' (Emacs 23+), +;; `bmkp-bmenu-isearch-marked-bookmarks-regexp' (Emacs 23+), +;; `bmkp-bmenu-make-sequence-from-marked', `bmkp-bmenu-mark-all', +;; `bmkp-bmenu-mark-autofile-bookmarks', +;; `bmkp-bmenu-mark-bookmark-file-bookmarks', +;; `bmkp-bmenu-mark-bookmarks-satisfying', +;; `bmkp-bmenu-mark-bookmarks-tagged-all', +;; `bmkp-bmenu-mark-bookmarks-tagged-none', +;; `bmkp-bmenu-mark-bookmarks-tagged-not-all', +;; `bmkp-bmenu-mark-bookmarks-tagged-regexp', +;; `bmkp-bmenu-mark-bookmarks-tagged-some', +;; `bmkp-bmenu-mark-desktop-bookmarks', +;; `bmkp-bmenu-mark-dired-bookmarks', +;; `bmkp-bmenu-mark-file-bookmarks', +;; `bmkp-bmenu-mark-gnus-bookmarks', +;; `bmkp-bmenu-mark-info-bookmarks', +;; `bmkp-bmenu-mark-lighted-bookmarks', +;; `bmkp-bmenu-mark-man-bookmarks', +;; `bmkp-bmenu-mark-non-file-bookmarks', +;; `bmkp-bmenu-mark-region-bookmarks', +;; `bmkp-bmenu-mark-specific-buffer-bookmarks', +;; `bmkp-bmenu-mark-specific-file-bookmarks', +;; `bmkp-bmenu-mark-url-bookmarks', +;; `bmkp-bmenu-mark-w3m-bookmarks', `bmkp-bmenu-mouse-3-menu', +;; `bmkp-bmenu-mode-status-help', `bmkp-bmenu-omit', +;; `bmkp-bmenu-omit-marked', `bmkp-bmenu-omit/unomit-marked', +;; `bmkp-bmenu-paste-add-tags', +;; `bmkp-bmenu-paste-add-tags-to-marked', +;; `bmkp-bmenu-paste-replace-tags', +;; `bmkp-bmenu-paste-replace-tags-for-marked', +;; `bmkp-bmenu-query-replace-marked-bookmarks-regexp', +;; `bmkp-bmenu-quit', `bmkp-bmenu-refresh-menu-list', +;; `bmkp-bmenu-regexp-mark', `bookmark-bmenu-relocate' (Emacs 20, +;; 21), `bmkp-bmenu-remove-all-tags', `bmkp-bmenu-remove-tags', +;; `bmkp-bmenu-remove-tags-from-marked', +;; `bmkp-bmenu-search-marked-bookmarks-regexp', +;; `bmkp-bmenu-set-tag-value', +;; `bmkp-bmenu-set-tag-value-for-marked', `bmkp-bmenu-show-all', +;; `bmkp-bmenu-show-only-autofiles', +;; `bmkp-bmenu-show-only-autonamed.', +;; `bmkp-bmenu-show-only-bookmark-files', +;; `bmkp-bmenu-show-only-desktops', `bmkp-bmenu-show-only-dired', +;; `bmkp-bmenu-show-only-files', `bmkp-bmenu-show-only-gnus', +;; `bmkp-bmenu-show-only-info-nodes', +;; `bmkp-bmenu-show-only-man-pages', +;; `bmkp-bmenu-show-only-non-files', +;; `bmkp-bmenu-show-only-omitted', `bmkp-bmenu-show-only-regions', +;; `bmkp-bmenu-show-only-specific-buffer', +;; `bmkp-bmenu-show-only-specific-file', +;; `bmkp-bmenu-show-only-tagged', `bmkp-bmenu-show-only-urls', +;; `bmkp-bmenu-show-only-variable-lists', +;; `bmkp-bmenu-show-only-w3m-urls', +;; `bmkp-bmenu-sort-by-bookmark-name', +;; `bmkp-bmenu-sort-by-bookmark-visit-frequency', +;; `bmkp-bmenu-sort-by-creation-time', +;; `bmkp-bmenu-sort-by-file-name', +;; `bmkp-bmenu-sort-by-Gnus-thread', +;; `bmkp-bmenu-sort-by-Info-location', +;; `bmkp-bmenu-sort-by-last-bookmark-access', +;; `bmkp-bmenu-sort-by-last-buffer-or-file-access', +;; `bmkp-bmenu-sort-by-last-local-file-access', +;; `bmkp-bmenu-sort-by-last-local-file-update', +;; `bmkp-bmenu-sort-by-local-file-size', +;; `bmkp-bmenu-sort-by-local-file-type', `bmkp-bmenu-sort-by-url', +;; `bmkp-bmenu-sort-marked-before-unmarked', +;; `bmkp-bmenu-toggle-marks', `bmkp-bmenu-toggle-show-only-marked', +;; `bmkp-bmenu-toggle-show-only-unmarked', `bmkp-bmenu-unmark-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-none', +;; `bmkp-bmenu-unmark-bookmarks-tagged-not-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-regexp', +;; `bmkp-bmenu-unmark-bookmarks-tagged-some', +;; `bmkp-bmenu-unomit-marked', `bmkp-bmenu-w32-open', +;; `bmkp-bmenu-w32-open-select', `bmkp-bmenu-w32-open-with-mouse', +;; `bmkp-define-tags-sort-command'. +;; +;; Faces defined here: +;; +;; `bmkp->-mark', `bmkp-a-mark', `bmkp-bad-bookmark', +;; `bmkp-bookmark-file', `bmkp-bookmark-list', `bmkp-buffer', +;; `bmkp-D-mark', `bmkp-desktop', `bmkp-function', `bmkp-gnus', +;; `bmkp-heading', `bmkp-info', `bmkp-local-directory', +;; `bmkp-local-file-with-region', `bmkp-local-file-without-region', +;; `bmkp-man', `bmkp-non-file', `bmkp-remote-file', +;; `bmkp-sequence', `bmkp-su-or-sudo', `bmkp-t-mark', `bmkp-url', +;; `bmkp-variable-list'. +;; +;; User options defined here: +;; +;; `bmkp-bmenu-commands-file', `bmkp-bmenu-omitted-bookmarks', +;; `bmkp-bmenu-state-file', `bmkp-propertize-bookmark-names-flag', +;; `bmkp-sort-orders-alist', `bmkp-sort-orders-for-cycling-alist'. +;; +;; Non-interactive functions defined here: +;; +;; `bmkp-bmenu-barf-if-not-in-menu-list', +;; `bmkp-bmenu-cancel-incremental-filtering', +;; `bmkp-bmenu-filter-alist-by-annotation-regexp', +;; `bmkp-bmenu-filter-alist-by-bookmark-name-regexp', +;; `bmkp-bmenu-filter-alist-by-file-name-regexp', +;; `bmkp-bmenu-filter-alist-by-tags-regexp', +;; `bmkp-bmenu-get-marked-files', `bmkp-bmenu-goto-bookmark-named', +;; `bmkp-bmenu-list-1', +;; `bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none', +;; `bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all', +;; `bmkp-bmenu-propertize-item', `bmkp-bmenu-read-filter-input', +;; `bmkp-maybe-unpropertize-bookmark-names', +;; `bmkp-reverse-multi-sort-order', `bmkp-reverse-sort-order'. +;; +;; Internal variables defined here: +;; +;; `bmkp-bmenu-before-hide-marked-alist', +;; `bmkp-bmenu-before-hide-unmarked-alist', +;; `bmkp-bmenu-define-command-menu', `bmkp-bmenu-filter-function', +;; `bmkp-bmenu-filter-pattern', `bmkp-bmenu-filter-prompt', +;; `bmkp-bmenu-filter-timer', `bmkp-bmenu-first-time-p', +;; `bmkp-bmenu-header-lines', `bmkp-bmenu-highlight-menu', +;; `bmkp-bmenu-line-overlay', `bmkp-bmenu-mark-menu', +;; `bmkp-bmenu-marked-bookmarks', `bmkp-bmenu-marks-width', +;; `bmkp-bmenu-menubar-menu', `bmkp-bmenu-omit-menu', +;; `bmkp-bmenu-show-menu', `bmkp-bmenu-sort-menu', +;; `bmkp-bmenu-tags-menu', `bmkp-bmenu-title', +;; `bmkp-bookmark-file-history', `bmkp-bookmark-list-history', +;; `bmkp-current-bookmark-file', `bmkp-current-nav-bookmark', +;; `bmkp-desktop-history', `bmkp-dired-history', +;; `bmkp-file-history', `bmkp-gnus-history', `bmkp-highlight-menu', +;; `bmkp-info-history', `bmkp-isearch-bookmarks' (Emacs 23+), +;; `bmkp-jump-display-function', `bmkp-jump-map', `bmkp-jump-menu', +;; `bmkp-jump-other-window-map', `bmkp-last-bmenu-bookmark'. +;; +;; +;; ***** NOTE: The following commands defined in `bookmark.el' +;; have been REDEFINED HERE: +;; +;; `bookmark-bmenu-execute-deletions', `bookmark-bmenu-list', +;; `bookmark-bmenu-mark', `bookmark-bmenu-1-window', +;; `bookmark-bmenu-2-window', `bookmark-bmenu-other-window', +;; `bookmark-bmenu-other-window-with-mouse', +;; `bookmark-bmenu-this-window', `bookmark-bmenu-rename', +;; `bookmark-bmenu-show-annotation', +;; `bookmark-bmenu-switch-other-window', `bookmark-bmenu-unmark'. +;; +;; +;; ***** NOTE: The following non-interactive functions defined in +;; `bookmark.el' have been REDEFINED HERE: +;; +;; `bookmark-bmenu-bookmark', `bookmark-bmenu-check-position', +;; `bookmark-bmenu-delete', `bookmark-bmenu-ensure-position' (Emacs +;; 23.2+), `bookmark-bmenu-hide-filenames', `bookmark-bmenu-mode', +;; `bookmark-bmenu-show-filenames', +;; `bookmark-bmenu-surreptitiously-rebuild-list', +;; `bookmark-bmenu-switch-other-window' (Emacs 20-22). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(eval-when-compile (require 'cl)) ;; case + +(require 'bookmark) +;; bookmark-alist, bookmark-bmenu-file-column, +;; bookmark-bmenu-hidden-bookmarks, bookmark-bmenu-mode-map, +;; bookmark-bmenu-select, bookmark-bmenu-toggle-filenames, +;; bookmark-get-annotation, bookmark-get-bookmark, +;; bookmark-get-filename, bookmark-get-handler, bookmark-kill-line, +;; bookmark-maybe-load-default-file, bookmark-name-from-full-record, +;; bookmark-name-from-record, bookmark-prop-get, +;; bookmark-show-annotation, bookmark-store + +;;; Fix incompatibility introduced by gratuitous Emacs name change. +(cond ((and (fboundp 'bookmark-name-from-record) (not (fboundp 'bookmark-name-from-full-record))) + (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record)) + ((and (fboundp 'bookmark-name-from-full-record) (not (fboundp 'bookmark-name-from-record))) + (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record))) + +(require 'bookmark+-mac) ;; bmkp-define-sort-command + +;; (eval-when-compile (require 'bookmark+-1)) +;; bmkp-add-tags, bmkp-alpha-p, bmkp-bookmark-creation-cp, +;; bmkp-bookmark-description, bmkp-bookmark-file-bookmark-p, +;; bmkp-bookmark-last-access-cp, bmkp-bookmark-list-bookmark-p, +;; bmkp-buffer-last-access-cp, bmkp-completing-read-buffer-name, +;; bmkp-completing-read-file-name, bmkp-current-bookmark-file, +;; bmkp-current-sort-order, bmkp-describe-bookmark, +;; bmkp-describe-bookmark-internals, bmkp-desktop-bookmark-p, +;; bmkp-edit-bookmark, bmkp-face-prop, bmkp-file-alpha-cp, +;; bmkp-file-remote-p, bmkp-function-bookmark-p, bmkp-get-buffer-name, +;; bmkp-get-tags, bmkp-gnus-bookmark-p, bmkp-gnus-cp, bmkp-handler-cp, +;; bmkp-incremental-filter-delay, bmkp-info-bookmark-p, bmkp-info-cp, +;; bmkp-isearch-bookmarks, bmkp-isearch-bookmarks-regexp, bmkp-jump-1, +;; bmkp-last-bookmark-file, bmkp-last-specific-buffer, +;; bmkp-last-specific-file, bmkp-latest-bookmark-alist, +;; bmkp-local-file-bookmark-p, bmkp-local-file-type-cp, +;; bmkp-local-file-accessed-more-recently-cp, +;; bmkp-local-file-updated-more-recently-cp, bmkp-man-bookmark-p, +;; bmkp-marked-bookmark-p, bmkp-marked-bookmarks-only, bmkp-marked-cp, +;; bmkp-msg-about-sort-order, bmkp-non-file-filename, +;; bmkp-read-tag-completing, bmkp-read-tags-completing, +;; bmkp-refresh-menu-list, bmkp-region-bookmark-p, +;; bmkp-remove-all-tags, bmkp-remove-if, bmkp-remove-tags, +;; bmkp-repeat-command, bmkp-reverse-multi-sort-p, +;; bmkp-reverse-sort-p, bmkp-root-or-sudo-logged-p, bmkp-same-file-p, +;; bmkp-save-menu-list-state, bmkp-sequence-bookmark-p, +;; bmkp-set-tag-value, bmkp-set-tag-value-for-bookmarks, +;; bmkp-set-union, bmkp-some, bmkp-some-marked-p, +;; bmkp-some-unmarked-p, bmkp-sort-omit, bmkp-sort-comparer, bmkp-sorted-alist, +;; bmkp-sort-orders-for-cycling-alist, bmkp-su-or-sudo-regexp, +;; bmkp-tag-name, bmkp-tags-list, bmkp-url-bookmark-p, bmkp-url-cp, +;; bmkp-unmarked-bookmarks-only, bmkp-variable-list-bookmark-p, +;; bmkp-visited-more-cp + +;; (eval-when-compile (require 'bookmark+-lit nil t)) +;; bmkp-get-lighting + +;;;;;;;;;;;;;;;;;;;;;;; + +;; Quiet the byte-compiler +(defvar dired-re-mark) ; Defined in `dired.el'. +(defvar tramp-file-name-regexp) ; Defined in `tramp.el'. + +(defvar bmkp-sort-orders-alist) ; Defined in `bookmark+-1.el'. +(defvar bmkp-sort-orders-for-cycling-alist) ; Defined in `bookmark+-1.el'. + +;;(@* "Faces (Customizable)") +;;; Faces (Customizable) --------------------------------------------- + +(defgroup bookmark-plus nil + "Bookmark enhancements." + :prefix "bmkp-" :group 'bookmark + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +Bookmark+ bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Download" "http://www.emacswiki.org/bookmark+.el") + :link '(url-link :tag "Description" "http://www.emacswiki.org/BookmarkPlus") + :link '(emacs-commentary-link :tag "Commentary" "bookmark+")) + +(defface bmkp->-mark '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + ;; (:foreground "Magenta2" :box (:line-width 1 :style pressed-button)))) + "*Face used for a `>' mark in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-a-mark '((((background dark)) (:background "SaddleBrown")) + (t (:background "SkyBlue"))) + "*Face used for an annotation mark (`a') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bad-bookmark '((t (:foreground "Red" :background "Chartreuse1"))) + "*Face used for a bookmark that seems to be bad: e.g., nonexistent file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bookmark-file + '((((background dark)) + (:foreground "#00005A5AFFFF" :background "#FFFF9B9BFFFF")) ; ~ blue, ~ pink + (t (:foreground "Orange" :background "DarkGreen"))) + "*Face used for a bookmark-file bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bookmark-list + '((((background dark)) (:foreground "#7474FFFFFFFF" :background "DimGray")) ; ~ cyan + (t (:foreground "DarkRed" :background "LightGray"))) + "*Face used for a bookmark-list bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-buffer + '((((background dark)) (:foreground "#FFFF9B9BFFFF")) ; ~ pink + (t (:foreground "DarkGreen"))) + "*Face used for a bookmarked existing buffer not associated with a file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-D-mark '((t (:foreground "Yellow" :background "Red"))) + "*Face used for a deletion mark (`D') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-desktop + '((((background dark)) (:foreground "Orange" :background "DarkSlateBlue")) + (t (:foreground "DarkBlue" :background "PaleGoldenrod"))) + "*Face used for a bookmarked desktop." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-function + '((((background dark)) (:foreground "#0000EBEB6C6C")) ; ~ green + (t (:foreground "DeepPink1"))) + "*Face used for a function bookmark: a bookmark that invokes a function." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-gnus + '((((background dark)) (:foreground "Gold")) + (t (:foreground "DarkBlue"))) + "*Face used for a gnus bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-info + '((((background dark)) (:foreground "#7474FFFFFFFF")) ; ~ light cyan + (t (:foreground "DarkRed"))) + "*Face used for a bookmarked Info node." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-directory + '((((background dark)) + (:foreground "Pink" :background "DarkBlue")) + (t (:foreground "DarkBlue" :background "HoneyDew2"))) + "*Face used for a bookmarked local directory." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-file-without-region + '((((background dark)) (:foreground "White")) + (t (:foreground "Black"))) + "*Face used for a bookmarked local file (without a region)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-file-with-region + '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + "*Face used for a region bookmark in a local file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-man + '((((background dark)) (:foreground "Orchid")) + (t (:foreground "Orange4"))) + "*Face used for a `man' page bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-non-file + '((t (:foreground "gray60"))) + "*Face used for a bookmark not associated with an existing file or buffer." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-remote-file + '((((background dark)) (:foreground "#6B6BFFFF2C2C")) ; ~ green + (t (:foreground "DarkViolet"))) + "*Face used for a bookmarked tramp remote file (/ssh:)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-sequence + '((((background dark)) (:foreground "DeepSkyBlue")) + (t (:foreground "DarkOrange2"))) + "*Face used for a sequence bookmark: one composed of other bookmarks." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-su-or-sudo '((t (:foreground "Red"))) + "*Face used for a bookmarked tramp file (/su: or /sudo:)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-t-mark '((t (:foreground "Red"))) + "*Face used for a tags mark (`t') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-url + '((((background dark)) (:foreground "#7474FFFF7474")) ; ~ green + (t (:foreground "DarkMagenta"))) + "*Face used for a bookmarked URL." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-variable-list + '((((background dark)) (:foreground "#FFFF74747474")) ; ~ salmon + (t (:foreground "DarkCyan"))) + "*Face used for a bookmarked list of variables." + :group 'bookmark-plus :group 'faces) + +;; $$$$$$ Not used now - using `bmkp-url' instead. +;; (defface bmkp-w3m +;; '((((background dark)) (:foreground "yellow")) +;; (t (:foreground "DarkMagenta"))) +;; "*Face used for a bookmarked w3m url." +;; :group 'bookmark-plus :group 'faces) + +;; Instead of vanilla `bookmark-menu-heading' (defined in Emacs 22+), to use a better default. +(defface bmkp-heading '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + "*Face used to highlight the headings in various Bookmark+ buffers." + :group 'bookmark-plus :version "22.1" :group 'faces) + +;;(@* "User Options (Customizable)") +;;; User Options (Customizable) -------------------------------------- + +;;;###autoload +(defcustom bmkp-bmenu-omitted-bookmarks () + "*List of names of omitted bookmarks. +They are generally not available for display in the bookmark list. +You can, however, use \\\ +`\\[bmkp-bmenu-show-only-omitted]' to see them. +You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]' + to make those that are marked available again for the bookmark list." + :type '(repeat (string :tag "Bookmark name")) :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-bmenu-commands-file (convert-standard-filename "~/.emacs-bmk-bmenu-commands.el") + "*File for saving user-defined bookmark-list commands. +This must be an absolute file name (possibly containing `~') or nil +\(it is not expanded). + +You can use `\\[bmkp-list-defuns-in-commands-file]' to list the +commands defined in the file and how many times each is defined. + +NOTE: Each time you define a command using \\\ +`\\[bmkp-bmenu-define-command]', `\\[bmkp-bmenu-define-full-snapshot-command]', \ +`\\[bmkp-bmenu-define-jump-marked-command], or `\\[bmkp-define-tags-sort-command]', +it is saved in the file. The new definition is simply appended to the +file - old definitions of the same command are not overwritten. So +you might want to clean up the file occasionally, to remove any old, +unused definitions. This is especially advisable if you used \ +`\\[bmkp-bmenu-define-full-snapshot-command]', +because such command definitions can be very large." + :type '(file :tag "File for saving menu-list state") :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-bmenu-state-file (convert-standard-filename "~/.emacs-bmk-bmenu-state.el") + "*File for saving `*Bookmark List*' state when you quit bookmark list. +This must be an absolute file name (possibly containing `~') or nil +\(it is not expanded). + +The state is also saved when you quit Emacs, even if you don't quit +the bookmark list first (using \\`\\[bmkp-bmenu-quit]'). + +Set this to nil if you do not want to restore the bookmark list as it +was the last time you used it." + :type '(choice + (const :tag "Do not save and restore menu-list state" nil) + (file :tag "File for saving menu-list state")) + :group 'bookmark-plus) + +;; This is a general option. It is in this file because it is used mainly by the bmenu code. +(when (> emacs-major-version 20) + (defcustom bmkp-sort-orders-alist () + "*Alist of all available sort functions. +This is a pseudo option - you probably do NOT want to customize this. +Instead: + + * To add a new sort function to this list, use macro + `bmkp-define-sort-command'. It defines a new sort function + and automatically adds it to this list. + + * To have fewer sort orders available for cycling by \\\ +`\\[bmkp-bmenu-change-sort-order-repeat]'..., + customize option `bmkp-sort-orders-for-cycling-alist'. + +Each alist element has the form (SORT-ORDER . COMPARER): + + SORT-ORDER is a short string or symbol describing the sort order. + Examples: \"by last access time\", \"by bookmark name\". + + COMPARER compares two bookmarks. It must be acceptable as a value of + `bmkp-sort-comparer'." + :type '(alist + :key-type (choice :tag "Sort order" string symbol) + :value-type (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate"))))) + :group 'bookmark-plus)) + +(unless (> emacs-major-version 20) ; Emacs 20: custom type `alist' doesn't exist. + (defcustom bmkp-sort-orders-alist () + "*Alist of all available sort functions. +This is a pseudo option - you probably do NOT want to customize this. +Instead: + + * To add a new sort function to this list, use macro + `bmkp-define-sort-command'. It defines a new sort function + and automatically adds it to this list. + + * To have fewer sort orders available for cycling by \\\ +`\\[bmkp-bmenu-change-sort-order-repeat]'..., + customize option `bmkp-sort-orders-for-cycling-alist'. + +Each alist element has the form (SORT-ORDER . COMPARER): + + SORT-ORDER is a short string or symbol describing the sort order. + Examples: \"by last access time\", \"by bookmark name\". + + COMPARER compares two bookmarks. It must be acceptable as a value of + `bmkp-sort-comparer'." + :type '(repeat + (cons + (choice :tag "Sort order" string symbol) + (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))))) + :group 'bookmark-plus)) + +(defcustom bmkp-propertize-bookmark-names-flag (> emacs-major-version 20) + "*Non-nil means to propertize bookmark names to hold full bookmark data. +This means that you can effectively have more than one bookmark with +the same name. + +Emacs 20 users: If you need to use your bookmarks with Emacs 20 then +set this to nil. In particular, if your bookmark file was written +with this as non-nil, then it contains propertized strings which are +unreadable by Emacs 20. To convert the file to be usable with Emacs +20 you must, in Emacs 21 or later, set this to nil and then do `M-x +bookmark-save'." + :type 'boolean :group 'bookmark-plus) + +;;(@* "Internal Variables") +;;; Internal Variables ----------------------------------------------- + +(defconst bmkp-bmenu-header-lines 2 + "Number of lines used for the `*Bookmark List*' header.") + +(defconst bmkp-bmenu-marks-width 4 + "Number of columns (chars) used for the `*Bookmark List*' marks columns.") + +(defvar bmkp-bmenu-marked-bookmarks () + "Names of the marked bookmarks. +This includes possibly omitted bookmarks, that is, bookmarks listed in +`bmkp-bmenu-omitted-bookmarks'.") + +(defvar bmkp-bmenu-before-hide-unmarked-alist () + "Copy of `bookmark-alist' made before hiding unmarked bookmarks.") + +(defvar bmkp-bmenu-before-hide-marked-alist () + "Copy of `bookmark-alist' made before hiding marked bookmarks.") + +(defvar bmkp-bmenu-filter-function nil "Latest filtering function for `*Bookmark List*' display.") + +(defvar bmkp-bmenu-title "" "Latest title for `*Bookmark List*' display.") + +(defvar bmkp-bmenu-filter-pattern "" "Regexp for incremental filtering.") + +(defvar bmkp-bmenu-filter-prompt "Pattern: " "Prompt for `bmkp-bmenu-filter-incrementally'.") + +(defvar bmkp-bmenu-filter-timer nil "Timer used for incremental filtering.") + +(defvar bmkp-bmenu-first-time-p t + "Non-nil means bookmark list has not yet been shown after quitting it. +Quitting the list or the Emacs session resets this to t. +The first time the list is displayed, it is set to nil.") + +;; This is a general variable. It is in this file because it is used only in the bmenu code. +(defvar bmkp-last-bmenu-bookmark nil "The name of the last bookmark current in the bookmark list.") + +;;(@* "Compatibility Code for Older Emacs Versions") +;;; Compatibility Code for Older Emacs Versions ---------------------- + +(when (< emacs-major-version 22) + (defun bookmark-bmenu-relocate () + "Change the file path of the bookmark on the current line, + prompting with completion for the new path." + (interactive) + (let ((bmk (bookmark-bmenu-bookmark)) + (thispoint (point))) + (bookmark-relocate bmk) + (goto-char thispoint)))) + +;;(@* "Menu List Replacements (`bookmark-bmenu-*')") +;;; Menu List Replacements (`bookmark-bmenu-*') ---------------------- + + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Return t. Value doesn't mean anything (didn't anyway), but must be non-nil for vanilla Emacs. +;; 2. Do not count lines. Just make sure we're on a bookmark line. +;; +(defalias 'bookmark-bmenu-check-position 'bookmark-bmenu-ensure-position) +(defun bookmark-bmenu-ensure-position () + "Move to the beginning of the nearest bookmark line." + (beginning-of-line) + (unless (bookmark-bmenu-bookmark) + (if (and (bolp) (eobp)) + (beginning-of-line 0) + (goto-char (point-min)) + (forward-line bmkp-bmenu-header-lines))) + t) ; Older vanilla bookmark code depends on non-nil value. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Add bookmark to `bmkp-bmenu-marked-bookmarks'. +;; 2. Don't call `bookmark-bmenu-ensure-position' again at end. +;; 3. Raise error if not in `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-mark () ; Bound to `m' in bookmark list + "Mark the bookmark on this line, using mark `>'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (beginning-of-line) + (let ((inhibit-read-only t)) + (push (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks) + (delete-char 1) (insert ?>) (put-text-property (1- (point)) (point) 'face 'bmkp->-mark) + (forward-line 1))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Remove bookmark from `bmkp-bmenu-marked-bookmarks'. +;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'. +;; 3. Don't call `bookmark-bmenu-ensure-position' again at end. +;; 4. Raise error if not in `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-unmark (&optional backup) ; Bound to `u' in bookmark list + "Unmark the bookmark on this line, then move down to the next. +Optional BACKUP means move up instead." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (beginning-of-line) + (let ((inhibit-read-only t)) + (delete-char 1) (insert " ") + (setq bmkp-bmenu-marked-bookmarks (bmkp-delete-bookmark-name-from-list + (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks))) + (forward-line (if backup -1 1))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Do not use `bookmark-bmenu-ensure-position' as a test - it always returns non-nil anyway. +;; And don't call it at again the end. +;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'. +;; 3. Use face `bmkp-bad-bookmark' on the `D' flag. +;; 4. Raise error if not in buffer `*Bookmark List*'. +;; 5. Remove bookmark from `bmkp-bmenu-marked-bookmarks'. +;; +;;;###autoload +(defun bookmark-bmenu-delete () ; Bound to `d', `k' in bookmark list + "Flag this bookmark for deletion, using mark `D'. +Use `\\\\[bookmark-bmenu-execute-deletions]' to carry out \ +the deletions." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (beginning-of-line) + (bookmark-bmenu-ensure-position) + (let ((inhibit-read-only t)) + (delete-char 1) (insert ?D) (put-text-property (1- (point)) (point) 'face 'bmkp-D-mark)) + (setq bmkp-bmenu-marked-bookmarks (bmkp-delete-bookmark-name-from-list + (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks)) + (forward-line 1)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Rebuild the menu list using the last filtered alist in use, `bmkp-latest-bookmark-alist'. +;; 2. Update the menu-list title. +;; +(defun bookmark-bmenu-surreptitiously-rebuild-list () + "Rebuild the bookmark list, if it exists." + (when (get-buffer "*Bookmark List*") + (save-excursion (save-window-excursion (let ((bookmark-alist bmkp-latest-bookmark-alist)) + (bookmark-bmenu-list 'filteredp)))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added args TITLE, FILTEREDP, DONT-TOGGLE-FILENAMES-P. +;; 2. Handles also region bookmarks and buffer (non-file) bookmarks. +;; 3. Uses `pop-to-buffer', not `switch-to-buffer', so we respect `special-display-*' +;; (but keep `one-window-p' if that's the case). +;; 4. If option `bmkp-bmenu-state-file' is non-nil, then the first time since the last quit +;; (or the last Emacs session) restores the last menu-list state. +;; 5. If option `bmkp-bmenu-commands-file' is non-nil, then read that file, which contains +;; user-defined `*Bookmark List*' commands. +;; +;;;###autoload +(defalias 'list-bookmarks 'bookmark-bmenu-list) +;;;###autoload +(defun bookmark-bmenu-list (&optional filteredp) ; Bound to `C-x r l' + "Display a list of existing bookmarks, in buffer `*Bookmark List*'. +The leftmost column of a bookmark entry shows `D' if the bookmark is + flagged for deletion, or `>' if it is marked normally. +The second column shows `t' if the bookmark has tags. +The third column shows `a' if the bookmark has an annotation. + +The following faces are used for the list entries. +Use `customize-face' if you want to change the appearance. + + `bmkp-bad-bookmark', `bmkp-bookmark-list', `bmkp-buffer', + `bmkp-desktop', `bmkp-function', `bmkp-gnus', `bmkp-info', + `bmkp-local-directory', `bmkp-local-file-without-region', + `bmkp-local-file-with-region', `bmkp-man', `bmkp-non-file', + `bmkp-remote-file', `bmkp-sequence', `bmkp-su-or-sudo', `bmkp-url', + `bmkp-variable-list'. + +If option `bmkp-bmenu-state-file' is non-nil then the state of the +displayed bookmark-list is saved when you quit it, and it is restored +when you next use this command. That saved state is not restored, +however, if it represents a different file from the current bookmark +file. + +If you call this interactively when buffer `*Bookmark List*' exists, +that buffer is refreshed to show all current bookmarks, and any +markings are removed. If you instead want to show the buffer in its +latest state then just do that: use `C-x b' or similar. If you want +to refresh the displayed buffer, to show the latest state, reflecting +any additions, deletions, renamings, and so on, use \\\ +`\\[bmkp-bmenu-refresh-menu-list]'. + +In Lisp code, non-nil optional argument FILTEREDP means the bookmark +list has been filtered, which means: + * Use `bmkp-bmenu-title' not the default menu-list title. + * Do not reset `bmkp-latest-bookmark-alist' to `bookmark-alist'." + (interactive) + (bookmark-maybe-load-default-file) + (when (and bmkp-bmenu-first-time-p bmkp-bmenu-commands-file + (file-readable-p bmkp-bmenu-commands-file)) + (with-current-buffer (let ((enable-local-variables ()) + (emacs-lisp-mode-hook nil)) + (find-file-noselect bmkp-bmenu-commands-file)) + (goto-char (point-min)) + (while (not (eobp)) (condition-case nil (eval (read (current-buffer))) (error nil))) + (kill-buffer (current-buffer)))) + (cond ((and bmkp-bmenu-first-time-p bmkp-bmenu-state-file ; Restore from state file. + (file-readable-p bmkp-bmenu-state-file)) + (let ((state ())) + (with-current-buffer (let ((enable-local-variables nil) + (emacs-lisp-mode-hook nil)) + (find-file-noselect bmkp-bmenu-state-file)) + (goto-char (point-min)) + (setq state (condition-case nil (read (current-buffer)) (error nil))) + (kill-buffer (current-buffer))) + (let ((last-bookmark-file-from-state (cdr (assq 'last-bookmark-file state)))) + (when (and (consp state) + ;; If bookmark file has changed, then do not use state saved from other file. + (or (not last-bookmark-file-from-state) + (bmkp-same-file-p last-bookmark-file-from-state + bmkp-current-bookmark-file))) + (setq bmkp-sort-comparer (cdr (assq 'last-sort-comparer state)) + bmkp-reverse-sort-p (cdr (assq 'last-reverse-sort-p state)) + bmkp-reverse-multi-sort-p (cdr (assq 'last-reverse-multi-sort-p state)) + bmkp-latest-bookmark-alist (cdr (assq 'last-latest-bookmark-alist state)) + bmkp-bmenu-omitted-bookmarks (cdr (assq 'last-bmenu-omitted-bookmarks state)) + bmkp-bmenu-marked-bookmarks (cdr (assq 'last-bmenu-marked-bookmarks state)) + bmkp-bmenu-filter-function (cdr (assq 'last-bmenu-filter-function state)) + bmkp-bmenu-filter-pattern + (or (cdr (assq 'last-bmenu-filter-pattern state)) "") + bmkp-bmenu-title (cdr (assq 'last-bmenu-title state)) + bmkp-last-bmenu-bookmark (cdr (assq 'last-bmenu-bookmark state)) + bmkp-last-specific-buffer (cdr (assq 'last-specific-buffer state)) + bmkp-last-specific-file (cdr (assq 'last-specific-file state)) + bookmark-bmenu-toggle-filenames (cdr (assq 'last-bmenu-toggle-filenames state)) + bmkp-last-bookmark-file bmkp-current-bookmark-file + bmkp-current-bookmark-file last-bookmark-file-from-state + bmkp-bmenu-before-hide-marked-alist + (cdr (assq 'last-bmenu-before-hide-marked-alist state)) + bmkp-bmenu-before-hide-unmarked-alist + (cdr (assq 'last-bmenu-before-hide-unmarked-alist state)))))) + (setq bmkp-bmenu-first-time-p nil) + (let ((bookmark-alist (or bmkp-latest-bookmark-alist bookmark-alist))) + (bmkp-bmenu-list-1 'filteredp nil (interactive-p))) + (when bmkp-last-bmenu-bookmark + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark)))) + (t + (setq bmkp-bmenu-first-time-p nil) + (bmkp-bmenu-list-1 filteredp + (or (interactive-p) (not (get-buffer "*Bookmark List*"))) + (interactive-p))))) + +(defun bmkp-bmenu-list-1 (filteredp reset-marked-p interactivep) + "Helper for `bookmark-bmenu-list'. +See `bookmark-bmenu-list' for the description of FILTEREDP. +Non-nil RESET-MARKED-P resets `bmkp-bmenu-marked-bookmarks'. +Non-nil INTERACTIVEP means `bookmark-bmenu-list' was called + interactively, so pop to the bookmark list and communicate the sort + order." + (when reset-marked-p (setq bmkp-bmenu-marked-bookmarks ())) + (unless filteredp (setq bmkp-latest-bookmark-alist bookmark-alist)) + (if interactivep + (let ((one-win-p (one-window-p))) + (pop-to-buffer (get-buffer-create "*Bookmark List*")) + (when one-win-p (delete-other-windows))) + (set-buffer (get-buffer-create "*Bookmark List*"))) + (let* ((inhibit-read-only t) + (title (if (and filteredp bmkp-bmenu-title (not (equal "" bmkp-bmenu-title))) + bmkp-bmenu-title + "All Bookmarks"))) + (erase-buffer) + (insert (format "%s\n%s\n" title (make-string (length title) ?-))) + (add-text-properties (point-min) (point) (bmkp-face-prop 'bmkp-heading)) + (let ((max-width 0) + name markedp tags annotation start) + (setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist + (and (not (eq bmkp-bmenu-filter-function + 'bmkp-omitted-alist-only)) + bmkp-bmenu-omitted-bookmarks))) + (dolist (bmk bmkp-sorted-alist) + (setq max-width (max max-width (length (bookmark-name-from-full-record bmk))))) + (setq max-width (+ max-width bmkp-bmenu-marks-width)) + (dolist (bmk bmkp-sorted-alist) + (setq name (bookmark-name-from-full-record bmk) + markedp (bmkp-marked-bookmark-p bmk) + tags (bmkp-get-tags bmk) + annotation (bookmark-get-annotation bmk) + start (+ bmkp-bmenu-marks-width (point))) + (if (not markedp) + (insert " ") + (insert ">") (put-text-property (1- (point)) (point) 'face 'bmkp->-mark)) + (if (null tags) + (insert " ") + (insert "t") (put-text-property (1- (point)) (point) 'face 'bmkp-t-mark)) + (if (not (and annotation (not (string-equal annotation "")))) + (insert " ") + (insert "a") (put-text-property (1- (point)) (point) 'face 'bmkp-a-mark)) + (insert " ") + (when (and (featurep 'bookmark+-lit) (bmkp-get-lighting bmk)) ; Highlight highlight overrides. + (put-text-property (1- (point)) (point) 'face 'bmkp-light-mark)) + (insert name) + (move-to-column max-width t) + (bmkp-bmenu-propertize-item bmk start (point)) + (insert "\n"))) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (bookmark-bmenu-mode) + (when bookmark-bmenu-toggle-filenames (bookmark-bmenu-toggle-filenames t)) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + (when (and interactivep bmkp-sort-comparer) + (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Redefined. +;; 1. Get name of the current bookmark from text property `bmkp-bookmark-name'. +;; 2. Added optional arg FULL, to return full bookmark record. +;; 3. Use `condition-case' in case we're at eob (so cannot advance). +;; +(defun bookmark-bmenu-bookmark (&optional full) + "Return the name of the bookmark on this line. +Normally, the string returned is propertized with property +`bmkp-full-record', which records the full bookmark record. +Non-nil optional FULL means return the bookmark record, not the name." + (condition-case nil + (let ((name (save-excursion (forward-line 0) (forward-char (1+ bmkp-bmenu-marks-width)) + (get-text-property (point) 'bmkp-bookmark-name)))) + (if full + (get-text-property 0 'bmkp-full-record name) + name)) + (error nil))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Only the doc string is different. +;; +(defun bookmark-bmenu-mode () + "Major mode for editing a list of bookmarks. +Each line represents an Emacs bookmark.\\ + +More bookmarking help below. Keys without prefix `C-x' are available +only in buffer `*Bookmark List*'. Others are available everywhere. + + +Help (Describe) +--------------- + +\\[bmkp-bmenu-describe-this-bookmark]\t- Show information about this bookmark (`C-u': \ +internal form) +\\[bmkp-bmenu-describe-this+move-down]\t- Show the info, then move to next bookmark +\\[bmkp-bmenu-describe-this+move-up]\t- Show the info, then move to previous bookmark +\\[bmkp-bmenu-describe-marked]\t- Show info about the marked bookmarks (`C-u': internal form) +\\[bookmark-bmenu-locate]\t- Show the location of this bookmark in the minibuffer +\\[bookmark-bmenu-show-annotation]\t- Show this bookmark's annotation +\\[bookmark-bmenu-show-all-annotations]\t- Show the annotations of all annotated bookmarks +\\[bookmark-bmenu-toggle-filenames]\t- Toggle showing filenames next to bookmarks + +\\[bmkp-list-defuns-in-commands-file] +\t- List the commands defined in `bmkp-bmenu-commands-file' + + +General +------- + +\\[bmkp-bmenu-refresh-menu-list]\t- Refresh (revert) to up-to-date bookmark list +\\[bmkp-bmenu-quit]\t- Quit (`*Bookmark List*') +\\[bmkp-bmenu-dired-marked]\t- Open Dired for the marked files and directories + +\\[bookmark-bmenu-load]\t- Add bookmarks from a different bookmark file (extra load) +\\[bmkp-switch-bookmark-file]\t- Switch to a different bookmark file (overwrite load) +C-u \\[bmkp-switch-bookmark-file]\t- Switch back to the last bookmark file (overwrite load) +\\[bmkp-set-bookmark-file-bookmark]\t- Create a bookmark to a bookmark file \ +\(`\\[bmkp-bookmark-file-jump]' to load) + +\\[bmkp-toggle-saving-bookmark-file]\t- Toggle autosaving the bookmark file +\\[bmkp-toggle-saving-menu-list-state]\t- Toggle autosaving bookmark-list display state (this list) +\\[bookmark-bmenu-save]\t- Save bookmarks (`C-u': prompt for the bookmark file to use) +\\[bmkp-save-menu-list-state]\t- Save bookmark-list display state + +\\[bmkp-choose-navlist-of-type]\t- Set the navlist to the bookmarks of a type you choose +\\[bmkp-choose-navlist-from-bookmark-list]\t- Set the navlist to the bookmarks of a \ +bookmark-list bookmark +\\[bmkp-navlist-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in navlist +\\[bmkp-this-buffer-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in current buffer +\\[bmkp-delete-bookmarks]\t- Delete some bookmarks at point or all in buffer + +\\[bmkp-toggle-bookmark-set-refreshes] +\t- Toggle whether `bookmark-set' refreshes the bookmark list +\\[bmkp-make-function-bookmark] +\t- Create a function bookmark +\\[bmkp-bmenu-make-sequence-from-marked] +\t- Create a sequence bookmark from the marked bookmarks + + +Create/Set +---------- + +\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Set/delete an autonamed bookmark here +\\[bmkp-autofile-set]\t- Set and autoname a bookmark for a file +\\[bmkp-file-target-set]\t- Set a bookmark for a file +\\[bmkp-url-target-set]\t- Set a bookmark for a URL +\\[bookmark-set]\t- Set a bookmark here +\\[bmkp-set-desktop-bookmark]\t- Set a bookmark for the current desktop +\\[bmkp-set-bookmark-file-bookmark]\t- Set a bookmark for a bookmark file + + +Jump to (Visit) +--------------- + +\\[bookmark-bmenu-select]\t- This bookmark and also visit bookmarks marked `>' +\\[bookmark-bmenu-this-window]\t- This bookmark in the same window +\\[bookmark-bmenu-other-window]\t- This bookmark in another window +\\[bookmark-bmenu-switch-other-window]\t- This bookmark in other window, without selecting it +\\[bookmark-bmenu-1-window]\t- This bookmark in a full-frame window +\\[bookmark-bmenu-2-window]\t- This bookmark and last-visited bookmark + +\\[bookmark-jump]\t- Bookmark by name +\\[bmkp-jump-to-type]\t- Bookmark by type +\\[bmkp-jump-in-navlist]\t- Bookmark in the navigation list +\\[bmkp-lighted-jump]\t- Highlighted bookmark +\\[bmkp-desktop-jump]\t- Desktop bookmark +\\[bmkp-bookmark-list-jump]\t- Bookmark-list bookmark +\\[bmkp-bookmark-file-jump]\t- Bookmark-file bookmark +\\[bmkp-dired-jump]\t- Dired bookmark +\\[bmkp-file-jump]\t- File or directory bookmark +\\[bmkp-dired-this-dir-jump]\t- Dired bookmark for this dir +\\[bmkp-file-this-dir-jump]\t- Bookmark for a file or subdir in this dir +\\[bmkp-local-file-jump]\t- Local-file bookmark +\\[bmkp-remote-file-jump]\t- Remote-file bookmark +\\[bmkp-region-jump]\t- Region bookmark +\\[bmkp-info-jump]\t- Info bookmark +\\[bmkp-man-jump]\t- `man'-page bookmark +\\[bmkp-non-file-jump]\t- Non-file (buffer) bookmark +\\[bmkp-gnus-jump]\t- Gnus bookmark +\\[bmkp-url-jump]\t- URL bookmark +\\[bmkp-variable-list-jump]\t- Variable-list bookmark +\\[bmkp-autonamed-jump]\t- Autonamed bookmark +\\[bmkp-autonamed-this-buffer-jump]\t- Autonamed bookmark in buffer +\\[bmkp-some-tags-jump]\t- Bookmark having some tags you specify +\\[bmkp-all-tags-jump]\t- Bookmark having each tag you specify +\\[bmkp-some-tags-regexp-jump]\t- Bookmark having a tag that matches a regexp +\\[bmkp-all-tags-regexp-jump]\t- Bookmark having all its tags match a regexp +\\[bmkp-file-some-tags-jump]\t- File bookmark having some tags you specify +\\[bmkp-file-all-tags-jump]\t- File bookmark having each tag you specify +\\[bmkp-file-some-tags-regexp-jump]\t- File bookmark having a tag that matches a regexp +\\[bmkp-file-all-tags-regexp-jump]\t- File bookmark having all its tags match a regexp +\\[bmkp-file-this-dir-some-tags-jump]\t- File in this dir having some tags you specify +\\[bmkp-file-this-dir-all-tags-jump]\t- File in this dir having each tag you specify +\\[bmkp-file-this-dir-some-tags-regexp-jump]\t- File in this dir having a tag that matches a regexp +\\[bmkp-file-this-dir-all-tags-regexp-jump]\t- File in this dir having all its tags match a regexp + + +Cycle Bookmarks and Autonamed Bookmarks +--------------------------------------- + +\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Create/delete autonamed bookmark at point +\\[bmkp-autonamed-jump]\t- Jump to an autonamed bookmark +\\[bmkp-autonamed-this-buffer-jump]\t- Jump to an autonamed bookmark in buffer +C-x p n n ...\t- Next bookmark in buffer (C-x p C-n, C-x p down) +C-x p p p ...\t- Previous bookmark in buffer (C-x p C-p, C-x p up) +C-x p f f ...\t- Next bookmark in navlist (C-x p C-f, C-x p right) +C-x p b b ...\t- Previous bookmark in navlist (C-x p C-b, C-x p left) +C-x p next ...\t- MS Windows `Open' next bookmark in navlist +C-x p prior ...\t- MS Windows `Open' previous bookmark in navlist +C-x C-down ...\t- Next highlighted bookmark in buffer +C-x C-up ...\t- Previous highlighted bookmark in buffer + +\\[bmkp-delete-all-autonamed-for-this-buffer] +\t- Delete all autonamed bookmarks in current buffer + + +Search-and-Replace Targets (in sort order) +-------------------------- + +M-s a C-s\t- Isearch the marked bookmarks (Emacs 23+) +M-s a C-M-s\t- Regexp-isearch the marked bookmarks (Emacs 23+) +\\[bmkp-bmenu-search-marked-bookmarks-regexp]\t- Regexp-search the marked file bookmarks +\\[bmkp-bmenu-query-replace-marked-bookmarks-regexp]\t\t- Query-replace the marked file \ +bookmarks + + +Mark/Unmark +----------- + +\(Mark means `>'. Flag means `D'. See also `Tags', below.) + +\\[bookmark-bmenu-delete]\t- Flag this bookmark `D' for deletion, then move down +\\[bookmark-bmenu-delete-backwards]\t- Flag this bookmark `D' for deletion, then move up + +\\[bookmark-bmenu-mark]\t- Mark this bookmark +\\[bookmark-bmenu-unmark]\t- Unmark this bookmark (`C-u': move up one line) +\\[bookmark-bmenu-backup-unmark]\t- Unmark previous bookmark (move up, then unmark) + +\\[bmkp-bmenu-mark-all]\t- Mark all bookmarks +\\[bmkp-bmenu-regexp-mark]\t- Mark all bookmarks whose names match a regexp +\\[bmkp-bmenu-unmark-all]\t- Unmark all bookmarks (`C-u': interactive query) +\\[bmkp-bmenu-toggle-marks]\t- Toggle marks: unmark the marked and mark the unmarked + +\\[bmkp-bmenu-mark-autofile-bookmarks]\t- Mark autofile bookmarks +\\[bmkp-bmenu-mark-non-file-bookmarks]\t- Mark non-file (i.e. buffer) bookmarks +\\[bmkp-bmenu-mark-dired-bookmarks]\t- Mark Dired bookmarks +\\[bmkp-bmenu-mark-file-bookmarks]\t- Mark file & directory bookmarks (`C-u': local only) +\\[bmkp-bmenu-mark-gnus-bookmarks]\t- Mark Gnus bookmarks +\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark the highlighted bookmarks +\\[bmkp-bmenu-mark-info-bookmarks]\t- Mark Info bookmarks +\\[bmkp-bmenu-mark-desktop-bookmarks]\t- Mark desktop bookmarks +\\[bmkp-bmenu-mark-bookmark-file-bookmarks]\t- Mark bookmark-file bookmarks +\\[bmkp-bmenu-mark-man-bookmarks]\t- Mark `man' page bookmarks (that's `M' twice, not Meta-M) +\\[bmkp-bmenu-mark-region-bookmarks]\t- Mark region bookmarks +\\[bmkp-bmenu-mark-url-bookmarks]\t- Mark URL bookmarks +\\[bmkp-bmenu-mark-w3m-bookmarks]\t- Mark W3M (URL) bookmarks + + +Modify +------ + +\(See also `Tags', next.) + +\\[bookmark-bmenu-edit-annotation]\t- Edit this bookmark's annotation +\\[bmkp-bmenu-edit-bookmark]\t- Rename and relocate this bookmark +\\[bookmark-bmenu-rename]\t- Rename this bookmark +\\[bookmark-bmenu-relocate]\t- Relocate this bookmark (change file) +\\[bmkp-bmenu-edit-tags]\t- Edit this bookmark's tags +\\[bookmark-bmenu-execute-deletions]\t- Delete (visible) bookmarks flagged `D' +\\[bmkp-bmenu-delete-marked]\t- Delete (visible) bookmarks marked `>' + + +Tags +---- + +\\[bmkp-add-tags]\t- Add some tags to a bookmark +\\[bmkp-remove-tags]\t- Remove some tags from a bookmark +\\[bmkp-remove-all-tags]\t- Remove all tags from a bookmark +\\[bmkp-remove-tags-from-all]\t- Remove some tags from all bookmarks +\\[bmkp-rename-tag]\t- Rename a tag in all bookmarks +\\[bmkp-list-all-tags]\t- List all tags used in any bookmarks (`C-u': show tag values) +\\[bmkp-bmenu-edit-tags]\t- Edit this bookmark's tags +\\[bmkp-bmenu-set-tag-value]\t- Set the value of a tag (as attribute) + +\\[bmkp-bmenu-add-tags-to-marked]\t- Add some tags to the marked bookmarks +\\[bmkp-bmenu-remove-tags-from-marked]\t- Remove some tags from the marked bookmarks + +\\[bmkp-bmenu-mark-bookmarks-tagged-regexp]\t- Mark bookmarks having at least one \ +tag that matches a regexp +\\[bmkp-bmenu-mark-bookmarks-tagged-some]\t- Mark bookmarks having at least one tag \ +in a set (OR) +\\[bmkp-bmenu-mark-bookmarks-tagged-all]\t- Mark bookmarks having all of the tags \ +in a set (AND) +\\[bmkp-bmenu-mark-bookmarks-tagged-none]\t- Mark bookmarks not having any of the tags \ +in a set (NOT OR) +\\[bmkp-bmenu-mark-bookmarks-tagged-not-all]\t- Mark bookmarks not having all of the \ +tags in a set (NOT AND) + +\\[bmkp-bmenu-unmark-bookmarks-tagged-regexp]\t- Unmark bookmarks having at least one \ +tag that matches a regexp +\\[bmkp-bmenu-unmark-bookmarks-tagged-some]\t- Unmark bookmarks having at least one \ +tag in a set (OR) +\\[bmkp-bmenu-unmark-bookmarks-tagged-all]\t- Unmark bookmarks having all of the tags \ +in a set (AND) +\\[bmkp-bmenu-unmark-bookmarks-tagged-none]\t- Unmark bookmarks not having any tags \ +in a set (NOT OR) +\\[bmkp-bmenu-unmark-bookmarks-tagged-not-all]\t- Unmark bookmarks not having all tags \ +in a set (NOT AND) + + +Bookmark Highlighting +--------------------- + +\\[bmkp-bmenu-show-only-lighted]\t- Show only the highlighted bookmarks +\\[bmkp-bmenu-set-lighting]\t- Set highlighting for this bookmark +\\[bmkp-bmenu-set-lighting-for-marked]\t- Set highlighting for marked bookmarks +\\[bmkp-bmenu-light]\t- Highlight this bookmark +\\[bmkp-bmenu-unlight]\t- Unhighlight this bookmark +\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark the highlighted bookmarks +\\[bmkp-bmenu-light-marked]\t- Highlight the marked bookmarks +\\[bmkp-bmenu-unlight-marked]\t- Unhighlight the marked bookmarks +\\[bmkp-light-bookmark-this-buffer]\t- Highlight a bookmark in current buffer +\\[bmkp-unlight-bookmark-this-buffer]\t- Unhighlight a bookmark in current buffer +\\[bmkp-light-bookmarks]\t- Highlight bookmarks (see prefix arg) +\\[bmkp-unlight-bookmarks]\t- Unhighlight bookmarks (see prefix arg) +\\[bmkp-bookmarks-lighted-at-point]\t- List bookmarks highlighted at point +\\[bmkp-unlight-bookmark-here]\t- Unhighlight a bookmark at point or on same line + + +Sort +---- + +\(Repeat to cycle normal/reversed/off, except as noted.) + +\\[bmkp-bmenu-sort-marked-before-unmarked]\t- Sort marked bookmarks first +\\[bmkp-bmenu-sort-by-last-buffer-or-file-access]\t- Sort by last buffer or file \ +access +\\[bmkp-bmenu-sort-by-Gnus-thread]\t- Sort by Gnus thread: group, article, message +\\[bmkp-bmenu-sort-by-Info-location]\t- Sort by Info manual, node, position +\\[bmkp-bmenu-sort-by-bookmark-type]\t- Sort by bookmark type +\\[bmkp-bmenu-sort-by-bookmark-name]\t- Sort by bookmark name +\\[bmkp-bmenu-sort-by-creation-time]\t- Sort by bookmark creation time +\\[bmkp-bmenu-sort-by-last-bookmark-access]\t- Sort by last bookmark access time +\\[bmkp-bmenu-sort-by-bookmark-visit-frequency]\t- Sort by bookmark visit frequency +\\[bmkp-bmenu-sort-by-url]\t- Sort by URL + +\\[bmkp-bmenu-sort-by-local-file-type]\t- Sort by local file type: file, symlink, dir +\\[bmkp-bmenu-sort-by-file-name]\t- Sort by file name +\\[bmkp-bmenu-sort-by-local-file-size]\t- Sort by local file size +\\[bmkp-bmenu-sort-by-last-local-file-access]\t- Sort by last local file access +\\[bmkp-bmenu-sort-by-last-local-file-update]\t- Sort by last local file update (edit) + +\\[bmkp-reverse-sort-order]\t- Reverse current sort direction (repeat to toggle) +\\[bmkp-reverse-multi-sort-order]\t- Complement sort predicate decisions (repeat \ +to toggle) +\\[bmkp-bmenu-change-sort-order-repeat]\t- Cycle sort orders (repeat \ +to cycle) + + +Hide/Show +--------- + +\\[bmkp-bmenu-show-all]\t- Show all bookmarks +\\[bmkp-bmenu-toggle-show-only-marked]\t- Toggle showing only marked bookmarks +\\[bmkp-bmenu-toggle-show-only-unmarked]\t- Toggle showing only unmarked bookmarks +\\[bmkp-bmenu-show-only-autofiles]\t- Show only autofile bookmarks +\\[bmkp-bmenu-show-only-autonamed]\t- Show only autonamed bookmarks +\\[bmkp-bmenu-show-only-non-files]\t- Show only non-file (i.e. buffer) bookmarks +\\[bmkp-bmenu-show-only-dired]\t- Show only Dired bookmarks +\\[bmkp-bmenu-show-only-files]\t- Show only file & directory bookmarks (`C-u': local only) +\\[bmkp-bmenu-show-only-gnus]\t- Show only Gnus bookmarks +\\[bmkp-bmenu-show-only-info-nodes]\t- Show only Info bookmarks +\\[bmkp-bmenu-show-only-desktops]\t- Show only desktop bookmarks +\\[bmkp-bmenu-show-only-bookmark-files]\t- Show only bookmark-file bookmarks +\\[bmkp-bmenu-show-only-man-pages]\t- Show only `man' page bookmarks +\\[bmkp-bmenu-show-only-regions]\t- Show only region bookmarks +\\[bmkp-bmenu-show-only-variable-lists]\t- Show only variable-list bookmarks +\\[bmkp-bmenu-show-only-urls]\t- Show only URL bookmarks +\\[bmkp-bmenu-show-only-w3m-urls]\t- Show only W3M (URL) bookmarks +\\[bmkp-bmenu-filter-bookmark-name-incrementally]\t- Incrementally show only bookmarks \ +whose names match a regexp +\\[bmkp-bmenu-filter-file-name-incrementally]\t- Incrementally show only bookmarks whose \ +files match a regexp +\\[bmkp-bmenu-filter-annotation-incrementally]\t- Incrementally show only bookmarks whose \ +annotations match a regexp +\\[bmkp-bmenu-filter-tags-incrementally]\t- Incrementally show only bookmarks whose tags \ +match a regexp +\\[bmkp-bmenu-show-only-tagged]\t- Show only bookmarks that have tags + + +Omit/Un-omit +------------ + +\\[bmkp-bmenu-show-only-omitted]\t- Show (only) the omitted bookmarks +\\[bmkp-bmenu-show-all]\t- Show the un-omitted bookmarks (all) +\\[bmkp-bmenu-omit/unomit-marked]\t- Omit the marked bookmarks; un-omit them if after \ +`\\[bmkp-bmenu-show-only-omitted]' +\\[bmkp-unomit-all]\t- Un-omit all omitted bookmarks + + +Define Commands for `*Bookmark List*' +------------------------------------- + +\\[bmkp-bmenu-define-command]\t- Define a command to restore the current sort order & filter +\\[bmkp-bmenu-define-full-snapshot-command]\t- Define a command to restore the current \ +bookmark-list state +\\[bmkp-define-tags-sort-command]\t- Define a command to sort bookmarks by tags +\\[bmkp-bmenu-define-jump-marked-command]\t- Define a command to jump to a bookmark that is \ +now marked + + +Options for `*Bookmark List*' +----------------------------- + +bookmark-bmenu-file-column - Bookmark width if files are shown +bookmark-bmenu-toggle-filenames - Show filenames initially? + +bmkp-bmenu-omitted-bookmarks - List of omitted bookmarks +bmkp-bmenu-state-file - File to save bookmark-list state + (\"home\") nil: do not save/restore +bmkp-sort-comparer - Initial sort +bmkp-sort-orders-for-cycling-alist +\t - Sort orders that `\\[bmkp-bmenu-change-sort-order-repeat]'... cycles + + +Other Options +------------- + +bookmark-automatically-show-annotations - Show annotation when visit? +bookmark-completion-ignore-case - Case-sensitive completion? +bookmark-default-file - File to save bookmarks in +bookmark-menu-length - Max size of bookmark-name menu item +bookmark-save-flag - Whether and when to save +bookmark-use-annotations - Query for annotation when saving? +bookmark-version-control - Numbered backups of bookmark file? + +bmkp-autoname-format - Format of autonamed bookmark name +bmkp-crosshairs-flag - Highlight position when visit? +bmkp-menu-popup-max-length - Use menus to choose bookmarks? +bmkp-save-new-location-flag - Save if bookmark relocated? +bmkp-sequence-jump-display-function - How to display a sequence +bmkp-sort-comparer - Predicates for sorting bookmarks +bmkp-su-or-sudo-regexp - Bounce-show each end of region? +bmkp-this-buffer-cycle-sort-comparer - This-buffer cycling sort +bmkp-use-region - Activate saved region when visit?" + (kill-all-local-variables) + (use-local-map bookmark-bmenu-mode-map) + (setq truncate-lines t + buffer-read-only t + major-mode 'bookmark-bmenu-mode + mode-name "Bookmark Menu") + (if (fboundp 'run-mode-hooks) + (run-mode-hooks 'bookmark-bmenu-mode-hook) + (run-hooks 'bookmark-bmenu-mode-hook))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Put `mouse-face' on whole line, with the same help-echo as for the bookmark name. +;; 2. Fit one-window frame. +;; 3. Added doc string. +;; +(defun bookmark-bmenu-show-filenames (&optional force) + "Show file names." + (if (and (not force) bookmark-bmenu-toggle-filenames) + nil ; Already shown, so do nothing. + (save-excursion + (save-window-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (setq bookmark-bmenu-hidden-bookmarks ()) + (let ((inhibit-read-only t)) + (while (< (point) (point-max)) + (let ((bmk (bookmark-bmenu-bookmark))) + (setq bookmark-bmenu-hidden-bookmarks (cons bmk bookmark-bmenu-hidden-bookmarks)) + (let ((start (save-excursion (end-of-line) (point)))) + (move-to-column bookmark-bmenu-file-column t)) + (delete-region (point) (progn (end-of-line) (point))) + (insert " ") + (bookmark-insert-location bmk t) ; Pass the NO-HISTORY arg. + (when (if (fboundp 'display-color-p) ; Emacs 21+. + (and (display-color-p) (display-mouse-p)) + window-system) + (let ((help (get-text-property (+ bmkp-bmenu-marks-width + (line-beginning-position)) 'help-echo))) + (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position)) + (point) 'mouse-face 'highlight) + (when help (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position)) + (point) 'help-echo help)))) + (forward-line 1)))))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Add text properties when hiding filenames. +;; 2. Do not set or use `bookmark-bmenu-bookmark-column' - use `bmkp-bmenu-marks-width' always. +;; 3. Fit one-window frame. +;; 4. Added doc string. +;; +(defun bookmark-bmenu-hide-filenames (&optional force) + "Hide filenames in bookmark-list buffer. +If either optional arg FORCE or `bookmark-bmenu-toggle-filenames' is +non-nil, then do nothing." + (when (and (not force) bookmark-bmenu-toggle-filenames) + (save-excursion + (save-window-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (setq bookmark-bmenu-hidden-bookmarks (nreverse bookmark-bmenu-hidden-bookmarks)) + (let ((max-width 0)) + (dolist (name bookmark-bmenu-hidden-bookmarks) + (setq max-width (max max-width (length name)))) + (setq max-width (+ max-width bmkp-bmenu-marks-width)) + (save-excursion + (let ((inhibit-read-only t)) + (while bookmark-bmenu-hidden-bookmarks + (move-to-column bmkp-bmenu-marks-width t) + (bookmark-kill-line) + (let ((name (car bookmark-bmenu-hidden-bookmarks)) + (start (point)) + end) + (insert name) + (move-to-column max-width t) + (setq end (point)) + (bmkp-bmenu-propertize-item name start end)) + (setq bookmark-bmenu-hidden-bookmarks (cdr bookmark-bmenu-hidden-bookmarks)) + (forward-line 1))))))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-1-window (&optional use-region-p) ; Bound to `1' in bookmark list + "Select this line's bookmark, alone, in full frame. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-jump-1 (bookmark-bmenu-bookmark) 'pop-to-buffer use-region-p) + (bury-buffer (other-buffer)) + (delete-other-windows)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-2-window (&optional use-region-p) ; Bound to `2' in bookmark list + "Select this line's bookmark, with previous buffer in second window. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark)) + (menu (current-buffer)) + (pop-up-windows t)) + (delete-other-windows) + (switch-to-buffer (other-buffer)) + ;; (let ((bookmark-automatically-show-annotations nil)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'pop-to-buffer use-region-p) + (bury-buffer menu))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-this-window (&optional use-region-p) ; Bound to `RET' in bookmark list + "Select this line's bookmark in this window. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Use `pop-to-buffer', not `switch-to-buffer-other-window'. +;; 2. Prefix arg reverses `bmkp-use-region'. +;; 3. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-other-window (&optional use-region-p) ; Bound to `o' in bookmark list + "Select this line's bookmark in other window. Show `*Bookmark List*' still. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark))) + ;; (bookmark-automatically-show-annotations t)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-switch-other-window (&optional use-region-p) ; Bound to `C-o' in bookmark list + "Make the other window select this line's bookmark. +The current window remains selected. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark)) + (pop-up-windows t) + (same-window-buffer-names ()) + (same-window-regexps ())) + ;; (bookmark-automatically-show-annotations t)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'display-buffer use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-other-window-with-mouse (event &optional use-region-p) + "Select clicked bookmark in other window. Show `*Bookmark List*' still." + (interactive "e\nP") + (with-current-buffer (window-buffer (posn-window (event-end event))) + (save-excursion (goto-char (posn-point (event-end event))) + (bookmark-bmenu-other-window use-region-p)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg MSGP. +;; 2. Call `bookmark-show-annotation' with arg MSGP. +;; 3. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-show-annotation (msgp) + "Show the annotation for the current bookmark in another window." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark (bookmark-bmenu-bookmark))) + (bookmark-show-annotation bookmark msgp))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg MARKEDP: handle bookmarks marked `>', not just those flagged `D'. +;; 2. Use `bookmark-bmenu-surreptitiously-rebuild-list', instead of using +;; `bookmark-bmenu-list', updating the modification count, and saving. +;; 3. Update `bmkp-latest-bookmark-alist' to reflect the deletions. +;; 4. Pass full bookmark, not name, to `delete' (and do not use `assoc'). +;; 5. Use `bmkp-bmenu-goto-bookmark-named'. +;; 6. Added status messages. +;; 7. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-execute-deletions (&optional markedp) ; Bound to `x' in bookmark list + "Delete (visible) bookmarks flagged `D'. +With a prefix argument, delete the bookmarks marked `>' instead, after +confirmation." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (not markedp) (yes-or-no-p "Delete bookmarks marked `>' (not `D') ")) + (let* ((mark-type (if markedp "^>" "^D")) + (o-str (and (not (looking-at mark-type)) (bookmark-bmenu-bookmark))) + (o-point (point)) + (count 0)) + (message "Deleting bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward mark-type (point-max) t) + (let* ((bmk-name (bookmark-bmenu-bookmark)) + (bmk (bookmark-get-bookmark bmk-name))) + (bookmark-delete bmk-name 'batch) + (setq count (1+ count) + bmkp-latest-bookmark-alist (delete bmk bmkp-latest-bookmark-alist)))) + (if (<= count 0) + (message (if markedp "No marked bookmarks" "No bookmarks flagged for deletion")) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Deleted %d bookmarks" count)) + (if o-str + (bmkp-bmenu-goto-bookmark-named o-str) + (goto-char o-point) + (beginning-of-line))) + (message "OK, nothing deleted"))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Do not call `bookmark-bmenu-list' (it was already called). +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; 3. Use `bmkp-bmenu-goto-bookmark-named' instead of just searching for name. +;; +;;;###autoload +(defun bookmark-bmenu-rename () ; Bound to `r' in bookmark list + "Rename bookmark on current line. Prompts for a new name." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((newname (bookmark-rename (bookmark-bmenu-bookmark)))) + (bmkp-bmenu-goto-bookmark-named newname))) + +;;(@* "Bookmark+ Functions (`bmkp-*')") +;;; Bookmark+ Functions (`bmkp-*') ----------------------------------- + + +;;(@* "Menu-List (`*-bmenu-*') Filter Commands") +;; *** Menu-List (`*-bmenu-*') Filter Commands *** + +;;;###autoload +(defun bmkp-bmenu-show-only-autofiles (&optional arg) ; Bound to `A S' in bookmark list + "Display (only) the autofile bookmarks. +This means bookmarks whose names are the same as their (non-directory) +file names. But with a prefix arg you are prompted for a prefix that +each bookmark name must have." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function (if (not arg) + 'bmkp-autofile-alist-only + (let ((prefix (read-string "Prefix for bookmark names: " + nil nil ""))) + `(lambda () (bmkp-autofile-alist-only ,prefix)))) + bmkp-bmenu-title "Autofile Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only autofile bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-autonamed () ; Bound to `# S' in bookmark list + "Display (only) the autonamed bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-autonamed-alist-only + bmkp-bmenu-title "Autonamed Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only autonamed bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-bookmark-files () ; Bound to `X S' in bookmark list + "Display (only) the bookmark-file bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-bookmark-file-alist-only + bmkp-bmenu-title "Bookmark-File Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only bookmark-file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-desktops () ; Bound to `K S' in bookmark list + "Display (only) the desktop bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-desktop-alist-only + bmkp-bmenu-title "Desktop Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only desktop bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-dired () ; Bound to `M-d M-s' in bookmark list + "Display (only) the Dired bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-dired-alist-only + bmkp-bmenu-title "Dired Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Dired bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-files (arg) ; Bound to `F S' in bookmark list + "Display a list of file and directory bookmarks (only). +With a prefix argument, do not include remote files or directories." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function (if arg 'bmkp-local-file-alist-only 'bmkp-file-alist-only) + bmkp-bmenu-title (if arg + "Local File and Directory Bookmarks" + "File and Directory Bookmarks")) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-non-files () ; Bound to `B S' in bookmark list + "Display (only) the non-file bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-non-file-alist-only + bmkp-bmenu-title "Non-File Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only non-file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-gnus () ; Bound to `G S' in bookmark list + "Display (only) the Gnus bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-gnus-alist-only + bmkp-bmenu-title "Gnus Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Gnus bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-info-nodes () ; Bound to `I S' in bookmark list + "Display (only) the Info bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-info-alist-only + bmkp-bmenu-title "Info Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Info bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-man-pages () ; Bound to `M S' in bookmark list + "Display (only) the `man' page bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-man-alist-only + bmkp-bmenu-title "`man' Page Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only `man' page bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-regions () ; Bound to `R S' in bookmark list + "Display (only) the bookmarks that record a region." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-region-alist-only + bmkp-bmenu-title "Region Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only bookmarks with regions are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-variable-lists () ; Bound to `V S' in bookmark list + "Display (only) the variable-list bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-variable-list-alist-only + bmkp-bmenu-title "Variable-list Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only variable-list bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-specific-buffer (&optional buffer) ; Bound to `= b S' in bookmark list + "Display (only) the bookmarks for BUFFER. +Interactively, read the BUFFER name. +If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it." + (interactive (list (bmkp-completing-read-buffer-name))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when buffer (setq bmkp-last-specific-buffer buffer)) + (setq bmkp-bmenu-filter-function 'bmkp-last-specific-buffer-alist-only + bmkp-bmenu-title (format "Buffer `%s' Bookmarks" bmkp-last-specific-buffer)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + (format "Only bookmarks for buffer `%s' are shown" + bmkp-last-specific-buffer)))) + +;;;###autoload +(defun bmkp-bmenu-show-only-specific-file (&optional file) ; Bound to `= f S' in bookmark list + "Display (only) the bookmarks for FILE, an absolute file name. +Interactively, read the FILE name. +If FILE is non-nil, set `bmkp-last-specific-file' to it." + (interactive (list (bmkp-completing-read-file-name))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when file (setq bmkp-last-specific-file file)) + (setq bmkp-bmenu-filter-function 'bmkp-last-specific-file-alist-only + bmkp-bmenu-title (format "File `%s' Bookmarks" bmkp-last-specific-file)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + (format "Only bookmarks for file `%s' are shown" + bmkp-last-specific-file)))) + +;;;###autoload +(defun bmkp-bmenu-show-only-urls () ; Bound to `M-u M-s' in bookmark list + "Display (only) the URL bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-url-alist-only + bmkp-bmenu-title "URL Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only URL bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-w3m-urls () ; Bound to `W S' in bookmark list + "Display (only) the W3M URL bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-w3m-alist-only + bmkp-bmenu-title "W3M Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only W3M bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-all () ; Bound to `.' in bookmark list + "Show all bookmarks known to the bookmark list (aka \"menu list\"). +Omitted bookmarks are not shown, however. +Also, this does not revert the bookmark list, to bring it up to date. +To revert the list, use `\\\\[bmkp-bmenu-refresh-menu-list]'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function nil + bmkp-bmenu-title "All Bookmarks" + bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "All bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-refresh-menu-list () ; Bound to `g' in bookmark list + "Refresh (revert) the bookmark list (\"menu list\"). +This brings the displayed list up to date. It does not change the +current filtering or sorting of the displayed list. + +If you want setting a bookmark to refresh the list automatically, you +can use command `bmkp-toggle-bookmark-set-refreshes'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-refresh-menu-list (bookmark-bmenu-bookmark))) + +;;;###autoload +(defun bmkp-bmenu-filter-bookmark-name-incrementally () ; Bound to `P B' in bookmark list + "Incrementally filter bookmarks by bookmark name using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-bookmark-name-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-bookmark-name-regexp () + "Filter bookmarks by bookmark name, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-bookmark-name-alist-only + bmkp-bmenu-title (format "Bookmarks with Names Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-file-name-incrementally () ; Bound to `P F' in bookmark list + "Incrementally filter bookmarks by file name using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-file-name-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-file-name-regexp () + "Filter bookmarks by file name, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-file-name-alist-only + bmkp-bmenu-title (format "Bookmarks with File Names Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-annotation-incrementally () ; Bound to `P A' in bookmark list + "Incrementally filter bookmarks by their annotations using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-annotation-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-annotation-regexp () + "Filter bookmarks by annoation, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-annotation-alist-only + bmkp-bmenu-title (format "Bookmarks with Annotations Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-tags-incrementally () ; Bound to `P T' in bookmark list + "Incrementally filter bookmarks by tags using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-tags-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-tags-regexp () + "Filter bookmarks by tags, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-tags-alist-only + bmkp-bmenu-title (format "Bookmarks with Tags Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +(defun bmkp-bmenu-read-filter-input () + "Read input and add it to `bmkp-bmenu-filter-pattern'." + (setq bmkp-bmenu-filter-pattern "") + (let ((tmp-list ()) + char) + (catch 'bmkp-bmenu-read-filter-input-1 + (while t + (catch 'bmkp-bmenu-read-filter-input-2 + (condition-case nil + (setq char (read-char (concat bmkp-bmenu-filter-prompt bmkp-bmenu-filter-pattern))) + (error (throw 'bmkp-bmenu-read-filter-input-1 nil))) + (case char + ((?\e ?\r) (throw 'bmkp-bmenu-read-filter-input-1 nil)) ; Break and exit. + (?\d + (pop tmp-list) ; Delete last char of `bmkp-bmenu-filter-pattern'. + (setq bmkp-bmenu-filter-pattern (mapconcat 'identity (reverse tmp-list) "")) + (throw 'bmkp-bmenu-read-filter-input-2 nil)) + (t + (push (text-char-description char) tmp-list) + (setq bmkp-bmenu-filter-pattern (mapconcat 'identity (reverse tmp-list) "")) + (throw 'bmkp-bmenu-read-filter-input-2 nil)))))))) + +(defun bmkp-bmenu-cancel-incremental-filtering () + "Cancel timer used for incrementally filtering bookmarks." + (cancel-timer bmkp-bmenu-filter-timer) + (setq bmkp-bmenu-filter-timer nil)) + +;;;###autoload +(defun bmkp-bmenu-toggle-show-only-unmarked () ; Bound to `<' in bookmark list + "Hide all marked bookmarks. Repeat to toggle, showing all." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (bmkp-some-marked-p bmkp-latest-bookmark-alist) + (bmkp-some-marked-p bmkp-bmenu-before-hide-marked-alist)) + (let ((bookmark-alist bmkp-latest-bookmark-alist) + status) + (if bmkp-bmenu-before-hide-marked-alist + (setq bookmark-alist bmkp-bmenu-before-hide-marked-alist + bmkp-bmenu-before-hide-marked-alist () + bmkp-latest-bookmark-alist bookmark-alist + status 'shown) + (setq bmkp-bmenu-before-hide-marked-alist bmkp-latest-bookmark-alist + bookmark-alist (bmkp-unmarked-bookmarks-only) + bmkp-latest-bookmark-alist bookmark-alist + status 'hidden)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (cond ((eq status 'hidden) + (bookmark-bmenu-ensure-position) + (message "Marked bookmarks are now hidden")) + (t + (goto-char (point-min)) + (when (re-search-forward "^>" (point-max) t) (forward-line 0)) + (message "Marked bookmarks no longer hidden")))) + (message "No marked bookmarks to hide")) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-toggle-show-only-marked () ; Bound to `>' in bookmark list + "Hide all unmarked bookmarks. Repeat to toggle, showing all." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (bmkp-some-unmarked-p bmkp-latest-bookmark-alist) + (bmkp-some-unmarked-p bmkp-bmenu-before-hide-unmarked-alist)) + (let ((bookmark-alist bmkp-latest-bookmark-alist) + status) + (if bmkp-bmenu-before-hide-unmarked-alist + (setq bookmark-alist bmkp-bmenu-before-hide-unmarked-alist + bmkp-bmenu-before-hide-unmarked-alist () + bmkp-latest-bookmark-alist bookmark-alist + status 'shown) + (setq bmkp-bmenu-before-hide-unmarked-alist bmkp-latest-bookmark-alist + bookmark-alist (bmkp-marked-bookmarks-only) + bmkp-latest-bookmark-alist bookmark-alist + status 'hidden)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (cond ((eq status 'hidden) + (bookmark-bmenu-ensure-position) + (message "Unmarked bookmarks are now hidden")) + (t + (goto-char (point-min)) + (when (re-search-forward "^>" (point-max) t) (forward-line 0)) + (message "Unmarked bookmarks no longer hidden")))) + (message "No unmarked bookmarks to hide")) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + + +;;(@* "Menu-List (`*-bmenu-*') Commands Involving Marks") +;; *** Menu-List (`*-bmenu-*') Commands Involving Marks *** + +;;;###autoload +(defun bmkp-bmenu-mark-all () ; Bound to `M-m' in bookmark list + "Mark all bookmarks, using mark `>'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (let ((count 0)) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) (bookmark-bmenu-mark) (setq count (1+ count))) + (message "Marked: %d" count)))) + +;; This is similar to `dired-unmark-all-files'. +;;;###autoload +(defun bmkp-bmenu-unmark-all (mark &optional arg) ; Bound to `M-DEL', `U' in bookmark list + "Remove a mark from each bookmark. +Hit the mark character (`>' or `D') to remove those marks, + or hit `RET' to remove all marks (both `>' and `D'). +With a prefix arg, you are queried to unmark each marked bookmark. +Use `\\[help-command]' during querying for help." + (interactive "cRemove marks (RET means all): \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (require 'dired-aux) + (save-excursion + (let* ((count 0) + (inhibit-read-only t) + (case-fold-search nil) + (query nil) + (string (format "\n%c" mark)) + (help-form "Type SPC or `y' to unmark one bookmark, DEL or `n' to skip to next, +`!' to unmark all remaining bookmarks with no more questions.")) + (goto-char (point-min)) + (forward-line (if (eq mark ?\r) + bmkp-bmenu-header-lines + (1- bmkp-bmenu-header-lines))) ; Because STRING starts with a newline. + (while (and (not (eobp)) + (if (eq mark ?\r) + (re-search-forward dired-re-mark nil t) + (let ((case-fold-search t)) ; Treat `d' the same as `D'. + (search-forward string nil t)))) + (when (or (not arg) (let ((bmk (bookmark-bmenu-bookmark))) + (and bmk (dired-query 'query "Unmark bookmark `%s'? " bmk)))) + (bookmark-bmenu-unmark) (forward-line -1) + (setq count (1+ count)))) + (if (= 1 count) (message "1 mark removed") (message "%d marks removed" count))))) + +;;;###autoload +(defun bmkp-bmenu-regexp-mark (regexp) ; Bound to `% m' in bookmark list + "Mark bookmarks that match REGEXP. +The entire bookmark line is tested: bookmark name and possibly file name." + (interactive "sRegexp: ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0)) + (while (and (not (eobp)) (re-search-forward regexp (point-max) t)) + (bookmark-bmenu-mark) + (setq count (1+ count))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-mark-autofile-bookmarks (&optional arg) ; Bound to `A M' in bookmark list + "Mark autofile bookmarks: those whose names are the same as their files. +With a prefix arg you are prompted for a prefix that each bookmark +name must have." + (interactive "P") + (if (not arg) + (bmkp-bmenu-mark-bookmarks-satisfying #'bmkp-autofile-bookmark-p) + (let ((prefix (read-string "Prefix for bookmark names: " nil nil ""))) + (bmkp-bmenu-mark-bookmarks-satisfying #'(lambda (bb) (bmkp-autofile-bookmark-p bb prefix)))))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmark-file-bookmarks () ; Bound to `X M' in bookmark list + "Mark bookmark-file bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-bookmark-file-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-desktop-bookmarks () ; Bound to `K M' in bookmark list + "Mark desktop bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-desktop-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-dired-bookmarks () ; Bound to `M-d M-m' in bookmark list + "Mark Dired bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-dired-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-file-bookmarks (arg) ; Bound to `F M' in bookmark list + "Mark file bookmarks. +With a prefix argument, do not mark remote files or directories." + (interactive "P") + (bmkp-bmenu-mark-bookmarks-satisfying + (if arg 'bmkp-local-file-bookmark-p 'bmkp-file-bookmark-p))) + +;;;###autoload +(defun bmkp-bmenu-mark-gnus-bookmarks () ; Bound to `G M' in bookmark list + "Mark Gnus bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-gnus-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-info-bookmarks () ; Bound to `I M' in bookmark list + "Mark Info bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-info-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-man-bookmarks () ; Bound to `M M' in bookmark list + "Mark `man' page bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-man-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-non-file-bookmarks () ; Bound to `B M' in bookmark list + "Mark non-file bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-non-file-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-region-bookmarks () ; Bound to `R M' in bookmark list + "Mark bookmarks that record a region." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-region-bookmark-p)) + +(when (featurep 'bookmark+-lit) + (defun bmkp-bmenu-mark-lighted-bookmarks () ; Bound to `H M' in bookmark list + "Mark the highlighted bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-lighted-p))) + +;;;###autoload +(defun bmkp-bmenu-mark-specific-buffer-bookmarks (&optional buffer) ; `= b M' in bookmark list + "Mark bookmarks for BUFFER. +Interactively, read the name of the buffer. +If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it." + (interactive (list (bmkp-completing-read-buffer-name))) + (when buffer (setq bmkp-last-specific-buffer buffer)) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-buffer-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-specific-file-bookmarks (&optional file) ; Bound to `= f M' in bookmark list + "Mark bookmarks for FILE, an absolute file name. +Interactively, read the file name. +If FILE is non-nil, set `bmkp-last-specific-file' to it." + (interactive (list (bmkp-completing-read-file-name))) + (when file (setq bmkp-last-specific-file file)) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-file-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-url-bookmarks () ; Bound to `M-u M-m' in bookmark list + "Mark URL bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-url-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-w3m-bookmarks () ; Bound to `W M' in bookmark list + "Mark W3M (URL) bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-w3m-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-satisfying (pred) ; Not bound + "Mark bookmarks that satisfy predicate PRED. +If you use this interactively, you are responsible for entering a +symbol that names a unnary predicate. The function you provide is not +checked - it is simply applied to each bookmark to test it." + (interactive "aPredicate: ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + bmk) + (while (not (eobp)) + (setq bmk (bookmark-bmenu-bookmark)) + (if (not (funcall pred bmk)) + (forward-line 1) + (bookmark-bmenu-mark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-toggle-marks () ; Bound to `t' in bookmark list + "Toggle marks: Unmark all marked bookmarks; mark all unmarked bookmarks. +This affects only the `>' mark, not the `D' flag." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked-count 0) + (unmarked-count 0)) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (if (not (bmkp-some-marked-p bmkp-latest-bookmark-alist)) + (bmkp-bmenu-mark-all) + (while (not (eobp)) + (cond ((bmkp-bookmark-name-member (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks) + (bookmark-bmenu-unmark) + (setq unmarked-count (1+ unmarked-count))) + (t + (bookmark-bmenu-mark) + (setq marked-count (1+ marked-count))))) + (message "Marked: %d, unmarked: %d" marked-count unmarked-count))))) + +;;;###autoload +(defun bmkp-bmenu-dired-marked (dirbufname) ; Bound to `M-d >' in bookmark list + "Dired in another window for the marked file and directory bookmarks. + +Absolute file names are used for the entries in the Dired buffer. +The only entries are for the marked files and directories. These can +be located anywhere. (In Emacs versions prior to release 23.2, remote +bookmarks are ignored, because of Emacs bug #5478.) + +You are prompted for the Dired buffer name. The `default-directory' +of the buffer is the same as that of buffer `*Bookmark List*'." + (interactive (list (read-string "Dired buffer name: "))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (when (or (bmkp-local-file-bookmark-p bmk) + (> emacs-major-version 23) + (and (= emacs-major-version 23) (> emacs-minor-version 1))) + (setq file (bookmark-get-filename bmk)) + (unless (file-name-absolute-p file) (setq file (expand-file-name file))) ; Should not happen. + (push file files))) + (dired-other-window (cons dirbufname files)))) + +;;;###autoload +(defun bmkp-bmenu-delete-marked () ; Bound to `D' in bookmark list + "Delete all (visible) bookmarks that are marked `>', after confirmation." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-execute-deletions 'marked)) + +;;;###autoload +(defun bmkp-bmenu-make-sequence-from-marked (bookmark-name &optional dont-omit-p) ; Not bound + "Create or update a sequence bookmark from the visible marked bookmarks. +The bookmarks that are currently marked are recorded as a sequence, in +their current order in buffer `*Bookmark List*'. +When you \"jump\" to the sequence bookmark, the bookmarks in the +sequence are processed in order. + +By default, omit the marked bookmarks, after creating the sequence. +With a prefix arg, do not omit them. + +If a bookmark with the specified name already exists, it is +overwritten. If a sequence bookmark with the name already exists, +then you are prompted whether to add the marked bookmarks to the +beginning of the existing sequence (or simply replace it). + +Note that another existing sequence bookmark can be marked, and thus +included in the sequence bookmark created or updated. That is, you +can include other sequences within a sequence bookmark. + +Returns the bookmark (internal record) created or updated." + (interactive "sName of sequence bookmark: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked-bmks ()) + (count 0)) + (message "Making sequence from marked bookmarks...") + (save-excursion + (with-current-buffer "*Bookmark List*" + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (push (bookmark-bmenu-bookmark) marked-bmks) + (setq count (1+ count))))) + (when (zerop count) (error "No marked bookmarks")) + (let ((new-seq (nreverse marked-bmks)) + (bmk (bookmark-get-bookmark bookmark-name 'noerror))) + (when (and bmk (bmkp-sequence-bookmark-p bmk)) + (if (y-or-n-p (format "ADD marked to existing sequence `%s' (otherwise, REPLACES it)? " + bookmark-name)) + (setq new-seq (nconc new-seq (bookmark-prop-get bmk 'sequence))) + "OK, existing sequence will be replaced")) + (bookmark-store bookmark-name `((filename . ,bmkp-non-file-filename) + (position . 0) + (sequence ,@new-seq) + (handler . bmkp-jump-sequence)) + nil))) + (let ((new (bookmark-get-bookmark bookmark-name 'noerror))) + (unless (memq new bmkp-latest-bookmark-alist) + (setq bmkp-latest-bookmark-alist (cons new bmkp-latest-bookmark-alist))) + (unless dont-omit-p + (bmkp-bmenu-omit-marked) + (message "Marked bookmarks now OMITTED - use `bmkp-bmenu-show-only-omitted' to show")) + (bookmark-bmenu-surreptitiously-rebuild-list) + (bmkp-bmenu-goto-bookmark-named bookmark-name) + new)) + + +;;(@* "Omitted Bookmarks") +;; *** Omitted Bookmarks *** + +;;;###autoload +(defun bmkp-bmenu-omit () ; Not bound + "Omit this bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (setq bmkp-bmenu-omitted-bookmarks (cons (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Omitted 1 bookmark")) + +;;;###autoload +(defun bmkp-bmenu-omit/unomit-marked () ; Bound to `O >' in bookmark list + "Omit all marked bookmarks or, if showing only omitted ones, unomit." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + (bmkp-bmenu-unomit-marked) + (bmkp-bmenu-omit-marked))) + +;;;###autoload +(defun bmkp-bmenu-omit-marked () ; Bound to `O >' in bookmark list + "Omit all marked bookmarks. +They will henceforth be invisible to the bookmark list. +You can, however, use \\`\\[bmkp-bmenu-show-only-omitted]' to see them. +You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]' to make those marked + available again for the bookmark list." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((o-str (and (not (looking-at "^>")) (bookmark-bmenu-bookmark))) + (o-point (point)) + (count 0)) + (message "Omitting marked bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (setq bmkp-bmenu-omitted-bookmarks (cons (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks) + count (1+ count))) + (if (<= count 0) + (message "No marked bookmarks") + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Omitted %d bookmarks" count)) + (if o-str + (bmkp-bmenu-goto-bookmark-named o-str) + (goto-char o-point) + (beginning-of-line))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-unomit-marked () ; `O >' in bookmark list when showing omitted bookmarks + "Remove all marked bookmarks from the list of omitted bookmarks. +They will henceforth be available for display in the bookmark list. +\(In order to see and then mark omitted bookmarks you must use \\\ +`\\[bmkp-bmenu-show-only-omitted]'.)" + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks to UN-omit")) + (unless (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + (error "You must use command `bmkp-bmenu-show-only-omitted' first")) + (let ((count 0)) + (message "UN-omitting marked bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (let ((bmk-name (bookmark-bmenu-bookmark))) + (when (bmkp-bookmark-name-member bmk-name bmkp-bmenu-omitted-bookmarks) + (setq bmkp-bmenu-omitted-bookmarks (bmkp-delete-bookmark-name-from-list + bmk-name bmkp-bmenu-omitted-bookmarks) + count (1+ count))))) + (if (<= count 0) + (message "No marked bookmarks") + (setq bmkp-bmenu-filter-function nil + bmkp-bmenu-title "All Bookmarks" + bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "UN-omitted %d bookmarks" count))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-show-only-omitted () ; Bound to `O S' in bookmark list to show only omitted + "Show only the omitted bookmarks. +You can then mark some of them and use `bmkp-bmenu-unomit-marked' to + make those that are marked available again for the bookmark list." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks")) + (setq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only + bmkp-bmenu-title "Omitted Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only omitted bookmarks are shown now"))) + + +;;(@* "Search-and-Replace Locations of Marked Bookmarks") +;; *** Search-and-Replace Locations of Marked Bookmarks *** + +(when (> emacs-major-version 22) + (defun bmkp-bmenu-isearch-marked-bookmarks () ; Bound to `M-s a C-s' in bookmark list + "Isearch the marked bookmark locations, in their current order." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((bookmarks (mapcar #'car (bmkp-sort-omit (bmkp-marked-bookmarks-only)))) + (bmkp-use-region nil)) ; Suppress region handling. + (bmkp-isearch-bookmarks bookmarks))) ; Defined in `bookmark+-1.el'. + + (defun bmkp-bmenu-isearch-marked-bookmarks-regexp () ; Bound to `M-s a M-C-s' in bookmark list + "Regexp Isearch the marked bookmark locations, in their current order." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((bookmarks (mapcar #'car (bmkp-sort-omit (bmkp-marked-bookmarks-only)))) + (bmkp-use-region nil)) ; Suppress region handling. + (bmkp-isearch-bookmarks-regexp bookmarks)))) ; Defined in `bookmark+-1.el'. + +;;;###autoload +(defun bmkp-bmenu-search-marked-bookmarks-regexp (regexp) ; Bound to `M-s a M-s' in bookmark list + "Search the marked file bookmarks, in their current order, for REGEXP. +Use `\\[tags-loop-continue]' to advance among the search hits. +Marked directory and non-file bookmarks are ignored." + (interactive "sSearch marked file bookmarks (regexp): ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (tags-search regexp '(let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (setq file (bookmark-get-filename bmk)) + (when (and (not (equal bmkp-non-file-filename file)) + (not (file-directory-p file))) + (push file files))) + (setq files (nreverse files))))) + +;;;###autoload +(defun bmkp-bmenu-query-replace-marked-bookmarks-regexp (from to ; Bound to `M-q' in bookmark list + &optional delimited) + "`query-replace-regexp' FROM with TO, for all marked file bookmarks. +DELIMITED (prefix arg) means replace only word-delimited matches. +If you exit (`\\[keyboard-quit]', `RET' or `q'), you can use \ +`\\[tags-loop-continue]' to resume where +you left off." + (interactive (let ((common (query-replace-read-args "Query replace regexp in marked files" t t))) + (list (nth 0 common) (nth 1 common) (nth 2 common)))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (tags-query-replace from to delimited + '(let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (setq file (bookmark-get-filename bmk)) + (let ((buffer (get-file-buffer file))) + (when (and buffer (with-current-buffer buffer buffer-read-only)) + (error "File `%s' is visited read-only" file))) + (when (and (not (equal bmkp-non-file-filename file)) + (not (file-directory-p file))) + (push file files))) + (setq files (nreverse files))))) + + +;;(@* "Tags") +;; *** Tags *** + +;;;###autoload +(defun bmkp-bmenu-show-only-tagged () ; Bound to `T S' in bookmark list + "Display (only) the bookmarks that have tags." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-some-tags-alist-only + bmkp-bmenu-title "Tagged Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only tagged bookmarks are shown"))) + +;; Not bound, but `T 0' is `bmkp-remove-all-tags'. +;;;###autoload +(defun bmkp-bmenu-remove-all-tags (&optional must-confirm-p) + "Remove all tags from this bookmark. +Interactively, you are required to confirm." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark (bookmark-bmenu-bookmark))) + (when (and must-confirm-p (null (bmkp-get-tags bookmark))) + (error "Bookmark has no tags to remove")) + (when (or (not must-confirm-p) (y-or-n-p "Remove all tags from this bookmark? ")) + (bmkp-remove-all-tags bookmark)))) + +;;;###autoload +(defun bmkp-bmenu-add-tags () ; Only on `mouse-3' menu in bookmark list. + "Add some tags to this bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-add-tags (bookmark-bmenu-bookmark) (bmkp-read-tags-completing))) + +;;;###autoload +(defun bmkp-bmenu-set-tag-value () ; Bound to `T v' in bookmark list + "Set the value of one of this bookmark's tags." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((this-bmk (bookmark-bmenu-bookmark))) + (bmkp-set-tag-value + this-bmk + (bmkp-read-tag-completing "Tag: " (mapcar 'bmkp-full-tag (bmkp-get-tags this-bmk))) + (read (read-string "Value: ")) + 'msg))) + +;;;###autoload +(defun bmkp-bmenu-set-tag-value-for-marked (tag value &optional msgp) ; `T > v' in bookmark list + "Set the value of TAG to VALUE, for each of the marked bookmarks. +If any of the bookmarks has no tag named TAG, then add one with VALUE." + (interactive (list (bmkp-read-tag-completing) (read (read-string "Value: ")) 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when msgp (message "Setting tag values...")) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Setting tag values...")) + (bmkp-set-tag-value-for-bookmarks marked tag value)) + (when (and msgp tag) (message "Setting tag values...done"))) + +;;;###autoload +(defun bmkp-bmenu-remove-tags (&optional msgp) ; Only on `mouse-3' menu in bookmark list. + "Remove some tags from this bookmark." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bmk (bookmark-bmenu-bookmark))) + (bmkp-remove-tags bmk + (bmkp-read-tags-completing (mapcar 'bmkp-full-tag (bmkp-get-tags bmk)) t) + msgp))) + +;;;###autoload +(defun bmkp-bmenu-add-tags-to-marked (tags &optional msgp) ; Bound to `T > +' in bookmark list + "Add TAGS to each of the marked bookmarks. +TAGS is a list of strings. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag, but you are not limited to +choosing existing tags." + (interactive (list (bmkp-read-tags-completing) 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Adding tags...")) + (dolist (bmk (mapcar #'car marked)) (bmkp-add-tags bmk tags nil 'NO-CACHE-UPDATE))) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when (and msgp tags) (message "Tags added: %S" tags))) + +;;;###autoload +(defun bmkp-bmenu-remove-tags-from-marked (tags &optional msgp) ; Bound to `T > -' in bookmark list + "Remove TAGS from each of the marked bookmarks. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag." + (interactive (let ((cand-tags ())) + (dolist (bmk (bmkp-marked-bookmarks-only)) + (setq cand-tags (bmkp-set-union cand-tags (bmkp-get-tags bmk)))) + (unless cand-tags (error "No tags to remove")) + (list (bmkp-read-tags-completing cand-tags t) 'msg))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Removing tags...")) + (dolist (bmk (mapcar #'car marked)) (bmkp-remove-tags bmk tags nil 'NO-CACHE-UPDATE))) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when (and msgp tags) (message "Tags removed: %S" tags))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-regexp (regexp &optional notp) ; `T m %' in bookmark list + "Mark bookmarks any of whose tags match REGEXP. +With a prefix arg, mark all that are tagged but have no matching tags." + (interactive "sRegexp: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + tags anyp) + (while (not (eobp)) + (setq tags (bmkp-get-tags (bookmark-bmenu-bookmark)) + anyp (and tags (bmkp-some (lambda (tag) (string-match regexp (bmkp-tag-name tag))) + tags))) + (if (not (and tags (if notp (not anyp) anyp))) + (forward-line 1) + (bookmark-bmenu-mark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-all (tags &optional none-p msgp) ; `T m *' in bookmark list + "Mark all visible bookmarks that are tagged with *each* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +any tags at all (i.e., at least one tag). + +With a prefix arg, mark all that are *not* tagged with *any* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags none-p nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-none (tags &optional allp msgp) ; `T m ~ +' in bookmark list + "Mark all visible bookmarks that are not tagged with *any* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +no tags at all. + +With a prefix arg, mark all that are tagged with *each* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-some (tags &optional somenotp msgp) ; `T m +' in bookmark list + "Mark all visible bookmarks that are tagged with *some* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +any tags at all. + +With a prefix arg, mark all that are *not* tagged with *all* TAGS. + +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-not-all (tags &optional somep msgp) ; `T m ~ *' in bmk list + "Mark all visible bookmarks that are *not* tagged with *all* TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +no tags at all. + +With a prefix arg, mark all that are tagged with *some* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-regexp (regexp &optional notp) ; `T u %' in bookmark list + "Unmark bookmarks any of whose tags match REGEXP. +With a prefix arg, mark all that are tagged but have no matching tags." + (interactive "sRegexp: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + tags anyp) + (while (not (eobp)) + (setq tags (bmkp-get-tags (bookmark-bmenu-bookmark)) + anyp (and tags (bmkp-some (lambda (tag) (string-match regexp (bmkp-tag-name tag))) + tags))) + (if (not (and tags (if notp (not anyp) anyp))) + (forward-line 1) + (bookmark-bmenu-unmark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-all (tags &optional none-p msgp) ; `T u *' in bookmark list + "Unmark all visible bookmarks that are tagged with *each* tag in TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +any tags at all. + +With a prefix arg, unmark all that are *not* tagged with *any* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags none-p 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-none (tags &optional allp msgp) ; `T u ~ +' in bookmark list + "Unmark all visible bookmarks that are *not* tagged with *any* TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +no tags at all. + +With a prefix arg, unmark all that are tagged with *each* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-some (tags &optional somenotp msgp) ; `T u +' in bmk list + "Unmark all visible bookmarks that are tagged with *some* tag in TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +any tags at all. + +With a prefix arg, unmark all that are *not* tagged with *all* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-not-all (tags &optional somep msgp) ; `T u ~ *' in bmk list + "Unmark all visible bookmarks that are *not* tagged with *all* TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +no tags at all. + +With a prefix arg, unmark all that are tagged with *some* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) 'UNMARK msgp)) + +(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none (tags &optional none-p unmarkp msgp) + "Mark or unmark visible bookmarks tagged with all or none of TAGS. +TAGS is a list of strings, the tag names. +NONEP non-nil means mark/unmark bookmarks that have none of the TAGS. +UNMARKP non-nil means unmark; nil means mark. +MSGP means display a status message. + +As a special case, if TAGS is empty, then mark or unmark the bookmarks +that have any tags at all, or if NONEP is non-nil then mark or unmark +those that have no tags at all." + (with-current-buffer "*Bookmark List*" + (save-excursion + (let ((count 0) + bmktags presentp) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) + (setq bmktags (bmkp-get-tags (bookmark-bmenu-bookmark))) + (if (not (if (null tags) + (if none-p (not bmktags) bmktags) + (and bmktags (catch 'bmkp-b-mu-b-t-an + (dolist (tag tags) + (setq presentp (assoc-default tag bmktags nil t)) + (unless (if none-p (not presentp) presentp) + (throw 'bmkp-b-mu-b-t-an nil))) + t)))) + (forward-line 1) + (if unmarkp (bookmark-bmenu-unmark) (bookmark-bmenu-mark)) + (setq count (1+ count)))) + (when msgp (if (= 1 count) + (message "1 bookmark matched") + (message "%d bookmarks matched" count))))))) + +(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all (tags &optional notallp unmarkp msgp) + "Mark or unmark visible bookmarks tagged with any or not all of TAGS. +TAGS is a list of strings, the tag names. +NOTALLP non-nil means mark/unmark bookmarks that do not have all TAGS. +UNMARKP non-nil means unmark; nil means mark. +MSGP means display a status message. + +As a special case, if TAGS is empty, then mark or unmark the bookmarks +that have any tags at all, or if NOTALLP is non-nil then mark or +unmark those that have no tags at all." + (with-current-buffer "*Bookmark List*" + (save-excursion + (let ((count 0) + bmktags presentp) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) + (setq bmktags (bmkp-get-tags (bookmark-bmenu-bookmark))) + (if (not (if (null tags) + (if notallp (not bmktags) bmktags) + (and bmktags (catch 'bmkp-b-mu-b-t-sna + (dolist (tag tags) + (setq presentp (assoc-default tag bmktags nil t)) + (when (if notallp (not presentp) presentp) + (throw 'bmkp-b-mu-b-t-sna t))) + nil)))) + (forward-line 1) + (if unmarkp (bookmark-bmenu-unmark) (bookmark-bmenu-mark)) + (setq count (1+ count)))) + (when msgp + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))))) + +;;;###autoload +(defun bmkp-bmenu-copy-tags (&optional msgp) ; `T c', `T M-w', `mouse-3' menu in bookmark list. + "Copy tags from this bookmark, so you can paste them to another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-copy-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-add-tags (&optional msgp) ; `T p', `T C-y', `mouse-3' menu in bookmark list. + "Add tags to this bookmark that were copied from another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-paste-add-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-replace-tags (&optional msgp) ; `T q', `mouse-3' menu. + "Replace tags for this bookmark with those copied from another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-paste-replace-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-add-tags-to-marked (&optional msgp) ; `T > p', `T > C-y' + "Add tags that were copied from another bookmark to the marked bookmarks." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Adding tags...")) + (dolist (bmk marked) (bmkp-paste-add-tags bmk nil 'NO-CACHE-UPDATE)) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when msgp (message "Tags added: %S" bmkp-copied-tags)))) + +;;;###autoload +(defun bmkp-bmenu-paste-replace-tags-for-marked (&optional msgp) ; `T > q' + "Replace tags for the marked bookmarks with tags copied previously." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Replacing tags...")) + (dolist (bmk marked) (bmkp-paste-replace-tags bmk nil 'NO-CACHE-UPDATE)) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when msgp (message "Replacement tags: %S" bmkp-copied-tags)))) + + +;;(@* "General Menu-List (`-*bmenu-*') Commands and Functions") +;; *** General Menu-List (`-*bmenu-*') Commands and Functions *** + +;;;###autoload +(defun bmkp-bmenu-w32-open () ; Bound to `M-RET' in bookmark list. + "Use `w32-browser' to open this bookmark." + (interactive) (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-this-window))) + +;;;###autoload +(defun bmkp-bmenu-w32-open-with-mouse (event) ; Bound to `M-mouse-2' in bookmark list. + "Use `w32-browser' to open the bookmark clicked." + (interactive "e") + (save-excursion + (with-current-buffer (window-buffer (posn-window (event-end event))) + (save-excursion (goto-char (posn-point (event-end event))) + (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-other-window)))))) + +;;;###autoload +(defun bmkp-bmenu-w32-open-select () ; Bound to `M-o' in bookmark-list. + "Use `w32-browser' to open this bookmark and all marked bookmarks." + (interactive) (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-select))) + +;;;###autoload +(defun bmkp-bmenu-mode-status-help () ; Bound to `C-h m' and `?' in bookmark list + "`describe-mode' + current status of `*Bookmark List*' + face legend." + (interactive) + (unless (string= (buffer-name) "*Help*") (bmkp-bmenu-barf-if-not-in-menu-list)) + (with-current-buffer (get-buffer-create "*Help*") + (with-output-to-temp-buffer "*Help*" + (let ((buffer-read-only nil) + top) + (erase-buffer) + (save-excursion + (let ((standard-output (current-buffer))) + (if (> emacs-major-version 21) + (describe-function-1 'bookmark-bmenu-mode) + (describe-function-1 'bookmark-bmenu-mode nil t))) + (help-setup-xref (list #'bmkp-bmenu-mode-status-help) (interactive-p)) + (goto-char (point-min)) + ;; This text must be the same as the last line of `bookmark-bmenu-mode' doc string. + (search-forward "Each line represents an Emacs bookmark.\n\n\n" nil t) + (delete-region (point-min) (point)) ; Get rid of intro from `describe-function'. + (insert "*************************** Bookmark List ***************************\n\n") + (insert "Major mode for editing a list of bookmarks.\n") + (insert "Each line represents an Emacs bookmark.\n\n") + (setq top (point)) + ;; Add buttons to access help and Customize. + ;; Not for Emacs 21.3 - its `help-insert-xref-button' signature is different. + (when (and (> emacs-major-version 21) ; In `help-mode.el'. + (condition-case nil (require 'help-mode nil t) (error nil)) + (fboundp 'help-insert-xref-button)) + (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button) + (insert " ") + (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button) + (insert " ") + (help-insert-xref-button "[Customize]" 'bmkp-customize-button) + (insert "\n\n") + (setq top (point)) + (goto-char (point-max)) + (insert "\nSend a Bookmark+ bug report: `\\[icicle-send-bug-report]'.\n\n") + (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button) + (insert " ") + (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button) + (insert " ") + (help-insert-xref-button "[Customize]" 'bmkp-customize-button) + (insert "\n\n") + (goto-char (point-min)) + (forward-line 2)) + (goto-char top) + (insert (format + "\nCurrent Status\n-------------------------------\n +Sorted:\t\t%s\nFiltering:\t%s\nMarked:\t\t%d\nOmitted:\t%d\nBookmark file:\t%s\n\n\n" + (if (not bmkp-sort-comparer) + "no" + (format "%s%s" (bmkp-current-sort-order) + ;; Code essentially the same as found in `bmkp-msg-about-sort-order'. + (if (not (and (consp bmkp-sort-comparer) ; Ordinary single predicate + (consp (car bmkp-sort-comparer)))) + (if bmkp-reverse-sort-p "; reversed" "") + (if (not (cadr (car bmkp-sort-comparer))) + ;; Single PRED. + (if (or (and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + (and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p))) + "; reversed" + "") + ;; In case we want to distinguish: + ;; (if (and bmkp-reverse-sort-p + ;; (not bmkp-reverse-multi-sort-p)) + ;; "; reversed" + ;; (if (and bmkp-reverse-multi-sort-p + ;; (not bmkp-reverse-sort-p)) + ;; "; reversed +" + ;; "")) + + ;; At least two PREDs. + (cond ((and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + "; reversed") + ((and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p)) + "; each predicate group reversed") + ((and bmkp-reverse-multi-sort-p bmkp-reverse-sort-p) + "; order of predicate groups reversed") + (t "")))))) + (or (and bmkp-bmenu-filter-function (downcase bmkp-bmenu-title)) "None") + (length bmkp-bmenu-marked-bookmarks) + (length bmkp-bmenu-omitted-bookmarks) + bmkp-current-bookmark-file)) + ;; Add face legend. + (let ((gnus "Gnus\n") + (info "Info node\n") + (man "Man page\n") + (url "URL\n") + (local-no-region "Local file with no region\n") + (local-w-region "Local file with a region\n") + (buffer "Buffer\n") + (no-buf "No current buffer\n") + (bad "Possibly invalid bookmark\n") + (remote "Remote file or directory\n") + (sudo "Remote accessed by `su' or `sudo'\n") + (local-dir "Local directory\n") + (bookmark-list "*Bookmark List*\n") + (bookmark-file "Bookmark file\n") + (desktop "Desktop\n") + (sequence "Sequence\n") + (variable-list "Variable list\n") + (function "Function\n")) + (put-text-property 0 (1- (length gnus)) 'face 'bmkp-gnus gnus) + (put-text-property 0 (1- (length info)) 'face 'bmkp-info info) + (put-text-property 0 (1- (length man)) 'face 'bmkp-man man) + (put-text-property 0 (1- (length url)) 'face 'bmkp-url url) + (put-text-property 0 (1- (length local-no-region)) + 'face 'bmkp-local-file-without-region local-no-region) + (put-text-property 0 (1- (length local-w-region)) + 'face 'bmkp-local-file-with-region local-w-region) + (put-text-property 0 (1- (length buffer)) 'face 'bmkp-buffer buffer) + (put-text-property 0 (1- (length no-buf)) 'face 'bmkp-non-file no-buf) + (put-text-property 0 (1- (length bad)) 'face 'bmkp-bad-bookmark bad) + (put-text-property 0 (1- (length remote)) 'face 'bmkp-remote-file remote) + (put-text-property 0 (1- (length sudo)) 'face 'bmkp-su-or-sudo sudo) + (put-text-property 0 (1- (length local-dir)) + 'face 'bmkp-local-directory local-dir) + (put-text-property 0 (1- (length bookmark-list)) + 'face 'bmkp-bookmark-list bookmark-list) + (put-text-property 0 (1- (length bookmark-file)) + 'face 'bmkp-bookmark-file bookmark-file) + (put-text-property 0 (1- (length desktop)) 'face 'bmkp-desktop desktop) + (put-text-property 0 (1- (length sequence)) 'face 'bmkp-sequence sequence) + (put-text-property 0 (1- (length variable-list)) 'face 'bmkp-variable-list variable-list) + (put-text-property 0 (1- (length function)) 'face 'bmkp-function function) + (insert "Face Legend for Bookmark Types\n------------------------------\n\n") + (insert gnus) (insert info) (insert man) (insert url) (insert local-no-region) + (insert local-w-region) (insert buffer) (insert no-buf) (insert bad) (insert remote) + (insert sudo) (insert local-dir) (insert bookmark-list) (insert bookmark-file) + (insert desktop) (insert sequence) (insert variable-list) (insert function) + (insert "\n\n"))))))) + +(when (and (> emacs-major-version 21) + (condition-case nil (require 'help-mode nil t) (error nil)) + (get 'help-xref 'button-category-symbol)) ; In `button.el' + (define-button-type 'bmkp-help-button + :supertype 'help-xref + 'help-function #'(lambda () (browse-url "http://www.emacswiki.org/emacs/BookmarkPlus")) + 'help-echo + (purecopy "mouse-2, RET: Bookmark+ documentation on the Emacs Wiki (requires Internet access)")) + (define-button-type 'bmkp-commentary-button + :supertype 'help-xref + 'help-function #'(lambda () + (message "Getting Bookmark+ doc from file commentary...") + (finder-commentary "bookmark+-doc") + (when (condition-case nil (require 'linkd nil t) (error nil)) (linkd-mode 1)) + (when (condition-case nil (require 'fit-frame nil t) (error nil)) + (fit-frame))) + 'help-echo (purecopy "mouse-2, RET: Bookmark+ documentation (no Internet needed)")) + (define-button-type 'bmkp-customize-button + :supertype 'help-xref + 'help-function #'(lambda () (customize-group-other-window 'bookmark-plus)) + 'help-echo (purecopy "mouse-2, RET: Customize/Browse Bookmark+ Options & Faces"))) + +;;;###autoload +(defun bmkp-bmenu-define-jump-marked-command () ; Bound to `M-c' in bookmark list + "Define a command to jump to a bookmark that is one of those now marked. +The bookmarks marked now will be those that are completion candidates +for the command (but omitted bookmarks are excluded). +Save the command definition in `bmkp-bmenu-commands-file'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let* ((cands (mapcar #'list + (bmkp-remove-if #'(lambda (bmk) + (bmkp-bookmark-name-member bmk + bmkp-bmenu-omitted-bookmarks)) + bmkp-bmenu-marked-bookmarks))) + (fn (intern (read-string "Define command to jump to a bookmark now marked: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn (bookmark-name &optional use-region-p) + (interactive (list (bmkp-read-bookmark-for-type nil ',cands t) current-prefix-arg)) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +;;;###autoload +(defun bmkp-bmenu-define-command () ; Bound to `c' in bookmark list + "Define a command to use the current sort order, filter, and omit list. +Prompt for the command name. Save the command definition in +`bmkp-bmenu-commands-file'. + +The current sort order, filter function, omit list, and title for +buffer `*Bookmark List*' are encapsulated as part of the command. +Use the command at any time to restore them." + (interactive) + (let* ((fn (intern (read-string "Define sort+filter command: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn () + (interactive) + (setq + bmkp-sort-comparer ',bmkp-sort-comparer + bmkp-reverse-sort-p ',bmkp-reverse-sort-p + bmkp-reverse-multi-sort-p ',bmkp-reverse-multi-sort-p + bmkp-bmenu-filter-function ',bmkp-bmenu-filter-function + bmkp-bmenu-filter-pattern ',bmkp-bmenu-filter-pattern + bmkp-bmenu-omitted-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks) + bmkp-bmenu-title ',bmkp-bmenu-title + bookmark-bmenu-toggle-filenames ',bookmark-bmenu-toggle-filenames) + (bmkp-bmenu-refresh-menu-list) + (when (interactive-p) + (bmkp-msg-about-sort-order + (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist))))))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +;;;###autoload +(defun bmkp-bmenu-define-full-snapshot-command () ; Bound to `C' in bookmark list + "Define a command to restore the current bookmark-list state. +Prompt for the command name. Save the command definition in +`bmkp-bmenu-commands-file'. + +Be aware that the command definition can be quite large, since it +copies the current bookmark list and accessory lists (hidden +bookmarks, marked bookmarks, etc.). For a lighter weight command, use +`bmkp-bmenu-define-full-snapshot-command' instead. That records only +the omit list and the sort & filter information." + (interactive) + (let* ((fn (intern (read-string "Define restore-snapshot command: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn () + (interactive) + (setq + bmkp-sort-comparer ',bmkp-sort-comparer + bmkp-reverse-sort-p ',bmkp-reverse-sort-p + bmkp-reverse-multi-sort-p ',bmkp-reverse-multi-sort-p + bmkp-latest-bookmark-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-latest-bookmark-alist) + bmkp-bmenu-omitted-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks) + bmkp-bmenu-marked-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-marked-bookmarks) + bmkp-bmenu-filter-function ',bmkp-bmenu-filter-function + bmkp-bmenu-filter-pattern ',bmkp-bmenu-filter-pattern + bmkp-bmenu-title ',bmkp-bmenu-title + bmkp-last-bmenu-bookmark ',(and (get-buffer "*Bookmark List*") + (with-current-buffer + (get-buffer "*Bookmark List*") + (bookmark-bmenu-bookmark))) + bmkp-last-specific-buffer ',bmkp-last-specific-buffer + bmkp-last-specific-file ',bmkp-last-specific-file + bookmark-bmenu-toggle-filenames ',bookmark-bmenu-toggle-filenames + bmkp-bmenu-before-hide-marked-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-marked-alist) + bmkp-bmenu-before-hide-unmarked-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-unmarked-alist) + bmkp-last-bookmark-file ',bmkp-last-bookmark-file + bmkp-current-bookmark-file ',bmkp-current-bookmark-file) + ;;(bmkp-bmenu-refresh-menu-list) + (let ((bookmark-alist (or bmkp-latest-bookmark-alist bookmark-alist))) + (bmkp-bmenu-list-1 'filteredp nil (interactive-p))) + (when bmkp-last-bmenu-bookmark + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark))) + (when (interactive-p) + (bmkp-msg-about-sort-order + (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist))))))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil) + (print-circle t)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +(defun bmkp-maybe-unpropertize-bookmark-names (list) + "Strip properties from the bookmark names in a copy of LIST. +LIST is a bookmark alist or a list of bookmark names (strings). +Return the updated copy. + +Note, however, that this is a shallow copy, so the names are also +stripped within any alist elements of the original LIST. + +We do this because Emacs 20 has no `print-circle'. and otherwise +property `bmkp-full-record' would make the state file unreadable. + +Do nothing in Emacs 21 or later or if +`bmkp-propertize-bookmark-names-flag' is nil. In these cases, just +return the list." + (if (and (> emacs-major-version 20) ; Emacs 21+. Cannot just use (boundp 'print-circle). + bmkp-propertize-bookmark-names-flag) + list + (let ((new-list (copy-sequence list))) + (dolist (bmk new-list) + (when (and (consp bmk) (stringp (car bmk))) (setq bmk (car bmk))) + (when (stringp bmk) (set-text-properties 0 (length bmk) nil bmk))) + new-list))) + +;; This is a general command. It is in this file because it uses macro `bmkp-define-sort-command' +;; and it is used mainly in the bookmark list display. +;;;###autoload +(defun bmkp-define-tags-sort-command (tags &optional msgp) ; Bound to `T s' in bookmark list + "Define a command to sort bookmarks in the bookmark list by tags. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. + +The new command sorts first by the first tag in TAGS, then by the +second, and so on. + +Besides sorting for these specific tags, any bookmark that has a tag +sorts before one that has no tags. Otherwise, sorting is by bookmark +name, alphabetically. + +The name of the new command is `bmkp-bmenu-sort-' followed by the +specified tags, in order, separated by hyphens (`-'). E.g., for TAGS +\(\"alpha\" \"beta\"), the name is `bmkp-bmenu-sort-alpha-beta'." + (interactive (list (bmkp-read-tags-completing) 'msg)) + (let ((sort-order (concat "tags-" (mapconcat #'identity tags "-"))) + (doc-string (read-string "Doc string for command: ")) + (comparer ()) + def) + (dolist (tag tags) + (push `(lambda (b1 b2) + (let ((tags1 (bmkp-get-tags b1)) + (tags2 (bmkp-get-tags b2))) + (cond ((and (assoc-default ,tag tags1 nil t) + (assoc-default ,tag tags2 nil t)) nil) + ((assoc-default ,tag tags1 nil t) '(t)) + ((assoc-default ,tag tags2 nil t) '(nil)) + ((and tags1 tags2) nil) + (tags1 '(t)) + (tags2 '(nil)) + (t nil)))) + comparer)) + (setq comparer (nreverse comparer) + comparer (list comparer 'bmkp-alpha-p)) + (eval (setq def (macroexpand `(bmkp-define-sort-command ,sort-order ,comparer ,doc-string)))) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (when msgp (message "Defined and saved command `%s'" + (concat "bmkp-bmenu-sort-" sort-order))))) + +;;;###autoload +(defun bmkp-bmenu-edit-bookmark (&optional internalp) ; Bound to `E' in bookmark list + "Edit the bookmark under the cursor: its name and file name. +With a prefix argument, edit the complete bookmark record (the +internal, Lisp form)." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bmk-name (bookmark-bmenu-bookmark))) + (if internalp + (bmkp-edit-bookmark-record bmk-name) + (let* ((new-data (bmkp-edit-bookmark bmk-name)) + (new-name (car new-data))) + (if (not new-data) + (message "No changes made") + (bmkp-refresh-menu-list new-name)))))) + +;;;###autoload +(defun bmkp-bmenu-edit-tags () ; Bound to `T e' in bookmark list + "Edit the tags of the bookmark under the cursor. +The edited value must be a list each of whose elements is either a +string or a cons whose key is a string." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-edit-tags (bookmark-bmenu-bookmark))) + +(defun bmkp-bmenu-propertize-item (bookmark start end) + "Propertize buffer from START to END, indicating bookmark types. +This propertizes the name of BOOKMARK. +Also give this region the property `bmkp-bookmark-name' with as value +the name of BOOKMARK as a propertized string. + +The propertized string has property `bmkp-full-record' with value +BOOKMARK, which is the full bookmark record, with the string as its +car. + +Return the propertized string (the bookmark name)." + (setq bookmark (bookmark-get-bookmark bookmark)) + (let* ((bookmark-name (bookmark-name-from-full-record bookmark)) + (buffp (bmkp-get-buffer-name bookmark)) + + (filep (bookmark-get-filename bookmark)) + (sudop (and filep (boundp 'tramp-file-name-regexp) + (string-match tramp-file-name-regexp filep) + (string-match bmkp-su-or-sudo-regexp filep)))) + ;; Put the full bookmark itself on string `bookmark-name' as property `bmkp-full-record'. + ;; Then put that string on the name in the buffer text as property `bmkp-bookmark-name'. + (put-text-property 0 (length bookmark-name) 'bmkp-full-record bookmark bookmark-name) + (put-text-property start end 'bmkp-bookmark-name bookmark-name) + ;; Add faces, mouse face, and tooltips, to characterize the bookmark type. + (add-text-properties + start end + (cond ((bmkp-sequence-bookmark-p bookmark) ; Sequence bookmark + (append (bmkp-face-prop 'bmkp-sequence) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke the bookmarks in this sequence"))) + ((bmkp-function-bookmark-p bookmark) ; Function bookmark + (append (bmkp-face-prop 'bmkp-function) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this function bookmark"))) + ((bmkp-variable-list-bookmark-p bookmark) ; Variable-list bookmark + (append (bmkp-face-prop 'bmkp-variable-list) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this variable-list bookmark"))) + ((bmkp-bookmark-list-bookmark-p bookmark) ; Bookmark-list bookmark + (append (bmkp-face-prop 'bmkp-bookmark-list) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this bookmark-list bookmark"))) + ((bmkp-desktop-bookmark-p bookmark) ; Desktop bookmark + (append (bmkp-face-prop 'bmkp-desktop) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this desktop bookmark"))) + ((bmkp-bookmark-file-bookmark-p bookmark) ; Bookmark-file bookmark + (append (bmkp-face-prop 'bmkp-bookmark-file) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Load this bookmark's bookmark file"))) + ((bmkp-info-bookmark-p bookmark) ; Info bookmark + (append (bmkp-face-prop 'bmkp-info) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this Info bookmark"))) + ((bmkp-man-bookmark-p bookmark) ; Man bookmark + (append (bmkp-face-prop 'bmkp-man) + '(mouse-face highlight follow-link t + help-echo (format "mouse-2 Goto `man' page")))) + ((bmkp-gnus-bookmark-p bookmark) ; Gnus bookmark + (append (bmkp-face-prop 'bmkp-gnus) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this Gnus bookmark"))) + ((bmkp-url-bookmark-p bookmark) ; URL bookmark + (append (bmkp-face-prop 'bmkp-url) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to URL `%s'" ,filep)))) + ((and sudop (not (bmkp-root-or-sudo-logged-p))) ; Root/sudo not logged in + (append (bmkp-face-prop 'bmkp-su-or-sudo) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep)))) + ;; Test for remoteness before any other tests of the file itself + ;; (e.g. `file-exists-p'), so we don't prompt for a password etc. + ((and filep (bmkp-file-remote-p filep) (not sudop)) ; Remote file (ssh, ftp) + (append (bmkp-face-prop 'bmkp-remote-file) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) remote file `%s'" ,filep)))) + ((and filep (file-directory-p filep)) ; Local directory + (append (bmkp-face-prop 'bmkp-local-directory) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Dired directory `%s'" ,filep)))) + ((and filep (file-exists-p filep) ; Local file with region + (bmkp-region-bookmark-p bookmark)) + (append (bmkp-face-prop 'bmkp-local-file-with-region) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Activate region in file `%s'" ,filep)))) + ((and filep (file-exists-p filep)) ; Local file without region + (append (bmkp-face-prop 'bmkp-local-file-without-region) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep)))) + ((and buffp (get-buffer buffp) (equal filep bmkp-non-file-filename)) ; Buffer + (append (bmkp-face-prop 'bmkp-buffer) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to buffer `%s'" ,buffp)))) + ((and buffp (or (not filep) (equal filep bmkp-non-file-filename) + (not (file-exists-p filep)))) ; Buffer bookmark, but no buffer. + (append (bmkp-face-prop 'bmkp-non-file) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to buffer `%s'" ,buffp)))) + (t (append (bmkp-face-prop 'bmkp-bad-bookmark) + `(mouse-face highlight follow-link t + help-echo (format "BAD BOOKMARK (maybe): `%s'" ,filep)))))) + bookmark-name)) + +;;;###autoload +(defun bmkp-bmenu-quit () ; Bound to `q' in bookmark list + "Quit the bookmark list (aka \"menu list\"). +If `bmkp-bmenu-state-file' is non-nil, then save the state, to be +restored the next time the bookmark list is shown. Otherwise, reset +the internal lists that record menu-list markings." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (not bmkp-bmenu-state-file) + (setq bmkp-bmenu-marked-bookmarks () + bmkp-bmenu-before-hide-marked-alist () + bmkp-bmenu-before-hide-unmarked-alist ()) + (bmkp-save-menu-list-state) + (setq bmkp-bmenu-first-time-p t)) + (quit-window)) + +(defun bmkp-bmenu-goto-bookmark-named (name) + "Go to the first bookmark whose name matches NAME (a string). +If NAME has non-nil property `bmkp-full-record' then go to the +bookmark it indicates. Otherwise, just go to the first bookmark with +the same name." + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((full (get-text-property 0 'bmkp-full-record name))) + (while (and (not (eobp)) + (not (if full + (equal full (get-text-property 0 'bmkp-full-record (bookmark-bmenu-bookmark))) + (equal name (bookmark-bmenu-bookmark))))) + (forward-line 1))) + (bookmark-bmenu-ensure-position)) ; Just in case we fall off the end. + +;; This is a general function. It is in this file because it is used only by the bmenu code. +(defun bmkp-bmenu-barf-if-not-in-menu-list () + "Raise an error if current buffer is not `*Bookmark List*'." + (unless (equal (buffer-name (current-buffer)) "*Bookmark List*") + (error "You can only use this command in buffer `*Bookmark List*'"))) + + +;;(@* "Sorting - Commands") +;; *** Sorting - Commands *** + +;;;###autoload +(defun bmkp-bmenu-change-sort-order-repeat (arg) ; Bound to `s s'... in bookmark list + "Cycle to the next sort order. +With a prefix arg, reverse current sort order. +This is a repeatable version of `bmkp-bmenu-change-sort-order'." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-bmenu-change-sort-order)) + +;;;###autoload +(defun bmkp-bmenu-change-sort-order (&optional arg) + "Cycle to the next sort order. +With a prefix arg, reverse the current sort order." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-sort-orders-for-cycling-alist (delq nil bmkp-sort-orders-for-cycling-alist)) + (if arg + (bmkp-reverse-sort-order) + (let ((current-bmk (bookmark-bmenu-bookmark)) + next-order) + (let ((orders (mapcar #'car bmkp-sort-orders-for-cycling-alist))) + (setq next-order (or (cadr (member (bmkp-current-sort-order) orders)) (car orders)) + bmkp-sort-comparer (cdr (assoc next-order bmkp-sort-orders-for-cycling-alist)))) + (message "Sorting...") + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk)) + (when (interactive-p) (bmkp-msg-about-sort-order next-order))))) + +;; This is a general command. It is in this file because it is used only by the bmenu code. +;;;###autoload +(defun bmkp-reverse-sort-order () ; Bound to `s r' in bookmark list + "Reverse the current bookmark sort order. +If you combine this with \\\ +`\\[bmkp-reverse-multi-sort-order]', then see the doc for that command." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-reverse-sort-p (not bmkp-reverse-sort-p)) + (let ((current-bmk (bookmark-bmenu-bookmark))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk))) + (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + +;; This is a general command. It is in this file because it is used only by the bmenu code. +;;;###autoload +(defun bmkp-reverse-multi-sort-order () ; Bound to `s C-r' in bookmark list + "Reverse the application of multi-sorting predicates. +These are the PRED predicates described for option +`bmkp-sort-comparer'. + +This reverses the order in which the predicates are tried, and it +also complements the truth value returned by each predicate. + +For example, if the list of multi-sorting predicates is (p1 p2 p3), +then the predicates are tried in the order: p3, p2, p1. And if a +predicate returns true, `(t)', then the effect is as if it returned +false, `(nil)', and vice versa. + +The use of multi-sorting predicates tends to group bookmarks, with the +first predicate corresponding to the first bookmark group etc. + +The effect of \\`\\[bmkp-reverse-multi-sort-order]' is \ +roughly as follows: + + - without also `\\[bmkp-reverse-sort-order]', it reverses the bookmark order in each \ +group + + - combined with `\\[bmkp-reverse-sort-order]', it reverses the order of the bookmark + groups, but not the bookmarks within a group + +This is a rough description. The actual behavior can be complex, +because of how each predicate is defined. If this description helps +you, fine. If not, just experiment and see what happens. \;-) + +Remember that ordinary `\\[bmkp-reverse-sort-order]' reversal on its own is \ +straightforward. +If you find `\\[bmkp-reverse-multi-sort-order]' confusing or not helpful, then do not \ +use it." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-reverse-multi-sort-p (not bmkp-reverse-multi-sort-p)) + (let ((current-bmk (bookmark-bmenu-bookmark))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk))) + (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + + + +;; The ORDER of the macro calls here defines the REVERSE ORDER of +;; `bmkp-sort-orders-alist'. The first here is thus also the DEFAULT sort order. +;; Entries are traversed by `s s'..., in `bmkp-sort-orders-alist' order. + +(bmkp-define-sort-command ; Bound to `s k' in bookmark list (`k' for "kind") + "by bookmark type" ; `bmkp-bmenu-sort-by-bookmark-type' + ((bmkp-info-cp bmkp-url-cp bmkp-gnus-cp bmkp-local-file-type-cp bmkp-handler-cp) + bmkp-alpha-p) + "Sort bookmarks by type: Info, URL, Gnus, files, other.") + +(bmkp-define-sort-command ; Bound to `s u' in bookmark list + "by url" ; `bmkp-bmenu-sort-by-url' + ((bmkp-url-cp) bmkp-alpha-p) + "Sort URL bookmarks alphabetically by their URL/filename. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +;; $$$$$$ Not used now. +;; (bmkp-define-sort-command ; Bound to `s w' in bookmark list +;; "by w3m url" ; `bmkp-bmenu-sort-by-w3m-url' +;; ((bmkp-w3m-cp) bmkp-alpha-p) +;; "Sort W3M bookmarks alphabetically by their URL/filename. +;; When two bookmarks are not comparable this way, compare them by +;; bookmark name.") + +(bmkp-define-sort-command ; Bound to `s g' in bookmark list + "by Gnus thread" ; `bmkp-bmenu-sort-by-Gnus-thread' + ((bmkp-gnus-cp) bmkp-alpha-p) + "Sort Gnus bookmarks by group, then by article, then by message. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s i' in bookmark list + "by Info location" ; `bmkp-bmenu-sort-by-Info-location' + ((bmkp-info-cp) bmkp-alpha-p) + "Sort Info bookmarks by file name, then node name, then position. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f u' in bookmark list + "by last local file update" ; `bmkp-bmenu-sort-by-last-local-file-update' + ((bmkp-local-file-updated-more-recently-cp) bmkp-alpha-p) + "Sort bookmarks by last local file update time. +Sort a local file before a remote file, and a remote file before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f t' in bookmark list + "by last local file access" ; `bmkp-bmenu-sort-by-last-local-file-access' + ((bmkp-local-file-accessed-more-recently-cp) bmkp-alpha-p) + "Sort bookmarks by last local file access time. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f s' in bookmark list + "by local file size" ; `bmkp-bmenu-sort-by-local-file-size' + ((bmkp-local-file-size-cp) bmkp-alpha-p) + "Sort bookmarks by local file size. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f n' in bookmark list + "by file name" ; `bmkp-bmenu-sort-by-file-name' + ((bmkp-file-alpha-cp) bmkp-alpha-p) + "Sort bookmarks by file name. +When two bookmarks are not comparable by file name, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f d' in bookmark list (`d' for "directory") + "by local file type" ; `bmkp-bmenu-sort-by-local-file-type' + ((bmkp-local-file-type-cp) bmkp-alpha-p) + "Sort bookmarks by local file type: file, symlink, directory. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s >' in bookmark list + "marked before unmarked" ; `bmkp-bmenu-sort-marked-before-unmarked' + ((bmkp-marked-cp) bmkp-alpha-p) + "Sort bookmarks by putting marked before unmarked. +Otherwise alphabetize by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s b' in bookmark list + "by last buffer or file access" ; `bmkp-bmenu-sort-by-last-buffer-or-file-access' + ((bmkp-buffer-last-access-cp bmkp-local-file-accessed-more-recently-cp) + bmkp-alpha-p) + "Sort bookmarks by last buffer access or last local file access. +Sort a bookmark accessed more recently before one accessed less +recently or not accessed. Sort a bookmark to an existing buffer +before a local file bookmark. When two bookmarks are not comparable +by such critera, sort them by bookmark name. (In particular, sort +remote-file bookmarks by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s v' in bookmark list + "by bookmark visit frequency" ; `bmkp-bmenu-sort-by-bookmark-visit-frequency' + ((bmkp-visited-more-cp) bmkp-alpha-p) + "Sort bookmarks by the number of times they were visited as bookmarks. +When two bookmarks are not comparable by visit frequency, compare them +by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s t' in bookmark list + "by last bookmark access" ; `bmkp-bmenu-sort-by-last-bookmark-access' + ((bmkp-bookmark-last-access-cp) bmkp-alpha-p) + "Sort bookmarks by the time of their last visit as bookmarks. +When two bookmarks are not comparable by visit time, compare them +by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s 0' in bookmark list + "by creation time" ; `bmkp-bmenu-sort-by-creation-time' + ((bmkp-bookmark-creation-cp) bmkp-alpha-p) + "Sort bookmarks by the time of their creation. +When one or both of the bookmarks does not have a `created' entry), +compare them by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s n' in bookmark list + "by bookmark name" ; `bmkp-bmenu-sort-by-bookmark-name' + bmkp-alpha-p + "Sort bookmarks by bookmark name, respecting `case-fold-search'.") + +;; This is a general option. It is in this file because it is used mainly by the bmenu code. +;; Its definitions MUST COME AFTER the calls to macro `bmkp-define-sort-command'. +;; Otherwise, they won't pick up a populated `bmkp-sort-orders-alist'. +(when (> emacs-major-version 20) + (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist) + "*Alist of sort orders used for cycling via `s s'... +This is a subset of the complete list of available sort orders, +`bmkp-sort-orders-alist'. This lets you cycle among fewer sort +orders, if there are some that you do not use often. + +See the doc for `bmkp-sort-orders-alist', for the structure of +this value." + :type '(alist + :key-type (choice :tag "Sort order" string symbol) + :value-type (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate"))))) + :group 'bookmark-plus)) + +(unless (> emacs-major-version 20) ; Emacs 20: custom type `alist' doesn't exist. + (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist) + "*Alist of sort orders used for cycling via `s s'... +This is a subset of the complete list of available sort orders, +`bmkp-sort-orders-alist'. This lets you cycle among fewer sort +orders, if there are some that you do not use often. + +See the doc for `bmkp-sort-orders-alist', for the structure of this +value." + :type '(repeat + (cons + (choice :tag "Sort order" string symbol) + (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))))) + :group 'bookmark-plus)) + + +;;(@* "Other Bookmark+ Functions (`bmkp-*')") +;; *** Other Bookmark+ Functions (`bmkp-*') *** + +;;;###autoload +(defun bmkp-bmenu-describe-this+move-down (&optional defn) ; Bound to `C-down' in bookmark list + "Describe bookmark of current line, then move down to the next bookmark. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-describe-this-bookmark) (forward-line 1)) + +;;;###autoload +(defun bmkp-bmenu-describe-this+move-up (&optional defn) ; Bound to `C-up' in bookmark list + "Describe bookmark of current line, then move down to the next bookmark. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-describe-this-bookmark) (forward-line -1)) + +;;;###autoload +(defun bmkp-bmenu-describe-this-bookmark (&optional defn) ; Bound to `C-h RET' in bookmark list + "Describe bookmark of current line. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (if defn + (bmkp-describe-bookmark-internals (bookmark-bmenu-bookmark)) + (bmkp-describe-bookmark (bookmark-bmenu-bookmark)))) + +;;;###autoload +(defun bmkp-bmenu-describe-marked (&optional defn) ; Bound to `C-h >' in bookmark list + "Describe the marked bookmarks. +With a prefix argument, show the internal definitions." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (help-setup-xref (list #'bmkp-describe-bookmark-marked) (interactive-p)) + (with-output-to-temp-buffer "*Help*" + (dolist (bmk (bmkp-marked-bookmarks-only)) + (if defn + (let* ((bname (bookmark-name-from-full-record bmk)) + (help-text (format "%s\n%s\n\n%s" bname (make-string (length bname) ?-) + (pp-to-string bmk)))) + (princ help-text) (terpri)) + (princ (bmkp-bookmark-description bmk)) (terpri))))) + +(defun bmkp-bmenu-get-marked-files () + "Return a list of the file names of the marked bookmarks. +Marked bookmarks that have no associated file are ignored." + (let ((files ())) + (dolist (bmk bmkp-bmenu-marked-bookmarks) + (when (bmkp-file-bookmark-p bmk) (push (bookmark-get-filename bmk) files))) + files)) + +;;(@* "Keymaps") +;;; Keymaps ---------------------------------------------------------- + +;; `bookmark-bmenu-mode-map' + +(when (< emacs-major-version 21) + (define-key bookmark-bmenu-mode-map (kbd "RET") 'bookmark-bmenu-this-window)) +(define-key bookmark-bmenu-mode-map "." 'bmkp-bmenu-show-all) +(define-key bookmark-bmenu-mode-map ">" 'bmkp-bmenu-toggle-show-only-marked) +(define-key bookmark-bmenu-mode-map "<" 'bmkp-bmenu-toggle-show-only-unmarked) +(define-key bookmark-bmenu-mode-map (kbd "M-") 'bmkp-bmenu-unmark-all) +(define-key bookmark-bmenu-mode-map "=" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "=bM" 'bmkp-bmenu-mark-specific-buffer-bookmarks) +(define-key bookmark-bmenu-mode-map "=fM" 'bmkp-bmenu-mark-specific-file-bookmarks) +(define-key bookmark-bmenu-mode-map "=bS" 'bmkp-bmenu-show-only-specific-buffer) +(define-key bookmark-bmenu-mode-map "=fS" 'bmkp-bmenu-show-only-specific-file) +(define-key bookmark-bmenu-mode-map "%" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "%m" 'bmkp-bmenu-regexp-mark) +(define-key bookmark-bmenu-mode-map "*" nil) ; For Emacs 20 +(when (< emacs-major-version 21) + (define-key bookmark-bmenu-mode-map "*m" 'bookmark-bmenu-mark)) +(define-key bookmark-bmenu-mode-map "#" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "#S" 'bmkp-bmenu-show-only-autonamed) +;; `A' is `bookmark-bmenu-show-all-annotations' in vanilla Emacs. +(define-key bookmark-bmenu-mode-map "\M-a" 'bookmark-bmenu-show-all-annotations) +(define-key bookmark-bmenu-mode-map "A" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "AM" 'bmkp-bmenu-mark-autofile-bookmarks) +(define-key bookmark-bmenu-mode-map "AS" 'bmkp-bmenu-show-only-autofiles) +(define-key bookmark-bmenu-mode-map "B" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "BM" 'bmkp-bmenu-mark-non-file-bookmarks) +(define-key bookmark-bmenu-mode-map "BS" 'bmkp-bmenu-show-only-non-files) +(define-key bookmark-bmenu-mode-map "c" 'bmkp-bmenu-define-command) +(define-key bookmark-bmenu-mode-map "C" 'bmkp-bmenu-define-full-snapshot-command) +(define-key bookmark-bmenu-mode-map "\M-c" 'bmkp-bmenu-define-jump-marked-command) +(define-key bookmark-bmenu-mode-map "D" 'bmkp-bmenu-delete-marked) +(define-key bookmark-bmenu-mode-map "\M-d" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "\M-d>" 'bmkp-bmenu-dired-marked) +(define-key bookmark-bmenu-mode-map "\M-d\M-m" 'bmkp-bmenu-mark-dired-bookmarks) +(define-key bookmark-bmenu-mode-map "\M-d\M-s" 'bmkp-bmenu-show-only-dired) +(define-key bookmark-bmenu-mode-map "E" 'bmkp-bmenu-edit-bookmark) +(define-key bookmark-bmenu-mode-map "F" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "FM" 'bmkp-bmenu-mark-file-bookmarks) +(define-key bookmark-bmenu-mode-map "FS" 'bmkp-bmenu-show-only-files) +(define-key bookmark-bmenu-mode-map "g" 'bmkp-bmenu-refresh-menu-list) +(define-key bookmark-bmenu-mode-map "G" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "GM" 'bmkp-bmenu-mark-gnus-bookmarks) +(define-key bookmark-bmenu-mode-map "GS" 'bmkp-bmenu-show-only-gnus) +(if (fboundp 'command-remapping) + (define-key bookmark-bmenu-mode-map [remap describe-mode] 'bmkp-bmenu-mode-status-help) + ;; In Emacs < 22, the `substitute-...' affects only `?', not `C-h m', so we add it separately. + (substitute-key-definition 'describe-mode 'bmkp-bmenu-mode-status-help bookmark-bmenu-mode-map) + (define-key bookmark-bmenu-mode-map "\C-hm" 'bmkp-bmenu-mode-status-help)) +(define-key bookmark-bmenu-mode-map (kbd "C-h >") 'bmkp-bmenu-describe-marked) +(define-key bookmark-bmenu-mode-map (kbd "C-h RET") 'bmkp-bmenu-describe-this-bookmark) +(define-key bookmark-bmenu-mode-map (kbd "C-h C-") 'bmkp-bmenu-describe-this-bookmark) +(define-key bookmark-bmenu-mode-map (kbd "C-") 'bmkp-bmenu-describe-this+move-down) +(define-key bookmark-bmenu-mode-map (kbd "C-") 'bmkp-bmenu-describe-this+move-up) +(define-key bookmark-bmenu-mode-map (kbd "M-") 'bmkp-bmenu-w32-open) +(define-key bookmark-bmenu-mode-map [M-mouse-2] 'bmkp-bmenu-w32-open-with-mouse) +(when (featurep 'bookmark+-lit) + (define-key bookmark-bmenu-mode-map "H" nil) ; For Emacs 20 + (define-key bookmark-bmenu-mode-map "H+" 'bmkp-bmenu-set-lighting) + (define-key bookmark-bmenu-mode-map "H>+" 'bmkp-bmenu-set-lighting-for-marked) + (define-key bookmark-bmenu-mode-map "H>H" 'bmkp-bmenu-light-marked) + (define-key bookmark-bmenu-mode-map "HH" 'bmkp-bmenu-light) + (define-key bookmark-bmenu-mode-map "HM" 'bmkp-bmenu-mark-lighted-bookmarks) + (define-key bookmark-bmenu-mode-map "HS" 'bmkp-bmenu-show-only-lighted) + (define-key bookmark-bmenu-mode-map "H>U" 'bmkp-bmenu-unlight-marked) + (define-key bookmark-bmenu-mode-map "HU" 'bmkp-bmenu-unlight)) +(define-key bookmark-bmenu-mode-map "I" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "IM" 'bmkp-bmenu-mark-info-bookmarks) +(define-key bookmark-bmenu-mode-map "IS" 'bmkp-bmenu-show-only-info-nodes) +(define-key bookmark-bmenu-mode-map "K" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "KM" 'bmkp-bmenu-mark-desktop-bookmarks) +(define-key bookmark-bmenu-mode-map "KS" 'bmkp-bmenu-show-only-desktops) +(define-key bookmark-bmenu-mode-map "L" 'bmkp-switch-bookmark-file) +(define-key bookmark-bmenu-mode-map "M" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "MM" 'bmkp-bmenu-mark-man-bookmarks) +(define-key bookmark-bmenu-mode-map "MS" 'bmkp-bmenu-show-only-man-pages) +(define-key bookmark-bmenu-mode-map "\M-m" 'bmkp-bmenu-mark-all) +(define-key bookmark-bmenu-mode-map "O" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "O>" 'bmkp-bmenu-omit/unomit-marked) +(define-key bookmark-bmenu-mode-map "OS" 'bmkp-bmenu-show-only-omitted) +(define-key bookmark-bmenu-mode-map "OU" 'bmkp-unomit-all) +(define-key bookmark-bmenu-mode-map "P" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "PA" 'bmkp-bmenu-filter-annotation-incrementally) +(define-key bookmark-bmenu-mode-map "PB" 'bmkp-bmenu-filter-bookmark-name-incrementally) +(define-key bookmark-bmenu-mode-map "PF" 'bmkp-bmenu-filter-file-name-incrementally) +(define-key bookmark-bmenu-mode-map "PT" 'bmkp-bmenu-filter-tags-incrementally) +(define-key bookmark-bmenu-mode-map "q" 'bmkp-bmenu-quit) +(define-key bookmark-bmenu-mode-map "\M-q" 'bmkp-bmenu-query-replace-marked-bookmarks-regexp) +(define-key bookmark-bmenu-mode-map "R" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "RM" 'bmkp-bmenu-mark-region-bookmarks) +(define-key bookmark-bmenu-mode-map "RS" 'bmkp-bmenu-show-only-regions) +(define-key bookmark-bmenu-mode-map "\M-r" 'bookmark-bmenu-relocate) ; `R' in Emacs +(define-key bookmark-bmenu-mode-map "S" 'bookmark-bmenu-save) ; `s' in Emacs +(define-key bookmark-bmenu-mode-map "s" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "s>" 'bmkp-bmenu-sort-marked-before-unmarked) +(define-key bookmark-bmenu-mode-map "s0" 'bmkp-bmenu-sort-by-creation-time) +(define-key bookmark-bmenu-mode-map "sb" 'bmkp-bmenu-sort-by-last-buffer-or-file-access) +(define-key bookmark-bmenu-mode-map "sfd" 'bmkp-bmenu-sort-by-local-file-type) +(define-key bookmark-bmenu-mode-map "sfn" 'bmkp-bmenu-sort-by-file-name) +(define-key bookmark-bmenu-mode-map "sfs" 'bmkp-bmenu-sort-by-local-file-size) +(define-key bookmark-bmenu-mode-map "sft" 'bmkp-bmenu-sort-by-last-local-file-access) +(define-key bookmark-bmenu-mode-map "sfu" 'bmkp-bmenu-sort-by-last-local-file-update) +(define-key bookmark-bmenu-mode-map "sg" 'bmkp-bmenu-sort-by-Gnus-thread) +(define-key bookmark-bmenu-mode-map "si" 'bmkp-bmenu-sort-by-Info-location) +(define-key bookmark-bmenu-mode-map "sk" 'bmkp-bmenu-sort-by-bookmark-type) +(define-key bookmark-bmenu-mode-map "sn" 'bmkp-bmenu-sort-by-bookmark-name) +(define-key bookmark-bmenu-mode-map "sr" 'bmkp-reverse-sort-order) +(define-key bookmark-bmenu-mode-map "s\C-r" 'bmkp-reverse-multi-sort-order) +(define-key bookmark-bmenu-mode-map "ss" 'bmkp-bmenu-change-sort-order-repeat) +(define-key bookmark-bmenu-mode-map "st" 'bmkp-bmenu-sort-by-last-bookmark-access) +(define-key bookmark-bmenu-mode-map "su" 'bmkp-bmenu-sort-by-url) +(define-key bookmark-bmenu-mode-map "sv" 'bmkp-bmenu-sort-by-bookmark-visit-frequency) +;; ;; (define-key bookmark-bmenu-mode-map "sw" 'bmkp-bmenu-sort-by-w3m-url) +(when (> emacs-major-version 22) ; Emacs 23+ + (define-key bookmark-bmenu-mode-map (kbd "M-s a C-s") 'bmkp-bmenu-isearch-marked-bookmarks) + (define-key bookmark-bmenu-mode-map (kbd "M-s a M-C-s") 'bmkp-bmenu-isearch-marked-bookmarks-regexp)) +(define-key bookmark-bmenu-mode-map (kbd "M-s a M-s") 'bmkp-bmenu-search-marked-bookmarks-regexp) +(define-key bookmark-bmenu-mode-map "T" nil) ; For Emacs20 +(define-key bookmark-bmenu-mode-map "T>+" 'bmkp-bmenu-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T>-" 'bmkp-bmenu-remove-tags-from-marked) +(define-key bookmark-bmenu-mode-map "T>p" 'bmkp-bmenu-paste-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T>q" 'bmkp-bmenu-paste-replace-tags-for-marked) +(define-key bookmark-bmenu-mode-map "T>v" 'bmkp-bmenu-set-tag-value-for-marked) +(define-key bookmark-bmenu-mode-map "T>\C-y" 'bmkp-bmenu-paste-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T0" 'bmkp-remove-all-tags) +(define-key bookmark-bmenu-mode-map "T+" 'bmkp-add-tags) +(define-key bookmark-bmenu-mode-map "T-" 'bmkp-remove-tags) +(define-key bookmark-bmenu-mode-map "Tc" 'bmkp-bmenu-copy-tags) +(define-key bookmark-bmenu-mode-map "Td" 'bmkp-remove-tags-from-all) +(define-key bookmark-bmenu-mode-map "Te" 'bmkp-bmenu-edit-tags) +(define-key bookmark-bmenu-mode-map "Tl" 'bmkp-list-all-tags) +(define-key bookmark-bmenu-mode-map "Tm*" 'bmkp-bmenu-mark-bookmarks-tagged-all) +(define-key bookmark-bmenu-mode-map "Tm%" 'bmkp-bmenu-mark-bookmarks-tagged-regexp) +(define-key bookmark-bmenu-mode-map "Tm+" 'bmkp-bmenu-mark-bookmarks-tagged-some) +(define-key bookmark-bmenu-mode-map "Tm~*" 'bmkp-bmenu-mark-bookmarks-tagged-not-all) +(define-key bookmark-bmenu-mode-map "Tm~+" 'bmkp-bmenu-mark-bookmarks-tagged-none) +(define-key bookmark-bmenu-mode-map "Tp" 'bmkp-bmenu-paste-add-tags) +(define-key bookmark-bmenu-mode-map "Tq" 'bmkp-bmenu-paste-replace-tags) +(define-key bookmark-bmenu-mode-map "Tr" 'bmkp-rename-tag) +(define-key bookmark-bmenu-mode-map "Ts" 'bmkp-define-tags-sort-command) +(define-key bookmark-bmenu-mode-map "TS" 'bmkp-bmenu-show-only-tagged) +(define-key bookmark-bmenu-mode-map "Tu*" 'bmkp-bmenu-unmark-bookmarks-tagged-all) +(define-key bookmark-bmenu-mode-map "Tu%" 'bmkp-bmenu-unmark-bookmarks-tagged-regexp) +(define-key bookmark-bmenu-mode-map "Tu+" 'bmkp-bmenu-unmark-bookmarks-tagged-some) +(define-key bookmark-bmenu-mode-map "Tu~*" 'bmkp-bmenu-unmark-bookmarks-tagged-not-all) +(define-key bookmark-bmenu-mode-map "Tu~+" 'bmkp-bmenu-unmark-bookmarks-tagged-none) +(define-key bookmark-bmenu-mode-map "Tv" 'bmkp-bmenu-set-tag-value) +(define-key bookmark-bmenu-mode-map "T\M-w" 'bmkp-bmenu-copy-tags) +(define-key bookmark-bmenu-mode-map "T\C-y" 'bmkp-bmenu-paste-add-tags) +(define-key bookmark-bmenu-mode-map "\M-l" 'bmkp-toggle-saving-menu-list-state) +(define-key bookmark-bmenu-mode-map "\M-~" 'bmkp-toggle-saving-bookmark-file) +(define-key bookmark-bmenu-mode-map "\M-t" 'bookmark-bmenu-toggle-filenames) ; `t' in Emacs +(define-key bookmark-bmenu-mode-map "t" 'bmkp-bmenu-toggle-marks) +(define-key bookmark-bmenu-mode-map "U" 'bmkp-bmenu-unmark-all) +(define-key bookmark-bmenu-mode-map "\M-u" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "\M-u\M-m" 'bmkp-bmenu-mark-url-bookmarks) +(define-key bookmark-bmenu-mode-map "\M-u\M-s" 'bmkp-bmenu-show-only-urls) +(define-key bookmark-bmenu-mode-map "V" nil) ; For Emacs20 +(define-key bookmark-bmenu-mode-map "VS" 'bmkp-bmenu-show-only-variable-lists) +(define-key bookmark-bmenu-mode-map "\M-o" 'bmkp-bmenu-w32-open-select) +(define-key bookmark-bmenu-mode-map "W" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "WM" 'bmkp-bmenu-mark-w3m-bookmarks) +(define-key bookmark-bmenu-mode-map "WS" 'bmkp-bmenu-show-only-w3m-urls) +(define-key bookmark-bmenu-mode-map "X" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "XM" 'bmkp-bmenu-mark-bookmark-file-bookmarks) +(define-key bookmark-bmenu-mode-map "XS" 'bmkp-bmenu-show-only-bookmark-files) + + +;;; `Bookmark+' menu-bar menu in `*Bookmark List*' + +(defvar bmkp-bmenu-menubar-menu (make-sparse-keymap "Bookmark+") "`Boomark+' menu-bar menu.") +(define-key bookmark-bmenu-mode-map [menu-bar bmkp] + (cons "Bookmark+" bmkp-bmenu-menubar-menu)) + +;; Top level +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-quit] + '(menu-item "Quit" bmkp-bmenu-quit + :help "Quit the bookmark list, saving its state and the current set of bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-marked] + '(menu-item "Describe Marked Bookmarks" bmkp-bmenu-describe-marked + :help "Describe the marked bookmarks. With `C-u' show internal format.")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-this-bookmark] + '(menu-item "Describe This Bookmark" bmkp-bmenu-describe-this-bookmark + :help "Describe this line's bookmark. With `C-u' show internal format.")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-mode-status-help] + '(menu-item "Current Status, Mode Help" bmkp-bmenu-mode-status-help :keys "?" + :help "Describe `*Bookmark List*' and show its current status")) +(define-key bmkp-bmenu-menubar-menu [top-sep2] '("--")) +(define-key bmkp-bmenu-menubar-menu [bmkp-toggle-saving-menu-list-state] + '(menu-item "Toggle Autosaving Display State" bmkp-toggle-saving-menu-list-state + :help "Toggle the value of option `bmkp-bmenu-state-file'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-toggle-saving-bookmark-file] + '(menu-item "Toggle Autosaving Bookmark File" bmkp-toggle-saving-bookmark-file + :help "Toggle the value of option `bookmark-save-flag'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-switch-bookmark-file] + '(menu-item "Switch to Bookmark File..." bmkp-switch-bookmark-file + :help "Switch to a different bookmark file, *replacing* the current set of bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-load] + '(menu-item "Add Bookmarks from File..." bookmark-bmenu-load + :help "Load additional bookmarks from a bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bmkp-empty-file] + '(menu-item "New (Empty) Bookmark File..." bmkp-empty-file + :help "Create a new, empty bookmark file, or empty an existing bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bookmark-write] + '(menu-item "Save As..." bookmark-write + :help "Write the current set of bookmarks to a file whose name you enter")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-save] + '(menu-item "Save" bookmark-bmenu-save + :help "Save the current set of bookmarks to the current bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-refresh-menu-list] + '(menu-item "Refresh (Revert)" bmkp-bmenu-refresh-menu-list + :help "Update the displayed bookmark list to reflect the currently defined bookmarks")) +(define-key bmkp-bmenu-menubar-menu [top-sep1] '("--")) + +(define-key bmkp-bmenu-menubar-menu [bmkp-make-function-bookmark] + '(menu-item "New Function Bookmark..." bmkp-make-function-bookmark + :help "Create a bookmark that will invoke FUNCTION when \"jumped\" to")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-make-sequence-from-marked] + '(menu-item "New Sequence Bookmark from Marked..." bmkp-bmenu-make-sequence-from-marked + :help "Create or update a sequence bookmark from the visible marked bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-from-bookmark-list] + '(menu-item "Set Navlist from Bookmark-List Bookmark..." bmkp-choose-navlist-from-bookmark-list + :help "Set the navigation list from a bookmark-list bookmark")) +(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-of-type] + '(menu-item "Set Navlist to Bookmarks of Type..." bmkp-choose-navlist-of-type + :help "Set the navigation list to the bookmarks of a certain type")) +(define-key bmkp-bmenu-menubar-menu [bmkp-list-defuns-in-commands-file] + '(menu-item "List User-Defined Bookmark Commands" bmkp-list-defuns-in-commands-file + :help "List the functions defined in `bmkp-bmenu-commands-file'")) + +(defvar bmkp-bmenu-define-command-menu (make-sparse-keymap "Define Command") + "`Define Command' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [define-command] + (cons "Define Command" bmkp-bmenu-define-command-menu)) + +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-full-snapshot-command] + '(menu-item "To Restore Full Bookmark-List State..." bmkp-bmenu-define-full-snapshot-command + :help "Define a command to restore the current bookmark-list state")) +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-command] + '(menu-item "To Restore Current Order and Filter..." bmkp-bmenu-define-command + :help "Define a command to use the current sort order, filter, and omit list")) +(define-key bmkp-bmenu-define-command-menu [bmkp-define-tags-sort-command] + '(menu-item "To Sort by Specific Tags..." bmkp-define-tags-sort-command + :help "Define a command to sort bookmarks in the bookmark list by certain tags")) +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-jump-marked-command] + '(menu-item "To Jump to a Bookmark Now Marked..." bmkp-bmenu-define-jump-marked-command + :help "Define a command to jump to one of the bookmarks that is now marked" + :enable bmkp-bmenu-marked-bookmarks)) + +(when (featurep 'bookmark+-lit) + (defvar bmkp-bmenu-highlight-menu (make-sparse-keymap "Highlight") + "`Highlight' submenu for menu-bar `Bookmark+' menu.") + (define-key bmkp-bmenu-menubar-menu [highlight] (cons "Highlight" bmkp-bmenu-highlight-menu)) + + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-show-only-lighted] + '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted + :help "Display (only) highlighted bookmarks")) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-set-lighting-for-marked] + '(menu-item "Set Highlighting for Marked" bmkp-bmenu-set-lighting-for-marked + :help "Set specific highlighting for the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks)) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-unlight-marked] + '(menu-item "Unhighlight Marked" bmkp-bmenu-unlight-marked + :help "Unhighlight the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks)) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-light-marked] + '(menu-item "Highlight Marked" bmkp-bmenu-light-marked + :help "Highlight the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks))) + +(defvar bmkp-bmenu-tags-menu (make-sparse-keymap "Tags") + "`Tags' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [tags] (cons "Tags" bmkp-bmenu-tags-menu)) + +(define-key bmkp-bmenu-tags-menu [bmkp-list-all-tags] + '(menu-item "List All Tags" bmkp-list-all-tags :help "List all tags used for any bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-purge-notags-autofiles] + '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles + :help "Delete all autofile bookmarks that have no tags")) +(define-key bmkp-bmenu-tags-menu [bmkp-untag-a-file] + '(menu-item "Untag a File (Remove Some)..." bmkp-untag-a-file + :help "Remove some tags from autofile bookmark for a file")) +(define-key bmkp-bmenu-tags-menu [bmkp-tag-a-file] + '(menu-item "Tag a File (Add Some)..." bmkp-tag-a-file + :help "Add some tags to the autofile bookmark for a file")) +(define-key bmkp-bmenu-tags-menu [bmkp-rename-tag] + '(menu-item "Rename Tag..." bmkp-rename-tag + :help "Rename a tag in all bookmarks, even those not showing")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-set-tag-value-for-marked] + '(menu-item "Set Tag Value for Marked..." bmkp-bmenu-set-tag-value-for-marked + :help "Set the value of a tag, for each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-remove-tags-from-all] + '(menu-item "Remove Some Tags from All..." bmkp-remove-tags-from-all + :help "Remove a set of tags from all bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-remove-tags-from-marked] + '(menu-item "Remove Some Tags from Marked..." bmkp-bmenu-remove-tags-from-marked + :help "Remove a set of tags from each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-add-tags-to-marked] + '(menu-item "Add Some Tags to Marked..." bmkp-bmenu-add-tags-to-marked + :help "Add a set of tags to each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-replace-tags-for-marked] + '(menu-item "Paste Tags to Marked (Replace)..." bmkp-bmenu-paste-replace-tags-for-marked + :help "Replace tags for the marked bookmarks with tags copied previously")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-add-tags-to-marked] + '(menu-item "Paste Tags to Marked (Add)..." bmkp-bmenu-paste-add-tags-to-marked + :help "Add tags copied from another bookmark to the marked bookmarks")) + +(defvar bmkp-bmenu-sort-menu (make-sparse-keymap "Sort") + "`Sort' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [sort] (cons "Sort" bmkp-bmenu-sort-menu)) + +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-url] + '(menu-item "By URL" bmkp-bmenu-sort-by-url + :help "Sort URL bookmarks alphabetically by their URL/filename")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Gnus-thread] + '(menu-item "By Gnus Thread" bmkp-bmenu-sort-by-Gnus-thread + :help "Sort Gnus bookmarks by group, then by article, then by message")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Info-location] + '(menu-item "By Info Node" bmkp-bmenu-sort-by-Info-location + :help "Sort Info bookmarks by file name, then node name, then position")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-local-file-update] + '(menu-item "By Last Local File Update" bmkp-bmenu-sort-by-last-local-file-update + :help "Sort bookmarks by last local file update time")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-buffer-or-file-access] + '(menu-item "By Last Buffer/File Access" bmkp-bmenu-sort-by-last-buffer-or-file-access + :help "Sort bookmarks by time of last buffer access or local-file access")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-size] + '(menu-item "By Local File Size" bmkp-bmenu-sort-by-local-file-size + :help "Sort bookmarks by local file size")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-type] + '(menu-item "By Local File Type" bmkp-bmenu-sort-by-local-file-type + :help "Sort bookmarks by local file type: file, symlink, directory")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-type] + '(menu-item "By Type" bmkp-bmenu-sort-by-bookmark-type + :help "Sort bookmarks by type: Info, URL, Gnus, files, other")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-file-name] + '(menu-item "By File Name" bmkp-bmenu-sort-by-file-name :help "Sort bookmarks by file name")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-name] + '(menu-item "By Bookmark Name" bmkp-bmenu-sort-by-bookmark-name + :help "Sort bookmarks by bookmark name, respecting `case-fold-search'")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-creation-time] + '(menu-item "By Creation Time" bmkp-bmenu-sort-by-creation-time + :help "Sort bookmarks by the time of their creation")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-bookmark-access] + '(menu-item "By Last Bookmark Access" bmkp-bmenu-sort-by-last-bookmark-access + :help "Sort bookmarks by the time of their last visit as bookmarks")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-visit-frequency] + '(menu-item "By Bookmark Use" bmkp-bmenu-sort-by-bookmark-visit-frequency + :help "Sort bookmarks by the number of times they were visited as bookmarks")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-marked-before-unmarked] + '(menu-item "Marked Before Unmarked" bmkp-bmenu-sort-marked-before-unmarked + :help "Sort bookmarks by putting marked before unmarked")) +(define-key bmkp-bmenu-sort-menu [bmkp-reverse-sort-order] + '(menu-item "Reverse" bmkp-reverse-sort-order :help "Reverse the current bookmark sort order")) + +(defvar bmkp-bmenu-show-menu (make-sparse-keymap "Show") + "`Show' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [show] (cons "Show" bmkp-bmenu-show-menu)) + +(define-key bmkp-bmenu-show-menu [bookmark-bmenu-show-all-annotations] + '(menu-item "Show Annotations" bookmark-bmenu-show-all-annotations + :help "Show the annotations for all bookmarks (in another window)")) +(define-key bmkp-bmenu-show-menu [bookmark-bmenu-toggle-filenames] + '(menu-item "Show/Hide File Names" bookmark-bmenu-toggle-filenames + :help "Toggle whether filenames are shown in the bookmark list")) +(define-key bmkp-bmenu-show-menu [show-sep1] '("--")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-all] + '(menu-item "Show All" bmkp-bmenu-show-all + :help "Show all bookmarks currently known to the bookmark list")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-tags-incrementally] + '(menu-item "Show Only Tag Matches..." bmkp-bmenu-filter-tags-incrementally + :help "Incrementally filter bookmarks by tags using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-annotation-incrementally] + '(menu-item "Show Only Annotation Matches..." bmkp-bmenu-filter-annotation-incrementally + :help "Incrementally filter bookmarks by annotation using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-file-name-incrementally] + '(menu-item "Show Only File Name Matches..." bmkp-bmenu-filter-file-name-incrementally + :help "Incrementally filter bookmarks by file name using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-bookmark-name-incrementally] + '(menu-item "Show Only Name Matches..." bmkp-bmenu-filter-bookmark-name-incrementally + :help "Incrementally filter bookmarks by bookmark name using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-file] + '(menu-item "Show Only for Specific File" bmkp-bmenu-show-only-specific-file + :help "Display (only) the bookmarks for a specific file")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-buffer] + '(menu-item "Show Only for Specific Buffer" bmkp-bmenu-show-only-specific-buffer + :help "Display (only) the bookmarks for a specific buffer")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-urls] + '(menu-item "Show Only URLs" bmkp-bmenu-show-only-urls + :help "Display (only) the URL bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-gnus] + '(menu-item "Show Only Gnus Messages" bmkp-bmenu-show-only-gnus + :help "Display (only) the Gnus bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-man-pages] + '(menu-item "Show Only UNIX Manual Pages" bmkp-bmenu-show-only-man-pages + :help "Display (only) the `man' page bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-info-nodes] + '(menu-item "Show Only Info Nodes" bmkp-bmenu-show-only-info-nodes + :help "Display (only) the Info bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-dired] + '(menu-item "Show Only Dired Buffers" bmkp-bmenu-show-only-dired + :help "Display (only) the Dired bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-bookmark-files] + '(menu-item "Show Only Bookmark Files" bmkp-bmenu-show-only-bookmark-files + :help "Display (only) the bookmark-file bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-desktops] + '(menu-item "Show Only Desktops" bmkp-bmenu-show-only-desktops + :help "Display (only) the desktop bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-regions] + '(menu-item "Show Only Regions" bmkp-bmenu-show-only-regions + :help "Display (only) the bookmarks that record a region")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-non-files] + '(menu-item "Show Only Non-Files (Buffers)" bmkp-bmenu-show-only-non-files + :help "Display (only) the non-file bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-files] + '(menu-item "Show Only Files" bmkp-bmenu-show-only-files + :help "Display (only) the file and directory bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autofiles] + '(menu-item "Show Only Autofiles" bmkp-bmenu-show-only-autofiles + :help "Display (only) the autofile bookmarks: those named the same as their files")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autonamed] + '(menu-item "Show Only Autonamed" bmkp-bmenu-show-only-autonamed + :help "Display (only) the autonamed bookmarks")) +(when (featurep 'bookmark+-lit) + (define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-lighted] + '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted + :help "Display (only) highlighted bookmarks"))) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-unmarked] + '(menu-item "Show Only Unmarked" bmkp-bmenu-toggle-show-only-unmarked + :help "Hide all marked bookmarks. Repeat to toggle, showing all")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-marked] + '(menu-item "Show Only Marked" bmkp-bmenu-toggle-show-only-marked + :help "Hide all unmarked bookmarks. Repeat to toggle, showing all")) + +(defvar bmkp-bmenu-omit-menu (make-sparse-keymap "Omit") + "`Omit' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [omitting] (cons "Omit" bmkp-bmenu-omit-menu)) + +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-all] + '(menu-item "Show All" bmkp-bmenu-show-all + :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + :help "Show all bookmarks (except omitted)")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-only-omitted] + '(menu-item "Show Only Omitted" bmkp-bmenu-show-only-omitted + :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)) + :enable bmkp-bmenu-omitted-bookmarks :help "Show only the omitted bookmarks")) +(define-key bmkp-bmenu-omit-menu [bmkp-unomit-all] + '(menu-item "Un-Omit All" bmkp-unomit-all + :visible bmkp-bmenu-omitted-bookmarks :help "Un-omit all omitted bookmarks")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-unomit-marked] + '(menu-item "Un-Omit Marked" bmkp-bmenu-unomit-marked + :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + :enable (and bmkp-bmenu-omitted-bookmarks + (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (re-search-forward "^>" (point-max) t))) + :help "Un-omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-omit-marked] + '(menu-item "Omit Marked" bmkp-bmenu-omit-marked + :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)) + :enable (and (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (re-search-forward "^>" (point-max) t))) + :help "Omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]")) + +(defvar bmkp-bmenu-mark-menu (make-sparse-keymap "Mark") + "`Mark' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [marking] (cons "Mark" bmkp-bmenu-mark-menu)) + +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-not-all] + '(menu-item "Unmark If Not Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-not-all + :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-none] + '(menu-item "Unmark If Tagged with None..." bmkp-bmenu-unmark-bookmarks-tagged-none + :help "Unmark all visible bookmarks that are *not* tagged with *any* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-all] + '(menu-item "Unmark If Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-all + :help "Unmark all visible bookmarks that are tagged with *each* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-some] + '(menu-item "Unmark If Tagged with Some..." bmkp-bmenu-unmark-bookmarks-tagged-some + :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-regexp] + '(menu-item "Unmark If Tagged Matching Regexp..." bmkp-bmenu-unmark-bookmarks-tagged-regexp + :help "Unmark bookmarks any of whose tags match a regexp you enter")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-not-all] + '(menu-item "Mark If Not Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-not-all + :help "Mark all visible bookmarks that are *not* tagged with *all* tags you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-none] + '(menu-item "Mark If Tagged with None..." bmkp-bmenu-mark-bookmarks-tagged-none + :help "Mark all visible bookmarks that are not tagged with *any* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-all] + '(menu-item "Mark If Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-all + :help "Mark all visible bookmarks that are tagged with *each* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-some] + '(menu-item "Mark If Tagged with Some..." bmkp-bmenu-mark-bookmarks-tagged-some + :help "Mark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-regexp] + '(menu-item "Mark If Tagged Matching Regexp..." bmkp-bmenu-mark-bookmarks-tagged-regexp + :help "Mark bookmarks any of whose tags match a regexp you enter")) +(define-key bmkp-bmenu-mark-menu [mark-sep1] '("--")) +(when (featurep 'bookmark+-lit) + (define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-lighted-bookmarks] + '(menu-item "Mark Highlighted" bmkp-bmenu-mark-lighted-bookmarks + :help "Mark highlighted bookmarks"))) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-file-bookmarks] + '(menu-item "Mark for Specific File" bmkp-bmenu-mark-specific-file-bookmarks + :help "Mark bookmarks for a specific file")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-buffer-bookmarks] + '(menu-item "Mark for Specific Buffer" bmkp-bmenu-mark-specific-buffer-bookmarks + :help "Mark bookmarks for a specific buffer")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-url-bookmarks] + '(menu-item "Mark URLs" bmkp-bmenu-mark-url-bookmarks :help "Mark URL bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-gnus-bookmarks] + '(menu-item "Mark Gnus Messages" bmkp-bmenu-mark-gnus-bookmarks :help "Mark Gnus bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-man-bookmarks] + '(menu-item "Mark UNIX Manual Pages" bmkp-bmenu-mark-man-bookmarks + :help "Mark `man' page bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-info-bookmarks] + '(menu-item "Mark Info Nodes" bmkp-bmenu-mark-info-bookmarks :help "Mark Info bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-dired-bookmarks] + '(menu-item "Mark Dired Buffers" bmkp-bmenu-mark-dired-bookmarks :help "Mark Dired bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmark-file-bookmarks] + '(menu-item "Mark Bookmark Files" bmkp-bmenu-mark-bookmark-file-bookmarks + :help "Mark the bookmark-file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-desktop-bookmarks] + '(menu-item "Mark Desktops" bmkp-bmenu-mark-desktop-bookmarks + :help "Mark desktop bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-region-bookmarks] + '(menu-item "Mark Regions" bmkp-bmenu-mark-region-bookmarks + :help "Mark bookmarks that record a region")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-non-file-bookmarks] + '(menu-item "Mark Non-Files (Buffers)" bmkp-bmenu-mark-non-file-bookmarks + :help "Mark non-file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-autofile-bookmarks] + '(menu-item "Mark Autofiles" bmkp-bmenu-mark-autofile-bookmarks + :help "Mark autofile bookmarks: those whose names are the same as their files")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-file-bookmarks] + '(menu-item "Mark Files" bmkp-bmenu-mark-file-bookmarks :help "Mark file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-all] + '(menu-item "Unmark All" bmkp-bmenu-unmark-all + :help "Remove a mark you specify (> or D) from each bookmark (RET to remove both kinds)")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-all] + '(menu-item "Mark All" bmkp-bmenu-mark-all :help "Mark all bookmarks, using mark `>'")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-toggle-marks] + '(menu-item "Toggle Marked/Unmarked" bmkp-bmenu-toggle-marks + :help "Unmark all marked bookmarks; mark all unmarked bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-regexp-mark] + '(menu-item "Mark Regexp Matches..." bmkp-bmenu-regexp-mark + :help "Mark bookmarks that match a regexp that you enter")) + +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-execute-deletions] + '(menu-item "Delete Flagged (D)" bookmark-bmenu-execute-deletions + :help "Delete the (visible) bookmarks flagged `D'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-delete-marked] + '(menu-item "Delete Marked (>)" bmkp-bmenu-delete-marked + :help "Delete all (visible) bookmarks marked `>', after confirmation")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-query-replace-marked-bookmarks-regexp] + '(menu-item "Query-Replace Marked..." bmkp-bmenu-query-replace-marked-bookmarks-regexp + :help "`query-replace-regexp' over all files whose bookmarks are marked")) +(when (fboundp 'bmkp-bmenu-isearch-marked-bookmarks) + (define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-isearch-marked-bookmarks-regexp] + '(menu-item "Regexp-Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks-regexp + :help "Regexp Isearch the marked bookmark locations, in their current order")) + (define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-isearch-marked-bookmarks] + '(menu-item "Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks + :help "Isearch the marked bookmark locations, in their current order"))) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-search-marked-bookmarks-regexp] + '(menu-item "Search Marked..." bmkp-bmenu-search-marked-bookmarks-regexp + :help "Regexp-search the files whose bookmarks are marked, in their current order")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-select] + '(menu-item "Jump to Marked" bookmark-bmenu-select + :help "Jump to this line's bookmark. Also visit each bookmark marked with `>'")) + + + +;;; Mouse-3 menu binding. + +(defvar bmkp-bmenu-line-overlay nil + "Overlay to highlight the current line for `bmkp-bmenu-mouse-3-menu'.") +(define-key bookmark-bmenu-mode-map [mouse-3] 'bmkp-bmenu-mouse-3-menu) + +;;;###autoload +(defun bmkp-bmenu-mouse-3-menu (event) + "Pop-up menu on `mouse-3' for a bookmark listed in `*Bookmark List*'." + (interactive "e") + (let* ((mouse-pos (event-start event)) + (inhibit-field-text-motion t) ; Just in case. + bol eol + (bmk-name (save-excursion + (with-current-buffer (window-buffer (posn-window mouse-pos)) + (save-excursion + (goto-char (posn-point mouse-pos)) + (save-excursion + (setq bol (progn (beginning-of-line) (point)) + eol (progn (end-of-line) (point)))) + (if bmkp-bmenu-line-overlay ; Don't recreate. + (move-overlay bmkp-bmenu-line-overlay bol eol + (current-buffer)) + (setq bmkp-bmenu-line-overlay (make-overlay bol eol)) + (overlay-put bmkp-bmenu-line-overlay 'face 'region)) + (bookmark-bmenu-bookmark)))))) + (sit-for 0) + (let ((menu-choice + (x-popup-menu event + (list "This Bookmark" + (if bmk-name + (list bmk-name + (if (bmkp-bookmark-name-member bmk-name + bmkp-bmenu-marked-bookmarks) + '("Unmark" . bookmark-bmenu-unmark) + '("Mark" . bookmark-bmenu-mark)) + (save-excursion + (goto-char (posn-point mouse-pos)) + (beginning-of-line) + (if (looking-at "^D") + '("Unmark" . bookmark-bmenu-unmark) + '("Flag for Deletion" . bookmark-bmenu-delete))) + '("Omit" . bmkp-bmenu-omit) + '("--") ; ---------------------------------------- + '("Jump To" . bookmark-bmenu-this-window) + '("Jump To in Other Window" . bookmark-bmenu-other-window) + '("--") ; ---------------------------------------- + '("Copy Tags" . bmkp-bmenu-copy-tags) + '("Paste Tags (Add)" . bmkp-bmenu-paste-add-tags) + '("Paste Tags (Replace)" . bmkp-bmenu-paste-replace-tags) + '("Add Some Tags..." . bmkp-bmenu-add-tags) + '("Remove Some Tags..." . bmkp-bmenu-remove-tags) + '("Remove All Tags..." . bmkp-bmenu-remove-all-tags) + '("Rename..." . bmkp-rename-tag) + '("Set Tag Value..." . bmkp-bmenu-set-tag-value) + (and (featurep 'bookmark+-lit) + '("--")) ; ---------------------------------------- + (and (featurep 'bookmark+-lit) + '("Highlight" . bmkp-bmenu-light)) + (and (featurep 'bookmark+-lit) + '("Unhighlight" . bmkp-bmenu-unlight)) + (and (featurep 'bookmark+-lit) + '("Set Lighting" . bmkp-bmenu-set-lighting)) + '("--") ; ---------------------------------------- + '("Show Annotation" . bookmark-bmenu-show-annotation) + '("Edit Annotation..." . bookmark-bmenu-edit-annotation) + '("Edit Name, File Name..." . bmkp-bmenu-edit-bookmark) + '("Rename..." . bookmark-bmenu-rename) + '("Relocate..." . bookmark-bmenu-relocate) + '("--") ; ---------------------------------------- + '("Describe" . bmkp-bmenu-describe-this-bookmark)) + '("" (""))))))) ; No menu: not on a bookmark line. + (when bmkp-bmenu-line-overlay (delete-overlay bmkp-bmenu-line-overlay)) + (and menu-choice (save-excursion (goto-char (posn-point mouse-pos)) + (call-interactively menu-choice)))))) + +;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-bmu) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-bmu.el ends here diff --git a/auto-install/bookmark+-bmu.el~ b/auto-install/bookmark+-bmu.el~ new file mode 100644 index 0000000..bad0d61 --- /dev/null +++ b/auto-install/bookmark+-bmu.el~ @@ -0,0 +1,4376 @@ +;;; bookmark+-bmu.el --- Bookmark+ code for the `*Bookmark List*' (bmenu). +;; +;; Filename: bookmark+-bmu.el +;; Description: Bookmark+ code for the `*Bookmark List*' (bmenu). +;; Author: Drew Adams, Thierry Volpiatto +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved. +;; Created: Mon Jul 12 09:05:21 2010 (-0700) +;; Last-Updated: Fri Jul 1 14:51:29 2011 (-0700) +;; By: dradams +;; Update #: 771 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-bmu.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `bookmark+-mac', `pp'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library contains code for buffer `*Bookmark List*' (mode +;; `bookmark-bmenu-mode'). +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (this file) +;; `bookmark+-1.el' - other required code (non-bmenu) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) + +;;(@> "Index") +;; +;; Index +;; ----- +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Things Defined Here") +;; (@> "Faces (Customizable)") +;; (@> "User Options (Customizable)") +;; (@> "Internal Variables") +;; (@> "Compatibility Code for Older Emacs Versions") +;; (@> "Menu List Replacements (`bookmark-bmenu-*')") +;; (@> "Bookmark+ Functions (`bmkp-*')") +;; (@> "Menu-List (`*-bmenu-*') Filter Commands") +;; (@> "Menu-List (`*-bmenu-*') Commands Involving Marks") +;; (@> "Omitted Bookmarks") +;; (@> "Search-and-Replace Locations of Marked Bookmarks") +;; (@> "Tags") +;; (@> "General Menu-List (`-*bmenu-*') Commands and Functions") +;; (@> "Sorting - Commands") +;; (@> "Other Bookmark+ Functions (`bmkp-*')") +;; (@> "Keymaps") + +;;(@* "Things Defined Here") +;; +;; Things Defined Here +;; ------------------- +;; +;; Commands defined here: +;; +;; `bmkp-bmenu-add-tags', `bmkp-bmenu-add-tags-to-marked', +;; `bmkp-bmenu-change-sort-order', +;; `bmkp-bmenu-change-sort-order-repeat', `bmkp-bmenu-copy-tags', +;; `bmkp-bmenu-define-command', +;; `bmkp-bmenu-define-full-snapshot-command', +;; `bmkp-bmenu-define-jump-marked-command', +;; `bmkp-bmenu-delete-marked', `bmkp-bmenu-describe-marked', +;; `bmkp-bmenu-describe-this+move-down', +;; `bmkp-bmenu-describe-this+move-up', +;; `bmkp-bmenu-describe-this-bookmark',`bmkp-bmenu-dired-marked', +;; `bmkp-bmenu-edit-bookmark', `bmkp-edit-tags-send', +;; `bmkp-bmenu-filter-annotation-incrementally', +;; `bmkp-bmenu-filter-bookmark-name-incrementally', +;; `bmkp-bmenu-filter-file-name-incrementally', +;; `bmkp-bmenu-filter-tags-incrementally', +;; `bmkp-bmenu-isearch-marked-bookmarks' (Emacs 23+), +;; `bmkp-bmenu-isearch-marked-bookmarks-regexp' (Emacs 23+), +;; `bmkp-bmenu-make-sequence-from-marked', `bmkp-bmenu-mark-all', +;; `bmkp-bmenu-mark-autofile-bookmarks', +;; `bmkp-bmenu-mark-bookmark-file-bookmarks', +;; `bmkp-bmenu-mark-bookmarks-satisfying', +;; `bmkp-bmenu-mark-bookmarks-tagged-all', +;; `bmkp-bmenu-mark-bookmarks-tagged-none', +;; `bmkp-bmenu-mark-bookmarks-tagged-not-all', +;; `bmkp-bmenu-mark-bookmarks-tagged-regexp', +;; `bmkp-bmenu-mark-bookmarks-tagged-some', +;; `bmkp-bmenu-mark-desktop-bookmarks', +;; `bmkp-bmenu-mark-dired-bookmarks', +;; `bmkp-bmenu-mark-file-bookmarks', +;; `bmkp-bmenu-mark-gnus-bookmarks', +;; `bmkp-bmenu-mark-info-bookmarks', +;; `bmkp-bmenu-mark-lighted-bookmarks', +;; `bmkp-bmenu-mark-man-bookmarks', +;; `bmkp-bmenu-mark-non-file-bookmarks', +;; `bmkp-bmenu-mark-region-bookmarks', +;; `bmkp-bmenu-mark-specific-buffer-bookmarks', +;; `bmkp-bmenu-mark-specific-file-bookmarks', +;; `bmkp-bmenu-mark-url-bookmarks', +;; `bmkp-bmenu-mark-w3m-bookmarks', `bmkp-bmenu-mouse-3-menu', +;; `bmkp-bmenu-mode-status-help', `bmkp-bmenu-omit', +;; `bmkp-bmenu-omit-marked', `bmkp-bmenu-omit/unomit-marked', +;; `bmkp-bmenu-paste-add-tags', +;; `bmkp-bmenu-paste-add-tags-to-marked', +;; `bmkp-bmenu-paste-replace-tags', +;; `bmkp-bmenu-paste-replace-tags-for-marked', +;; `bmkp-bmenu-query-replace-marked-bookmarks-regexp', +;; `bmkp-bmenu-quit', `bmkp-bmenu-refresh-menu-list', +;; `bmkp-bmenu-regexp-mark', `bookmark-bmenu-relocate' (Emacs 20, +;; 21), `bmkp-bmenu-remove-all-tags', `bmkp-bmenu-remove-tags', +;; `bmkp-bmenu-remove-tags-from-marked', +;; `bmkp-bmenu-search-marked-bookmarks-regexp', +;; `bmkp-bmenu-set-tag-value', +;; `bmkp-bmenu-set-tag-value-for-marked', `bmkp-bmenu-show-all', +;; `bmkp-bmenu-show-only-autofiles', +;; `bmkp-bmenu-show-only-autonamed.', +;; `bmkp-bmenu-show-only-bookmark-files', +;; `bmkp-bmenu-show-only-desktops', `bmkp-bmenu-show-only-dired', +;; `bmkp-bmenu-show-only-files', `bmkp-bmenu-show-only-gnus', +;; `bmkp-bmenu-show-only-info-nodes', +;; `bmkp-bmenu-show-only-man-pages', +;; `bmkp-bmenu-show-only-non-files', +;; `bmkp-bmenu-show-only-omitted', `bmkp-bmenu-show-only-regions', +;; `bmkp-bmenu-show-only-specific-buffer', +;; `bmkp-bmenu-show-only-specific-file', +;; `bmkp-bmenu-show-only-tagged', `bmkp-bmenu-show-only-urls', +;; `bmkp-bmenu-show-only-variable-lists', +;; `bmkp-bmenu-show-only-w3m-urls', +;; `bmkp-bmenu-sort-by-bookmark-name', +;; `bmkp-bmenu-sort-by-bookmark-visit-frequency', +;; `bmkp-bmenu-sort-by-creation-time', +;; `bmkp-bmenu-sort-by-file-name', +;; `bmkp-bmenu-sort-by-Gnus-thread', +;; `bmkp-bmenu-sort-by-Info-location', +;; `bmkp-bmenu-sort-by-last-bookmark-access', +;; `bmkp-bmenu-sort-by-last-buffer-or-file-access', +;; `bmkp-bmenu-sort-by-last-local-file-access', +;; `bmkp-bmenu-sort-by-last-local-file-update', +;; `bmkp-bmenu-sort-by-local-file-size', +;; `bmkp-bmenu-sort-by-local-file-type', `bmkp-bmenu-sort-by-url', +;; `bmkp-bmenu-sort-marked-before-unmarked', +;; `bmkp-bmenu-toggle-marks', `bmkp-bmenu-toggle-show-only-marked', +;; `bmkp-bmenu-toggle-show-only-unmarked', `bmkp-bmenu-unmark-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-none', +;; `bmkp-bmenu-unmark-bookmarks-tagged-not-all', +;; `bmkp-bmenu-unmark-bookmarks-tagged-regexp', +;; `bmkp-bmenu-unmark-bookmarks-tagged-some', +;; `bmkp-bmenu-unomit-marked', `bmkp-bmenu-w32-open', +;; `bmkp-bmenu-w32-open-select', `bmkp-bmenu-w32-open-with-mouse', +;; `bmkp-define-tags-sort-command'. +;; +;; Faces defined here: +;; +;; `bmkp->-mark', `bmkp-a-mark', `bmkp-bad-bookmark', +;; `bmkp-bookmark-file', `bmkp-bookmark-list', `bmkp-buffer', +;; `bmkp-D-mark', `bmkp-desktop', `bmkp-function', `bmkp-gnus', +;; `bmkp-heading', `bmkp-info', `bmkp-local-directory', +;; `bmkp-local-file-with-region', `bmkp-local-file-without-region', +;; `bmkp-man', `bmkp-non-file', `bmkp-remote-file', +;; `bmkp-sequence', `bmkp-su-or-sudo', `bmkp-t-mark', `bmkp-url', +;; `bmkp-variable-list'. +;; +;; User options defined here: +;; +;; `bmkp-bmenu-commands-file', `bmkp-bmenu-omitted-bookmarks', +;; `bmkp-bmenu-state-file', `bmkp-propertize-bookmark-names-flag', +;; `bmkp-sort-orders-alist', `bmkp-sort-orders-for-cycling-alist'. +;; +;; Non-interactive functions defined here: +;; +;; `bmkp-bmenu-barf-if-not-in-menu-list', +;; `bmkp-bmenu-cancel-incremental-filtering', +;; `bmkp-bmenu-filter-alist-by-annotation-regexp', +;; `bmkp-bmenu-filter-alist-by-bookmark-name-regexp', +;; `bmkp-bmenu-filter-alist-by-file-name-regexp', +;; `bmkp-bmenu-filter-alist-by-tags-regexp', +;; `bmkp-bmenu-get-marked-files', `bmkp-bmenu-goto-bookmark-named', +;; `bmkp-bmenu-list-1', +;; `bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none', +;; `bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all', +;; `bmkp-bmenu-propertize-item', `bmkp-bmenu-read-filter-input', +;; `bmkp-maybe-unpropertize-bookmark-names', +;; `bmkp-reverse-multi-sort-order', `bmkp-reverse-sort-order'. +;; +;; Internal variables defined here: +;; +;; `bmkp-bmenu-before-hide-marked-alist', +;; `bmkp-bmenu-before-hide-unmarked-alist', +;; `bmkp-bmenu-define-command-menu', `bmkp-bmenu-filter-function', +;; `bmkp-bmenu-filter-pattern', `bmkp-bmenu-filter-prompt', +;; `bmkp-bmenu-filter-timer', `bmkp-bmenu-first-time-p', +;; `bmkp-bmenu-header-lines', `bmkp-bmenu-highlight-menu', +;; `bmkp-bmenu-line-overlay', `bmkp-bmenu-mark-menu', +;; `bmkp-bmenu-marked-bookmarks', `bmkp-bmenu-marks-width', +;; `bmkp-bmenu-menubar-menu', `bmkp-bmenu-omit-menu', +;; `bmkp-bmenu-show-menu', `bmkp-bmenu-sort-menu', +;; `bmkp-bmenu-tags-menu', `bmkp-bmenu-title', +;; `bmkp-bookmark-file-history', `bmkp-bookmark-list-history', +;; `bmkp-current-bookmark-file', `bmkp-current-nav-bookmark', +;; `bmkp-desktop-history', `bmkp-dired-history', +;; `bmkp-file-history', `bmkp-gnus-history', `bmkp-highlight-menu', +;; `bmkp-info-history', `bmkp-isearch-bookmarks' (Emacs 23+), +;; `bmkp-jump-display-function', `bmkp-jump-map', `bmkp-jump-menu', +;; `bmkp-jump-other-window-map', `bmkp-last-bmenu-bookmark'. +;; +;; +;; ***** NOTE: The following commands defined in `bookmark.el' +;; have been REDEFINED HERE: +;; +;; `bookmark-bmenu-execute-deletions', `bookmark-bmenu-list', +;; `bookmark-bmenu-mark', `bookmark-bmenu-1-window', +;; `bookmark-bmenu-2-window', `bookmark-bmenu-other-window', +;; `bookmark-bmenu-other-window-with-mouse', +;; `bookmark-bmenu-this-window', `bookmark-bmenu-rename', +;; `bookmark-bmenu-show-annotation', +;; `bookmark-bmenu-switch-other-window', `bookmark-bmenu-unmark'. +;; +;; +;; ***** NOTE: The following non-interactive functions defined in +;; `bookmark.el' have been REDEFINED HERE: +;; +;; `bookmark-bmenu-bookmark', `bookmark-bmenu-check-position', +;; `bookmark-bmenu-delete', `bookmark-bmenu-ensure-position' (Emacs +;; 23.2+), `bookmark-bmenu-hide-filenames', `bookmark-bmenu-mode', +;; `bookmark-bmenu-show-filenames', +;; `bookmark-bmenu-surreptitiously-rebuild-list', +;; `bookmark-bmenu-switch-other-window' (Emacs 20-22). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(eval-when-compile (require 'cl)) ;; case + +(require 'bookmark) +;; bookmark-alist, bookmark-bmenu-file-column, +;; bookmark-bmenu-hidden-bookmarks, bookmark-bmenu-mode-map, +;; bookmark-bmenu-select, bookmark-bmenu-toggle-filenames, +;; bookmark-get-annotation, bookmark-get-bookmark, +;; bookmark-get-filename, bookmark-get-handler, bookmark-kill-line, +;; bookmark-maybe-load-default-file, bookmark-name-from-full-record, +;; bookmark-name-from-record, bookmark-prop-get, +;; bookmark-show-annotation, bookmark-store + +;;; Fix incompatibility introduced by gratuitous Emacs name change. +(cond ((and (fboundp 'bookmark-name-from-record) (not (fboundp 'bookmark-name-from-full-record))) + (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record)) + ((and (fboundp 'bookmark-name-from-full-record) (not (fboundp 'bookmark-name-from-record))) + (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record))) + +(require 'bookmark+-mac) ;; bmkp-define-sort-command + +;; (eval-when-compile (require 'bookmark+-1)) +;; bmkp-add-tags, bmkp-alpha-p, bmkp-bookmark-creation-cp, +;; bmkp-bookmark-description, bmkp-bookmark-file-bookmark-p, +;; bmkp-bookmark-last-access-cp, bmkp-bookmark-list-bookmark-p, +;; bmkp-buffer-last-access-cp, bmkp-completing-read-buffer-name, +;; bmkp-completing-read-file-name, bmkp-current-bookmark-file, +;; bmkp-current-sort-order, bmkp-describe-bookmark, +;; bmkp-describe-bookmark-internals, bmkp-desktop-bookmark-p, +;; bmkp-edit-bookmark, bmkp-face-prop, bmkp-file-alpha-cp, +;; bmkp-file-remote-p, bmkp-function-bookmark-p, bmkp-get-buffer-name, +;; bmkp-get-tags, bmkp-gnus-bookmark-p, bmkp-gnus-cp, bmkp-handler-cp, +;; bmkp-incremental-filter-delay, bmkp-info-bookmark-p, bmkp-info-cp, +;; bmkp-isearch-bookmarks, bmkp-isearch-bookmarks-regexp, bmkp-jump-1, +;; bmkp-last-bookmark-file, bmkp-last-specific-buffer, +;; bmkp-last-specific-file, bmkp-latest-bookmark-alist, +;; bmkp-local-file-bookmark-p, bmkp-local-file-type-cp, +;; bmkp-local-file-accessed-more-recently-cp, +;; bmkp-local-file-updated-more-recently-cp, bmkp-man-bookmark-p, +;; bmkp-marked-bookmark-p, bmkp-marked-bookmarks-only, bmkp-marked-cp, +;; bmkp-msg-about-sort-order, bmkp-non-file-filename, +;; bmkp-read-tag-completing, bmkp-read-tags-completing, +;; bmkp-refresh-menu-list, bmkp-region-bookmark-p, +;; bmkp-remove-all-tags, bmkp-remove-if, bmkp-remove-tags, +;; bmkp-repeat-command, bmkp-reverse-multi-sort-p, +;; bmkp-reverse-sort-p, bmkp-root-or-sudo-logged-p, bmkp-same-file-p, +;; bmkp-save-menu-list-state, bmkp-sequence-bookmark-p, +;; bmkp-set-tag-value, bmkp-set-tag-value-for-bookmarks, +;; bmkp-set-union, bmkp-some, bmkp-some-marked-p, +;; bmkp-some-unmarked-p, bmkp-sort-omit, bmkp-sort-comparer, bmkp-sorted-alist, +;; bmkp-sort-orders-for-cycling-alist, bmkp-su-or-sudo-regexp, +;; bmkp-tag-name, bmkp-tags-list, bmkp-url-bookmark-p, bmkp-url-cp, +;; bmkp-unmarked-bookmarks-only, bmkp-variable-list-bookmark-p, +;; bmkp-visited-more-cp + +;; (eval-when-compile (require 'bookmark+-lit nil t)) +;; bmkp-get-lighting + +;;;;;;;;;;;;;;;;;;;;;;; + +;; Quiet the byte-compiler +(defvar dired-re-mark) ; Defined in `dired.el'. +(defvar tramp-file-name-regexp) ; Defined in `tramp.el'. + +(defvar bmkp-sort-orders-alist) ; Defined in `bookmark+-1.el'. +(defvar bmkp-sort-orders-for-cycling-alist) ; Defined in `bookmark+-1.el'. + +;;(@* "Faces (Customizable)") +;;; Faces (Customizable) --------------------------------------------- + +(defgroup bookmark-plus nil + "Bookmark enhancements." + :prefix "bmkp-" :group 'bookmark + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +Bookmark+ bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Download" "http://www.emacswiki.org/bookmark+.el") + :link '(url-link :tag "Description" "http://www.emacswiki.org/BookmarkPlus") + :link '(emacs-commentary-link :tag "Commentary" "bookmark+")) + +(defface bmkp->-mark '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + ;; (:foreground "Magenta2" :box (:line-width 1 :style pressed-button)))) + "*Face used for a `>' mark in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-a-mark '((((background dark)) (:background "SaddleBrown")) + (t (:background "SkyBlue"))) + "*Face used for an annotation mark (`a') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bad-bookmark '((t (:foreground "Red" :background "Chartreuse1"))) + "*Face used for a bookmark that seems to be bad: e.g., nonexistent file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bookmark-file + '((((background dark)) + (:foreground "#00005A5AFFFF" :background "#FFFF9B9BFFFF")) ; ~ blue, ~ pink + (t (:foreground "Orange" :background "DarkGreen"))) + "*Face used for a bookmark-file bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-bookmark-list + '((((background dark)) (:foreground "#7474FFFFFFFF" :background "DimGray")) ; ~ cyan + (t (:foreground "DarkRed" :background "LightGray"))) + "*Face used for a bookmark-list bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-buffer + '((((background dark)) (:foreground "#FFFF9B9BFFFF")) ; ~ pink + (t (:foreground "DarkGreen"))) + "*Face used for a bookmarked existing buffer not associated with a file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-D-mark '((t (:foreground "Yellow" :background "Red"))) + "*Face used for a deletion mark (`D') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-desktop + '((((background dark)) (:foreground "Orange" :background "DarkSlateBlue")) + (t (:foreground "DarkBlue" :background "PaleGoldenrod"))) + "*Face used for a bookmarked desktop." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-function + '((((background dark)) (:foreground "#0000EBEB6C6C")) ; ~ green + (t (:foreground "DeepPink1"))) + "*Face used for a function bookmark: a bookmark that invokes a function." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-gnus + '((((background dark)) (:foreground "Gold")) + (t (:foreground "DarkBlue"))) + "*Face used for a gnus bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-info + '((((background dark)) (:foreground "#7474FFFFFFFF")) ; ~ light cyan + (t (:foreground "DarkRed"))) + "*Face used for a bookmarked Info node." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-directory + '((((background dark)) + (:foreground "Pink" :background "DarkBlue")) + (t (:foreground "DarkBlue" :background "HoneyDew2"))) + "*Face used for a bookmarked local directory." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-file-without-region + '((((background dark)) (:foreground "White")) + (t (:foreground "Black"))) + "*Face used for a bookmarked local file (without a region)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-local-file-with-region + '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + "*Face used for a region bookmark in a local file." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-man + '((((background dark)) (:foreground "Orchid")) + (t (:foreground "Orange4"))) + "*Face used for a `man' page bookmark." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-non-file + '((t (:foreground "gray60"))) + "*Face used for a bookmark not associated with an existing file or buffer." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-remote-file + '((((background dark)) (:foreground "#6B6BFFFF2C2C")) ; ~ green + (t (:foreground "DarkViolet"))) + "*Face used for a bookmarked tramp remote file (/ssh:)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-sequence + '((((background dark)) (:foreground "DeepSkyBlue")) + (t (:foreground "DarkOrange2"))) + "*Face used for a sequence bookmark: one composed of other bookmarks." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-su-or-sudo '((t (:foreground "Red"))) + "*Face used for a bookmarked tramp file (/su: or /sudo:)." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-t-mark '((t (:foreground "Red"))) + "*Face used for a tags mark (`t') in the bookmark list." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-url + '((((background dark)) (:foreground "#7474FFFF7474")) ; ~ green + (t (:foreground "DarkMagenta"))) + "*Face used for a bookmarked URL." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-variable-list + '((((background dark)) (:foreground "#FFFF74747474")) ; ~ salmon + (t (:foreground "DarkCyan"))) + "*Face used for a bookmarked list of variables." + :group 'bookmark-plus :group 'faces) + +;; $$$$$$ Not used now - using `bmkp-url' instead. +;; (defface bmkp-w3m +;; '((((background dark)) (:foreground "yellow")) +;; (t (:foreground "DarkMagenta"))) +;; "*Face used for a bookmarked w3m url." +;; :group 'bookmark-plus :group 'faces) + +;; Instead of vanilla `bookmark-menu-heading' (defined in Emacs 22+), to use a better default. +(defface bmkp-heading '((((background dark)) (:foreground "Yellow")) + (t (:foreground "Blue"))) + "*Face used to highlight the headings in various Bookmark+ buffers." + :group 'bookmark-plus :version "22.1" :group 'faces) + +;;(@* "User Options (Customizable)") +;;; User Options (Customizable) -------------------------------------- + +;;;###autoload +(defcustom bmkp-bmenu-omitted-bookmarks () + "*List of names of omitted bookmarks. +They are generally not available for display in the bookmark list. +You can, however, use \\\ +`\\[bmkp-bmenu-show-only-omitted]' to see them. +You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]' + to make those that are marked available again for the bookmark list." + :type '(repeat (string :tag "Bookmark name")) :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-bmenu-commands-file (convert-standard-filename "~/.emacs-bmk-bmenu-commands.el") + "*File for saving user-defined bookmark-list commands. +This must be an absolute file name (possibly containing `~') or nil +\(it is not expanded). + +You can use `\\[bmkp-list-defuns-in-commands-file]' to list the +commands defined in the file and how many times each is defined. + +NOTE: Each time you define a command using \\\ +`\\[bmkp-bmenu-define-command]', `\\[bmkp-bmenu-define-full-snapshot-command]', \ +`\\[bmkp-bmenu-define-jump-marked-command], or `\\[bmkp-define-tags-sort-command]', +it is saved in the file. The new definition is simply appended to the +file - old definitions of the same command are not overwritten. So +you might want to clean up the file occasionally, to remove any old, +unused definitions. This is especially advisable if you used \ +`\\[bmkp-bmenu-define-full-snapshot-command]', +because such command definitions can be very large." + :type '(file :tag "File for saving menu-list state") :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-bmenu-state-file (convert-standard-filename "~/.emacs-bmk-bmenu-state.el") + "*File for saving `*Bookmark List*' state when you quit bookmark list. +This must be an absolute file name (possibly containing `~') or nil +\(it is not expanded). + +The state is also saved when you quit Emacs, even if you don't quit +the bookmark list first (using \\`\\[bmkp-bmenu-quit]'). + +Set this to nil if you do not want to restore the bookmark list as it +was the last time you used it." + :type '(choice + (const :tag "Do not save and restore menu-list state" nil) + (file :tag "File for saving menu-list state")) + :group 'bookmark-plus) + +;; This is a general option. It is in this file because it is used mainly by the bmenu code. +(when (> emacs-major-version 20) + (defcustom bmkp-sort-orders-alist () + "*Alist of all available sort functions. +This is a pseudo option - you probably do NOT want to customize this. +Instead: + + * To add a new sort function to this list, use macro + `bmkp-define-sort-command'. It defines a new sort function + and automatically adds it to this list. + + * To have fewer sort orders available for cycling by \\\ +`\\[bmkp-bmenu-change-sort-order-repeat]'..., + customize option `bmkp-sort-orders-for-cycling-alist'. + +Each alist element has the form (SORT-ORDER . COMPARER): + + SORT-ORDER is a short string or symbol describing the sort order. + Examples: \"by last access time\", \"by bookmark name\". + + COMPARER compares two bookmarks. It must be acceptable as a value of + `bmkp-sort-comparer'." + :type '(alist + :key-type (choice :tag "Sort order" string symbol) + :value-type (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate"))))) + :group 'bookmark-plus)) + +(unless (> emacs-major-version 20) ; Emacs 20: custom type `alist' doesn't exist. + (defcustom bmkp-sort-orders-alist () + "*Alist of all available sort functions. +This is a pseudo option - you probably do NOT want to customize this. +Instead: + + * To add a new sort function to this list, use macro + `bmkp-define-sort-command'. It defines a new sort function + and automatically adds it to this list. + + * To have fewer sort orders available for cycling by \\\ +`\\[bmkp-bmenu-change-sort-order-repeat]'..., + customize option `bmkp-sort-orders-for-cycling-alist'. + +Each alist element has the form (SORT-ORDER . COMPARER): + + SORT-ORDER is a short string or symbol describing the sort order. + Examples: \"by last access time\", \"by bookmark name\". + + COMPARER compares two bookmarks. It must be acceptable as a value of + `bmkp-sort-comparer'." + :type '(repeat + (cons + (choice :tag "Sort order" string symbol) + (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))))) + :group 'bookmark-plus)) + +(defcustom bmkp-propertize-bookmark-names-flag (> emacs-major-version 20) + "*Non-nil means to propertize bookmark names to hold full bookmark data. +This means that you can effectively have more than one bookmark with +the same name. + +Emacs 20 users: If you need to use your bookmarks with Emacs 20 then +set this to nil. In particular, if your bookmark file was written +with this as non-nil, then it contains propertized strings which are +unreadable by Emacs 20. To convert the file to be usable with Emacs +20 you must, in Emacs 21 or later, set this to nil and then do `M-x +bookmark-save'." + :type 'boolean :group 'bookmark-plus) + +;;(@* "Internal Variables") +;;; Internal Variables ----------------------------------------------- + +(defconst bmkp-bmenu-header-lines 2 + "Number of lines used for the `*Bookmark List*' header.") + +(defconst bmkp-bmenu-marks-width 4 + "Number of columns (chars) used for the `*Bookmark List*' marks columns.") + +(defvar bmkp-bmenu-marked-bookmarks () + "Names of the marked bookmarks. +This includes possibly omitted bookmarks, that is, bookmarks listed in +`bmkp-bmenu-omitted-bookmarks'.") + +(defvar bmkp-bmenu-before-hide-unmarked-alist () + "Copy of `bookmark-alist' made before hiding unmarked bookmarks.") + +(defvar bmkp-bmenu-before-hide-marked-alist () + "Copy of `bookmark-alist' made before hiding marked bookmarks.") + +(defvar bmkp-bmenu-filter-function nil "Latest filtering function for `*Bookmark List*' display.") + +(defvar bmkp-bmenu-title "" "Latest title for `*Bookmark List*' display.") + +(defvar bmkp-bmenu-filter-pattern "" "Regexp for incremental filtering.") + +(defvar bmkp-bmenu-filter-prompt "Pattern: " "Prompt for `bmkp-bmenu-filter-incrementally'.") + +(defvar bmkp-bmenu-filter-timer nil "Timer used for incremental filtering.") + +(defvar bmkp-bmenu-first-time-p t + "Non-nil means bookmark list has not yet been shown after quitting it. +Quitting the list or the Emacs session resets this to t. +The first time the list is displayed, it is set to nil.") + +;; This is a general variable. It is in this file because it is used only in the bmenu code. +(defvar bmkp-last-bmenu-bookmark nil "The name of the last bookmark current in the bookmark list.") + +;;(@* "Compatibility Code for Older Emacs Versions") +;;; Compatibility Code for Older Emacs Versions ---------------------- + +(when (< emacs-major-version 22) + (defun bookmark-bmenu-relocate () + "Change the file path of the bookmark on the current line, + prompting with completion for the new path." + (interactive) + (let ((bmk (bookmark-bmenu-bookmark)) + (thispoint (point))) + (bookmark-relocate bmk) + (goto-char thispoint)))) + +;;(@* "Menu List Replacements (`bookmark-bmenu-*')") +;;; Menu List Replacements (`bookmark-bmenu-*') ---------------------- + + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Return t. Value doesn't mean anything (didn't anyway), but must be non-nil for vanilla Emacs. +;; 2. Do not count lines. Just make sure we're on a bookmark line. +;; +(defalias 'bookmark-bmenu-check-position 'bookmark-bmenu-ensure-position) +(defun bookmark-bmenu-ensure-position () + "Move to the beginning of the nearest bookmark line." + (beginning-of-line) + (unless (bookmark-bmenu-bookmark) + (if (and (bolp) (eobp)) + (beginning-of-line 0) + (goto-char (point-min)) + (forward-line bmkp-bmenu-header-lines))) + t) ; Older vanilla bookmark code depends on non-nil value. + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Add bookmark to `bmkp-bmenu-marked-bookmarks'. +;; 2. Don't call `bookmark-bmenu-ensure-position' again at end. +;; 3. Raise error if not in `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-mark () ; Bound to `m' in bookmark list + "Mark the bookmark on this line, using mark `>'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (beginning-of-line) + (let ((inhibit-read-only t)) + (push (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks) + (delete-char 1) (insert ?>) (put-text-property (1- (point)) (point) 'face 'bmkp->-mark) + (forward-line 1))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Remove bookmark from `bmkp-bmenu-marked-bookmarks'. +;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'. +;; 3. Don't call `bookmark-bmenu-ensure-position' again at end. +;; 4. Raise error if not in `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-unmark (&optional backup) ; Bound to `u' in bookmark list + "Unmark the bookmark on this line, then move down to the next. +Optional BACKUP means move up instead." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (beginning-of-line) + (let ((inhibit-read-only t)) + (delete-char 1) (insert " ") + (setq bmkp-bmenu-marked-bookmarks (bmkp-delete-bookmark-name-from-list + (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks))) + (forward-line (if backup -1 1))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Do not use `bookmark-bmenu-ensure-position' as a test - it always returns non-nil anyway. +;; And don't call it at again the end. +;; 2. Use `bmkp-delete-bookmark-name-from-list', not `delete'. +;; 3. Use face `bmkp-bad-bookmark' on the `D' flag. +;; 4. Raise error if not in buffer `*Bookmark List*'. +;; 5. Remove bookmark from `bmkp-bmenu-marked-bookmarks'. +;; +;;;###autoload +(defun bookmark-bmenu-delete () ; Bound to `d', `k' in bookmark list + "Flag this bookmark for deletion, using mark `D'. +Use `\\\\[bookmark-bmenu-execute-deletions]' to carry out \ +the deletions." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (beginning-of-line) + (bookmark-bmenu-ensure-position) + (let ((inhibit-read-only t)) + (delete-char 1) (insert ?D) (put-text-property (1- (point)) (point) 'face 'bmkp-D-mark)) + (setq bmkp-bmenu-marked-bookmarks (bmkp-delete-bookmark-name-from-list + (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks)) + (forward-line 1)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Rebuild the menu list using the last filtered alist in use, `bmkp-latest-bookmark-alist'. +;; 2. Update the menu-list title. +;; +(defun bookmark-bmenu-surreptitiously-rebuild-list () + "Rebuild the bookmark list, if it exists." + (when (get-buffer "*Bookmark List*") + (save-excursion (save-window-excursion (let ((bookmark-alist bmkp-latest-bookmark-alist)) + (bookmark-bmenu-list 'filteredp)))))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added args TITLE, FILTEREDP, DONT-TOGGLE-FILENAMES-P. +;; 2. Handles also region bookmarks and buffer (non-file) bookmarks. +;; 3. Uses `pop-to-buffer', not `switch-to-buffer', so we respect `special-display-*' +;; (but keep `one-window-p' if that's the case). +;; 4. If option `bmkp-bmenu-state-file' is non-nil, then the first time since the last quit +;; (or the last Emacs session) restores the last menu-list state. +;; 5. If option `bmkp-bmenu-commands-file' is non-nil, then read that file, which contains +;; user-defined `*Bookmark List*' commands. +;; +;;;###autoload +(defalias 'list-bookmarks 'bookmark-bmenu-list) +;;;###autoload +(defun bookmark-bmenu-list (&optional filteredp) ; Bound to `C-x r l' + "Display a list of existing bookmarks, in buffer `*Bookmark List*'. +The leftmost column of a bookmark entry shows `D' if the bookmark is + flagged for deletion, or `>' if it is marked normally. +The second column shows `t' if the bookmark has tags. +The third column shows `a' if the bookmark has an annotation. + +The following faces are used for the list entries. +Use `customize-face' if you want to change the appearance. + + `bmkp-bad-bookmark', `bmkp-bookmark-list', `bmkp-buffer', + `bmkp-desktop', `bmkp-function', `bmkp-gnus', `bmkp-info', + `bmkp-local-directory', `bmkp-local-file-without-region', + `bmkp-local-file-with-region', `bmkp-man', `bmkp-non-file', + `bmkp-remote-file', `bmkp-sequence', `bmkp-su-or-sudo', `bmkp-url', + `bmkp-variable-list'. + +If option `bmkp-bmenu-state-file' is non-nil then the state of the +displayed bookmark-list is saved when you quit it, and it is restored +when you next use this command. That saved state is not restored, +however, if it represents a different file from the current bookmark +file. + +If you call this interactively when buffer `*Bookmark List*' exists, +that buffer is refreshed to show all current bookmarks, and any +markings are removed. If you instead want to show the buffer in its +latest state then just do that: use `C-x b' or similar. If you want +to refresh the displayed buffer, to show the latest state, reflecting +any additions, deletions, renamings, and so on, use \\\ +`\\[bmkp-bmenu-refresh-menu-list]'. + +In Lisp code, non-nil optional argument FILTEREDP means the bookmark +list has been filtered, which means: + * Use `bmkp-bmenu-title' not the default menu-list title. + * Do not reset `bmkp-latest-bookmark-alist' to `bookmark-alist'." + (interactive) + (bookmark-maybe-load-default-file) + (when (and bmkp-bmenu-first-time-p bmkp-bmenu-commands-file + (file-readable-p bmkp-bmenu-commands-file)) + (with-current-buffer (let ((enable-local-variables ()) + (emacs-lisp-mode-hook nil)) + (find-file-noselect bmkp-bmenu-commands-file)) + (goto-char (point-min)) + (while (not (eobp)) (condition-case nil (eval (read (current-buffer))) (error nil))) + (kill-buffer (current-buffer)))) + (cond ((and bmkp-bmenu-first-time-p bmkp-bmenu-state-file ; Restore from state file. + (file-readable-p bmkp-bmenu-state-file)) + (let ((state ())) + (with-current-buffer (let ((enable-local-variables nil) + (emacs-lisp-mode-hook nil)) + (find-file-noselect bmkp-bmenu-state-file)) + (goto-char (point-min)) + (setq state (condition-case nil (read (current-buffer)) (error nil))) + (kill-buffer (current-buffer))) + (let ((last-bookmark-file-from-state (cdr (assq 'last-bookmark-file state)))) + (when (and (consp state) + ;; If bookmark file has changed, then do not use state saved from other file. + (or (not last-bookmark-file-from-state) + (bmkp-same-file-p last-bookmark-file-from-state + bmkp-current-bookmark-file))) + (setq bmkp-sort-comparer (cdr (assq 'last-sort-comparer state)) + bmkp-reverse-sort-p (cdr (assq 'last-reverse-sort-p state)) + bmkp-reverse-multi-sort-p (cdr (assq 'last-reverse-multi-sort-p state)) + bmkp-latest-bookmark-alist (cdr (assq 'last-latest-bookmark-alist state)) + bmkp-bmenu-omitted-bookmarks (cdr (assq 'last-bmenu-omitted-bookmarks state)) + bmkp-bmenu-marked-bookmarks (cdr (assq 'last-bmenu-marked-bookmarks state)) + bmkp-bmenu-filter-function (cdr (assq 'last-bmenu-filter-function state)) + bmkp-bmenu-filter-pattern + (or (cdr (assq 'last-bmenu-filter-pattern state)) "") + bmkp-bmenu-title (cdr (assq 'last-bmenu-title state)) + bmkp-last-bmenu-bookmark (cdr (assq 'last-bmenu-bookmark state)) + bmkp-last-specific-buffer (cdr (assq 'last-specific-buffer state)) + bmkp-last-specific-file (cdr (assq 'last-specific-file state)) + bookmark-bmenu-toggle-filenames (cdr (assq 'last-bmenu-toggle-filenames state)) + bmkp-last-bookmark-file bmkp-current-bookmark-file + bmkp-current-bookmark-file last-bookmark-file-from-state + bmkp-bmenu-before-hide-marked-alist + (cdr (assq 'last-bmenu-before-hide-marked-alist state)) + bmkp-bmenu-before-hide-unmarked-alist + (cdr (assq 'last-bmenu-before-hide-unmarked-alist state)))))) + (setq bmkp-bmenu-first-time-p nil) + (let ((bookmark-alist (or bmkp-latest-bookmark-alist bookmark-alist))) + (bmkp-bmenu-list-1 'filteredp nil (interactive-p))) + (when bmkp-last-bmenu-bookmark + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark)))) + (t + (setq bmkp-bmenu-first-time-p nil) + (bmkp-bmenu-list-1 filteredp + (or (interactive-p) (not (get-buffer "*Bookmark List*"))) + (interactive-p))))) + +(defun bmkp-bmenu-list-1 (filteredp reset-marked-p interactivep) + "Helper for `bookmark-bmenu-list'. +See `bookmark-bmenu-list' for the description of FILTEREDP. +Non-nil RESET-MARKED-P resets `bmkp-bmenu-marked-bookmarks'. +Non-nil INTERACTIVEP means `bookmark-bmenu-list' was called + interactively, so pop to the bookmark list and communicate the sort + order." + (when reset-marked-p (setq bmkp-bmenu-marked-bookmarks ())) + (unless filteredp (setq bmkp-latest-bookmark-alist bookmark-alist)) + (if interactivep + (let ((one-win-p (one-window-p))) + (pop-to-buffer (get-buffer-create "*Bookmark List*")) + (when one-win-p (delete-other-windows))) + (set-buffer (get-buffer-create "*Bookmark List*"))) + (let* ((inhibit-read-only t) + (title (if (and filteredp bmkp-bmenu-title (not (equal "" bmkp-bmenu-title))) + bmkp-bmenu-title + "All Bookmarks"))) + (erase-buffer) + (insert (format "%s\n%s\n" title (make-string (length title) ?-))) + (add-text-properties (point-min) (point) (bmkp-face-prop 'bmkp-heading)) + (let ((max-width 0) + name markedp tags annotation start) + (setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist + (and (not (eq bmkp-bmenu-filter-function + 'bmkp-omitted-alist-only)) + bmkp-bmenu-omitted-bookmarks))) + (dolist (bmk bmkp-sorted-alist) + (setq max-width (max max-width (length (bookmark-name-from-full-record bmk))))) + (setq max-width (+ max-width bmkp-bmenu-marks-width)) + (dolist (bmk bmkp-sorted-alist) + (setq name (bookmark-name-from-full-record bmk) + markedp (bmkp-marked-bookmark-p bmk) + tags (bmkp-get-tags bmk) + annotation (bookmark-get-annotation bmk) + start (+ bmkp-bmenu-marks-width (point))) + (if (not markedp) + (insert " ") + (insert ">") (put-text-property (1- (point)) (point) 'face 'bmkp->-mark)) + (if (null tags) + (insert " ") + (insert "t") (put-text-property (1- (point)) (point) 'face 'bmkp-t-mark)) + (if (not (and annotation (not (string-equal annotation "")))) + (insert " ") + (insert "a") (put-text-property (1- (point)) (point) 'face 'bmkp-a-mark)) + (insert " ") + (when (and (featurep 'bookmark+-lit) (bmkp-get-lighting bmk)) ; Highlight highlight overrides. + (put-text-property (1- (point)) (point) 'face 'bmkp-light-mark)) + (insert name) + (move-to-column max-width t) + (bmkp-bmenu-propertize-item bmk start (point)) + (insert "\n"))) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (bookmark-bmenu-mode) + (when bookmark-bmenu-toggle-filenames (bookmark-bmenu-toggle-filenames t)) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + (when (and interactivep bmkp-sort-comparer) + (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Redefined. +;; 1. Get name of the current bookmark from text property `bmkp-bookmark-name'. +;; 2. Added optional arg FULL, to return full bookmark record. +;; 3. Use `condition-case' in case we're at eob (so cannot advance). +;; +(defun bookmark-bmenu-bookmark (&optional full) + "Return the name of the bookmark on this line. +Normally, the string returned is propertized with property +`bmkp-full-record', which records the full bookmark record. +Non-nil optional FULL means return the bookmark record, not the name." + (condition-case nil + (let ((name (save-excursion (forward-line 0) (forward-char (1+ bmkp-bmenu-marks-width)) + (get-text-property (point) 'bmkp-bookmark-name)))) + (if full + (get-text-property 0 'bmkp-full-record name) + name)) + (error nil))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; Only the doc string is different. +;; +(defun bookmark-bmenu-mode () + "Major mode for editing a list of bookmarks. +Each line represents an Emacs bookmark.\\ + +More bookmarking help below. Keys without prefix `C-x' are available +only in buffer `*Bookmark List*'. Others are available everywhere. + + +Help (Describe) +--------------- + +\\[bmkp-bmenu-describe-this-bookmark]\t- Show information about this bookmark (`C-u': \ +internal form) +\\[bmkp-bmenu-describe-this+move-down]\t- Show the info, then move to next bookmark +\\[bmkp-bmenu-describe-this+move-up]\t- Show the info, then move to previous bookmark +\\[bmkp-bmenu-describe-marked]\t- Show info about the marked bookmarks (`C-u': internal form) +\\[bookmark-bmenu-locate]\t- Show the location of this bookmark in the minibuffer +\\[bookmark-bmenu-show-annotation]\t- Show this bookmark's annotation +\\[bookmark-bmenu-show-all-annotations]\t- Show the annotations of all annotated bookmarks +\\[bookmark-bmenu-toggle-filenames]\t- Toggle showing filenames next to bookmarks + +\\[bmkp-list-defuns-in-commands-file] +\t- List the commands defined in `bmkp-bmenu-commands-file' + + +General +------- + +\\[bmkp-bmenu-refresh-menu-list]\t- Refresh (revert) to up-to-date bookmark list +\\[bmkp-bmenu-quit]\t- Quit (`*Bookmark List*') +\\[bmkp-bmenu-dired-marked]\t- Open Dired for the marked files and directories + +\\[bookmark-bmenu-load]\t- Add bookmarks from a different bookmark file (extra load) +\\[bmkp-switch-bookmark-file]\t- Switch to a different bookmark file (overwrite load) +C-u \\[bmkp-switch-bookmark-file]\t- Switch back to the last bookmark file (overwrite load) +\\[bmkp-set-bookmark-file-bookmark]\t- Create a bookmark to a bookmark file \ +\(`\\[bmkp-bookmark-file-jump]' to load) + +\\[bmkp-toggle-saving-bookmark-file]\t- Toggle autosaving the bookmark file +\\[bmkp-toggle-saving-menu-list-state]\t- Toggle autosaving bookmark-list display state (this list) +\\[bookmark-bmenu-save]\t- Save bookmarks (`C-u': prompt for the bookmark file to use) +\\[bmkp-save-menu-list-state]\t- Save bookmark-list display state + +\\[bmkp-choose-navlist-of-type]\t- Set the navlist to the bookmarks of a type you choose +\\[bmkp-choose-navlist-from-bookmark-list]\t- Set the navlist to the bookmarks of a \ +bookmark-list bookmark +\\[bmkp-navlist-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in navlist +\\[bmkp-this-buffer-bmenu-list]\t- Open `*Bookmark List*' for bookmarks in current buffer +\\[bmkp-delete-bookmarks]\t- Delete some bookmarks at point or all in buffer + +\\[bmkp-toggle-bookmark-set-refreshes] +\t- Toggle whether `bookmark-set' refreshes the bookmark list +\\[bmkp-make-function-bookmark] +\t- Create a function bookmark +\\[bmkp-bmenu-make-sequence-from-marked] +\t- Create a sequence bookmark from the marked bookmarks + + +Create/Set +---------- + +\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Set/delete an autonamed bookmark here +\\[bmkp-autofile-set]\t- Set and autoname a bookmark for a file +\\[bmkp-file-target-set]\t- Set a bookmark for a file +\\[bmkp-url-target-set]\t- Set a bookmark for a URL +\\[bookmark-set]\t- Set a bookmark here +\\[bmkp-set-desktop-bookmark]\t- Set a bookmark for the current desktop +\\[bmkp-set-bookmark-file-bookmark]\t- Set a bookmark for a bookmark file + + +Jump to (Visit) +--------------- + +\\[bookmark-bmenu-select]\t- This bookmark and also visit bookmarks marked `>' +\\[bookmark-bmenu-this-window]\t- This bookmark in the same window +\\[bookmark-bmenu-other-window]\t- This bookmark in another window +\\[bookmark-bmenu-switch-other-window]\t- This bookmark in other window, without selecting it +\\[bookmark-bmenu-1-window]\t- This bookmark in a full-frame window +\\[bookmark-bmenu-2-window]\t- This bookmark and last-visited bookmark + +\\[bookmark-jump]\t- Bookmark by name +\\[bmkp-jump-to-type]\t- Bookmark by type +\\[bmkp-jump-in-navlist]\t- Bookmark in the navigation list +\\[bmkp-lighted-jump]\t- Highlighted bookmark +\\[bmkp-desktop-jump]\t- Desktop bookmark +\\[bmkp-bookmark-list-jump]\t- Bookmark-list bookmark +\\[bmkp-bookmark-file-jump]\t- Bookmark-file bookmark +\\[bmkp-dired-jump]\t- Dired bookmark +\\[bmkp-file-jump]\t- File or directory bookmark +\\[bmkp-dired-this-dir-jump]\t- Dired bookmark for this dir +\\[bmkp-file-this-dir-jump]\t- Bookmark for a file or subdir in this dir +\\[bmkp-local-file-jump]\t- Local-file bookmark +\\[bmkp-remote-file-jump]\t- Remote-file bookmark +\\[bmkp-region-jump]\t- Region bookmark +\\[bmkp-info-jump]\t- Info bookmark +\\[bmkp-man-jump]\t- `man'-page bookmark +\\[bmkp-non-file-jump]\t- Non-file (buffer) bookmark +\\[bmkp-gnus-jump]\t- Gnus bookmark +\\[bmkp-url-jump]\t- URL bookmark +\\[bmkp-variable-list-jump]\t- Variable-list bookmark +\\[bmkp-autonamed-jump]\t- Autonamed bookmark +\\[bmkp-autonamed-this-buffer-jump]\t- Autonamed bookmark in buffer +\\[bmkp-some-tags-jump]\t- Bookmark having some tags you specify +\\[bmkp-all-tags-jump]\t- Bookmark having each tag you specify +\\[bmkp-some-tags-regexp-jump]\t- Bookmark having a tag that matches a regexp +\\[bmkp-all-tags-regexp-jump]\t- Bookmark having all its tags match a regexp +\\[bmkp-file-some-tags-jump]\t- File bookmark having some tags you specify +\\[bmkp-file-all-tags-jump]\t- File bookmark having each tag you specify +\\[bmkp-file-some-tags-regexp-jump]\t- File bookmark having a tag that matches a regexp +\\[bmkp-file-all-tags-regexp-jump]\t- File bookmark having all its tags match a regexp +\\[bmkp-file-this-dir-some-tags-jump]\t- File in this dir having some tags you specify +\\[bmkp-file-this-dir-all-tags-jump]\t- File in this dir having each tag you specify +\\[bmkp-file-this-dir-some-tags-regexp-jump]\t- File in this dir having a tag that matches a regexp +\\[bmkp-file-this-dir-all-tags-regexp-jump]\t- File in this dir having all its tags match a regexp + + +Cycle Bookmarks and Autonamed Bookmarks +--------------------------------------- + +\\[bmkp-toggle-autonamed-bookmark-set/delete]\t- Create/delete autonamed bookmark at point +\\[bmkp-autonamed-jump]\t- Jump to an autonamed bookmark +\\[bmkp-autonamed-this-buffer-jump]\t- Jump to an autonamed bookmark in buffer +C-x p n n ...\t- Next bookmark in buffer (C-x p C-n, C-x p down) +C-x p p p ...\t- Previous bookmark in buffer (C-x p C-p, C-x p up) +C-x p f f ...\t- Next bookmark in navlist (C-x p C-f, C-x p right) +C-x p b b ...\t- Previous bookmark in navlist (C-x p C-b, C-x p left) +C-x p next ...\t- MS Windows `Open' next bookmark in navlist +C-x p prior ...\t- MS Windows `Open' previous bookmark in navlist +C-x C-down ...\t- Next highlighted bookmark in buffer +C-x C-up ...\t- Previous highlighted bookmark in buffer + +\\[bmkp-delete-all-autonamed-for-this-buffer] +\t- Delete all autonamed bookmarks in current buffer + + +Search-and-Replace Targets (in sort order) +-------------------------- + +M-s a C-s\t- Isearch the marked bookmarks (Emacs 23+) +M-s a C-M-s\t- Regexp-isearch the marked bookmarks (Emacs 23+) +\\[bmkp-bmenu-search-marked-bookmarks-regexp]\t- Regexp-search the marked file bookmarks +\\[bmkp-bmenu-query-replace-marked-bookmarks-regexp]\t\t- Query-replace the marked file \ +bookmarks + + +Mark/Unmark +----------- + +\(Mark means `>'. Flag means `D'. See also `Tags', below.) + +\\[bookmark-bmenu-delete]\t- Flag this bookmark `D' for deletion, then move down +\\[bookmark-bmenu-delete-backwards]\t- Flag this bookmark `D' for deletion, then move up + +\\[bookmark-bmenu-mark]\t- Mark this bookmark +\\[bookmark-bmenu-unmark]\t- Unmark this bookmark (`C-u': move up one line) +\\[bookmark-bmenu-backup-unmark]\t- Unmark previous bookmark (move up, then unmark) + +\\[bmkp-bmenu-mark-all]\t- Mark all bookmarks +\\[bmkp-bmenu-regexp-mark]\t- Mark all bookmarks whose names match a regexp +\\[bmkp-bmenu-unmark-all]\t- Unmark all bookmarks (`C-u': interactive query) +\\[bmkp-bmenu-toggle-marks]\t- Toggle marks: unmark the marked and mark the unmarked + +\\[bmkp-bmenu-mark-autofile-bookmarks]\t- Mark autofile bookmarks +\\[bmkp-bmenu-mark-non-file-bookmarks]\t- Mark non-file (i.e. buffer) bookmarks +\\[bmkp-bmenu-mark-dired-bookmarks]\t- Mark Dired bookmarks +\\[bmkp-bmenu-mark-file-bookmarks]\t- Mark file & directory bookmarks (`C-u': local only) +\\[bmkp-bmenu-mark-gnus-bookmarks]\t- Mark Gnus bookmarks +\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark the highlighted bookmarks +\\[bmkp-bmenu-mark-info-bookmarks]\t- Mark Info bookmarks +\\[bmkp-bmenu-mark-desktop-bookmarks]\t- Mark desktop bookmarks +\\[bmkp-bmenu-mark-bookmark-file-bookmarks]\t- Mark bookmark-file bookmarks +\\[bmkp-bmenu-mark-man-bookmarks]\t- Mark `man' page bookmarks (that's `M' twice, not Meta-M) +\\[bmkp-bmenu-mark-region-bookmarks]\t- Mark region bookmarks +\\[bmkp-bmenu-mark-url-bookmarks]\t- Mark URL bookmarks +\\[bmkp-bmenu-mark-w3m-bookmarks]\t- Mark W3M (URL) bookmarks + + +Modify +------ + +\(See also `Tags', next.) + +\\[bookmark-bmenu-edit-annotation]\t- Edit this bookmark's annotation +\\[bmkp-bmenu-edit-bookmark]\t- Rename and relocate this bookmark +\\[bookmark-bmenu-rename]\t- Rename this bookmark +\\[bookmark-bmenu-relocate]\t- Relocate this bookmark (change file) +\\[bmkp-bmenu-edit-tags]\t- Edit this bookmark's tags +\\[bookmark-bmenu-execute-deletions]\t- Delete (visible) bookmarks flagged `D' +\\[bmkp-bmenu-delete-marked]\t- Delete (visible) bookmarks marked `>' + + +Tags +---- + +\\[bmkp-add-tags]\t- Add some tags to a bookmark +\\[bmkp-remove-tags]\t- Remove some tags from a bookmark +\\[bmkp-remove-all-tags]\t- Remove all tags from a bookmark +\\[bmkp-remove-tags-from-all]\t- Remove some tags from all bookmarks +\\[bmkp-rename-tag]\t- Rename a tag in all bookmarks +\\[bmkp-list-all-tags]\t- List all tags used in any bookmarks (`C-u': show tag values) +\\[bmkp-bmenu-edit-tags]\t- Edit this bookmark's tags +\\[bmkp-bmenu-set-tag-value]\t- Set the value of a tag (as attribute) + +\\[bmkp-bmenu-add-tags-to-marked]\t- Add some tags to the marked bookmarks +\\[bmkp-bmenu-remove-tags-from-marked]\t- Remove some tags from the marked bookmarks + +\\[bmkp-bmenu-mark-bookmarks-tagged-regexp]\t- Mark bookmarks having at least one \ +tag that matches a regexp +\\[bmkp-bmenu-mark-bookmarks-tagged-some]\t- Mark bookmarks having at least one tag \ +in a set (OR) +\\[bmkp-bmenu-mark-bookmarks-tagged-all]\t- Mark bookmarks having all of the tags \ +in a set (AND) +\\[bmkp-bmenu-mark-bookmarks-tagged-none]\t- Mark bookmarks not having any of the tags \ +in a set (NOT OR) +\\[bmkp-bmenu-mark-bookmarks-tagged-not-all]\t- Mark bookmarks not having all of the \ +tags in a set (NOT AND) + +\\[bmkp-bmenu-unmark-bookmarks-tagged-regexp]\t- Unmark bookmarks having at least one \ +tag that matches a regexp +\\[bmkp-bmenu-unmark-bookmarks-tagged-some]\t- Unmark bookmarks having at least one \ +tag in a set (OR) +\\[bmkp-bmenu-unmark-bookmarks-tagged-all]\t- Unmark bookmarks having all of the tags \ +in a set (AND) +\\[bmkp-bmenu-unmark-bookmarks-tagged-none]\t- Unmark bookmarks not having any tags \ +in a set (NOT OR) +\\[bmkp-bmenu-unmark-bookmarks-tagged-not-all]\t- Unmark bookmarks not having all tags \ +in a set (NOT AND) + + +Bookmark Highlighting +--------------------- + +\\[bmkp-bmenu-show-only-lighted]\t- Show only the highlighted bookmarks +\\[bmkp-bmenu-set-lighting]\t- Set highlighting for this bookmark +\\[bmkp-bmenu-set-lighting-for-marked]\t- Set highlighting for marked bookmarks +\\[bmkp-bmenu-light]\t- Highlight this bookmark +\\[bmkp-bmenu-unlight]\t- Unhighlight this bookmark +\\[bmkp-bmenu-mark-lighted-bookmarks]\t- Mark the highlighted bookmarks +\\[bmkp-bmenu-light-marked]\t- Highlight the marked bookmarks +\\[bmkp-bmenu-unlight-marked]\t- Unhighlight the marked bookmarks +\\[bmkp-light-bookmark-this-buffer]\t- Highlight a bookmark in current buffer +\\[bmkp-unlight-bookmark-this-buffer]\t- Unhighlight a bookmark in current buffer +\\[bmkp-light-bookmarks]\t- Highlight bookmarks (see prefix arg) +\\[bmkp-unlight-bookmarks]\t- Unhighlight bookmarks (see prefix arg) +\\[bmkp-bookmarks-lighted-at-point]\t- List bookmarks highlighted at point +\\[bmkp-unlight-bookmark-here]\t- Unhighlight a bookmark at point or on same line + + +Sort +---- + +\(Repeat to cycle normal/reversed/off, except as noted.) + +\\[bmkp-bmenu-sort-marked-before-unmarked]\t- Sort marked bookmarks first +\\[bmkp-bmenu-sort-by-last-buffer-or-file-access]\t- Sort by last buffer or file \ +access +\\[bmkp-bmenu-sort-by-Gnus-thread]\t- Sort by Gnus thread: group, article, message +\\[bmkp-bmenu-sort-by-Info-location]\t- Sort by Info manual, node, position +\\[bmkp-bmenu-sort-by-bookmark-type]\t- Sort by bookmark type +\\[bmkp-bmenu-sort-by-bookmark-name]\t- Sort by bookmark name +\\[bmkp-bmenu-sort-by-creation-time]\t- Sort by bookmark creation time +\\[bmkp-bmenu-sort-by-last-bookmark-access]\t- Sort by last bookmark access time +\\[bmkp-bmenu-sort-by-bookmark-visit-frequency]\t- Sort by bookmark visit frequency +\\[bmkp-bmenu-sort-by-url]\t- Sort by URL + +\\[bmkp-bmenu-sort-by-local-file-type]\t- Sort by local file type: file, symlink, dir +\\[bmkp-bmenu-sort-by-file-name]\t- Sort by file name +\\[bmkp-bmenu-sort-by-local-file-size]\t- Sort by local file size +\\[bmkp-bmenu-sort-by-last-local-file-access]\t- Sort by last local file access +\\[bmkp-bmenu-sort-by-last-local-file-update]\t- Sort by last local file update (edit) + +\\[bmkp-reverse-sort-order]\t- Reverse current sort direction (repeat to toggle) +\\[bmkp-reverse-multi-sort-order]\t- Complement sort predicate decisions (repeat \ +to toggle) +\\[bmkp-bmenu-change-sort-order-repeat]\t- Cycle sort orders (repeat \ +to cycle) + + +Hide/Show +--------- + +\\[bmkp-bmenu-show-all]\t- Show all bookmarks +\\[bmkp-bmenu-toggle-show-only-marked]\t- Toggle showing only marked bookmarks +\\[bmkp-bmenu-toggle-show-only-unmarked]\t- Toggle showing only unmarked bookmarks +\\[bmkp-bmenu-show-only-autofiles]\t- Show only autofile bookmarks +\\[bmkp-bmenu-show-only-autonamed]\t- Show only autonamed bookmarks +\\[bmkp-bmenu-show-only-non-files]\t- Show only non-file (i.e. buffer) bookmarks +\\[bmkp-bmenu-show-only-dired]\t- Show only Dired bookmarks +\\[bmkp-bmenu-show-only-files]\t- Show only file & directory bookmarks (`C-u': local only) +\\[bmkp-bmenu-show-only-gnus]\t- Show only Gnus bookmarks +\\[bmkp-bmenu-show-only-info-nodes]\t- Show only Info bookmarks +\\[bmkp-bmenu-show-only-desktops]\t- Show only desktop bookmarks +\\[bmkp-bmenu-show-only-bookmark-files]\t- Show only bookmark-file bookmarks +\\[bmkp-bmenu-show-only-man-pages]\t- Show only `man' page bookmarks +\\[bmkp-bmenu-show-only-regions]\t- Show only region bookmarks +\\[bmkp-bmenu-show-only-variable-lists]\t- Show only variable-list bookmarks +\\[bmkp-bmenu-show-only-urls]\t- Show only URL bookmarks +\\[bmkp-bmenu-show-only-w3m-urls]\t- Show only W3M (URL) bookmarks +\\[bmkp-bmenu-filter-bookmark-name-incrementally]\t- Incrementally show only bookmarks \ +whose names match a regexp +\\[bmkp-bmenu-filter-file-name-incrementally]\t- Incrementally show only bookmarks whose \ +files match a regexp +\\[bmkp-bmenu-filter-annotation-incrementally]\t- Incrementally show only bookmarks whose \ +annotations match a regexp +\\[bmkp-bmenu-filter-tags-incrementally]\t- Incrementally show only bookmarks whose tags \ +match a regexp +\\[bmkp-bmenu-show-only-tagged]\t- Show only bookmarks that have tags + + +Omit/Un-omit +------------ + +\\[bmkp-bmenu-show-only-omitted]\t- Show (only) the omitted bookmarks +\\[bmkp-bmenu-show-all]\t- Show the un-omitted bookmarks (all) +\\[bmkp-bmenu-omit/unomit-marked]\t- Omit the marked bookmarks; un-omit them if after \ +`\\[bmkp-bmenu-show-only-omitted]' +\\[bmkp-unomit-all]\t- Un-omit all omitted bookmarks + + +Define Commands for `*Bookmark List*' +------------------------------------- + +\\[bmkp-bmenu-define-command]\t- Define a command to restore the current sort order & filter +\\[bmkp-bmenu-define-full-snapshot-command]\t- Define a command to restore the current \ +bookmark-list state +\\[bmkp-define-tags-sort-command]\t- Define a command to sort bookmarks by tags +\\[bmkp-bmenu-define-jump-marked-command]\t- Define a command to jump to a bookmark that is \ +now marked + + +Options for `*Bookmark List*' +----------------------------- + +bookmark-bmenu-file-column - Bookmark width if files are shown +bookmark-bmenu-toggle-filenames - Show filenames initially? + +bmkp-bmenu-omitted-bookmarks - List of omitted bookmarks +bmkp-bmenu-state-file - File to save bookmark-list state + (\"home\") nil: do not save/restore +bmkp-sort-comparer - Initial sort +bmkp-sort-orders-for-cycling-alist +\t - Sort orders that `\\[bmkp-bmenu-change-sort-order-repeat]'... cycles + + +Other Options +------------- + +bookmark-automatically-show-annotations - Show annotation when visit? +bookmark-completion-ignore-case - Case-sensitive completion? +bookmark-default-file - File to save bookmarks in +bookmark-menu-length - Max size of bookmark-name menu item +bookmark-save-flag - Whether and when to save +bookmark-use-annotations - Query for annotation when saving? +bookmark-version-control - Numbered backups of bookmark file? + +bmkp-autoname-format - Format of autonamed bookmark name +bmkp-crosshairs-flag - Highlight position when visit? +bmkp-menu-popup-max-length - Use menus to choose bookmarks? +bmkp-save-new-location-flag - Save if bookmark relocated? +bmkp-sequence-jump-display-function - How to display a sequence +bmkp-sort-comparer - Predicates for sorting bookmarks +bmkp-su-or-sudo-regexp - Bounce-show each end of region? +bmkp-this-buffer-cycle-sort-comparer - This-buffer cycling sort +bmkp-use-region - Activate saved region when visit?" + (kill-all-local-variables) + (use-local-map bookmark-bmenu-mode-map) + (setq truncate-lines t + buffer-read-only t + major-mode 'bookmark-bmenu-mode + mode-name "Bookmark Menu") + (if (fboundp 'run-mode-hooks) + (run-mode-hooks 'bookmark-bmenu-mode-hook) + (run-hooks 'bookmark-bmenu-mode-hook))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Put `mouse-face' on whole line, with the same help-echo as for the bookmark name. +;; 2. Fit one-window frame. +;; 3. Added doc string. +;; +(defun bookmark-bmenu-show-filenames (&optional force) + "Show file names." + (if (and (not force) bookmark-bmenu-toggle-filenames) + nil ; Already shown, so do nothing. + (save-excursion + (save-window-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (setq bookmark-bmenu-hidden-bookmarks ()) + (let ((inhibit-read-only t)) + (while (< (point) (point-max)) + (let ((bmk (bookmark-bmenu-bookmark))) + (setq bookmark-bmenu-hidden-bookmarks (cons bmk bookmark-bmenu-hidden-bookmarks)) + (let ((start (save-excursion (end-of-line) (point)))) + (move-to-column bookmark-bmenu-file-column t)) + (delete-region (point) (progn (end-of-line) (point))) + (insert " ") + (bookmark-insert-location bmk t) ; Pass the NO-HISTORY arg. + (when (if (fboundp 'display-color-p) ; Emacs 21+. + (and (display-color-p) (display-mouse-p)) + window-system) + (let ((help (get-text-property (+ bmkp-bmenu-marks-width + (line-beginning-position)) 'help-echo))) + (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position)) + (point) 'mouse-face 'highlight) + (when help (put-text-property (+ bmkp-bmenu-marks-width (line-beginning-position)) + (point) 'help-echo help)))) + (forward-line 1)))))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Add text properties when hiding filenames. +;; 2. Do not set or use `bookmark-bmenu-bookmark-column' - use `bmkp-bmenu-marks-width' always. +;; 3. Fit one-window frame. +;; 4. Added doc string. +;; +(defun bookmark-bmenu-hide-filenames (&optional force) + "Hide filenames in bookmark-list buffer. +If either optional arg FORCE or `bookmark-bmenu-toggle-filenames' is +non-nil, then do nothing." + (when (and (not force) bookmark-bmenu-toggle-filenames) + (save-excursion + (save-window-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (setq bookmark-bmenu-hidden-bookmarks (nreverse bookmark-bmenu-hidden-bookmarks)) + (let ((max-width 0)) + (dolist (name bookmark-bmenu-hidden-bookmarks) + (setq max-width (max max-width (length name)))) + (setq max-width (+ max-width bmkp-bmenu-marks-width)) + (save-excursion + (let ((inhibit-read-only t)) + (while bookmark-bmenu-hidden-bookmarks + (move-to-column bmkp-bmenu-marks-width t) + (bookmark-kill-line) + (let ((name (car bookmark-bmenu-hidden-bookmarks)) + (start (point)) + end) + (insert name) + (move-to-column max-width t) + (setq end (point)) + (bmkp-bmenu-propertize-item name start end)) + (setq bookmark-bmenu-hidden-bookmarks (cdr bookmark-bmenu-hidden-bookmarks)) + (forward-line 1))))))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-1-window (&optional use-region-p) ; Bound to `1' in bookmark list + "Select this line's bookmark, alone, in full frame. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-jump-1 (bookmark-bmenu-bookmark) 'pop-to-buffer use-region-p) + (bury-buffer (other-buffer)) + (delete-other-windows)) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-2-window (&optional use-region-p) ; Bound to `2' in bookmark list + "Select this line's bookmark, with previous buffer in second window. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark)) + (menu (current-buffer)) + (pop-up-windows t)) + (delete-other-windows) + (switch-to-buffer (other-buffer)) + ;; (let ((bookmark-automatically-show-annotations nil)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'pop-to-buffer use-region-p) + (bury-buffer menu))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-this-window (&optional use-region-p) ; Bound to `RET' in bookmark list + "Select this line's bookmark in this window. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Use `pop-to-buffer', not `switch-to-buffer-other-window'. +;; 2. Prefix arg reverses `bmkp-use-region'. +;; 3. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-other-window (&optional use-region-p) ; Bound to `o' in bookmark list + "Select this line's bookmark in other window. Show `*Bookmark List*' still. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark))) + ;; (bookmark-automatically-show-annotations t)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-switch-other-window (&optional use-region-p) ; Bound to `C-o' in bookmark list + "Make the other window select this line's bookmark. +The current window remains selected. +See `bookmark-jump' for info about the prefix arg." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark-name (bookmark-bmenu-bookmark)) + (pop-up-windows t) + (same-window-buffer-names ()) + (same-window-regexps ())) + ;; (bookmark-automatically-show-annotations t)) ; $$$$$$ Needed? + (bmkp-jump-1 bookmark-name 'display-buffer use-region-p))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Prefix arg reverses `bmkp-use-region'. +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-other-window-with-mouse (event &optional use-region-p) + "Select clicked bookmark in other window. Show `*Bookmark List*' still." + (interactive "e\nP") + (with-current-buffer (window-buffer (posn-window (event-end event))) + (save-excursion (goto-char (posn-point (event-end event))) + (bookmark-bmenu-other-window use-region-p)))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg MSGP. +;; 2. Call `bookmark-show-annotation' with arg MSGP. +;; 3. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-show-annotation (msgp) + "Show the annotation for the current bookmark in another window." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark (bookmark-bmenu-bookmark))) + (bookmark-show-annotation bookmark msgp))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Added optional arg MARKEDP: handle bookmarks marked `>', not just those flagged `D'. +;; 2. Use `bookmark-bmenu-surreptitiously-rebuild-list', instead of using +;; `bookmark-bmenu-list', updating the modification count, and saving. +;; 3. Update `bmkp-latest-bookmark-alist' to reflect the deletions. +;; 4. Pass full bookmark, not name, to `delete' (and do not use `assoc'). +;; 5. Use `bmkp-bmenu-goto-bookmark-named'. +;; 6. Added status messages. +;; 7. Raise error if not in buffer `*Bookmark List*'. +;; +;;;###autoload +(defun bookmark-bmenu-execute-deletions (&optional markedp) ; Bound to `x' in bookmark list + "Delete (visible) bookmarks flagged `D'. +With a prefix argument, delete the bookmarks marked `>' instead, after +confirmation." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (not markedp) (yes-or-no-p "Delete bookmarks marked `>' (not `D') ")) + (let* ((mark-type (if markedp "^>" "^D")) + (o-str (and (not (looking-at mark-type)) (bookmark-bmenu-bookmark))) + (o-point (point)) + (count 0)) + (message "Deleting bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward mark-type (point-max) t) + (let* ((bmk-name (bookmark-bmenu-bookmark)) + (bmk (bookmark-get-bookmark bmk-name))) + (bookmark-delete bmk-name 'batch) + (setq count (1+ count) + bmkp-latest-bookmark-alist (delete bmk bmkp-latest-bookmark-alist)))) + (if (<= count 0) + (message (if markedp "No marked bookmarks" "No bookmarks flagged for deletion")) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Deleted %d bookmarks" count)) + (if o-str + (bmkp-bmenu-goto-bookmark-named o-str) + (goto-char o-point) + (beginning-of-line))) + (message "OK, nothing deleted"))) + + +;; REPLACES ORIGINAL in `bookmark.el'. +;; +;; 1. Do not call `bookmark-bmenu-list' (it was already called). +;; 2. Raise error if not in buffer `*Bookmark List*'. +;; 3. Use `bmkp-bmenu-goto-bookmark-named' instead of just searching for name. +;; +;;;###autoload +(defun bookmark-bmenu-rename () ; Bound to `r' in bookmark list + "Rename bookmark on current line. Prompts for a new name." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((newname (bookmark-rename (bookmark-bmenu-bookmark)))) + (bmkp-bmenu-goto-bookmark-named newname))) + +;;(@* "Bookmark+ Functions (`bmkp-*')") +;;; Bookmark+ Functions (`bmkp-*') ----------------------------------- + + +;;(@* "Menu-List (`*-bmenu-*') Filter Commands") +;; *** Menu-List (`*-bmenu-*') Filter Commands *** + +;;;###autoload +(defun bmkp-bmenu-show-only-autofiles (&optional arg) ; Bound to `A S' in bookmark list + "Display (only) the autofile bookmarks. +This means bookmarks whose names are the same as their (non-directory) +file names. But with a prefix arg you are prompted for a prefix that +each bookmark name must have." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function (if (not arg) + 'bmkp-autofile-alist-only + (let ((prefix (read-string "Prefix for bookmark names: " + nil nil ""))) + `(lambda () (bmkp-autofile-alist-only ,prefix)))) + bmkp-bmenu-title "Autofile Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only autofile bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-autonamed () ; Bound to `# S' in bookmark list + "Display (only) the autonamed bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-autonamed-alist-only + bmkp-bmenu-title "Autonamed Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only autonamed bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-bookmark-files () ; Bound to `X S' in bookmark list + "Display (only) the bookmark-file bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-bookmark-file-alist-only + bmkp-bmenu-title "Bookmark-File Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only bookmark-file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-desktops () ; Bound to `K S' in bookmark list + "Display (only) the desktop bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-desktop-alist-only + bmkp-bmenu-title "Desktop Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only desktop bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-dired () ; Bound to `M-d M-s' in bookmark list + "Display (only) the Dired bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-dired-alist-only + bmkp-bmenu-title "Dired Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Dired bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-files (arg) ; Bound to `F S' in bookmark list + "Display a list of file and directory bookmarks (only). +With a prefix argument, do not include remote files or directories." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function (if arg 'bmkp-local-file-alist-only 'bmkp-file-alist-only) + bmkp-bmenu-title (if arg + "Local File and Directory Bookmarks" + "File and Directory Bookmarks")) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-non-files () ; Bound to `B S' in bookmark list + "Display (only) the non-file bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-non-file-alist-only + bmkp-bmenu-title "Non-File Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only non-file bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-gnus () ; Bound to `G S' in bookmark list + "Display (only) the Gnus bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-gnus-alist-only + bmkp-bmenu-title "Gnus Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Gnus bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-info-nodes () ; Bound to `I S' in bookmark list + "Display (only) the Info bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-info-alist-only + bmkp-bmenu-title "Info Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only Info bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-man-pages () ; Bound to `M S' in bookmark list + "Display (only) the `man' page bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-man-alist-only + bmkp-bmenu-title "`man' Page Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only `man' page bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-regions () ; Bound to `R S' in bookmark list + "Display (only) the bookmarks that record a region." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-region-alist-only + bmkp-bmenu-title "Region Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only bookmarks with regions are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-variable-lists () ; Bound to `V S' in bookmark list + "Display (only) the variable-list bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-variable-list-alist-only + bmkp-bmenu-title "Variable-list Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only variable-list bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-specific-buffer (&optional buffer) ; Bound to `= b S' in bookmark list + "Display (only) the bookmarks for BUFFER. +Interactively, read the BUFFER name. +If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it." + (interactive (list (bmkp-completing-read-buffer-name))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when buffer (setq bmkp-last-specific-buffer buffer)) + (setq bmkp-bmenu-filter-function 'bmkp-last-specific-buffer-alist-only + bmkp-bmenu-title (format "Buffer `%s' Bookmarks" bmkp-last-specific-buffer)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + (format "Only bookmarks for buffer `%s' are shown" + bmkp-last-specific-buffer)))) + +;;;###autoload +(defun bmkp-bmenu-show-only-specific-file (&optional file) ; Bound to `= f S' in bookmark list + "Display (only) the bookmarks for FILE, an absolute file name. +Interactively, read the FILE name. +If FILE is non-nil, set `bmkp-last-specific-file' to it." + (interactive (list (bmkp-completing-read-file-name))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when file (setq bmkp-last-specific-file file)) + (setq bmkp-bmenu-filter-function 'bmkp-last-specific-file-alist-only + bmkp-bmenu-title (format "File `%s' Bookmarks" bmkp-last-specific-file)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) + (format "Only bookmarks for file `%s' are shown" + bmkp-last-specific-file)))) + +;;;###autoload +(defun bmkp-bmenu-show-only-urls () ; Bound to `M-u M-s' in bookmark list + "Display (only) the URL bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-url-alist-only + bmkp-bmenu-title "URL Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only URL bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-only-w3m-urls () ; Bound to `W S' in bookmark list + "Display (only) the W3M URL bookmarks." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-w3m-alist-only + bmkp-bmenu-title "W3M Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only W3M bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-show-all () ; Bound to `.' in bookmark list + "Show all bookmarks known to the bookmark list (aka \"menu list\"). +Omitted bookmarks are not shown, however. +Also, this does not revert the bookmark list, to bring it up to date. +To revert the list, use `\\\\[bmkp-bmenu-refresh-menu-list]'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function nil + bmkp-bmenu-title "All Bookmarks" + bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "All bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-refresh-menu-list () ; Bound to `g' in bookmark list + "Refresh (revert) the bookmark list (\"menu list\"). +This brings the displayed list up to date. It does not change the +current filtering or sorting of the displayed list. + +If you want setting a bookmark to refresh the list automatically, you +can use command `bmkp-toggle-bookmark-set-refreshes'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-refresh-menu-list (bookmark-bmenu-bookmark))) + +;;;###autoload +(defun bmkp-bmenu-filter-bookmark-name-incrementally () ; Bound to `P B' in bookmark list + "Incrementally filter bookmarks by bookmark name using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-bookmark-name-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-bookmark-name-regexp () + "Filter bookmarks by bookmark name, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-bookmark-name-alist-only + bmkp-bmenu-title (format "Bookmarks with Names Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-file-name-incrementally () ; Bound to `P F' in bookmark list + "Incrementally filter bookmarks by file name using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-file-name-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-file-name-regexp () + "Filter bookmarks by file name, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-file-name-alist-only + bmkp-bmenu-title (format "Bookmarks with File Names Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-annotation-incrementally () ; Bound to `P A' in bookmark list + "Incrementally filter bookmarks by their annotations using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-annotation-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-annotation-regexp () + "Filter bookmarks by annoation, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-annotation-alist-only + bmkp-bmenu-title (format "Bookmarks with Annotations Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +;;;###autoload +(defun bmkp-bmenu-filter-tags-incrementally () ; Bound to `P T' in bookmark list + "Incrementally filter bookmarks by tags using a regexp." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unwind-protect + (progn (setq bmkp-bmenu-filter-timer + (run-with-timer 0 bmkp-incremental-filter-delay + #'bmkp-bmenu-filter-alist-by-tags-regexp)) + (bmkp-bmenu-read-filter-input)) + (bmkp-bmenu-cancel-incremental-filtering))) + +(defun bmkp-bmenu-filter-alist-by-tags-regexp () + "Filter bookmarks by tags, then refresh the bookmark list." + (setq bmkp-bmenu-filter-function 'bmkp-regexp-filtered-tags-alist-only + bmkp-bmenu-title (format "Bookmarks with Tags Matching Regexp `%s'" + bmkp-bmenu-filter-pattern)) + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp))) + +(defun bmkp-bmenu-read-filter-input () + "Read input and add it to `bmkp-bmenu-filter-pattern'." + (setq bmkp-bmenu-filter-pattern "") + (let ((tmp-list ()) + char) + (catch 'bmkp-bmenu-read-filter-input-1 + (while t + (catch 'bmkp-bmenu-read-filter-input-2 + (condition-case nil + (setq char (read-char (concat bmkp-bmenu-filter-prompt bmkp-bmenu-filter-pattern))) + (error (throw 'bmkp-bmenu-read-filter-input-1 nil))) + (case char + ((?\e ?\r) (throw 'bmkp-bmenu-read-filter-input-1 nil)) ; Break and exit. + (?\d + (pop tmp-list) ; Delete last char of `bmkp-bmenu-filter-pattern'. + (setq bmkp-bmenu-filter-pattern (mapconcat 'identity (reverse tmp-list) "")) + (throw 'bmkp-bmenu-read-filter-input-2 nil)) + (t + (push (text-char-description char) tmp-list) + (setq bmkp-bmenu-filter-pattern (mapconcat 'identity (reverse tmp-list) "")) + (throw 'bmkp-bmenu-read-filter-input-2 nil)))))))) + +(defun bmkp-bmenu-cancel-incremental-filtering () + "Cancel timer used for incrementally filtering bookmarks." + (cancel-timer bmkp-bmenu-filter-timer) + (setq bmkp-bmenu-filter-timer nil)) + +;;;###autoload +(defun bmkp-bmenu-toggle-show-only-unmarked () ; Bound to `<' in bookmark list + "Hide all marked bookmarks. Repeat to toggle, showing all." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (bmkp-some-marked-p bmkp-latest-bookmark-alist) + (bmkp-some-marked-p bmkp-bmenu-before-hide-marked-alist)) + (let ((bookmark-alist bmkp-latest-bookmark-alist) + status) + (if bmkp-bmenu-before-hide-marked-alist + (setq bookmark-alist bmkp-bmenu-before-hide-marked-alist + bmkp-bmenu-before-hide-marked-alist () + bmkp-latest-bookmark-alist bookmark-alist + status 'shown) + (setq bmkp-bmenu-before-hide-marked-alist bmkp-latest-bookmark-alist + bookmark-alist (bmkp-unmarked-bookmarks-only) + bmkp-latest-bookmark-alist bookmark-alist + status 'hidden)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (cond ((eq status 'hidden) + (bookmark-bmenu-ensure-position) + (message "Marked bookmarks are now hidden")) + (t + (goto-char (point-min)) + (when (re-search-forward "^>" (point-max) t) (forward-line 0)) + (message "Marked bookmarks no longer hidden")))) + (message "No marked bookmarks to hide")) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-toggle-show-only-marked () ; Bound to `>' in bookmark list + "Hide all unmarked bookmarks. Repeat to toggle, showing all." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (or (bmkp-some-unmarked-p bmkp-latest-bookmark-alist) + (bmkp-some-unmarked-p bmkp-bmenu-before-hide-unmarked-alist)) + (let ((bookmark-alist bmkp-latest-bookmark-alist) + status) + (if bmkp-bmenu-before-hide-unmarked-alist + (setq bookmark-alist bmkp-bmenu-before-hide-unmarked-alist + bmkp-bmenu-before-hide-unmarked-alist () + bmkp-latest-bookmark-alist bookmark-alist + status 'shown) + (setq bmkp-bmenu-before-hide-unmarked-alist bmkp-latest-bookmark-alist + bookmark-alist (bmkp-marked-bookmarks-only) + bmkp-latest-bookmark-alist bookmark-alist + status 'hidden)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (cond ((eq status 'hidden) + (bookmark-bmenu-ensure-position) + (message "Unmarked bookmarks are now hidden")) + (t + (goto-char (point-min)) + (when (re-search-forward "^>" (point-max) t) (forward-line 0)) + (message "Unmarked bookmarks no longer hidden")))) + (message "No unmarked bookmarks to hide")) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + + +;;(@* "Menu-List (`*-bmenu-*') Commands Involving Marks") +;; *** Menu-List (`*-bmenu-*') Commands Involving Marks *** + +;;;###autoload +(defun bmkp-bmenu-mark-all () ; Bound to `M-m' in bookmark list + "Mark all bookmarks, using mark `>'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (let ((count 0)) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) (bookmark-bmenu-mark) (setq count (1+ count))) + (message "Marked: %d" count)))) + +;; This is similar to `dired-unmark-all-files'. +;;;###autoload +(defun bmkp-bmenu-unmark-all (mark &optional arg) ; Bound to `M-DEL', `U' in bookmark list + "Remove a mark from each bookmark. +Hit the mark character (`>' or `D') to remove those marks, + or hit `RET' to remove all marks (both `>' and `D'). +With a prefix arg, you are queried to unmark each marked bookmark. +Use `\\[help-command]' during querying for help." + (interactive "cRemove marks (RET means all): \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (require 'dired-aux) + (save-excursion + (let* ((count 0) + (inhibit-read-only t) + (case-fold-search nil) + (query nil) + (string (format "\n%c" mark)) + (help-form "Type SPC or `y' to unmark one bookmark, DEL or `n' to skip to next, +`!' to unmark all remaining bookmarks with no more questions.")) + (goto-char (point-min)) + (forward-line (if (eq mark ?\r) + bmkp-bmenu-header-lines + (1- bmkp-bmenu-header-lines))) ; Because STRING starts with a newline. + (while (and (not (eobp)) + (if (eq mark ?\r) + (re-search-forward dired-re-mark nil t) + (let ((case-fold-search t)) ; Treat `d' the same as `D'. + (search-forward string nil t)))) + (when (or (not arg) (let ((bmk (bookmark-bmenu-bookmark))) + (and bmk (dired-query 'query "Unmark bookmark `%s'? " bmk)))) + (bookmark-bmenu-unmark) (forward-line -1) + (setq count (1+ count)))) + (if (= 1 count) (message "1 mark removed") (message "%d marks removed" count))))) + +;;;###autoload +(defun bmkp-bmenu-regexp-mark (regexp) ; Bound to `% m' in bookmark list + "Mark bookmarks that match REGEXP. +The entire bookmark line is tested: bookmark name and possibly file name." + (interactive "sRegexp: ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0)) + (while (and (not (eobp)) (re-search-forward regexp (point-max) t)) + (bookmark-bmenu-mark) + (setq count (1+ count))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-mark-autofile-bookmarks (&optional arg) ; Bound to `A M' in bookmark list + "Mark autofile bookmarks: those whose names are the same as their files. +With a prefix arg you are prompted for a prefix that each bookmark +name must have." + (interactive "P") + (if (not arg) + (bmkp-bmenu-mark-bookmarks-satisfying #'bmkp-autofile-bookmark-p) + (let ((prefix (read-string "Prefix for bookmark names: " nil nil ""))) + (bmkp-bmenu-mark-bookmarks-satisfying #'(lambda (bb) (bmkp-autofile-bookmark-p bb prefix)))))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmark-file-bookmarks () ; Bound to `X M' in bookmark list + "Mark bookmark-file bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-bookmark-file-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-desktop-bookmarks () ; Bound to `K M' in bookmark list + "Mark desktop bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-desktop-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-dired-bookmarks () ; Bound to `M-d M-m' in bookmark list + "Mark Dired bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-dired-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-file-bookmarks (arg) ; Bound to `F M' in bookmark list + "Mark file bookmarks. +With a prefix argument, do not mark remote files or directories." + (interactive "P") + (bmkp-bmenu-mark-bookmarks-satisfying + (if arg 'bmkp-local-file-bookmark-p 'bmkp-file-bookmark-p))) + +;;;###autoload +(defun bmkp-bmenu-mark-gnus-bookmarks () ; Bound to `G M' in bookmark list + "Mark Gnus bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-gnus-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-info-bookmarks () ; Bound to `I M' in bookmark list + "Mark Info bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-info-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-man-bookmarks () ; Bound to `M M' in bookmark list + "Mark `man' page bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-man-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-non-file-bookmarks () ; Bound to `B M' in bookmark list + "Mark non-file bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-non-file-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-region-bookmarks () ; Bound to `R M' in bookmark list + "Mark bookmarks that record a region." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-region-bookmark-p)) + +(when (featurep 'bookmark+-lit) + (defun bmkp-bmenu-mark-lighted-bookmarks () ; Bound to `H M' in bookmark list + "Mark the highlighted bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-lighted-p))) + +;;;###autoload +(defun bmkp-bmenu-mark-specific-buffer-bookmarks (&optional buffer) ; `= b M' in bookmark list + "Mark bookmarks for BUFFER. +Interactively, read the name of the buffer. +If BUFFER is non-nil, set `bmkp-last-specific-buffer' to it." + (interactive (list (bmkp-completing-read-buffer-name))) + (when buffer (setq bmkp-last-specific-buffer buffer)) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-buffer-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-specific-file-bookmarks (&optional file) ; Bound to `= f M' in bookmark list + "Mark bookmarks for FILE, an absolute file name. +Interactively, read the file name. +If FILE is non-nil, set `bmkp-last-specific-file' to it." + (interactive (list (bmkp-completing-read-file-name))) + (when file (setq bmkp-last-specific-file file)) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-last-specific-file-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-url-bookmarks () ; Bound to `M-u M-m' in bookmark list + "Mark URL bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-url-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-w3m-bookmarks () ; Bound to `W M' in bookmark list + "Mark W3M (URL) bookmarks." + (interactive) + (bmkp-bmenu-mark-bookmarks-satisfying 'bmkp-w3m-bookmark-p)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-satisfying (pred) ; Not bound + "Mark bookmarks that satisfy predicate PRED. +If you use this interactively, you are responsible for entering a +symbol that names a unnary predicate. The function you provide is not +checked - it is simply applied to each bookmark to test it." + (interactive "aPredicate: ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + bmk) + (while (not (eobp)) + (setq bmk (bookmark-bmenu-bookmark)) + (if (not (funcall pred bmk)) + (forward-line 1) + (bookmark-bmenu-mark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-toggle-marks () ; Bound to `t' in bookmark list + "Toggle marks: Unmark all marked bookmarks; mark all unmarked bookmarks. +This affects only the `>' mark, not the `D' flag." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked-count 0) + (unmarked-count 0)) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (if (not (bmkp-some-marked-p bmkp-latest-bookmark-alist)) + (bmkp-bmenu-mark-all) + (while (not (eobp)) + (cond ((bmkp-bookmark-name-member (bookmark-bmenu-bookmark) bmkp-bmenu-marked-bookmarks) + (bookmark-bmenu-unmark) + (setq unmarked-count (1+ unmarked-count))) + (t + (bookmark-bmenu-mark) + (setq marked-count (1+ marked-count))))) + (message "Marked: %d, unmarked: %d" marked-count unmarked-count))))) + +;;;###autoload +(defun bmkp-bmenu-dired-marked (dirbufname) ; Bound to `M-d >' in bookmark list + "Dired in another window for the marked file and directory bookmarks. + +Absolute file names are used for the entries in the Dired buffer. +The only entries are for the marked files and directories. These can +be located anywhere. (In Emacs versions prior to release 23.2, remote +bookmarks are ignored, because of Emacs bug #5478.) + +You are prompted for the Dired buffer name. The `default-directory' +of the buffer is the same as that of buffer `*Bookmark List*'." + (interactive (list (read-string "Dired buffer name: "))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (when (or (bmkp-local-file-bookmark-p bmk) + (> emacs-major-version 23) + (and (= emacs-major-version 23) (> emacs-minor-version 1))) + (setq file (bookmark-get-filename bmk)) + (unless (file-name-absolute-p file) (setq file (expand-file-name file))) ; Should not happen. + (push file files))) + (dired-other-window (cons dirbufname files)))) + +;;;###autoload +(defun bmkp-bmenu-delete-marked () ; Bound to `D' in bookmark list + "Delete all (visible) bookmarks that are marked `>', after confirmation." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-execute-deletions 'marked)) + +;;;###autoload +(defun bmkp-bmenu-make-sequence-from-marked (bookmark-name &optional dont-omit-p) ; Not bound + "Create or update a sequence bookmark from the visible marked bookmarks. +The bookmarks that are currently marked are recorded as a sequence, in +their current order in buffer `*Bookmark List*'. +When you \"jump\" to the sequence bookmark, the bookmarks in the +sequence are processed in order. + +By default, omit the marked bookmarks, after creating the sequence. +With a prefix arg, do not omit them. + +If a bookmark with the specified name already exists, it is +overwritten. If a sequence bookmark with the name already exists, +then you are prompted whether to add the marked bookmarks to the +beginning of the existing sequence (or simply replace it). + +Note that another existing sequence bookmark can be marked, and thus +included in the sequence bookmark created or updated. That is, you +can include other sequences within a sequence bookmark. + +Returns the bookmark (internal record) created or updated." + (interactive "sName of sequence bookmark: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked-bmks ()) + (count 0)) + (message "Making sequence from marked bookmarks...") + (save-excursion + (with-current-buffer "*Bookmark List*" + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (push (bookmark-bmenu-bookmark) marked-bmks) + (setq count (1+ count))))) + (when (zerop count) (error "No marked bookmarks")) + (let ((new-seq (nreverse marked-bmks)) + (bmk (bookmark-get-bookmark bookmark-name 'noerror))) + (when (and bmk (bmkp-sequence-bookmark-p bmk)) + (if (y-or-n-p (format "ADD marked to existing sequence `%s' (otherwise, REPLACES it)? " + bookmark-name)) + (setq new-seq (nconc new-seq (bookmark-prop-get bmk 'sequence))) + "OK, existing sequence will be replaced")) + (bookmark-store bookmark-name `((filename . ,bmkp-non-file-filename) + (position . 0) + (sequence ,@new-seq) + (handler . bmkp-jump-sequence)) + nil))) + (let ((new (bookmark-get-bookmark bookmark-name 'noerror))) + (unless (memq new bmkp-latest-bookmark-alist) + (setq bmkp-latest-bookmark-alist (cons new bmkp-latest-bookmark-alist))) + (unless dont-omit-p + (bmkp-bmenu-omit-marked) + (message "Marked bookmarks now OMITTED - use `bmkp-bmenu-show-only-omitted' to show")) + (bookmark-bmenu-surreptitiously-rebuild-list) + (bmkp-bmenu-goto-bookmark-named bookmark-name) + new)) + + +;;(@* "Omitted Bookmarks") +;; *** Omitted Bookmarks *** + +;;;###autoload +(defun bmkp-bmenu-omit () ; Not bound + "Omit this bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (setq bmkp-bmenu-omitted-bookmarks (cons (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks)) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Omitted 1 bookmark")) + +;;;###autoload +(defun bmkp-bmenu-omit/unomit-marked () ; Bound to `O >' in bookmark list + "Omit all marked bookmarks or, if showing only omitted ones, unomit." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + (bmkp-bmenu-unomit-marked) + (bmkp-bmenu-omit-marked))) + +;;;###autoload +(defun bmkp-bmenu-omit-marked () ; Bound to `O >' in bookmark list + "Omit all marked bookmarks. +They will henceforth be invisible to the bookmark list. +You can, however, use \\`\\[bmkp-bmenu-show-only-omitted]' to see them. +You can then mark some of them and use `\\[bmkp-bmenu-omit/unomit-marked]' to make those marked + available again for the bookmark list." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((o-str (and (not (looking-at "^>")) (bookmark-bmenu-bookmark))) + (o-point (point)) + (count 0)) + (message "Omitting marked bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (setq bmkp-bmenu-omitted-bookmarks (cons (bookmark-bmenu-bookmark) bmkp-bmenu-omitted-bookmarks) + count (1+ count))) + (if (<= count 0) + (message "No marked bookmarks") + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "Omitted %d bookmarks" count)) + (if o-str + (bmkp-bmenu-goto-bookmark-named o-str) + (goto-char o-point) + (beginning-of-line))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-unomit-marked () ; `O >' in bookmark list when showing omitted bookmarks + "Remove all marked bookmarks from the list of omitted bookmarks. +They will henceforth be available for display in the bookmark list. +\(In order to see and then mark omitted bookmarks you must use \\\ +`\\[bmkp-bmenu-show-only-omitted]'.)" + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks to UN-omit")) + (unless (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + (error "You must use command `bmkp-bmenu-show-only-omitted' first")) + (let ((count 0)) + (message "UN-omitting marked bookmarks...") + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (re-search-forward "^>" (point-max) t) + (let ((bmk-name (bookmark-bmenu-bookmark))) + (when (bmkp-bookmark-name-member bmk-name bmkp-bmenu-omitted-bookmarks) + (setq bmkp-bmenu-omitted-bookmarks (bmkp-delete-bookmark-name-from-list + bmk-name bmkp-bmenu-omitted-bookmarks) + count (1+ count))))) + (if (<= count 0) + (message "No marked bookmarks") + (setq bmkp-bmenu-filter-function nil + bmkp-bmenu-title "All Bookmarks" + bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-surreptitiously-rebuild-list) + (message "UN-omitted %d bookmarks" count))) + (when (and (fboundp 'fit-frame-if-one-window) + (eq (selected-window) (get-buffer-window (get-buffer-create "*Bookmark List*") 0))) + (fit-frame-if-one-window))) + +;;;###autoload +(defun bmkp-bmenu-show-only-omitted () ; Bound to `O S' in bookmark list to show only omitted + "Show only the omitted bookmarks. +You can then mark some of them and use `bmkp-bmenu-unomit-marked' to + make those that are marked available again for the bookmark list." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (unless bmkp-bmenu-omitted-bookmarks (error "No omitted bookmarks")) + (setq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only + bmkp-bmenu-title "Omitted Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only omitted bookmarks are shown now"))) + + +;;(@* "Search-and-Replace Locations of Marked Bookmarks") +;; *** Search-and-Replace Locations of Marked Bookmarks *** + +(when (> emacs-major-version 22) + (defun bmkp-bmenu-isearch-marked-bookmarks () ; Bound to `M-s a C-s' in bookmark list + "Isearch the marked bookmark locations, in their current order." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((bookmarks (mapcar #'car (bmkp-sort-omit (bmkp-marked-bookmarks-only)))) + (bmkp-use-region nil)) ; Suppress region handling. + (bmkp-isearch-bookmarks bookmarks))) ; Defined in `bookmark+-1.el'. + + (defun bmkp-bmenu-isearch-marked-bookmarks-regexp () ; Bound to `M-s a M-C-s' in bookmark list + "Regexp Isearch the marked bookmark locations, in their current order." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((bookmarks (mapcar #'car (bmkp-sort-omit (bmkp-marked-bookmarks-only)))) + (bmkp-use-region nil)) ; Suppress region handling. + (bmkp-isearch-bookmarks-regexp bookmarks)))) ; Defined in `bookmark+-1.el'. + +;;;###autoload +(defun bmkp-bmenu-search-marked-bookmarks-regexp (regexp) ; Bound to `M-s a M-s' in bookmark list + "Search the marked file bookmarks, in their current order, for REGEXP. +Use `\\[tags-loop-continue]' to advance among the search hits. +Marked directory and non-file bookmarks are ignored." + (interactive "sSearch marked file bookmarks (regexp): ") + (bmkp-bmenu-barf-if-not-in-menu-list) + (tags-search regexp '(let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (setq file (bookmark-get-filename bmk)) + (when (and (not (equal bmkp-non-file-filename file)) + (not (file-directory-p file))) + (push file files))) + (setq files (nreverse files))))) + +;;;###autoload +(defun bmkp-bmenu-query-replace-marked-bookmarks-regexp (from to ; Bound to `M-q' in bookmark list + &optional delimited) + "`query-replace-regexp' FROM with TO, for all marked file bookmarks. +DELIMITED (prefix arg) means replace only word-delimited matches. +If you exit (`\\[keyboard-quit]', `RET' or `q'), you can use \ +`\\[tags-loop-continue]' to resume where +you left off." + (interactive (let ((common (query-replace-read-args "Query replace regexp in marked files" t t))) + (list (nth 0 common) (nth 1 common) (nth 2 common)))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (tags-query-replace from to delimited + '(let ((files ()) + file) + (dolist (bmk (bmkp-sort-omit (bmkp-marked-bookmarks-only))) + (setq file (bookmark-get-filename bmk)) + (let ((buffer (get-file-buffer file))) + (when (and buffer (with-current-buffer buffer buffer-read-only)) + (error "File `%s' is visited read-only" file))) + (when (and (not (equal bmkp-non-file-filename file)) + (not (file-directory-p file))) + (push file files))) + (setq files (nreverse files))))) + + +;;(@* "Tags") +;; *** Tags *** + +;;;###autoload +(defun bmkp-bmenu-show-only-tagged () ; Bound to `T S' in bookmark list + "Display (only) the bookmarks that have tags." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-some-tags-alist-only + bmkp-bmenu-title "Tagged Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only tagged bookmarks are shown"))) + +;; Not bound, but `T 0' is `bmkp-remove-all-tags'. +;;;###autoload +(defun bmkp-bmenu-remove-all-tags (&optional must-confirm-p) + "Remove all tags from this bookmark. +Interactively, you are required to confirm." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bookmark (bookmark-bmenu-bookmark))) + (when (and must-confirm-p (null (bmkp-get-tags bookmark))) + (error "Bookmark has no tags to remove")) + (when (or (not must-confirm-p) (y-or-n-p "Remove all tags from this bookmark? ")) + (bmkp-remove-all-tags bookmark)))) + +;;;###autoload +(defun bmkp-bmenu-add-tags () ; Only on `mouse-3' menu in bookmark list. + "Add some tags to this bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-add-tags (bookmark-bmenu-bookmark) (bmkp-read-tags-completing))) + +;;;###autoload +(defun bmkp-bmenu-set-tag-value () ; Bound to `T v' in bookmark list + "Set the value of one of this bookmark's tags." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((this-bmk (bookmark-bmenu-bookmark))) + (bmkp-set-tag-value + this-bmk + (bmkp-read-tag-completing "Tag: " (mapcar 'bmkp-full-tag (bmkp-get-tags this-bmk))) + (read (read-string "Value: ")) + 'msg))) + +;;;###autoload +(defun bmkp-bmenu-set-tag-value-for-marked (tag value &optional msgp) ; `T > v' in bookmark list + "Set the value of TAG to VALUE, for each of the marked bookmarks. +If any of the bookmarks has no tag named TAG, then add one with VALUE." + (interactive (list (bmkp-read-tag-completing) (read (read-string "Value: ")) 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when msgp (message "Setting tag values...")) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Setting tag values...")) + (bmkp-set-tag-value-for-bookmarks marked tag value)) + (when (and msgp tag) (message "Setting tag values...done"))) + +;;;###autoload +(defun bmkp-bmenu-remove-tags (&optional msgp) ; Only on `mouse-3' menu in bookmark list. + "Remove some tags from this bookmark." + (interactive "p") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bmk (bookmark-bmenu-bookmark))) + (bmkp-remove-tags bmk + (bmkp-read-tags-completing (mapcar 'bmkp-full-tag (bmkp-get-tags bmk)) t) + msgp))) + +;;;###autoload +(defun bmkp-bmenu-add-tags-to-marked (tags &optional msgp) ; Bound to `T > +' in bookmark list + "Add TAGS to each of the marked bookmarks. +TAGS is a list of strings. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag, but you are not limited to +choosing existing tags." + (interactive (list (bmkp-read-tags-completing) 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Adding tags...")) + (dolist (bmk (mapcar #'car marked)) (bmkp-add-tags bmk tags nil 'NO-CACHE-UPDATE))) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when (and msgp tags) (message "Tags added: %S" tags))) + +;;;###autoload +(defun bmkp-bmenu-remove-tags-from-marked (tags &optional msgp) ; Bound to `T > -' in bookmark list + "Remove TAGS from each of the marked bookmarks. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag." + (interactive (let ((cand-tags ())) + (dolist (bmk (bmkp-marked-bookmarks-only)) + (setq cand-tags (bmkp-set-union cand-tags (bmkp-get-tags bmk)))) + (unless cand-tags (error "No tags to remove")) + (list (bmkp-read-tags-completing cand-tags t) 'msg))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Removing tags...")) + (dolist (bmk (mapcar #'car marked)) (bmkp-remove-tags bmk tags nil 'NO-CACHE-UPDATE))) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when (and msgp tags) (message "Tags removed: %S" tags))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-regexp (regexp &optional notp) ; `T m %' in bookmark list + "Mark bookmarks any of whose tags match REGEXP. +With a prefix arg, mark all that are tagged but have no matching tags." + (interactive "sRegexp: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + tags anyp) + (while (not (eobp)) + (setq tags (bmkp-get-tags (bookmark-bmenu-bookmark)) + anyp (and tags (bmkp-some (lambda (tag) (string-match regexp (bmkp-tag-name tag))) + tags))) + (if (not (and tags (if notp (not anyp) anyp))) + (forward-line 1) + (bookmark-bmenu-mark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-all (tags &optional none-p msgp) ; `T m *' in bookmark list + "Mark all visible bookmarks that are tagged with *each* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +any tags at all (i.e., at least one tag). + +With a prefix arg, mark all that are *not* tagged with *any* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags none-p nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-none (tags &optional allp msgp) ; `T m ~ +' in bookmark list + "Mark all visible bookmarks that are not tagged with *any* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +no tags at all. + +With a prefix arg, mark all that are tagged with *each* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-some (tags &optional somenotp msgp) ; `T m +' in bookmark list + "Mark all visible bookmarks that are tagged with *some* tag in TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +any tags at all. + +With a prefix arg, mark all that are *not* tagged with *all* TAGS. + +Hit `RET' to enter each tag, then hit `RET' again after the last tag. +You can use completion to enter each tag." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-mark-bookmarks-tagged-not-all (tags &optional somep msgp) ; `T m ~ *' in bmk list + "Mark all visible bookmarks that are *not* tagged with *all* TAGS. +As a special case, if TAGS is empty, then mark the bookmarks that have +no tags at all. + +With a prefix arg, mark all that are tagged with *some* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) nil msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-regexp (regexp &optional notp) ; `T u %' in bookmark list + "Unmark bookmarks any of whose tags match REGEXP. +With a prefix arg, mark all that are tagged but have no matching tags." + (interactive "sRegexp: \nP") + (bmkp-bmenu-barf-if-not-in-menu-list) + (save-excursion + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((count 0) + tags anyp) + (while (not (eobp)) + (setq tags (bmkp-get-tags (bookmark-bmenu-bookmark)) + anyp (and tags (bmkp-some (lambda (tag) (string-match regexp (bmkp-tag-name tag))) + tags))) + (if (not (and tags (if notp (not anyp) anyp))) + (forward-line 1) + (bookmark-bmenu-unmark) + (setq count (1+ count)))) + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-all (tags &optional none-p msgp) ; `T u *' in bookmark list + "Unmark all visible bookmarks that are tagged with *each* tag in TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +any tags at all. + +With a prefix arg, unmark all that are *not* tagged with *any* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags none-p 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-none (tags &optional allp msgp) ; `T u ~ +' in bookmark list + "Unmark all visible bookmarks that are *not* tagged with *any* TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +no tags at all. + +With a prefix arg, unmark all that are tagged with *each* tag in TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none tags (not allp) 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-some (tags &optional somenotp msgp) ; `T u +' in bmk list + "Unmark all visible bookmarks that are tagged with *some* tag in TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +any tags at all. + +With a prefix arg, unmark all that are *not* tagged with *all* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags somenotp 'UNMARK msgp)) + +;;;###autoload +(defun bmkp-bmenu-unmark-bookmarks-tagged-not-all (tags &optional somep msgp) ; `T u ~ *' in bmk list + "Unmark all visible bookmarks that are *not* tagged with *all* TAGS. +As a special case, if TAGS is empty, then unmark the bookmarks that have +no tags at all. + +With a prefix arg, unmark all that are tagged with *some* TAGS." + (interactive (list (bmkp-read-tags-completing) current-prefix-arg 'msg)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all tags (not somep) 'UNMARK msgp)) + +(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-all/none (tags &optional none-p unmarkp msgp) + "Mark or unmark visible bookmarks tagged with all or none of TAGS. +TAGS is a list of strings, the tag names. +NONEP non-nil means mark/unmark bookmarks that have none of the TAGS. +UNMARKP non-nil means unmark; nil means mark. +MSGP means display a status message. + +As a special case, if TAGS is empty, then mark or unmark the bookmarks +that have any tags at all, or if NONEP is non-nil then mark or unmark +those that have no tags at all." + (with-current-buffer "*Bookmark List*" + (save-excursion + (let ((count 0) + bmktags presentp) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) + (setq bmktags (bmkp-get-tags (bookmark-bmenu-bookmark))) + (if (not (if (null tags) + (if none-p (not bmktags) bmktags) + (and bmktags (catch 'bmkp-b-mu-b-t-an + (dolist (tag tags) + (setq presentp (assoc-default tag bmktags nil t)) + (unless (if none-p (not presentp) presentp) + (throw 'bmkp-b-mu-b-t-an nil))) + t)))) + (forward-line 1) + (if unmarkp (bookmark-bmenu-unmark) (bookmark-bmenu-mark)) + (setq count (1+ count)))) + (when msgp (if (= 1 count) + (message "1 bookmark matched") + (message "%d bookmarks matched" count))))))) + +(defun bmkp-bmenu-mark/unmark-bookmarks-tagged-some/not-all (tags &optional notallp unmarkp msgp) + "Mark or unmark visible bookmarks tagged with any or not all of TAGS. +TAGS is a list of strings, the tag names. +NOTALLP non-nil means mark/unmark bookmarks that do not have all TAGS. +UNMARKP non-nil means unmark; nil means mark. +MSGP means display a status message. + +As a special case, if TAGS is empty, then mark or unmark the bookmarks +that have any tags at all, or if NOTALLP is non-nil then mark or +unmark those that have no tags at all." + (with-current-buffer "*Bookmark List*" + (save-excursion + (let ((count 0) + bmktags presentp) + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (while (not (eobp)) + (setq bmktags (bmkp-get-tags (bookmark-bmenu-bookmark))) + (if (not (if (null tags) + (if notallp (not bmktags) bmktags) + (and bmktags (catch 'bmkp-b-mu-b-t-sna + (dolist (tag tags) + (setq presentp (assoc-default tag bmktags nil t)) + (when (if notallp (not presentp) presentp) + (throw 'bmkp-b-mu-b-t-sna t))) + nil)))) + (forward-line 1) + (if unmarkp (bookmark-bmenu-unmark) (bookmark-bmenu-mark)) + (setq count (1+ count)))) + (when msgp + (if (= 1 count) (message "1 bookmark matched") (message "%d bookmarks matched" count))))))) + +;;;###autoload +(defun bmkp-bmenu-copy-tags (&optional msgp) ; `T c', `T M-w', `mouse-3' menu in bookmark list. + "Copy tags from this bookmark, so you can paste them to another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-copy-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-add-tags (&optional msgp) ; `T p', `T C-y', `mouse-3' menu in bookmark list. + "Add tags to this bookmark that were copied from another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-paste-add-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-replace-tags (&optional msgp) ; `T q', `mouse-3' menu. + "Replace tags for this bookmark with those copied from another bookmark." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-paste-replace-tags (bookmark-bmenu-bookmark) msgp)) + +;;;###autoload +(defun bmkp-bmenu-paste-add-tags-to-marked (&optional msgp) ; `T > p', `T > C-y' + "Add tags that were copied from another bookmark to the marked bookmarks." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Adding tags...")) + (dolist (bmk marked) (bmkp-paste-add-tags bmk nil 'NO-CACHE-UPDATE)) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when msgp (message "Tags added: %S" bmkp-copied-tags)))) + +;;;###autoload +(defun bmkp-bmenu-paste-replace-tags-for-marked (&optional msgp) ; `T > q' + "Replace tags for the marked bookmarks with tags copied previously." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (when msgp (message "Replacing tags...")) + (dolist (bmk marked) (bmkp-paste-replace-tags bmk nil 'NO-CACHE-UPDATE)) + (bmkp-tags-list) ; Update the tags cache (only once, at end). + (when msgp (message "Replacement tags: %S" bmkp-copied-tags)))) + + +;;(@* "General Menu-List (`-*bmenu-*') Commands and Functions") +;; *** General Menu-List (`-*bmenu-*') Commands and Functions *** + +;;;###autoload +(defun bmkp-bmenu-w32-open () ; Bound to `M-RET' in bookmark list. + "Use `w32-browser' to open this bookmark." + (interactive) (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-this-window))) + +;;;###autoload +(defun bmkp-bmenu-w32-open-with-mouse (event) ; Bound to `M-mouse-2' in bookmark list. + "Use `w32-browser' to open the bookmark clicked." + (interactive "e") + (save-excursion + (with-current-buffer (window-buffer (posn-window (event-end event))) + (save-excursion (goto-char (posn-point (event-end event))) + (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-other-window)))))) + +;;;###autoload +(defun bmkp-bmenu-w32-open-select () ; Bound to `M-o' in bookmark-list. + "Use `w32-browser' to open this bookmark and all marked bookmarks." + (interactive) (let ((bmkp-use-w32-browser-p t)) (bookmark-bmenu-select))) + +;;;###autoload +(defun bmkp-bmenu-mode-status-help () ; Bound to `C-h m' and `?' in bookmark list + "`describe-mode' + current status of `*Bookmark List*' + face legend." + (interactive) + (unless (string= (buffer-name) "*Help*") (bmkp-bmenu-barf-if-not-in-menu-list)) + (with-current-buffer (get-buffer-create "*Help*") + (with-output-to-temp-buffer "*Help*" + (let ((buffer-read-only nil) + top) + (erase-buffer) + (save-excursion + (let ((standard-output (current-buffer))) + (if (> emacs-major-version 21) + (describe-function-1 'bookmark-bmenu-mode) + (describe-function-1 'bookmark-bmenu-mode nil t))) + (help-setup-xref (list #'bmkp-bmenu-mode-status-help) (interactive-p)) + (goto-char (point-min)) + ;; This text must be the same as the last line of `bookmark-bmenu-mode' doc string. + (search-forward "Each line represents an Emacs bookmark.\n\n\n" nil t) + (delete-region (point-min) (point)) ; Get rid of intro from `describe-function'. + (insert "*************************** Bookmark List ***************************\n\n") + (insert "Major mode for editing a list of bookmarks.\n") + (insert "Each line represents an Emacs bookmark.\n\n") + (setq top (point)) + ;; Add buttons to access help and Customize. + ;; Not for Emacs 21.3 - its `help-insert-xref-button' signature is different. + (when (and (> emacs-major-version 21) ; In `help-mode.el'. + (condition-case nil (require 'help-mode nil t) (error nil)) + (fboundp 'help-insert-xref-button)) + (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button) + (insert " ") + (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button) + (insert " ") + (help-insert-xref-button "[Customize]" 'bmkp-customize-button) + (insert "\n\n") + (setq top (point)) + (goto-char (point-max)) + (insert "\nSend a Bookmark+ bug report: `\\[icicle-send-bug-report]'.\n\n") + (help-insert-xref-button "[Doc in Commentary]" 'bmkp-commentary-button) + (insert " ") + (help-insert-xref-button "[Doc on the Web]" 'bmkp-help-button) + (insert " ") + (help-insert-xref-button "[Customize]" 'bmkp-customize-button) + (insert "\n\n") + (goto-char (point-min)) + (forward-line 2)) + (goto-char top) + (insert (format + "\nCurrent Status\n-------------------------------\n +Sorted:\t\t%s\nFiltering:\t%s\nMarked:\t\t%d\nOmitted:\t%d\nBookmark file:\t%s\n\n\n" + (if (not bmkp-sort-comparer) + "no" + (format "%s%s" (bmkp-current-sort-order) + ;; Code essentially the same as found in `bmkp-msg-about-sort-order'. + (if (not (and (consp bmkp-sort-comparer) ; Ordinary single predicate + (consp (car bmkp-sort-comparer)))) + (if bmkp-reverse-sort-p "; reversed" "") + (if (not (cadr (car bmkp-sort-comparer))) + ;; Single PRED. + (if (or (and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + (and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p))) + "; reversed" + "") + ;; In case we want to distinguish: + ;; (if (and bmkp-reverse-sort-p + ;; (not bmkp-reverse-multi-sort-p)) + ;; "; reversed" + ;; (if (and bmkp-reverse-multi-sort-p + ;; (not bmkp-reverse-sort-p)) + ;; "; reversed +" + ;; "")) + + ;; At least two PREDs. + (cond ((and bmkp-reverse-sort-p (not bmkp-reverse-multi-sort-p)) + "; reversed") + ((and bmkp-reverse-multi-sort-p (not bmkp-reverse-sort-p)) + "; each predicate group reversed") + ((and bmkp-reverse-multi-sort-p bmkp-reverse-sort-p) + "; order of predicate groups reversed") + (t "")))))) + (or (and bmkp-bmenu-filter-function (downcase bmkp-bmenu-title)) "None") + (length bmkp-bmenu-marked-bookmarks) + (length bmkp-bmenu-omitted-bookmarks) + bmkp-current-bookmark-file)) + ;; Add face legend. + (let ((gnus "Gnus\n") + (info "Info node\n") + (man "Man page\n") + (url "URL\n") + (local-no-region "Local file with no region\n") + (local-w-region "Local file with a region\n") + (buffer "Buffer\n") + (no-buf "No current buffer\n") + (bad "Possibly invalid bookmark\n") + (remote "Remote file or directory\n") + (sudo "Remote accessed by `su' or `sudo'\n") + (local-dir "Local directory\n") + (bookmark-list "*Bookmark List*\n") + (bookmark-file "Bookmark file\n") + (desktop "Desktop\n") + (sequence "Sequence\n") + (variable-list "Variable list\n") + (function "Function\n")) + (put-text-property 0 (1- (length gnus)) 'face 'bmkp-gnus gnus) + (put-text-property 0 (1- (length info)) 'face 'bmkp-info info) + (put-text-property 0 (1- (length man)) 'face 'bmkp-man man) + (put-text-property 0 (1- (length url)) 'face 'bmkp-url url) + (put-text-property 0 (1- (length local-no-region)) + 'face 'bmkp-local-file-without-region local-no-region) + (put-text-property 0 (1- (length local-w-region)) + 'face 'bmkp-local-file-with-region local-w-region) + (put-text-property 0 (1- (length buffer)) 'face 'bmkp-buffer buffer) + (put-text-property 0 (1- (length no-buf)) 'face 'bmkp-non-file no-buf) + (put-text-property 0 (1- (length bad)) 'face 'bmkp-bad-bookmark bad) + (put-text-property 0 (1- (length remote)) 'face 'bmkp-remote-file remote) + (put-text-property 0 (1- (length sudo)) 'face 'bmkp-su-or-sudo sudo) + (put-text-property 0 (1- (length local-dir)) + 'face 'bmkp-local-directory local-dir) + (put-text-property 0 (1- (length bookmark-list)) + 'face 'bmkp-bookmark-list bookmark-list) + (put-text-property 0 (1- (length bookmark-file)) + 'face 'bmkp-bookmark-file bookmark-file) + (put-text-property 0 (1- (length desktop)) 'face 'bmkp-desktop desktop) + (put-text-property 0 (1- (length sequence)) 'face 'bmkp-sequence sequence) + (put-text-property 0 (1- (length variable-list)) 'face 'bmkp-variable-list variable-list) + (put-text-property 0 (1- (length function)) 'face 'bmkp-function function) + (insert "Face Legend for Bookmark Types\n------------------------------\n\n") + (insert gnus) (insert info) (insert man) (insert url) (insert local-no-region) + (insert local-w-region) (insert buffer) (insert no-buf) (insert bad) (insert remote) + (insert sudo) (insert local-dir) (insert bookmark-list) (insert bookmark-file) + (insert desktop) (insert sequence) (insert variable-list) (insert function) + (insert "\n\n"))))))) + +(when (and (> emacs-major-version 21) + (condition-case nil (require 'help-mode nil t) (error nil)) + (get 'help-xref 'button-category-symbol)) ; In `button.el' + (define-button-type 'bmkp-help-button + :supertype 'help-xref + 'help-function #'(lambda () (browse-url "http://www.emacswiki.org/emacs/BookmarkPlus")) + 'help-echo + (purecopy "mouse-2, RET: Bookmark+ documentation on the Emacs Wiki (requires Internet access)")) + (define-button-type 'bmkp-commentary-button + :supertype 'help-xref + 'help-function #'(lambda () + (message "Getting Bookmark+ doc from file commentary...") + (finder-commentary "bookmark+-doc") + (when (condition-case nil (require 'linkd nil t) (error nil)) (linkd-mode 1)) + (when (condition-case nil (require 'fit-frame nil t) (error nil)) + (fit-frame))) + 'help-echo (purecopy "mouse-2, RET: Bookmark+ documentation (no Internet needed)")) + (define-button-type 'bmkp-customize-button + :supertype 'help-xref + 'help-function #'(lambda () (customize-group-other-window 'bookmark-plus)) + 'help-echo (purecopy "mouse-2, RET: Customize/Browse Bookmark+ Options & Faces"))) + +;;;###autoload +(defun bmkp-bmenu-define-jump-marked-command () ; Bound to `M-c' in bookmark list + "Define a command to jump to a bookmark that is one of those now marked. +The bookmarks marked now will be those that are completion candidates +for the command (but omitted bookmarks are excluded). +Save the command definition in `bmkp-bmenu-commands-file'." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (let* ((cands (mapcar #'list + (bmkp-remove-if #'(lambda (bmk) + (bmkp-bookmark-name-member bmk + bmkp-bmenu-omitted-bookmarks)) + bmkp-bmenu-marked-bookmarks))) + (fn (intern (read-string "Define command to jump to a bookmark now marked: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn (bookmark-name &optional use-region-p) + (interactive (list (bmkp-read-bookmark-for-type nil ',cands t) current-prefix-arg)) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +;;;###autoload +(defun bmkp-bmenu-define-command () ; Bound to `c' in bookmark list + "Define a command to use the current sort order, filter, and omit list. +Prompt for the command name. Save the command definition in +`bmkp-bmenu-commands-file'. + +The current sort order, filter function, omit list, and title for +buffer `*Bookmark List*' are encapsulated as part of the command. +Use the command at any time to restore them." + (interactive) + (let* ((fn (intern (read-string "Define sort+filter command: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn () + (interactive) + (setq + bmkp-sort-comparer ',bmkp-sort-comparer + bmkp-reverse-sort-p ',bmkp-reverse-sort-p + bmkp-reverse-multi-sort-p ',bmkp-reverse-multi-sort-p + bmkp-bmenu-filter-function ',bmkp-bmenu-filter-function + bmkp-bmenu-filter-pattern ',bmkp-bmenu-filter-pattern + bmkp-bmenu-omitted-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks) + bmkp-bmenu-title ',bmkp-bmenu-title + bookmark-bmenu-toggle-filenames ',bookmark-bmenu-toggle-filenames) + (bmkp-bmenu-refresh-menu-list) + (when (interactive-p) + (bmkp-msg-about-sort-order + (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist))))))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +;;;###autoload +(defun bmkp-bmenu-define-full-snapshot-command () ; Bound to `C' in bookmark list + "Define a command to restore the current bookmark-list state. +Prompt for the command name. Save the command definition in +`bmkp-bmenu-commands-file'. + +Be aware that the command definition can be quite large, since it +copies the current bookmark list and accessory lists (hidden +bookmarks, marked bookmarks, etc.). For a lighter weight command, use +`bmkp-bmenu-define-full-snapshot-command' instead. That records only +the omit list and the sort & filter information." + (interactive) + (let* ((fn (intern (read-string "Define restore-snapshot command: " nil + 'bmkp-bmenu-define-command-history))) + (def `(defun ,fn () + (interactive) + (setq + bmkp-sort-comparer ',bmkp-sort-comparer + bmkp-reverse-sort-p ',bmkp-reverse-sort-p + bmkp-reverse-multi-sort-p ',bmkp-reverse-multi-sort-p + bmkp-latest-bookmark-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-latest-bookmark-alist) + bmkp-bmenu-omitted-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-omitted-bookmarks) + bmkp-bmenu-marked-bookmarks ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-marked-bookmarks) + bmkp-bmenu-filter-function ',bmkp-bmenu-filter-function + bmkp-bmenu-filter-pattern ',bmkp-bmenu-filter-pattern + bmkp-bmenu-title ',bmkp-bmenu-title + bmkp-last-bmenu-bookmark ',(and (get-buffer "*Bookmark List*") + (with-current-buffer + (get-buffer "*Bookmark List*") + (bookmark-bmenu-bookmark))) + bmkp-last-specific-buffer ',bmkp-last-specific-buffer + bmkp-last-specific-file ',bmkp-last-specific-file + bookmark-bmenu-toggle-filenames ',bookmark-bmenu-toggle-filenames + bmkp-bmenu-before-hide-marked-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-marked-alist) + bmkp-bmenu-before-hide-unmarked-alist ',(bmkp-maybe-unpropertize-bookmark-names + bmkp-bmenu-before-hide-unmarked-alist) + bmkp-last-bookmark-file ',bmkp-last-bookmark-file + bmkp-current-bookmark-file ',bmkp-current-bookmark-file) + ;;(bmkp-bmenu-refresh-menu-list) + (let ((bookmark-alist (or bmkp-latest-bookmark-alist bookmark-alist))) + (bmkp-bmenu-list-1 'filteredp nil (interactive-p))) + (when bmkp-last-bmenu-bookmark + (with-current-buffer (get-buffer "*Bookmark List*") + (bmkp-bmenu-goto-bookmark-named bmkp-last-bmenu-bookmark))) + (when (interactive-p) + (bmkp-msg-about-sort-order + (car (rassoc bmkp-sort-comparer bmkp-sort-orders-alist))))))) + (eval def) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil) + (print-circle t)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (message "Command `%s' defined and saved in file `%s'" fn bmkp-bmenu-commands-file))) + +(defun bmkp-maybe-unpropertize-bookmark-names (list) + "Strip properties from the bookmark names in a copy of LIST. +LIST is a bookmark alist or a list of bookmark names (strings). +Return the updated copy. + +Note, however, that this is a shallow copy, so the names are also +stripped within any alist elements of the original LIST. + +We do this because Emacs 20 has no `print-circle'. and otherwise +property `bmkp-full-record' would make the state file unreadable. + +Do nothing in Emacs 21 or later or if +`bmkp-propertize-bookmark-names-flag' is nil. In these cases, just +return the list." + (if (and (> emacs-major-version 20) ; Emacs 21+. Cannot just use (boundp 'print-circle). + bmkp-propertize-bookmark-names-flag) + list + (let ((new-list (copy-sequence list))) + (dolist (bmk new-list) + (when (and (consp bmk) (stringp (car bmk))) (setq bmk (car bmk))) + (when (stringp bmk) (set-text-properties 0 (length bmk) nil bmk))) + new-list))) + +;; This is a general command. It is in this file because it uses macro `bmkp-define-sort-command' +;; and it is used mainly in the bookmark list display. +;;;###autoload +(defun bmkp-define-tags-sort-command (tags &optional msgp) ; Bound to `T s' in bookmark list + "Define a command to sort bookmarks in the bookmark list by tags. +Hit `RET' to enter each tag, then hit `RET' again after the last tag. + +The new command sorts first by the first tag in TAGS, then by the +second, and so on. + +Besides sorting for these specific tags, any bookmark that has a tag +sorts before one that has no tags. Otherwise, sorting is by bookmark +name, alphabetically. + +The name of the new command is `bmkp-bmenu-sort-' followed by the +specified tags, in order, separated by hyphens (`-'). E.g., for TAGS +\(\"alpha\" \"beta\"), the name is `bmkp-bmenu-sort-alpha-beta'." + (interactive (list (bmkp-read-tags-completing) 'msg)) + (let ((sort-order (concat "tags-" (mapconcat #'identity tags "-"))) + (doc-string (read-string "Doc string for command: ")) + (comparer ()) + def) + (dolist (tag tags) + (push `(lambda (b1 b2) + (let ((tags1 (bmkp-get-tags b1)) + (tags2 (bmkp-get-tags b2))) + (cond ((and (assoc-default ,tag tags1 nil t) + (assoc-default ,tag tags2 nil t)) nil) + ((assoc-default ,tag tags1 nil t) '(t)) + ((assoc-default ,tag tags2 nil t) '(nil)) + ((and tags1 tags2) nil) + (tags1 '(t)) + (tags2 '(nil)) + (t nil)))) + comparer)) + (setq comparer (nreverse comparer) + comparer (list comparer 'bmkp-alpha-p)) + (eval (setq def (macroexpand `(bmkp-define-sort-command ,sort-order ,comparer ,doc-string)))) + (with-current-buffer (get-buffer-create " *User Bookmark List Commands*") + (goto-char (point-min)) + (delete-region (point-min) (point-max)) + (let ((print-length nil) + (print-level nil)) + (pp def (current-buffer)) + (insert "\n") + (condition-case nil + (write-region (point-min) (point-max) bmkp-bmenu-commands-file 'append) + (file-error (error "Cannot write `%s'" bmkp-bmenu-commands-file))) + (kill-buffer (current-buffer)))) + (when msgp (message "Defined and saved command `%s'" + (concat "bmkp-bmenu-sort-" sort-order))))) + +;;;###autoload +(defun bmkp-bmenu-edit-bookmark (&optional internalp) ; Bound to `E' in bookmark list + "Edit the bookmark under the cursor: its name and file name. +With a prefix argument, edit the complete bookmark record (the +internal, Lisp form)." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (let ((bmk-name (bookmark-bmenu-bookmark))) + (if internalp + (bmkp-edit-bookmark-record bmk-name) + (let* ((new-data (bmkp-edit-bookmark bmk-name)) + (new-name (car new-data))) + (if (not new-data) + (message "No changes made") + (bmkp-refresh-menu-list new-name)))))) + +;;;###autoload +(defun bmkp-bmenu-edit-tags () ; Bound to `T e' in bookmark list + "Edit the tags of the bookmark under the cursor. +The edited value must be a list each of whose elements is either a +string or a cons whose key is a string." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bookmark-bmenu-ensure-position) + (bmkp-edit-tags (bookmark-bmenu-bookmark))) + +(defun bmkp-bmenu-propertize-item (bookmark start end) + "Propertize buffer from START to END, indicating bookmark types. +This propertizes the name of BOOKMARK. +Also give this region the property `bmkp-bookmark-name' with as value +the name of BOOKMARK as a propertized string. + +The propertized string has property `bmkp-full-record' with value +BOOKMARK, which is the full bookmark record, with the string as its +car. + +Return the propertized string (the bookmark name)." + (setq bookmark (bookmark-get-bookmark bookmark)) + (let* ((bookmark-name (bookmark-name-from-full-record bookmark)) + (buffp (bmkp-get-buffer-name bookmark)) + + (filep (bookmark-get-filename bookmark)) + (sudop (and filep (boundp 'tramp-file-name-regexp) + (string-match tramp-file-name-regexp filep) + (string-match bmkp-su-or-sudo-regexp filep)))) + ;; Put the full bookmark itself on string `bookmark-name' as property `bmkp-full-record'. + ;; Then put that string on the name in the buffer text as property `bmkp-bookmark-name'. + (put-text-property 0 (length bookmark-name) 'bmkp-full-record bookmark bookmark-name) + (put-text-property start end 'bmkp-bookmark-name bookmark-name) + ;; Add faces, mouse face, and tooltips, to characterize the bookmark type. + (add-text-properties + start end + (cond ((bmkp-sequence-bookmark-p bookmark) ; Sequence bookmark + (append (bmkp-face-prop 'bmkp-sequence) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke the bookmarks in this sequence"))) + ((bmkp-function-bookmark-p bookmark) ; Function bookmark + (append (bmkp-face-prop 'bmkp-function) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this function bookmark"))) + ((bmkp-variable-list-bookmark-p bookmark) ; Variable-list bookmark + (append (bmkp-face-prop 'bmkp-variable-list) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this variable-list bookmark"))) + ((bmkp-bookmark-list-bookmark-p bookmark) ; Bookmark-list bookmark + (append (bmkp-face-prop 'bmkp-bookmark-list) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Invoke this bookmark-list bookmark"))) + ((bmkp-desktop-bookmark-p bookmark) ; Desktop bookmark + (append (bmkp-face-prop 'bmkp-desktop) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this desktop bookmark"))) + ((bmkp-bookmark-file-bookmark-p bookmark) ; Bookmark-file bookmark + (append (bmkp-face-prop 'bmkp-bookmark-file) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Load this bookmark's bookmark file"))) + ((bmkp-info-bookmark-p bookmark) ; Info bookmark + (append (bmkp-face-prop 'bmkp-info) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this Info bookmark"))) + ((bmkp-man-bookmark-p bookmark) ; Man bookmark + (append (bmkp-face-prop 'bmkp-man) + '(mouse-face highlight follow-link t + help-echo (format "mouse-2 Goto `man' page")))) + ((bmkp-gnus-bookmark-p bookmark) ; Gnus bookmark + (append (bmkp-face-prop 'bmkp-gnus) + '(mouse-face highlight follow-link t + help-echo "mouse-2: Jump to this Gnus bookmark"))) + ((bmkp-url-bookmark-p bookmark) ; URL bookmark + (append (bmkp-face-prop 'bmkp-url) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to URL `%s'" ,filep)))) + ((and sudop (not (bmkp-root-or-sudo-logged-p))) ; Root/sudo not logged in + (append (bmkp-face-prop 'bmkp-su-or-sudo) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep)))) + ;; Test for remoteness before any other tests of the file itself + ;; (e.g. `file-exists-p'), so we don't prompt for a password etc. + ((and filep (bmkp-file-remote-p filep) (not sudop)) ; Remote file (ssh, ftp) + (append (bmkp-face-prop 'bmkp-remote-file) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) remote file `%s'" ,filep)))) + ((and filep (file-directory-p filep)) ; Local directory + (append (bmkp-face-prop 'bmkp-local-directory) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Dired directory `%s'" ,filep)))) + ((and filep (file-exists-p filep) ; Local file with region + (bmkp-region-bookmark-p bookmark)) + (append (bmkp-face-prop 'bmkp-local-file-with-region) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Activate region in file `%s'" ,filep)))) + ((and filep (file-exists-p filep)) ; Local file without region + (append (bmkp-face-prop 'bmkp-local-file-without-region) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to (visit) file `%s'" ,filep)))) + ((and buffp (get-buffer buffp) (equal filep bmkp-non-file-filename)) ; Buffer + (append (bmkp-face-prop 'bmkp-buffer) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to buffer `%s'" ,buffp)))) + ((and buffp (or (not filep) (equal filep bmkp-non-file-filename) + (not (file-exists-p filep)))) ; Buffer bookmark, but no buffer. + (append (bmkp-face-prop 'bmkp-non-file) + `(mouse-face highlight follow-link t + help-echo (format "mouse-2: Jump to buffer `%s'" ,buffp)))) + (t (append (bmkp-face-prop 'bmkp-bad-bookmark) + `(mouse-face highlight follow-link t + help-echo (format "BAD BOOKMARK (maybe): `%s'" ,filep)))))) + bookmark-name)) + +;;;###autoload +(defun bmkp-bmenu-quit () ; Bound to `q' in bookmark list + "Quit the bookmark list (aka \"menu list\"). +If `bmkp-bmenu-state-file' is non-nil, then save the state, to be +restored the next time the bookmark list is shown. Otherwise, reset +the internal lists that record menu-list markings." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (if (not bmkp-bmenu-state-file) + (setq bmkp-bmenu-marked-bookmarks () + bmkp-bmenu-before-hide-marked-alist () + bmkp-bmenu-before-hide-unmarked-alist ()) + (bmkp-save-menu-list-state) + (setq bmkp-bmenu-first-time-p t)) + (quit-window)) + +(defun bmkp-bmenu-goto-bookmark-named (name) + "Go to the first bookmark whose name matches NAME (a string). +If NAME has non-nil property `bmkp-full-record' then go to the +bookmark it indicates. Otherwise, just go to the first bookmark with +the same name." + (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (let ((full (get-text-property 0 'bmkp-full-record name))) + (while (and (not (eobp)) + (not (if full + (equal full (get-text-property 0 'bmkp-full-record (bookmark-bmenu-bookmark))) + (equal name (bookmark-bmenu-bookmark))))) + (forward-line 1))) + (bookmark-bmenu-ensure-position)) ; Just in case we fall off the end. + +;; This is a general function. It is in this file because it is used only by the bmenu code. +(defun bmkp-bmenu-barf-if-not-in-menu-list () + "Raise an error if current buffer is not `*Bookmark List*'." + (unless (equal (buffer-name (current-buffer)) "*Bookmark List*") + (error "You can only use this command in buffer `*Bookmark List*'"))) + + +;;(@* "Sorting - Commands") +;; *** Sorting - Commands *** + +;;;###autoload +(defun bmkp-bmenu-change-sort-order-repeat (arg) ; Bound to `s s'... in bookmark list + "Cycle to the next sort order. +With a prefix arg, reverse current sort order. +This is a repeatable version of `bmkp-bmenu-change-sort-order'." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-bmenu-change-sort-order)) + +;;;###autoload +(defun bmkp-bmenu-change-sort-order (&optional arg) + "Cycle to the next sort order. +With a prefix arg, reverse the current sort order." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-sort-orders-for-cycling-alist (delq nil bmkp-sort-orders-for-cycling-alist)) + (if arg + (bmkp-reverse-sort-order) + (let ((current-bmk (bookmark-bmenu-bookmark)) + next-order) + (let ((orders (mapcar #'car bmkp-sort-orders-for-cycling-alist))) + (setq next-order (or (cadr (member (bmkp-current-sort-order) orders)) (car orders)) + bmkp-sort-comparer (cdr (assoc next-order bmkp-sort-orders-for-cycling-alist)))) + (message "Sorting...") + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk)) + (when (interactive-p) (bmkp-msg-about-sort-order next-order))))) + +;; This is a general command. It is in this file because it is used only by the bmenu code. +;;;###autoload +(defun bmkp-reverse-sort-order () ; Bound to `s r' in bookmark list + "Reverse the current bookmark sort order. +If you combine this with \\\ +`\\[bmkp-reverse-multi-sort-order]', then see the doc for that command." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-reverse-sort-p (not bmkp-reverse-sort-p)) + (let ((current-bmk (bookmark-bmenu-bookmark))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk))) + (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + +;; This is a general command. It is in this file because it is used only by the bmenu code. +;;;###autoload +(defun bmkp-reverse-multi-sort-order () ; Bound to `s C-r' in bookmark list + "Reverse the application of multi-sorting predicates. +These are the PRED predicates described for option +`bmkp-sort-comparer'. + +This reverses the order in which the predicates are tried, and it +also complements the truth value returned by each predicate. + +For example, if the list of multi-sorting predicates is (p1 p2 p3), +then the predicates are tried in the order: p3, p2, p1. And if a +predicate returns true, `(t)', then the effect is as if it returned +false, `(nil)', and vice versa. + +The use of multi-sorting predicates tends to group bookmarks, with the +first predicate corresponding to the first bookmark group etc. + +The effect of \\`\\[bmkp-reverse-multi-sort-order]' is \ +roughly as follows: + + - without also `\\[bmkp-reverse-sort-order]', it reverses the bookmark order in each \ +group + + - combined with `\\[bmkp-reverse-sort-order]', it reverses the order of the bookmark + groups, but not the bookmarks within a group + +This is a rough description. The actual behavior can be complex, +because of how each predicate is defined. If this description helps +you, fine. If not, just experiment and see what happens. \;-) + +Remember that ordinary `\\[bmkp-reverse-sort-order]' reversal on its own is \ +straightforward. +If you find `\\[bmkp-reverse-multi-sort-order]' confusing or not helpful, then do not \ +use it." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-reverse-multi-sort-p (not bmkp-reverse-multi-sort-p)) + (let ((current-bmk (bookmark-bmenu-bookmark))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (when current-bmk ; Put cursor back on the right line. + (bmkp-bmenu-goto-bookmark-named current-bmk))) + (when (interactive-p) (bmkp-msg-about-sort-order (bmkp-current-sort-order)))) + + + +;; The ORDER of the macro calls here defines the REVERSE ORDER of +;; `bmkp-sort-orders-alist'. The first here is thus also the DEFAULT sort order. +;; Entries are traversed by `s s'..., in `bmkp-sort-orders-alist' order. + +(bmkp-define-sort-command ; Bound to `s k' in bookmark list (`k' for "kind") + "by bookmark type" ; `bmkp-bmenu-sort-by-bookmark-type' + ((bmkp-info-cp bmkp-url-cp bmkp-gnus-cp bmkp-local-file-type-cp bmkp-handler-cp) + bmkp-alpha-p) + "Sort bookmarks by type: Info, URL, Gnus, files, other.") + +(bmkp-define-sort-command ; Bound to `s u' in bookmark list + "by url" ; `bmkp-bmenu-sort-by-url' + ((bmkp-url-cp) bmkp-alpha-p) + "Sort URL bookmarks alphabetically by their URL/filename. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +;; $$$$$$ Not used now. +;; (bmkp-define-sort-command ; Bound to `s w' in bookmark list +;; "by w3m url" ; `bmkp-bmenu-sort-by-w3m-url' +;; ((bmkp-w3m-cp) bmkp-alpha-p) +;; "Sort W3M bookmarks alphabetically by their URL/filename. +;; When two bookmarks are not comparable this way, compare them by +;; bookmark name.") + +(bmkp-define-sort-command ; Bound to `s g' in bookmark list + "by Gnus thread" ; `bmkp-bmenu-sort-by-Gnus-thread' + ((bmkp-gnus-cp) bmkp-alpha-p) + "Sort Gnus bookmarks by group, then by article, then by message. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s i' in bookmark list + "by Info location" ; `bmkp-bmenu-sort-by-Info-location' + ((bmkp-info-cp) bmkp-alpha-p) + "Sort Info bookmarks by file name, then node name, then position. +When two bookmarks are not comparable this way, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f u' in bookmark list + "by last local file update" ; `bmkp-bmenu-sort-by-last-local-file-update' + ((bmkp-local-file-updated-more-recently-cp) bmkp-alpha-p) + "Sort bookmarks by last local file update time. +Sort a local file before a remote file, and a remote file before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f t' in bookmark list + "by last local file access" ; `bmkp-bmenu-sort-by-last-local-file-access' + ((bmkp-local-file-accessed-more-recently-cp) bmkp-alpha-p) + "Sort bookmarks by last local file access time. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f s' in bookmark list + "by local file size" ; `bmkp-bmenu-sort-by-local-file-size' + ((bmkp-local-file-size-cp) bmkp-alpha-p) + "Sort bookmarks by local file size. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f n' in bookmark list + "by file name" ; `bmkp-bmenu-sort-by-file-name' + ((bmkp-file-alpha-cp) bmkp-alpha-p) + "Sort bookmarks by file name. +When two bookmarks are not comparable by file name, compare them by +bookmark name.") + +(bmkp-define-sort-command ; Bound to `s f d' in bookmark list (`d' for "directory") + "by local file type" ; `bmkp-bmenu-sort-by-local-file-type' + ((bmkp-local-file-type-cp) bmkp-alpha-p) + "Sort bookmarks by local file type: file, symlink, directory. +A local file sorts before a remote file, which sorts before other +bookmarks. Otherwise, sort by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s >' in bookmark list + "marked before unmarked" ; `bmkp-bmenu-sort-marked-before-unmarked' + ((bmkp-marked-cp) bmkp-alpha-p) + "Sort bookmarks by putting marked before unmarked. +Otherwise alphabetize by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s b' in bookmark list + "by last buffer or file access" ; `bmkp-bmenu-sort-by-last-buffer-or-file-access' + ((bmkp-buffer-last-access-cp bmkp-local-file-accessed-more-recently-cp) + bmkp-alpha-p) + "Sort bookmarks by last buffer access or last local file access. +Sort a bookmark accessed more recently before one accessed less +recently or not accessed. Sort a bookmark to an existing buffer +before a local file bookmark. When two bookmarks are not comparable +by such critera, sort them by bookmark name. (In particular, sort +remote-file bookmarks by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s v' in bookmark list + "by bookmark visit frequency" ; `bmkp-bmenu-sort-by-bookmark-visit-frequency' + ((bmkp-visited-more-cp) bmkp-alpha-p) + "Sort bookmarks by the number of times they were visited as bookmarks. +When two bookmarks are not comparable by visit frequency, compare them +by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s t' in bookmark list + "by last bookmark access" ; `bmkp-bmenu-sort-by-last-bookmark-access' + ((bmkp-bookmark-last-access-cp) bmkp-alpha-p) + "Sort bookmarks by the time of their last visit as bookmarks. +When two bookmarks are not comparable by visit time, compare them +by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s 0' in bookmark list + "by creation time" ; `bmkp-bmenu-sort-by-creation-time' + ((bmkp-bookmark-creation-cp) bmkp-alpha-p) + "Sort bookmarks by the time of their creation. +When one or both of the bookmarks does not have a `created' entry), +compare them by bookmark name.") + +(bmkp-define-sort-command ; Bound to `s n' in bookmark list + "by bookmark name" ; `bmkp-bmenu-sort-by-bookmark-name' + bmkp-alpha-p + "Sort bookmarks by bookmark name, respecting `case-fold-search'.") + +;; This is a general option. It is in this file because it is used mainly by the bmenu code. +;; Its definitions MUST COME AFTER the calls to macro `bmkp-define-sort-command'. +;; Otherwise, they won't pick up a populated `bmkp-sort-orders-alist'. +(when (> emacs-major-version 20) + (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist) + "*Alist of sort orders used for cycling via `s s'... +This is a subset of the complete list of available sort orders, +`bmkp-sort-orders-alist'. This lets you cycle among fewer sort +orders, if there are some that you do not use often. + +See the doc for `bmkp-sort-orders-alist', for the structure of +this value." + :type '(alist + :key-type (choice :tag "Sort order" string symbol) + :value-type (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate"))))) + :group 'bookmark-plus)) + +(unless (> emacs-major-version 20) ; Emacs 20: custom type `alist' doesn't exist. + (defcustom bmkp-sort-orders-for-cycling-alist (copy-sequence bmkp-sort-orders-alist) + "*Alist of sort orders used for cycling via `s s'... +This is a subset of the complete list of available sort orders, +`bmkp-sort-orders-alist'. This lets you cycle among fewer sort +orders, if there are some that you do not use often. + +See the doc for `bmkp-sort-orders-alist', for the structure of this +value." + :type '(repeat + (cons + (choice :tag "Sort order" string symbol) + (choice + (const :tag "None (do not sort)" nil) + (function :tag "Sorting Predicate") + (list :tag "Sorting Multi-Predicate" + (repeat (function :tag "Component Predicate")) + (choice + (const :tag "None" nil) + (function :tag "Final Predicate")))))) + :group 'bookmark-plus)) + + +;;(@* "Other Bookmark+ Functions (`bmkp-*')") +;; *** Other Bookmark+ Functions (`bmkp-*') *** + +;;;###autoload +(defun bmkp-bmenu-describe-this+move-down (&optional defn) ; Bound to `C-down' in bookmark list + "Describe bookmark of current line, then move down to the next bookmark. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-describe-this-bookmark) (forward-line 1)) + +;;;###autoload +(defun bmkp-bmenu-describe-this+move-up (&optional defn) ; Bound to `C-up' in bookmark list + "Describe bookmark of current line, then move down to the next bookmark. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-describe-this-bookmark) (forward-line -1)) + +;;;###autoload +(defun bmkp-bmenu-describe-this-bookmark (&optional defn) ; Bound to `C-h RET' in bookmark list + "Describe bookmark of current line. +With a prefix argument, show the internal definition of the bookmark." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (if defn + (bmkp-describe-bookmark-internals (bookmark-bmenu-bookmark)) + (bmkp-describe-bookmark (bookmark-bmenu-bookmark)))) + +;;;###autoload +(defun bmkp-bmenu-describe-marked (&optional defn) ; Bound to `C-h >' in bookmark list + "Describe the marked bookmarks. +With a prefix argument, show the internal definitions." + (interactive "P") + (bmkp-bmenu-barf-if-not-in-menu-list) + (help-setup-xref (list #'bmkp-describe-bookmark-marked) (interactive-p)) + (with-output-to-temp-buffer "*Help*" + (dolist (bmk (bmkp-marked-bookmarks-only)) + (if defn + (let* ((bname (bookmark-name-from-full-record bmk)) + (help-text (format "%s\n%s\n\n%s" bname (make-string (length bname) ?-) + (pp-to-string bmk)))) + (princ help-text) (terpri)) + (princ (bmkp-bookmark-description bmk)) (terpri))))) + +(defun bmkp-bmenu-get-marked-files () + "Return a list of the file names of the marked bookmarks. +Marked bookmarks that have no associated file are ignored." + (let ((files ())) + (dolist (bmk bmkp-bmenu-marked-bookmarks) + (when (bmkp-file-bookmark-p bmk) (push (bookmark-get-filename bmk) files))) + files)) + +;;(@* "Keymaps") +;;; Keymaps ---------------------------------------------------------- + +;; `bookmark-bmenu-mode-map' + +(when (< emacs-major-version 21) + (define-key bookmark-bmenu-mode-map (kbd "RET") 'bookmark-bmenu-this-window)) +(define-key bookmark-bmenu-mode-map "." 'bmkp-bmenu-show-all) +(define-key bookmark-bmenu-mode-map ">" 'bmkp-bmenu-toggle-show-only-marked) +(define-key bookmark-bmenu-mode-map "<" 'bmkp-bmenu-toggle-show-only-unmarked) +(define-key bookmark-bmenu-mode-map (kbd "M-") 'bmkp-bmenu-unmark-all) +(define-key bookmark-bmenu-mode-map "=" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "=bM" 'bmkp-bmenu-mark-specific-buffer-bookmarks) +(define-key bookmark-bmenu-mode-map "=fM" 'bmkp-bmenu-mark-specific-file-bookmarks) +(define-key bookmark-bmenu-mode-map "=bS" 'bmkp-bmenu-show-only-specific-buffer) +(define-key bookmark-bmenu-mode-map "=fS" 'bmkp-bmenu-show-only-specific-file) +(define-key bookmark-bmenu-mode-map "%" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "%m" 'bmkp-bmenu-regexp-mark) +(define-key bookmark-bmenu-mode-map "*" nil) ; For Emacs 20 +(when (< emacs-major-version 21) + (define-key bookmark-bmenu-mode-map "*m" 'bookmark-bmenu-mark)) +(define-key bookmark-bmenu-mode-map "#" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "#S" 'bmkp-bmenu-show-only-autonamed) +;; `A' is `bookmark-bmenu-show-all-annotations' in vanilla Emacs. +(define-key bookmark-bmenu-mode-map "\M-a" 'bookmark-bmenu-show-all-annotations) +(define-key bookmark-bmenu-mode-map "A" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "AM" 'bmkp-bmenu-mark-autofile-bookmarks) +(define-key bookmark-bmenu-mode-map "AS" 'bmkp-bmenu-show-only-autofiles) +(define-key bookmark-bmenu-mode-map "B" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "BM" 'bmkp-bmenu-mark-non-file-bookmarks) +(define-key bookmark-bmenu-mode-map "BS" 'bmkp-bmenu-show-only-non-files) +(define-key bookmark-bmenu-mode-map "c" 'bmkp-bmenu-define-command) +(define-key bookmark-bmenu-mode-map "C" 'bmkp-bmenu-define-full-snapshot-command) +(define-key bookmark-bmenu-mode-map "\M-c" 'bmkp-bmenu-define-jump-marked-command) +(define-key bookmark-bmenu-mode-map "D" 'bmkp-bmenu-delete-marked) +(define-key bookmark-bmenu-mode-map "\M-d" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "\M-d>" 'bmkp-bmenu-dired-marked) +(define-key bookmark-bmenu-mode-map "\M-d\M-m" 'bmkp-bmenu-mark-dired-bookmarks) +(define-key bookmark-bmenu-mode-map "\M-d\M-s" 'bmkp-bmenu-show-only-dired) +(define-key bookmark-bmenu-mode-map "E" 'bmkp-bmenu-edit-bookmark) +(define-key bookmark-bmenu-mode-map "F" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "FM" 'bmkp-bmenu-mark-file-bookmarks) +(define-key bookmark-bmenu-mode-map "FS" 'bmkp-bmenu-show-only-files) +(define-key bookmark-bmenu-mode-map "g" 'bmkp-bmenu-refresh-menu-list) +(define-key bookmark-bmenu-mode-map "G" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "GM" 'bmkp-bmenu-mark-gnus-bookmarks) +(define-key bookmark-bmenu-mode-map "GS" 'bmkp-bmenu-show-only-gnus) +(if (fboundp 'command-remapping) + (define-key bookmark-bmenu-mode-map [remap describe-mode] 'bmkp-bmenu-mode-status-help) + ;; In Emacs < 22, the `substitute-...' affects only `?', not `C-h m', so we add it separately. + (substitute-key-definition 'describe-mode 'bmkp-bmenu-mode-status-help bookmark-bmenu-mode-map) + (define-key bookmark-bmenu-mode-map "\C-hm" 'bmkp-bmenu-mode-status-help)) +(define-key bookmark-bmenu-mode-map (kbd "C-h >") 'bmkp-bmenu-describe-marked) +(define-key bookmark-bmenu-mode-map (kbd "C-h RET") 'bmkp-bmenu-describe-this-bookmark) +(define-key bookmark-bmenu-mode-map (kbd "C-h C-") 'bmkp-bmenu-describe-this-bookmark) +(define-key bookmark-bmenu-mode-map (kbd "C-") 'bmkp-bmenu-describe-this+move-down) +(define-key bookmark-bmenu-mode-map (kbd "C-") 'bmkp-bmenu-describe-this+move-up) +(define-key bookmark-bmenu-mode-map (kbd "M-") 'bmkp-bmenu-w32-open) +(define-key bookmark-bmenu-mode-map [M-mouse-2] 'bmkp-bmenu-w32-open-with-mouse) +(when (featurep 'bookmark+-lit) + (define-key bookmark-bmenu-mode-map "H" nil) ; For Emacs 20 + (define-key bookmark-bmenu-mode-map "H+" 'bmkp-bmenu-set-lighting) + (define-key bookmark-bmenu-mode-map "H>+" 'bmkp-bmenu-set-lighting-for-marked) + (define-key bookmark-bmenu-mode-map "H>H" 'bmkp-bmenu-light-marked) + (define-key bookmark-bmenu-mode-map "HH" 'bmkp-bmenu-light) + (define-key bookmark-bmenu-mode-map "HM" 'bmkp-bmenu-mark-lighted-bookmarks) + (define-key bookmark-bmenu-mode-map "HS" 'bmkp-bmenu-show-only-lighted) + (define-key bookmark-bmenu-mode-map "H>U" 'bmkp-bmenu-unlight-marked) + (define-key bookmark-bmenu-mode-map "HU" 'bmkp-bmenu-unlight)) +(define-key bookmark-bmenu-mode-map "I" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "IM" 'bmkp-bmenu-mark-info-bookmarks) +(define-key bookmark-bmenu-mode-map "IS" 'bmkp-bmenu-show-only-info-nodes) +(define-key bookmark-bmenu-mode-map "K" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "KM" 'bmkp-bmenu-mark-desktop-bookmarks) +(define-key bookmark-bmenu-mode-map "KS" 'bmkp-bmenu-show-only-desktops) +(define-key bookmark-bmenu-mode-map "L" 'bmkp-switch-bookmark-file) +(define-key bookmark-bmenu-mode-map "M" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "MM" 'bmkp-bmenu-mark-man-bookmarks) +(define-key bookmark-bmenu-mode-map "MS" 'bmkp-bmenu-show-only-man-pages) +(define-key bookmark-bmenu-mode-map "\M-m" 'bmkp-bmenu-mark-all) +(define-key bookmark-bmenu-mode-map "O" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "O>" 'bmkp-bmenu-omit/unomit-marked) +(define-key bookmark-bmenu-mode-map "OS" 'bmkp-bmenu-show-only-omitted) +(define-key bookmark-bmenu-mode-map "OU" 'bmkp-unomit-all) +(define-key bookmark-bmenu-mode-map "P" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "PA" 'bmkp-bmenu-filter-annotation-incrementally) +(define-key bookmark-bmenu-mode-map "PB" 'bmkp-bmenu-filter-bookmark-name-incrementally) +(define-key bookmark-bmenu-mode-map "PF" 'bmkp-bmenu-filter-file-name-incrementally) +(define-key bookmark-bmenu-mode-map "PT" 'bmkp-bmenu-filter-tags-incrementally) +(define-key bookmark-bmenu-mode-map "q" 'bmkp-bmenu-quit) +(define-key bookmark-bmenu-mode-map "\M-q" 'bmkp-bmenu-query-replace-marked-bookmarks-regexp) +(define-key bookmark-bmenu-mode-map "R" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "RM" 'bmkp-bmenu-mark-region-bookmarks) +(define-key bookmark-bmenu-mode-map "RS" 'bmkp-bmenu-show-only-regions) +(define-key bookmark-bmenu-mode-map "\M-r" 'bookmark-bmenu-relocate) ; `R' in Emacs +(define-key bookmark-bmenu-mode-map "S" 'bookmark-bmenu-save) ; `s' in Emacs +(define-key bookmark-bmenu-mode-map "s" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "s>" 'bmkp-bmenu-sort-marked-before-unmarked) +(define-key bookmark-bmenu-mode-map "s0" 'bmkp-bmenu-sort-by-creation-time) +(define-key bookmark-bmenu-mode-map "sb" 'bmkp-bmenu-sort-by-last-buffer-or-file-access) +(define-key bookmark-bmenu-mode-map "sfd" 'bmkp-bmenu-sort-by-local-file-type) +(define-key bookmark-bmenu-mode-map "sfn" 'bmkp-bmenu-sort-by-file-name) +(define-key bookmark-bmenu-mode-map "sfs" 'bmkp-bmenu-sort-by-local-file-size) +(define-key bookmark-bmenu-mode-map "sft" 'bmkp-bmenu-sort-by-last-local-file-access) +(define-key bookmark-bmenu-mode-map "sfu" 'bmkp-bmenu-sort-by-last-local-file-update) +(define-key bookmark-bmenu-mode-map "sg" 'bmkp-bmenu-sort-by-Gnus-thread) +(define-key bookmark-bmenu-mode-map "si" 'bmkp-bmenu-sort-by-Info-location) +(define-key bookmark-bmenu-mode-map "sk" 'bmkp-bmenu-sort-by-bookmark-type) +(define-key bookmark-bmenu-mode-map "sn" 'bmkp-bmenu-sort-by-bookmark-name) +(define-key bookmark-bmenu-mode-map "sr" 'bmkp-reverse-sort-order) +(define-key bookmark-bmenu-mode-map "s\C-r" 'bmkp-reverse-multi-sort-order) +(define-key bookmark-bmenu-mode-map "ss" 'bmkp-bmenu-change-sort-order-repeat) +(define-key bookmark-bmenu-mode-map "st" 'bmkp-bmenu-sort-by-last-bookmark-access) +(define-key bookmark-bmenu-mode-map "su" 'bmkp-bmenu-sort-by-url) +(define-key bookmark-bmenu-mode-map "sv" 'bmkp-bmenu-sort-by-bookmark-visit-frequency) +;; ;; (define-key bookmark-bmenu-mode-map "sw" 'bmkp-bmenu-sort-by-w3m-url) +(when (> emacs-major-version 22) ; Emacs 23+ + (define-key bookmark-bmenu-mode-map (kbd "M-s a C-s") 'bmkp-bmenu-isearch-marked-bookmarks) + (define-key bookmark-bmenu-mode-map (kbd "M-s a M-C-s") 'bmkp-bmenu-isearch-marked-bookmarks-regexp)) +(define-key bookmark-bmenu-mode-map (kbd "M-s a M-s") 'bmkp-bmenu-search-marked-bookmarks-regexp) +(define-key bookmark-bmenu-mode-map "T" nil) ; For Emacs20 +(define-key bookmark-bmenu-mode-map "T>+" 'bmkp-bmenu-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T>-" 'bmkp-bmenu-remove-tags-from-marked) +(define-key bookmark-bmenu-mode-map "T>p" 'bmkp-bmenu-paste-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T>q" 'bmkp-bmenu-paste-replace-tags-for-marked) +(define-key bookmark-bmenu-mode-map "T>v" 'bmkp-bmenu-set-tag-value-for-marked) +(define-key bookmark-bmenu-mode-map "T>\C-y" 'bmkp-bmenu-paste-add-tags-to-marked) +(define-key bookmark-bmenu-mode-map "T0" 'bmkp-remove-all-tags) +(define-key bookmark-bmenu-mode-map "T+" 'bmkp-add-tags) +(define-key bookmark-bmenu-mode-map "T-" 'bmkp-remove-tags) +(define-key bookmark-bmenu-mode-map "Tc" 'bmkp-bmenu-copy-tags) +(define-key bookmark-bmenu-mode-map "Td" 'bmkp-remove-tags-from-all) +(define-key bookmark-bmenu-mode-map "Te" 'bmkp-bmenu-edit-tags) +(define-key bookmark-bmenu-mode-map "Tl" 'bmkp-list-all-tags) +(define-key bookmark-bmenu-mode-map "Tm*" 'bmkp-bmenu-mark-bookmarks-tagged-all) +(define-key bookmark-bmenu-mode-map "Tm%" 'bmkp-bmenu-mark-bookmarks-tagged-regexp) +(define-key bookmark-bmenu-mode-map "Tm+" 'bmkp-bmenu-mark-bookmarks-tagged-some) +(define-key bookmark-bmenu-mode-map "Tm~*" 'bmkp-bmenu-mark-bookmarks-tagged-not-all) +(define-key bookmark-bmenu-mode-map "Tm~+" 'bmkp-bmenu-mark-bookmarks-tagged-none) +(define-key bookmark-bmenu-mode-map "Tp" 'bmkp-bmenu-paste-add-tags) +(define-key bookmark-bmenu-mode-map "Tq" 'bmkp-bmenu-paste-replace-tags) +(define-key bookmark-bmenu-mode-map "Tr" 'bmkp-rename-tag) +(define-key bookmark-bmenu-mode-map "Ts" 'bmkp-define-tags-sort-command) +(define-key bookmark-bmenu-mode-map "TS" 'bmkp-bmenu-show-only-tagged) +(define-key bookmark-bmenu-mode-map "Tu*" 'bmkp-bmenu-unmark-bookmarks-tagged-all) +(define-key bookmark-bmenu-mode-map "Tu%" 'bmkp-bmenu-unmark-bookmarks-tagged-regexp) +(define-key bookmark-bmenu-mode-map "Tu+" 'bmkp-bmenu-unmark-bookmarks-tagged-some) +(define-key bookmark-bmenu-mode-map "Tu~*" 'bmkp-bmenu-unmark-bookmarks-tagged-not-all) +(define-key bookmark-bmenu-mode-map "Tu~+" 'bmkp-bmenu-unmark-bookmarks-tagged-none) +(define-key bookmark-bmenu-mode-map "Tv" 'bmkp-bmenu-set-tag-value) +(define-key bookmark-bmenu-mode-map "T\M-w" 'bmkp-bmenu-copy-tags) +(define-key bookmark-bmenu-mode-map "T\C-y" 'bmkp-bmenu-paste-add-tags) +(define-key bookmark-bmenu-mode-map "\M-l" 'bmkp-toggle-saving-menu-list-state) +(define-key bookmark-bmenu-mode-map "\M-~" 'bmkp-toggle-saving-bookmark-file) +(define-key bookmark-bmenu-mode-map "\M-t" 'bookmark-bmenu-toggle-filenames) ; `t' in Emacs +(define-key bookmark-bmenu-mode-map "t" 'bmkp-bmenu-toggle-marks) +(define-key bookmark-bmenu-mode-map "U" 'bmkp-bmenu-unmark-all) +(define-key bookmark-bmenu-mode-map "\M-u" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "\M-u\M-m" 'bmkp-bmenu-mark-url-bookmarks) +(define-key bookmark-bmenu-mode-map "\M-u\M-s" 'bmkp-bmenu-show-only-urls) +(define-key bookmark-bmenu-mode-map "V" nil) ; For Emacs20 +(define-key bookmark-bmenu-mode-map "VS" 'bmkp-bmenu-show-only-variable-lists) +(define-key bookmark-bmenu-mode-map "\M-o" 'bmkp-bmenu-w32-open-select) +(define-key bookmark-bmenu-mode-map "W" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "WM" 'bmkp-bmenu-mark-w3m-bookmarks) +(define-key bookmark-bmenu-mode-map "WS" 'bmkp-bmenu-show-only-w3m-urls) +(define-key bookmark-bmenu-mode-map "X" nil) ; For Emacs 20 +(define-key bookmark-bmenu-mode-map "XM" 'bmkp-bmenu-mark-bookmark-file-bookmarks) +(define-key bookmark-bmenu-mode-map "XS" 'bmkp-bmenu-show-only-bookmark-files) + + +;;; `Bookmark+' menu-bar menu in `*Bookmark List*' + +(defvar bmkp-bmenu-menubar-menu (make-sparse-keymap "Bookmark+") "`Boomark+' menu-bar menu.") +(define-key bookmark-bmenu-mode-map [menu-bar bmkp] + (cons "Bookmark+" bmkp-bmenu-menubar-menu)) + +;; Top level +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-quit] + '(menu-item "Quit" bmkp-bmenu-quit + :help "Quit the bookmark list, saving its state and the current set of bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-marked] + '(menu-item "Describe Marked Bookmarks" bmkp-bmenu-describe-marked + :help "Describe the marked bookmarks. With `C-u' show internal format.")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-describe-this-bookmark] + '(menu-item "Describe This Bookmark" bmkp-bmenu-describe-this-bookmark + :help "Describe this line's bookmark. With `C-u' show internal format.")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-mode-status-help] + '(menu-item "Current Status, Mode Help" bmkp-bmenu-mode-status-help :keys "?" + :help "Describe `*Bookmark List*' and show its current status")) +(define-key bmkp-bmenu-menubar-menu [top-sep2] '("--")) +(define-key bmkp-bmenu-menubar-menu [bmkp-toggle-saving-menu-list-state] + '(menu-item "Toggle Autosaving Display State" bmkp-toggle-saving-menu-list-state + :help "Toggle the value of option `bmkp-bmenu-state-file'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-toggle-saving-bookmark-file] + '(menu-item "Toggle Autosaving Bookmark File" bmkp-toggle-saving-bookmark-file + :help "Toggle the value of option `bookmark-save-flag'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-switch-bookmark-file] + '(menu-item "Switch to Bookmark File..." bmkp-switch-bookmark-file + :help "Switch to a different bookmark file, *replacing* the current set of bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-load] + '(menu-item "Add Bookmarks from File..." bookmark-bmenu-load + :help "Load additional bookmarks from a bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bmkp-empty-file] + '(menu-item "New (Empty) Bookmark File..." bmkp-empty-file + :help "Create a new, empty bookmark file, or empty an existing bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bookmark-write] + '(menu-item "Save As..." bookmark-write + :help "Write the current set of bookmarks to a file whose name you enter")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-save] + '(menu-item "Save" bookmark-bmenu-save + :help "Save the current set of bookmarks to the current bookmark file")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-refresh-menu-list] + '(menu-item "Refresh (Revert)" bmkp-bmenu-refresh-menu-list + :help "Update the displayed bookmark list to reflect the currently defined bookmarks")) +(define-key bmkp-bmenu-menubar-menu [top-sep1] '("--")) + +(define-key bmkp-bmenu-menubar-menu [bmkp-make-function-bookmark] + '(menu-item "New Function Bookmark..." bmkp-make-function-bookmark + :help "Create a bookmark that will invoke FUNCTION when \"jumped\" to")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-make-sequence-from-marked] + '(menu-item "New Sequence Bookmark from Marked..." bmkp-bmenu-make-sequence-from-marked + :help "Create or update a sequence bookmark from the visible marked bookmarks")) +(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-from-bookmark-list] + '(menu-item "Set Navlist from Bookmark-List Bookmark..." bmkp-choose-navlist-from-bookmark-list + :help "Set the navigation list from a bookmark-list bookmark")) +(define-key bmkp-bmenu-menubar-menu [bmkp-choose-navlist-of-type] + '(menu-item "Set Navlist to Bookmarks of Type..." bmkp-choose-navlist-of-type + :help "Set the navigation list to the bookmarks of a certain type")) +(define-key bmkp-bmenu-menubar-menu [bmkp-list-defuns-in-commands-file] + '(menu-item "List User-Defined Bookmark Commands" bmkp-list-defuns-in-commands-file + :help "List the functions defined in `bmkp-bmenu-commands-file'")) + +(defvar bmkp-bmenu-define-command-menu (make-sparse-keymap "Define Command") + "`Define Command' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [define-command] + (cons "Define Command" bmkp-bmenu-define-command-menu)) + +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-full-snapshot-command] + '(menu-item "To Restore Full Bookmark-List State..." bmkp-bmenu-define-full-snapshot-command + :help "Define a command to restore the current bookmark-list state")) +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-command] + '(menu-item "To Restore Current Order and Filter..." bmkp-bmenu-define-command + :help "Define a command to use the current sort order, filter, and omit list")) +(define-key bmkp-bmenu-define-command-menu [bmkp-define-tags-sort-command] + '(menu-item "To Sort by Specific Tags..." bmkp-define-tags-sort-command + :help "Define a command to sort bookmarks in the bookmark list by certain tags")) +(define-key bmkp-bmenu-define-command-menu [bmkp-bmenu-define-jump-marked-command] + '(menu-item "To Jump to a Bookmark Now Marked..." bmkp-bmenu-define-jump-marked-command + :help "Define a command to jump to one of the bookmarks that is now marked" + :enable bmkp-bmenu-marked-bookmarks)) + +(when (featurep 'bookmark+-lit) + (defvar bmkp-bmenu-highlight-menu (make-sparse-keymap "Highlight") + "`Highlight' submenu for menu-bar `Bookmark+' menu.") + (define-key bmkp-bmenu-menubar-menu [highlight] (cons "Highlight" bmkp-bmenu-highlight-menu)) + + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-show-only-lighted] + '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted + :help "Display (only) highlighted bookmarks")) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-set-lighting-for-marked] + '(menu-item "Set Highlighting for Marked" bmkp-bmenu-set-lighting-for-marked + :help "Set specific highlighting for the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks)) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-unlight-marked] + '(menu-item "Unhighlight Marked" bmkp-bmenu-unlight-marked + :help "Unhighlight the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks)) + (define-key bmkp-bmenu-highlight-menu [bmkp-bmenu-light-marked] + '(menu-item "Highlight Marked" bmkp-bmenu-light-marked + :help "Highlight the marked bookmarks" + :enable bmkp-bmenu-marked-bookmarks))) + +(defvar bmkp-bmenu-tags-menu (make-sparse-keymap "Tags") + "`Tags' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [tags] (cons "Tags" bmkp-bmenu-tags-menu)) + +(define-key bmkp-bmenu-tags-menu [bmkp-list-all-tags] + '(menu-item "List All Tags" bmkp-list-all-tags :help "List all tags used for any bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-purge-notags-autofiles] + '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles + :help "Delete all autofile bookmarks that have no tags")) +(define-key bmkp-bmenu-tags-menu [bmkp-untag-a-file] + '(menu-item "Untag a File (Remove Some)..." bmkp-untag-a-file + :help "Remove some tags from autofile bookmark for a file")) +(define-key bmkp-bmenu-tags-menu [bmkp-tag-a-file] + '(menu-item "Tag a File (Add Some)..." bmkp-tag-a-file + :help "Add some tags to the autofile bookmark for a file")) +(define-key bmkp-bmenu-tags-menu [bmkp-rename-tag] + '(menu-item "Rename Tag..." bmkp-rename-tag + :help "Rename a tag in all bookmarks, even those not showing")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-set-tag-value-for-marked] + '(menu-item "Set Tag Value for Marked..." bmkp-bmenu-set-tag-value-for-marked + :help "Set the value of a tag, for each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-remove-tags-from-all] + '(menu-item "Remove Some Tags from All..." bmkp-remove-tags-from-all + :help "Remove a set of tags from all bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-remove-tags-from-marked] + '(menu-item "Remove Some Tags from Marked..." bmkp-bmenu-remove-tags-from-marked + :help "Remove a set of tags from each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-add-tags-to-marked] + '(menu-item "Add Some Tags to Marked..." bmkp-bmenu-add-tags-to-marked + :help "Add a set of tags to each of the marked bookmarks")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-replace-tags-for-marked] + '(menu-item "Paste Tags to Marked (Replace)..." bmkp-bmenu-paste-replace-tags-for-marked + :help "Replace tags for the marked bookmarks with tags copied previously")) +(define-key bmkp-bmenu-tags-menu [bmkp-bmenu-paste-add-tags-to-marked] + '(menu-item "Paste Tags to Marked (Add)..." bmkp-bmenu-paste-add-tags-to-marked + :help "Add tags copied from another bookmark to the marked bookmarks")) + +(defvar bmkp-bmenu-sort-menu (make-sparse-keymap "Sort") + "`Sort' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [sort] (cons "Sort" bmkp-bmenu-sort-menu)) + +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-url] + '(menu-item "By URL" bmkp-bmenu-sort-by-url + :help "Sort URL bookmarks alphabetically by their URL/filename")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Gnus-thread] + '(menu-item "By Gnus Thread" bmkp-bmenu-sort-by-Gnus-thread + :help "Sort Gnus bookmarks by group, then by article, then by message")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-Info-location] + '(menu-item "By Info Node" bmkp-bmenu-sort-by-Info-location + :help "Sort Info bookmarks by file name, then node name, then position")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-local-file-update] + '(menu-item "By Last Local File Update" bmkp-bmenu-sort-by-last-local-file-update + :help "Sort bookmarks by last local file update time")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-buffer-or-file-access] + '(menu-item "By Last Buffer/File Access" bmkp-bmenu-sort-by-last-buffer-or-file-access + :help "Sort bookmarks by time of last buffer access or local-file access")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-size] + '(menu-item "By Local File Size" bmkp-bmenu-sort-by-local-file-size + :help "Sort bookmarks by local file size")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-local-file-type] + '(menu-item "By Local File Type" bmkp-bmenu-sort-by-local-file-type + :help "Sort bookmarks by local file type: file, symlink, directory")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-type] + '(menu-item "By Type" bmkp-bmenu-sort-by-bookmark-type + :help "Sort bookmarks by type: Info, URL, Gnus, files, other")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-file-name] + '(menu-item "By File Name" bmkp-bmenu-sort-by-file-name :help "Sort bookmarks by file name")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-name] + '(menu-item "By Bookmark Name" bmkp-bmenu-sort-by-bookmark-name + :help "Sort bookmarks by bookmark name, respecting `case-fold-search'")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-creation-time] + '(menu-item "By Creation Time" bmkp-bmenu-sort-by-creation-time + :help "Sort bookmarks by the time of their creation")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-last-bookmark-access] + '(menu-item "By Last Bookmark Access" bmkp-bmenu-sort-by-last-bookmark-access + :help "Sort bookmarks by the time of their last visit as bookmarks")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-by-bookmark-visit-frequency] + '(menu-item "By Bookmark Use" bmkp-bmenu-sort-by-bookmark-visit-frequency + :help "Sort bookmarks by the number of times they were visited as bookmarks")) +(define-key bmkp-bmenu-sort-menu [bmkp-bmenu-sort-marked-before-unmarked] + '(menu-item "Marked Before Unmarked" bmkp-bmenu-sort-marked-before-unmarked + :help "Sort bookmarks by putting marked before unmarked")) +(define-key bmkp-bmenu-sort-menu [bmkp-reverse-sort-order] + '(menu-item "Reverse" bmkp-reverse-sort-order :help "Reverse the current bookmark sort order")) + +(defvar bmkp-bmenu-show-menu (make-sparse-keymap "Show") + "`Show' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [show] (cons "Show" bmkp-bmenu-show-menu)) + +(define-key bmkp-bmenu-show-menu [bookmark-bmenu-show-all-annotations] + '(menu-item "Show Annotations" bookmark-bmenu-show-all-annotations + :help "Show the annotations for all bookmarks (in another window)")) +(define-key bmkp-bmenu-show-menu [bookmark-bmenu-toggle-filenames] + '(menu-item "Show/Hide File Names" bookmark-bmenu-toggle-filenames + :help "Toggle whether filenames are shown in the bookmark list")) +(define-key bmkp-bmenu-show-menu [show-sep1] '("--")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-all] + '(menu-item "Show All" bmkp-bmenu-show-all + :help "Show all bookmarks currently known to the bookmark list")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-tags-incrementally] + '(menu-item "Show Only Tag Matches..." bmkp-bmenu-filter-tags-incrementally + :help "Incrementally filter bookmarks by tags using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-annotation-incrementally] + '(menu-item "Show Only Annotation Matches..." bmkp-bmenu-filter-annotation-incrementally + :help "Incrementally filter bookmarks by annotation using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-file-name-incrementally] + '(menu-item "Show Only File Name Matches..." bmkp-bmenu-filter-file-name-incrementally + :help "Incrementally filter bookmarks by file name using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-filter-bookmark-name-incrementally] + '(menu-item "Show Only Name Matches..." bmkp-bmenu-filter-bookmark-name-incrementally + :help "Incrementally filter bookmarks by bookmark name using a regexp")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-file] + '(menu-item "Show Only for Specific File" bmkp-bmenu-show-only-specific-file + :help "Display (only) the bookmarks for a specific file")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-specific-buffer] + '(menu-item "Show Only for Specific Buffer" bmkp-bmenu-show-only-specific-buffer + :help "Display (only) the bookmarks for a specific buffer")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-urls] + '(menu-item "Show Only URLs" bmkp-bmenu-show-only-urls + :help "Display (only) the URL bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-gnus] + '(menu-item "Show Only Gnus Messages" bmkp-bmenu-show-only-gnus + :help "Display (only) the Gnus bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-man-pages] + '(menu-item "Show Only UNIX Manual Pages" bmkp-bmenu-show-only-man-pages + :help "Display (only) the `man' page bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-info-nodes] + '(menu-item "Show Only Info Nodes" bmkp-bmenu-show-only-info-nodes + :help "Display (only) the Info bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-dired] + '(menu-item "Show Only Dired Buffers" bmkp-bmenu-show-only-dired + :help "Display (only) the Dired bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-bookmark-files] + '(menu-item "Show Only Bookmark Files" bmkp-bmenu-show-only-bookmark-files + :help "Display (only) the bookmark-file bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-desktops] + '(menu-item "Show Only Desktops" bmkp-bmenu-show-only-desktops + :help "Display (only) the desktop bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-regions] + '(menu-item "Show Only Regions" bmkp-bmenu-show-only-regions + :help "Display (only) the bookmarks that record a region")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-non-files] + '(menu-item "Show Only Non-Files (Buffers)" bmkp-bmenu-show-only-non-files + :help "Display (only) the non-file bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-files] + '(menu-item "Show Only Files" bmkp-bmenu-show-only-files + :help "Display (only) the file and directory bookmarks")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autofiles] + '(menu-item "Show Only Autofiles" bmkp-bmenu-show-only-autofiles + :help "Display (only) the autofile bookmarks: those named the same as their files")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-autonamed] + '(menu-item "Show Only Autonamed" bmkp-bmenu-show-only-autonamed + :help "Display (only) the autonamed bookmarks")) +(when (featurep 'bookmark+-lit) + (define-key bmkp-bmenu-show-menu [bmkp-bmenu-show-only-lighted] + '(menu-item "Show Only Highlighted" bmkp-bmenu-show-only-lighted + :help "Display (only) highlighted bookmarks"))) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-unmarked] + '(menu-item "Show Only Unmarked" bmkp-bmenu-toggle-show-only-unmarked + :help "Hide all marked bookmarks. Repeat to toggle, showing all")) +(define-key bmkp-bmenu-show-menu [bmkp-bmenu-toggle-show-only-marked] + '(menu-item "Show Only Marked" bmkp-bmenu-toggle-show-only-marked + :help "Hide all unmarked bookmarks. Repeat to toggle, showing all")) + +(defvar bmkp-bmenu-omit-menu (make-sparse-keymap "Omit") + "`Omit' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [omitting] (cons "Omit" bmkp-bmenu-omit-menu)) + +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-all] + '(menu-item "Show All" bmkp-bmenu-show-all + :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + :help "Show all bookmarks (except omitted)")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-show-only-omitted] + '(menu-item "Show Only Omitted" bmkp-bmenu-show-only-omitted + :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)) + :enable bmkp-bmenu-omitted-bookmarks :help "Show only the omitted bookmarks")) +(define-key bmkp-bmenu-omit-menu [bmkp-unomit-all] + '(menu-item "Un-Omit All" bmkp-unomit-all + :visible bmkp-bmenu-omitted-bookmarks :help "Un-omit all omitted bookmarks")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-unomit-marked] + '(menu-item "Un-Omit Marked" bmkp-bmenu-unomit-marked + :visible (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only) + :enable (and bmkp-bmenu-omitted-bookmarks + (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (re-search-forward "^>" (point-max) t))) + :help "Un-omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]")) +(define-key bmkp-bmenu-omit-menu [bmkp-bmenu-omit-marked] + '(menu-item "Omit Marked" bmkp-bmenu-omit-marked + :visible (not (eq bmkp-bmenu-filter-function 'bmkp-omitted-alist-only)) + :enable (and (save-excursion (goto-char (point-min)) (forward-line bmkp-bmenu-header-lines) + (re-search-forward "^>" (point-max) t))) + :help "Omit the marked bookmarks" :keys "\\[bmkp-bmenu-omit/unomit-marked]")) + +(defvar bmkp-bmenu-mark-menu (make-sparse-keymap "Mark") + "`Mark' submenu for menu-bar `Bookmark+' menu.") +(define-key bmkp-bmenu-menubar-menu [marking] (cons "Mark" bmkp-bmenu-mark-menu)) + +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-not-all] + '(menu-item "Unmark If Not Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-not-all + :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-none] + '(menu-item "Unmark If Tagged with None..." bmkp-bmenu-unmark-bookmarks-tagged-none + :help "Unmark all visible bookmarks that are *not* tagged with *any* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-all] + '(menu-item "Unmark If Tagged with All..." bmkp-bmenu-unmark-bookmarks-tagged-all + :help "Unmark all visible bookmarks that are tagged with *each* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-some] + '(menu-item "Unmark If Tagged with Some..." bmkp-bmenu-unmark-bookmarks-tagged-some + :help "Unmark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-bookmarks-tagged-regexp] + '(menu-item "Unmark If Tagged Matching Regexp..." bmkp-bmenu-unmark-bookmarks-tagged-regexp + :help "Unmark bookmarks any of whose tags match a regexp you enter")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-not-all] + '(menu-item "Mark If Not Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-not-all + :help "Mark all visible bookmarks that are *not* tagged with *all* tags you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-none] + '(menu-item "Mark If Tagged with None..." bmkp-bmenu-mark-bookmarks-tagged-none + :help "Mark all visible bookmarks that are not tagged with *any* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-all] + '(menu-item "Mark If Tagged with All..." bmkp-bmenu-mark-bookmarks-tagged-all + :help "Mark all visible bookmarks that are tagged with *each* tag you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-some] + '(menu-item "Mark If Tagged with Some..." bmkp-bmenu-mark-bookmarks-tagged-some + :help "Mark all visible bookmarks that are tagged with *some* tag in a set you specify")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmarks-tagged-regexp] + '(menu-item "Mark If Tagged Matching Regexp..." bmkp-bmenu-mark-bookmarks-tagged-regexp + :help "Mark bookmarks any of whose tags match a regexp you enter")) +(define-key bmkp-bmenu-mark-menu [mark-sep1] '("--")) +(when (featurep 'bookmark+-lit) + (define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-lighted-bookmarks] + '(menu-item "Mark Highlighted" bmkp-bmenu-mark-lighted-bookmarks + :help "Mark highlighted bookmarks"))) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-file-bookmarks] + '(menu-item "Mark for Specific File" bmkp-bmenu-mark-specific-file-bookmarks + :help "Mark bookmarks for a specific file")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-specific-buffer-bookmarks] + '(menu-item "Mark for Specific Buffer" bmkp-bmenu-mark-specific-buffer-bookmarks + :help "Mark bookmarks for a specific buffer")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-url-bookmarks] + '(menu-item "Mark URLs" bmkp-bmenu-mark-url-bookmarks :help "Mark URL bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-gnus-bookmarks] + '(menu-item "Mark Gnus Messages" bmkp-bmenu-mark-gnus-bookmarks :help "Mark Gnus bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-man-bookmarks] + '(menu-item "Mark UNIX Manual Pages" bmkp-bmenu-mark-man-bookmarks + :help "Mark `man' page bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-info-bookmarks] + '(menu-item "Mark Info Nodes" bmkp-bmenu-mark-info-bookmarks :help "Mark Info bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-dired-bookmarks] + '(menu-item "Mark Dired Buffers" bmkp-bmenu-mark-dired-bookmarks :help "Mark Dired bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-bookmark-file-bookmarks] + '(menu-item "Mark Bookmark Files" bmkp-bmenu-mark-bookmark-file-bookmarks + :help "Mark the bookmark-file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-desktop-bookmarks] + '(menu-item "Mark Desktops" bmkp-bmenu-mark-desktop-bookmarks + :help "Mark desktop bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-region-bookmarks] + '(menu-item "Mark Regions" bmkp-bmenu-mark-region-bookmarks + :help "Mark bookmarks that record a region")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-non-file-bookmarks] + '(menu-item "Mark Non-Files (Buffers)" bmkp-bmenu-mark-non-file-bookmarks + :help "Mark non-file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-autofile-bookmarks] + '(menu-item "Mark Autofiles" bmkp-bmenu-mark-autofile-bookmarks + :help "Mark autofile bookmarks: those whose names are the same as their files")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-file-bookmarks] + '(menu-item "Mark Files" bmkp-bmenu-mark-file-bookmarks :help "Mark file bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-unmark-all] + '(menu-item "Unmark All" bmkp-bmenu-unmark-all + :help "Remove a mark you specify (> or D) from each bookmark (RET to remove both kinds)")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-mark-all] + '(menu-item "Mark All" bmkp-bmenu-mark-all :help "Mark all bookmarks, using mark `>'")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-toggle-marks] + '(menu-item "Toggle Marked/Unmarked" bmkp-bmenu-toggle-marks + :help "Unmark all marked bookmarks; mark all unmarked bookmarks")) +(define-key bmkp-bmenu-mark-menu [bmkp-bmenu-regexp-mark] + '(menu-item "Mark Regexp Matches..." bmkp-bmenu-regexp-mark + :help "Mark bookmarks that match a regexp that you enter")) + +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-execute-deletions] + '(menu-item "Delete Flagged (D)" bookmark-bmenu-execute-deletions + :help "Delete the (visible) bookmarks flagged `D'")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-delete-marked] + '(menu-item "Delete Marked (>)" bmkp-bmenu-delete-marked + :help "Delete all (visible) bookmarks marked `>', after confirmation")) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-query-replace-marked-bookmarks-regexp] + '(menu-item "Query-Replace Marked..." bmkp-bmenu-query-replace-marked-bookmarks-regexp + :help "`query-replace-regexp' over all files whose bookmarks are marked")) +(when (fboundp 'bmkp-bmenu-isearch-marked-bookmarks) + (define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-isearch-marked-bookmarks-regexp] + '(menu-item "Regexp-Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks-regexp + :help "Regexp Isearch the marked bookmark locations, in their current order")) + (define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-isearch-marked-bookmarks] + '(menu-item "Isearch Marked..." bmkp-bmenu-isearch-marked-bookmarks + :help "Isearch the marked bookmark locations, in their current order"))) +(define-key bmkp-bmenu-menubar-menu [bmkp-bmenu-search-marked-bookmarks-regexp] + '(menu-item "Search Marked..." bmkp-bmenu-search-marked-bookmarks-regexp + :help "Regexp-search the files whose bookmarks are marked, in their current order")) +(define-key bmkp-bmenu-menubar-menu [bookmark-bmenu-select] + '(menu-item "Jump to Marked" bookmark-bmenu-select + :help "Jump to this line's bookmark. Also visit each bookmark marked with `>'")) + + + +;;; Mouse-3 menu binding. + +(defvar bmkp-bmenu-line-overlay nil + "Overlay to highlight the current line for `bmkp-bmenu-mouse-3-menu'.") +(define-key bookmark-bmenu-mode-map [mouse-3] 'bmkp-bmenu-mouse-3-menu) + +;;;###autoload +(defun bmkp-bmenu-mouse-3-menu (event) + "Pop-up menu on `mouse-3' for a bookmark listed in `*Bookmark List*'." + (interactive "e") + (let* ((mouse-pos (event-start event)) + (inhibit-field-text-motion t) ; Just in case. + bol eol + (bmk-name (save-excursion + (with-current-buffer (window-buffer (posn-window mouse-pos)) + (save-excursion + (goto-char (posn-point mouse-pos)) + (save-excursion + (setq bol (progn (beginning-of-line) (point)) + eol (progn (end-of-line) (point)))) + (if bmkp-bmenu-line-overlay ; Don't recreate. + (move-overlay bmkp-bmenu-line-overlay bol eol + (current-buffer)) + (setq bmkp-bmenu-line-overlay (make-overlay bol eol)) + (overlay-put bmkp-bmenu-line-overlay 'face 'region)) + (bookmark-bmenu-bookmark)))))) + (sit-for 0) + (let ((menu-choice + (x-popup-menu event + (list "This Bookmark" + (if bmk-name + (list bmk-name + (if (bmkp-bookmark-name-member bmk-name + bmkp-bmenu-marked-bookmarks) + '("Unmark" . bookmark-bmenu-unmark) + '("Mark" . bookmark-bmenu-mark)) + (save-excursion + (goto-char (posn-point mouse-pos)) + (beginning-of-line) + (if (looking-at "^D") + '("Unmark" . bookmark-bmenu-unmark) + '("Flag for Deletion" . bookmark-bmenu-delete))) + '("Omit" . bmkp-bmenu-omit) + '("--") ; ---------------------------------------- + '("Jump To" . bookmark-bmenu-this-window) + '("Jump To in Other Window" . bookmark-bmenu-other-window) + '("--") ; ---------------------------------------- + '("Copy Tags" . bmkp-bmenu-copy-tags) + '("Paste Tags (Add)" . bmkp-bmenu-paste-add-tags) + '("Paste Tags (Replace)" . bmkp-bmenu-paste-replace-tags) + '("Add Some Tags..." . bmkp-bmenu-add-tags) + '("Remove Some Tags..." . bmkp-bmenu-remove-tags) + '("Remove All Tags..." . bmkp-bmenu-remove-all-tags) + '("Rename..." . bmkp-rename-tag) + '("Set Tag Value..." . bmkp-bmenu-set-tag-value) + (and (featurep 'bookmark+-lit) + '("--")) ; ---------------------------------------- + (and (featurep 'bookmark+-lit) + '("Highlight" . bmkp-bmenu-light)) + (and (featurep 'bookmark+-lit) + '("Unhighlight" . bmkp-bmenu-unlight)) + (and (featurep 'bookmark+-lit) + '("Set Lighting" . bmkp-bmenu-set-lighting)) + '("--") ; ---------------------------------------- + '("Show Annotation" . bookmark-bmenu-show-annotation) + '("Edit Annotation..." . bookmark-bmenu-edit-annotation) + '("Edit Name, File Name..." . bmkp-bmenu-edit-bookmark) + '("Rename..." . bookmark-bmenu-rename) + '("Relocate..." . bookmark-bmenu-relocate) + '("--") ; ---------------------------------------- + '("Describe" . bmkp-bmenu-describe-this-bookmark)) + '("" (""))))))) ; No menu: not on a bookmark line. + (when bmkp-bmenu-line-overlay (delete-overlay bmkp-bmenu-line-overlay)) + (and menu-choice (save-excursion (goto-char (posn-point mouse-pos)) + (call-interactively menu-choice)))))) + +;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-bmu) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-bmu.el ends here diff --git a/auto-install/bookmark+-chg.el b/auto-install/bookmark+-chg.el new file mode 100644 index 0000000..8e10aad --- /dev/null +++ b/auto-install/bookmark+-chg.el @@ -0,0 +1,1609 @@ +;;; bookmark+-chg.el - Change logs for Bookmark+ libraries. +;; +;; Filename: bookmark+-chg.el +;; Description: Change logs for Bookmark+ libraries. +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Created: Fri Sep 15 07:58:41 2000 +;; Last-Updated: Tue Aug 9 10:29:22 2011 (-0700) +;; By: dradams +;; Update #: 13732 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-chg.el +;; Keywords: bookmarks, bookmark+ +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Change log for the Bookmark+ libraries, which extend standard +;; library `bookmark.el'. This file contains no code, so you need +;; not load it. +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) code library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other (non-bmenu) required code +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc' - documentation (comment-only file) +;; `bookmark+-chg' - change log (this file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you put library +;; `bookmark+-doc.el' in your `load-path'.) +;; +;; +;; ****** NOTE ****** +;; +;; On 2010-06-18, I changed the prefix used by package Bookmark+ +;; from `bookmarkp-' to `bmkp-'. THIS IS AN INCOMPATIBLE CHANGE. +;; I apologize for the inconvenience, but the new prefix is +;; preferable for a number of reasons, including easier +;; distinction from standard `bookmark.el' names. +;; +;; This change means that YOU MUST MANUALLY REPLACE ALL +;; OCCURRENCES of `bookmarkp-' by `bmkp-' in the following +;; places, if you used Bookmark+ prior to this change: +;; +;; 1. In your init file (`~/.emacs') or your `custom-file', if +;; you have one. This is needed if you customized any +;; Bookmark+ features. +;; +;; 2. In your default bookmark file, `bookmark-default-file' +;; (`.emacs.bmk'), and in any other bookmark files you might +;; have. +;; +;; 3. In your `*Bookmark List*' state file, +;; `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el'). +;; +;; 4. In your `*Bookmark List*' commands file, +;; `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'), +;; if you have one. +;; +;; You can do this editing in a virgin Emacs session (`emacs +;; -Q'), that is, without loading Bookmark+. +;; +;; Alternatively, you can do this editing in an Emacs session +;; where Bookmark+ has been loaded, but in that case you must +;; TURN OFF AUTOMATIC SAVING of both your default bookmark file +;; and your `*Bookmark List*' state file. Otherwise, when you +;; quit Emacs your manually edits will be overwritten. +;; +;; To turn off this automatic saving, you can use `M-~' and `M-l' +;; in buffer `*Bookmark List*' (commands +;; `bmkp-toggle-saving-bookmark-file' and +;; `bmkp-toggle-saving-menu-list-state' - they are also in the +;; `Bookmark+' menu). +;; +;; +;; Again, sorry for this inconvenience. + +;;(@> "Index") +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "CHANGE LOG FOR `bookmark+-1.el'") +;; (@> "CHANGE LOG FOR `bookmark+-bmu.el'") +;; (@> "CHANGE LOG FOR `bookmark+-key.el'") +;; (@> "CHANGE LOG FOR `bookmark+-lit.el'") +;; (@> "CHANGE LOG FOR `bookmark+-mac.el'") +;; (@> "CHANGE LOG FOR `bookmark+.el'") + +;;;(@* "CHANGE LOG FOR `bookmark+-1.el'") +;; +;; 2011/08/09 dadams +;; Bind icicle-unpropertize-completion-result-flag to t for all calls to completing-read. +;; 2011/08/07 dadams +;; Added: bmkp-guess-default-handler-for-file-flag, bmkp-file-bookmark-handlers. +;; bmkp-file-bookmark-p: Use bmkp-file-bookmark-handlers, which means also image-bookmark-jump. +;; bmkp-make-record-for-target-file (need to keep in sync with diredp-bookmark): +;; Instead of image-bookmark-make-record, use explicit function that includes file and type. +;; bmkp-default-handler-for-file: +;; Use bmkp-guess-default only if bmkp-guess-default-handler-for-file-flag is non-nil. +;; bmkp-default-handler-associations: Updated doc string. +;; 2011/08/05 dadams +;; bmkp-file-bookmark-p: Allow handler to be bmkp-default-handler-for-file, e.g. for image files. +;; bmkp-all-tags-alist-only: Corrected. +;; bmkp-refresh-menu-list: Ensure BOOKMARK is a string. +;; bmkp-every: Removed unused binding. +;; 2011/05/08 dadams +;; Just put some definitions in alphabetic order - no real change. +;; 2011/04/25 dadams +;; bmkp-bookmark-description: Added optional arg NO-IMAGE. +;; bmkp-url-target-set: Protect url-get-url-at-point with fboundp. +;; bmkp-(file-target|autofile)-set, bmkp-autofile-(add|remove)-tags: +;; Added buffer-file-name as a default possibility. Removed URL functions for that purpose. +;; 2011/04/24 dadams +;; Added: bmkp-purge-notags-autofiles. +;; bookmark-delete: Redefined to accept either bookmark or name as arg. +;; bmkp-(url|file|compilation|occur)-target-set(-all), bmkp-autofile-(set|(add|remove)-tags): +;; Removed optional args when read prefix. +;; bmkp-occur-target-set-all: Made PREFIX arg optional too. +;; Added some missing autoload cookies. Removed some from non-def sexps. +;; 2011/04/21 dadams +;; Added: bmkp-copied-tags, bmkp-copy-tags, bmkp-paste-add-tags, bmkp-paste-replace-tags.. +;; 2011/04/20 dadams +;; bmkp-remove-all-tags: Added optional arg no-cache-update-p. +;; 2011/04/19 dadams +;; bmkp-make-record-for-target-file: Fixed backquotes on lambdas. +;; 2011/04/17 dadams +;; bmkp-edit-tags: Do not apply bmkp-full-tag to the tags. +;; 2011/04/16 dadams +;; Added: bmkp-edit-tags(-send|-mode(-map)), bmkp-return-buffer. +;; bookmark-(rename|relocate|send-edited-annotation), bmkp-update-autonamed-bookmark, +;; bmkp-(add|remove(-all)-tags: +;; Wrap with-current-buffer around bmkp-refresh-menu-list. +;; bookmark-(store|rename|write-file): Test emacs-major-version, not just (boundp 'print-circle). +;; bmkp-autofile-add-tags: Fix interactive args - forgot to include DIR arg (= nil). +;; 2011/04/15 dadams +;; Added: bmkp-autofile-alist-only, bmkp-autofile-bookmark-p. +;; 2011/04/13 dadams +;; Added: bmkp-autofile-jump(-other-window) (aliases), bmkp-find-file(-other-window). +;; bmkp-find-file-(all|some)-tags(-regexp)(-other-window): Bind use-file-dialog to nil. +;; 2011/04/12 +;; Added: bmkp-bookmark-name-member, bmkp-names-same-bookmark-p, bmkp-sort-omit, +;; bmkp-remove-omitted, bmkp-delete-bookmark-name-from-list, bmkp-bookmark-a-file (alias), +;; bmkp-autofile-(add|remove)-tags, bmkp-(un)tag-a-file (aliases), +;; bmkp-get-autofile-bookmark, bmkp-find-file-(all|some)-tags(-regexp)(-other-window). +;; Removed: bmkp-remove-assoc-dups, bmkp-sort-and-remove-dups. +;; Applied renaming: bmkp-bmenu-omitted-list to bmkp-bmenu-omitted-bookmarks. +;; bookmark-store: Redefine for all Emacs versions now: +;; Put the bookmark on the name as property bmkp-full-record. Use bmkp-maybe-save-bookmarks. +;; Return the bookmark. +;; bookmark-get-bookmark: Redefine for all Emacs versions now: +;; If BOOKMARK is a bookmark-name string that has property bmkp-full-record, return that value. +;; bookmark-send-edited-annotation: Make sure it's the annotation buffer that gets killed. +;; bookmark-default-handler: Return nil, like vanilla (but why?). +;; bookmark-location: Pass full bookmark to the various "get" functions. +;; bookmark-rename: Put bmkp-full-record property on new name. +;; bookmark-delete: +;; Use bmkp-delete-bookmark-name-from-list: If name has bmkp-full-record property, use that +;; with name to find bookmark to delete. +;; Pass full bookmark to unlight. +;; bmkp-edit-bookmark: Save if either is non-empty, not if both are. Thx to Michael Heerdegen. +;; bmkp-edit-bookmark-record: Bind print-circle to t around pp. +;; bmkp-default-bookmark-name: +;; Use bookmark-name-from-full-record plus bookmark-get-bookmark, not assoc. +;; If BNAME is nil (no default) then do not try to look it up in alist. +;; bookmark-write-file: Unpropertize only for Emacs 20 or nil bmkp-propertize-bookmark-names-flag. +;; Bind print-circle to t around pp. +;; bmkp-save-menu-list-state: Make it interactive (a command). Bind print-circle. +;; Use bmkp-maybe-unpropertize-bookmark-names on alists and name lists. +;; Bind print-circle to t around pp. +;; bmkp-unomit-all: Use bmkp-delete-bookmark-name-from-list, not delete. +;; bmkp-dired-this-dir-bookmark-p: Use bmkp-same-file-p, not string=. +;; bmkp-url-target-set, bmkp-replace-existing-bookmark:: Return the bookmark. +;; bmkp-file-target-set: Return bookmark. Added arg MSGP: msg if no file yet. +;; bmkp-autofile-set: +;; Added DIR arg and MSGP arg: msg if no file yet. Return the bookmark. +;; If read absolute file name, create bmk in its dir, not in default-directory. Else use DIR. +;; Use bmkp-get-autofile-bookmark, so uses bmkp-same-file-p for each file part (not equal). +;; bmkp-marked-bookmark-p, bmkp-omitted-bookmark-p: Use bmkp-bookmark-name-member, not member. +;; bookmark-location: Pass full bookmark to the various "get" functions. +;; bmkp-choose-navlist-from-bookmark-list, bmkp-cycle-this-buffer: +;; Use bmkp-sort-omit, not bmkp-sort-and-remove-dups. +;; bmkp-bookmark-description, bmkp-describe-bookmark-internals: Add Bookmark `' to title. +;; bmkp-make-bookmark-list-record: Use bmkp-maybe-unpropertize-bookmark-names on lists. +;; bmkp-printable-p: Bind print-circle to t around prin1. +;; bmkp-delete-autonamed(-this-buffer)-no-confirm: +;; Do nothing if bookmarks not loaded. Thx to Christoph Scholtes. +;; 2011/04/03 dadams +;; Added: bmkp-make-record-for-target-file, bmkp-replace-existing-bookmark (not used). +;; bmkp-file-this-dir-bookmark-p: Corrected it to compare directory to default-directory. +;; bmkp-file-target-set: Added arg NO-OVERWRITE (pass to bookmark-store). +;; Use (new) bmkp-make-record-for-target-file. +;; bmkp-autofile-set: Do nothing if bookmark with same name, file and dir exists. +;; Else create one, even if the bookmark name is the same. +;; You can have multiple autofile bookmarks with the same name (diff files). +;; 2011/04/02 dadams +;; Added: bmkp-autofile-set, bmkp-file-this-dir-(all|some)-tags(-regexp)-jump(-other-window), +;; bmkp-file-this-dir-(all|some)-tags(-regexp)-alist-only. +;; 2011/04/01 dadams +;; Moved key and menu bindings to (new) bookmark+-key.el. +;; Added: bmkp-(dired|file)-this-dir-alist-only, bmkp-(dired|file)-this-dir-bookmark-p, +;; bmkp-file-this-dir-jump(-other-window). +;; Renamed: bmkp-dired-jump-current(*) to bmkp-dired-this-dir-jump(*). +;; bmkp-dired-this-dir-jump(-other-window): Use bmkp-dired-this-dir-alist-only. +;; bmkp-types-alist: Added (dired|file)-this-dir. +;; Bound bmkp-(dired|file)-this-dir-jump to C-d and C-f in bookmark-jump(-other-window)-map. +;; bmkp-jump-dired, bmkp-jump-man: Treat null bmkp-jump-display-function as display-buffer. +;; 2011/03/26 dadams +;; Added: bmkp-file-(all|some)-tags(-regexp)-(alist-only|jump(-other-window)). +;; bmkp-jump-menu: Added the new commands, but not Emacs 20, to avoid crash if byte-compiled. +;; bmkp-bookmark-jump*-other-window: Simplified doc strings - refer to same-window version. +;; 2011/03/17 dadams +;; bmkp-describe-bookmark: Added 10-pixel margin around thumbnail image. +;; 2011/03/11 dadams +;; Protect use of mouse-wheel-*-event with boundp. Thx to Chris Poole. +;; 2011/03/04 dadams +;; bmkp-bookmark-description, bmkp-describe-bookmark: Added clickable thumbnail to the help. +;; bmkp-bookmark-description: Split file name into dir & relname, so shorter line, in help. +;; 2011/03/03 dadams +;; Added: bmkp-all-exif-data, bmkp-bookmark-image-bookmark-p. +;; bmkp-bookmark-description: Handle image EXIF data. +;; 2011/01/03 dadams +;; Removed autoload cookies from non def* sexps and from define-key and define-prefix-command. +;; Added some missing autoload cookies for commands, in particular redefined standard commands. +;; 2010/12/10 dadams +;; Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change. +;; 2010/10/22 dadams +;; Uncommented key bindings for mouse wheel, since Emacs bug #6256 has now been fixed. +;; bmkp-repeat-command: Don't bother to let-bind repeat-previous-repeated-command, +;; and use setq, not let, for last-repeatable-command. Thx to Stefan Monnier. +;; 2010/09/28 dadams +;; Added: bmkp-delete-autonamed(-this-buffer)-no-confirm. +;; 2010/09/25 dadams +;; Added: option bmkp-default-bookmark-name, bmkp-annotated-alist-only. +;; Added: bmkp-(next|previous)-*(-repeat), using macro bmkp-define-next+prev-cycle-commands. +;; bmkp-default-bookmark-name: Respect option. +;; bookmark-edit-annotation-mode, bookmark-edit-annotation: +;; Use bmkp-annotated-alist-only (and new bmkp-default-bookmark-name). +;; bookmark-send-edited-annotation: +;; End in orig buffer, not bmenu buffer. Delete edit window. Thx to Joe Bloggs. +;; 2010/09/24 dadams +;; Added: bmkp-autonamed(-this-buffer)-jump(-other-window). Bound to C-x j # (#|.) and menus. +;; Added, using bmkp-define-cycle-command: +;; bmkp-cycle-(autonamed|bookmark-list|desktop|dired|gnus|info|lighted|(local-|remote-)file| +;; man|non-file|remote-file|specific-(buffers|files)|variable-list|url) +;; (-other-window). +;; Added redefinitions: bookmark-edit-annotation(-mode). +;; Renamed: *varlist* to *variable-list*. +;; bmkp-autoname-format: Added ^ to anchor numeral at beginning. +;; bookmark--jump-via: Don't update autonamed if using w32 association. +;; bmkp-update-autonamed-bookmark: bmkp-refresh-menu-list only if buffer list is displayed. +;; *-(relocate|rename), *-update-autonamed-bookmark, *-remove-all-tags, *-(add|remove)-tags: +;; Don't create bookmark-list buffer if doesn't exist. +;; bookmark-show-(annotation|all-annotations): Restore selected window and frame focus. +;; bmkp-completing-read-(buffer|file)-name: Added optional NO-DEFAULT-P arg. +;; bmkp-describe-bookmark: Default to highlighted bookmarks on line, if there are any. +;; bmkp-specific-(buffers|files)-jump(-other-window): Allow empty input, to end loop. +;; bmkp-cycle: Ensure bmkp-current-nav-bookmark is a bookmark, else redefine. Use %9d, not %d. +;; bmkp-cycle-other-window: Added optional STARTOVERP arg here too. +;; 2010/09/20 dadams +;; bmkp-choose-navlist-of-type: Empty input means "any". +;; 2010/09/16 dadams +;; bmkp-read-bookmark-file-name: +;; Removed extra default-filename in call to read-file-name. Thx to Pedro Insua. +;; 2010/08/22 dadams +;; Added: bmkp-regexp-filtered-annotation-alist-only. +;; 2010/08/20 dadams +;; Added: bmkp-read-bookmark-file-name. +;; bookmark-save, bookmark-load, bmkp-switch-bookmark-file, bmkp-use-bookmark-file-create: +;; Use bmkp-read-bookmark-file-name. +;; 2010/08/19 dadams +;; Require gnus-sum.el when compile (for macro). Thx to S. Nemec. +;; 2010/08/18 dadams +;; Removed eval-when-compile for bookmark+-lit.el. +;; Replaced defvar of bmkp-edit-bookmark-record-mode-map with a define-key after derived mode. +;; 2010/08/17 dadams +;; bmkp-edit-bookmark: Made interactive. Bound to C-x p E. Added optional INTERNALP arg. +;; bmkp-info-bookmark-p: Return nil if a different handler. +;; 2010/08/15 dadams +;; Moved bmkp-define-file-sort-predicate, bmkp-menu-bar-make-toggle to bookmark+-mac.el. +;; Require: bookmark.el, bookmark+-mac.el. +;; Require for compile: bookmark+-bmu.el, bookmark+-lit.el (soft). +;; Ensure this file is loaded before compiling. +;; bmkp-set-bookmark-file-bookmark: Added missing arg for error format string. +;; 2010/08/08 dadams +;; bookmark-jump: Added optional arg DISPLAY-FUNCTION (Emacs 24). +;; bookmark-handle-bookmark: +;; Move non-default handler call outside condition-case. +;; Updated for Emacs 24: Use error condition bookmark-error-no-filename. Added props for it. +;; bookmark-default-handler: Updated for Emacs 24: +;; Signal condition bookmark-error-no-filename, not file-error, and pass (stringp FILE). +;; bookmark-make-record-default: Added optional args NO-CONTEXT, POSITION (Emacs 24), and VISITS. +;; bookmark-load: Updated for Emacs 24: Wrap with abbreviate-file-name. +;; bmkp-jump-1: Allow arg to be a bookmark or its name. +;; bmkp-gnus-bookmark-p: Updated for Emacs 24: Added gnus-summary-bookmark-jump. +;; bmkp-jump-gnus: Different gnus-fetch-group call for Emacs 20, 21. +;; bmkp-make-(desktop|varlist|bookmark-(file|list))-record: Call *-record-default with NO-CONTEXT. +;; w3m-current-title: Use w3m-current-title as bookmark name. +;; bmkp-w3m-set-new-buffer-name, bmkp-jump-w3m*: Require w3m. +;; bmkp-make-gnus-record: Get bookmark name from gnus-summary-article-header. +;; Update for Emacs 24: Bypass bmkp specific Gnus, man, and woman code. +;; 2010/08/06 dadams +;; Added (and bound the commands): +;; bmkp-(compilation|occur)-target-set(-all), bmkp-(file|url)-target-set, +;; bmkp-default-handler-associations, bmkp-compilation-file+line-at, +;; bmkp-default-handler-(for-file|user), bmkp-sound-jump. +;; bmkp-occur-create-autonamed-bookmarks: Do not define it for Emacs < 22. Protect wrt POS, BUF. +;; Added to Bookmark menu: bmkp-(file|url)-target-set, bmkp-set-(bookmark-file|desktop)-bookmark. +;; 2010/08/04 dadams +;; bmkp-edit-bookmark: Use new bookmark name for update of dired-directory. Thx to Kai Tetzlaff. +;; 2010/08/03 dadams +;; bmkp-make-url-browse-record: Remove text properties from URL arg. +;; 2010/07/17 dadams +;; Added: bmkp-url-jump-(other-window), bmkp-url(-browse)-(alist-only|bookmark-p), bmkp-url-cp, +;; bmkp-url-history, bmkp-make-url-browse-record, bmkp-jump-url-browse. +;; bmkp-sort-comparer: Use bmkp-url-cp, not bmkp-w3m-cp. +;; bmkp-types-alist: w3m -> url. +;; bookmark-alist: Updated doc string to mention LOCATION. W3M -> URL. +;; bmkp-bookmark-description: Treat URL. Set no-position-p depending on start. +;; Bind bmkp-url-jump*. Replace W3M by URL in menu items. +;; 2010/07/14 dadams +;; Created from bookmark+.el code. + +;;;(@* "CHANGE LOG FOR `bookmark+-bmu.el'") +;; +;; 2011/07/01 dadams +;; bmkp-bmenu-change-sort-order, bmkp(-multi)-reverse-sort-order: Handle null CURRENT-BMK. +;; 2011/04/24 dadams +;; Added to Tags menu: Purge Autofiles with No Tags. +;; 2011/04/23 dadams +;; Bound bmkp-bmenu-set-tag-value-for-marked to T > v and added to bmkp-bmenu-tags-menu. +;; bmkp-bmenu-mouse-3-menu: Added bmkp-rename-tag. +;; 2011/04/22 dadams +;; Bound *-copy-tags to T c, T M-w, *-paste(-add|replace)-tags to T p, T C-y, T q. +;; 2011/04/21 dadams +;; Added: bmkp-bmenu-copy-tags, bmkp-bmenu-paste-add-tags(-to-marked), +;; bmkp-bmenu-paste-replace-tags(-for-marked). +;; Bound and added to menus: bmkp-bmenu-paste-add-tags-to-marked, +;; bmkp-bmenu-paste-replace-tags-for-marked. +;; Added to This Bookmark menu: bmkp-bmenu-copy-tags, bmkp-bmenu-paste(-add|replace)-tags. +;; 2011/04/19 dadams +;; Added: bmkp-bmenu-unmark-bookmarks-tagged-regexp. Bound it to T u %. Added it to menu. +;; 2011/04/16 dadams +;; Added: bmkp-edit-tags-send. Bound it to T e in bookmark-bmenu-mode-map. +;; bookmark-bmenu-mode: Updated help text for tags editing. +;; bmkp-maybe-unpropertize-bookmark-names: +;; Test emacs-major-version, not just (boundp 'print-circle). +;; 2011/04/15 dadams +;; Added: bmkp-bmenu-mark-autofile-bookmarks, bmkp-bmenu-show-only-autofiles. +;; And added them to menus. +;; bookmark-bmenu-mode-map: +;; Bind bmkp-bmenu-mark-autofile-bookmarks, bmkp-bmenu-show-only-autofiles to A M, A S. +;; Bind bookmark-bmenu-show-all-annotations to M-a, not A. +;; Bind bmkp-bmenu-search-marked-bookmarks-regexp to M-s a M-s, not M-a. +;; Bind *-mark-url-bookmarks, *-show-only-urls to M-u M-m, M-u M-s, not M-u M, M-u S. +;; bookmark-bmenu-mode: Updated help to reflect latest bindings. +;; 2011/04/13 dadams +;; bmkp-bmenu-tags-menu: Added: bmkp-(un)tag-a-file. +;; 2011/04/12 +;; Added: bmkp-propertize-bookmark-names-flag, bmkp-maybe-unpropertize-bookmark-names, +;; bmkp-bmenu-get-marked-files. +;; Renamed: bmkp-bmenu-omitted-list to bmkp-bmenu-omitted-bookmarks. +;; bmkp-bmenu-define-full-snapshot-command: +;; Bind print-circle to t around pp. Use bmkp-maybe-unpropertize-bookmark-names on lists. +;; bookmark-bmenu-(show|hide)-filenames, bmkp-bmenu-toggle-show-only-(un)marked, +;; bmkp-bmenu-(un)omit-marked: +;; Fit one-window frame only if selected window is *Bookmark List*. +;; bookmark-bmenu-bookmark: Added optional arg FULL. Non-nil means return full bookmark record. +;; bookmark-bmenu-unmark, bookmark-bmenu-delete, bmkp-bmenu-unomit-marked: +;; Use bmkp-delete-bookmark-name-from-list, not delete. +;; bookmark-bmenu-execute-deletions: Pass full bookmark, not name, to delete, and don't use assoc. +;; bookmark-bmenu-rename: Use bmkp-bmenu-goto-bookmark-named instead of just searching for name. +;; bmkp-bmenu-toggle-marks, bmkp-bmenu-unomit-marked, bmkp-bmenu-define-jump-marked-command, +;; bmkp-bmenu-mouse-3-menu: +;; Use bmkp-bookmark-name-member, not member. +;; bmkp-bmenu-make-sequence-from-marked: Do not invoke bookmark-bmenu-list when no displayed list. +;; bmkp-bmenu-define-command: Use bmkp-maybe-unpropertize-bookmark-names on *-omitted-bookmarks. +;; bmkp-bmenu-list-1: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups. +;; Pass full bookmark to bmkp-bmenu-propertize-item. +;; bmkp-bmenu-propertize-item: +;; First arg is now a full bookmark, not a bookmark name. Get bookmark name from it. +;; Put prop bmkp-bookmark-name on buffer text with propertized bookmark-name string as value. +;; String has property bmkp-full-record with value the full bookmark record, with string as car. +;; Return propertized bookmark-name string. +;; bmkp-bmenu-isearch-marked-bookmarks(-regexp), bmkp-bmenu-dired-marked, +;; bmkp-bmenu-(search|query-replace)-marked-bookmarks-regexp: +;; Use bmkp-sort-omit, not bmkp-sort-and-remove-dups. +;; bmkp-bmenu-goto-bookmark-named: +;; If NAME has property bmkp-full-record then go to the bookmark it indicates. Otherwise, just +;; go to the first bookmark with the same name. +;; bookmark-bmenu-mode: Added bmkp-save-menu-list-state (now a command) to the mode help. +;; 2011/04/02 dadams +;; bookmark-bmenu-mode: Added to mode help: bmkp-file-this-dir-(all|some)-tags(-regexp)-jump., +;; Create/Set section, with bmkp-autofile-set. +;; 2011/04/01 dadams +;; bookmark-bmenu-mode: Added to mode help: bmkp-(dired|file)-this-dir-jump. +;; 2011/03/26 dadams +;; bookmark-bmenu-mode: Added new file-with-tags jump commands to the help. +;; 2011/03/05 dadams +;; bmkp-bmenu-edit-bookmark: Use bmkp-refresh-menu-list, not *-surreptitiously-rebuild-list. +;; 2011/02/11 dadams +;; Faces: Better defaults for dark background. +;; 2011/01/03 dadams +;; Removed autoload cookies from non def* sexps and from define-key. +;; Added missing autoload cookies for commands, in particular redefined std commands & defalias. +;; 2010/12/10 dadams +;; Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change. +;; 2010/09/24 dadams +;; Added: bmkp-bmenu-show-only-autonamed. Bound to # S. Added to bmkp-bmenu-show-menu. +;; bookmark-bmenu-mode: Updated doc string for autonamed jumps, show. +;; Renamed varlist to variable-list everywhere. +;; 2010/08/22 dadams +;; Added: bmkp-bmenu-filter-annotation-incrementally, bookmark-bmenu-relocate (Emacs 20, 21), +;; bmkp-bmenu-filter-alist-by-annotation-regexp. Bound, added to menus and help. +;; 2010/08/18 dadams +;; Removed eval-when-compile for bookmark+-(lit|1).el. +;; bmkp-bmenu-propertize-item: Inconsequential simplification. +;; 2010/08/17 dadams +;; bmkp-bmenu-edit-bookmark: Added optional arg INTERNALP (prefix arg), for editing record. +;; 2010/08/15 dadams +;; Moved to bookmark+-mac.el: +;; bmkp-define-sort-command, bmkp-replace-regexp-in-string, bmkp-assoc-delete-all. +;; Renamed: bmkp-barf-if-not-in-menu-list to bmkp-bmenu-barf-if-not-in-menu-list. +;; Require bookmark.el, bookmark+-mac.el. +;; Require when compile: bookmark+-1.el, bookmark+-lit.el (soft). +;; 2010/07/17 dadams +;; Added: bmkp-bmenu-mark-url-bookmarks, bmkp-bmenu-show-only-urls, bmkp-bmenu-sort-by-url. +;; Removed: bmkp-bmenu-sort-by-w3m-url. +;; Replaced face bmkp-w3m by bmkp-url. +;; bookmark-bmenu-mode: Added mark and show URL commands. +;; bookmark-bmenu-mode, *-status-help, *-sort-by-bookmark-type, *-define-sort-command: w3m -> url. +;; Bind bmkp-bmenu-sort-by-url, not bmkp-bmenu-sort-by-w3m-url. +;; Bind bmkp-bmenu-mark-url-bookmarks, bmkp-bmenu-show-only-urls. +;; Replace W3M by URL in menu items. +;; 2010/07/14 dadams +;; Created from bookmark+.el code. + +;;;(@* "CHANGE LOG FOR `bookmark+-key.el'") +;; +;; 2011/04/24 dadams +;; Added to Bookmarks menu and its Tags submenu: Purge Autofiles with No Tags. +;; 2011/04/23 dadams +;; bmkp-tags-menu: +;; Added bmkp-set-tag-value, bmkp-(add|remove|copy)-tags, bmkp-paste-(add|replace)-tags. +;; 2011/04/21 dadams +;; Bound: bmkp-copy-tags, bmkp-paste-add-tags, bmkp-paste-replace-tags. +;; 2011/04/16 dadams +;; Added: bmkp-tags-map. Bound tag commands to prefix C-x p t. +;; 2011/04/14 dadams +;; Renamed menu Jump To Bookmark to just Jump To, in menu-bar-bookmark-map. +;; 2011/04/13 dadams +;; Added: +;; bmkp-find-file-menu (bmkp-find-file(-(all|some)-tags(-regexp)(-other-window)), +;; bmkp-jump-tags-menu (what was in main, plus bmkp-find-file-*-tags-regexp*), +;; bmkp-tags-menu (list all, rename, remove from all, (un)tag a file). +;; bmkp-jump(-other-window)-map: +;; Added bmkp-find-file(-other-window) to menu. +;; Bound keys for bmkp-find-file-(all|some)-tags(-regexp)(-other-window): C-x (4) j t a... +;; 2011/04/02 dadams +;; Added bindings for (new) bmkp-autofile-set, +;; bmkp-file-this-dir-(all|some)-tags(-regexp)-jump(-other-window). +;; 2011/04/01 dadams +;; Added to bmkp-jump-menu: bmkp-(dired|file)-this-dir-jump-other-window. +;; Created from code in bookmark+-1.el. + +;;;(@* "CHANGE LOG FOR `bookmark+-lit.el'") +;; +;; 2011/08/09 dadams +;; Bind icicle-unpropertize-completion-result-flag to t for all calls to completing-read. +;; 2011/04/12 +;; bmkp-cycle-lighted-this-buffer: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups. +;; 2011/04/01 dadams +;; bmkp-light-bookmark(s): Don't call bookmark-handle-bookmark. Wrap with with-current-buffer. +;; 2011/01/03 dadams +;; Added autoload cookies: defcustoms and commands. +;; 2010/12/10 dadams +;; Added defalias for bookmark-name-from(-full)-record, to fix gratuitous Emacs name change. +;; 2010/09/25 dadams +;; Added: bmkp-set-lighting-for(bookmarks|(-this)-buffer). Requested by Joe Bloggs. +;; bmkp-set-lighting-for-bookmark: Added LIGHT-NOW-P arg (from prefix arg). +;; 2010/09/11 dadams +;; Removed eval-when-compile for bookmark+-bmu, bookmark+-1. +;; 2010/08/15 dadams +;; Require: bookmark.el. +;; Require when compile: bookmark+-bmu.el, bookmark+-1.el, pp+.el (soft). +;; Applied renaming of bmkp-barf-if-not-in-menu-list to bmkp-bmenu-barf-if-not-in-menu-list. +;; bmkp-light-bookmark(s): Added missing arg to throw call. +;; bmkp-light-bookmarks: Use bmkp-remove-if, not remove-if. +;; bmkp-light-bookmarks-in-region, bmkp-light-non-autonamed-this-buffer: +;; Use bmkp-remove-if-not, not remove-if-not. +;; bmkp-read-set-lighting-args: Use pp-read-expression-map only if bound (pp+.el). +;; 2010/07/03 dadams +;; bmkp-set-lighting-for-bookmark, bmkp-bmenu-set-lighting-for-marked: +;; Use *-refresh-menu-list, not *-surreptitiously-*. +;; 2010/07/01 dadams +;; Created. + +;;;(@* "CHANGE LOG FOR `bookmark+-mac.el'") +;; +;; 2011/04/12 +;; bmkp-define-cycle-command: Use bmkp-sort-omit, not bmkp-sort-and-remove-dups. +;; 2011/01/03 dadams +;; Added autoload cookies: defmacro. +;; 2010/09/25 dadams +;; Added: bmkp-define-next+prev-cycle-commands. +;; 2010/09/24 dadams +;; Added: bmkp-define-cycle-command. +;; 2010/08/18 dadams +;; Removed eval-when-compile for bookmark+-(bmu|1).el. +;; 2010/08/15 dadams +;; Created, from code in other Bookmark+ files. + +;;;(@* "CHANGE LOG FOR `bookmark+.el'") +;; +;; 2011/04/12 dadams +;; Version 3.2.2. +;; 2011/04/01 dadams +;; Require bookmark+-key.el (new). Version 3.2.1. +;; 2011/01/03 dadams +;; Added autoload cookies: defconst, command. +;; 2010/08/19 +;; bmkp-version-number: Version 3.2.0. +;; 2010/08/15 dadams +;; Require bookmark+-mac.el. +;; Do not ensure loaded before compile (not needed here now). +;; 2010/07/14 dadams +;; Version 3.1.1. +;; Moved main content of bookmark+.el to new files bookmark+-1.el and bookmark+-bmu.el. +;; 2010/07/13 dadams +;; Version 3.1.0. +;; Added redefinitions: bookmark-bmenu-(1|2)-window, bookmark-bmenu-other-window-with-mouse, +;; bookmark-bmenu-this-window, bookmark-bmenu-switch-other-window. +;; Added: bmkp-last-bookmark-file, bmkp-switch-to-last-bookmark-file. +;; Removed pre-23 version of bookmark-bmenu-switch-other-window. +;; bookmark-load: Use bmkp-last-bookmark-file when read file name. Added missing prefix arg. +;; Save old current as bmkp-last-bookmark-file. +;; bookmark-bmenu-list: If bookmark file has changed do not restore state saved from other file. +;; Save old current as bmkp-last-bookmark-file. +;; bmkp-bmenu-list-1: Do not use bmkp-bmenu-title if it is empty (""). +;; bookmark-bmenu-mode: Added to doc string: bmkp-switch-bookmark-file. +;; bookmark-bmenu-other-window: Do not bind bookmark-automatically-show-annotations (per vanilla). +;; bookmark-bmenu-show-annotation: Ensure in bmenu list and on a bookmark line. +;; bmkp-switch-bookmark-file: Use bmkp-last-bookmark-file when read file name. +;; bmkp-bmenu-define-full-snapshot-command: Set bmkp-last-bookmark-file. +;; bmkp-bookmark-description: Fixed typo: bmkp-bookmark-file-bookmark-p (not desktop). +;; bmkp-make-bookmark-file-record: Use arg file (not bmkp-non-file-filename) as filename entry. +;; +;; Added more autoload cookies. +;; 2010/07/09 dadams +;; Added: bmkp-bmenu-mark-bookmark-file-bookmarks, bmkp-bmenu-show-only-bookmark-files, +;; bmkp-bookmark-file-jump, bmkp-set-bookmark-file-bookmark, bmkp-bookmark-file-history, +;; bmkp-use-bookmark-file-create, bmkp-bookmark-file, bmkp-bookmark-file-alist-only, +;; bmkp-bookmark-file-bookmark-p, bmkp-jump-bookmark-file, bmkp-make-bookmark-file-record. +;; bmkp-types-alist, bmkp-buffer-names, bmkp-bmenu-mode-status-help, bmkp-bmenu-propertize-item, +;; bmkp-this-buffer-p, bmkp-last-specific-buffer-p, bmkp-specific-buffers-alist-only, +;; bmkp-bookmark-description, bookmark-bmenu-mode: Updated for bookmark-file bookmarks. +;; bookmark--jump-via: Added a catch, so a handler can skip all other processing when it's done. +;; bookmark-load: Final msg says whether overwritten. +;; Bound and added to menus: bmkp-set-bookmark-file-bookmark, +;; bmkp-bmenu-mark-bookmark-file-bookmarks, +;; bmkp-bmenu-show-only-bookmark-files, bmkp-bookmark-file-jump. +;; 2010/07/07 dadams +;; bookmark-handle-bookmark: Bind use-dialog-box, use-file-dialog to nil. +;; bookmark-location: From Emacs 23: Use location property and -- Unknown location --. +;; bmkp-switch-bookmark-file: Bind insert-default-directory to nil. +;; bmkp-empty-file: Expand FILE. Return FILE. +;; 2010/07/03 dadams +;; Added: bmkp-bmenu-describe-marked, bmkp-bookmark-description. +;; bmkp-describe-bookmark: Rewrote to use bmkp-bookmark-description. +;; Bound bmkp-bmenu-describe-marked to C-h >. +;; bmkp-bmenu-menubar-menu: Added bmkp-bmenu-describe-(marked|bookmark). +;; Updated doc string of bookmark-alist. +;; 2010/07/01 dadams +;; Added: bmkp-bmenu-mark-lighted-bookmarks, bmkp-bmenu-set-tag-value-for-marked, +;; bmkp-bmenu-show-only-tagged, bmkp-occur-create-autonamed-bookmarks, +;; bmkp-set-autonamed-bookmark, bmkp-set-autonamed-bookmark-at-line, +;; bmkp-set-autonamed-regexp-buffer, bmkp-set-autonamed-regexp-region, +;; bmkp-set-tag-value-for-navlist, bmkp-prompt-for-tags-flag, bmkp-menu-bar-make-toggle, +;; bmkp-same-creation-time-p, bmkp-set-tag-value-for-bookmarks, +;; bmkp(-bmenu)-highlight-menu, bmkp-options-menu. +;; Renamed: bmkp-use-region-flag to bmkp-use-region, +;; bmkp-bmenu-jump-menu to bmkp-jump-menu. +;; Removed: bmkp-cycle-this-buffer-buff (unused). +;; Soft-require new library bookmark+-lit.el. +;; Split off new file bookmark+-chg.el from bookmark+-doc.el. +;; Changed default values of faces bmkp->-mark, bmkp-t-mark. +;; bmkp-crosshairs-flag: Added :set instead of add-hook at top level. +;; bmkp-use-region: Changed from boolean to choice - added cycling-too value. +;; bookmark-set: Added INTERACTIVEP arg. Prompt for tags when bmkp-prompt-for-tags-flag. +;; Auto-highlight when set, per bmkp-auto-light-when-set. +;; bookmark--jump-via: Auto-highlight when jump, per bmkp-auto-light-when-jump. +;; Set BOOKMARK to result of bmkp-update-autonamed-bookmark. +;; Bind orig-buff when running hook. +;; bookmark-default-handler: Pass the bookmark too as an arg to bmkp-goto-position. +;; bookmark-relocate, bookmark-rename, bmkp-bmenu-list-1, bmkp-remove(-all)-tags, bmkp-add-tags: +;; Add 0 as FRAME arg to get-buffer-window. +;; bookmark-delete: Remove any highlighting on bookmark. +;; bmkp-bmenu-list-1: Add highlight-overrides indicator. +;; bmkp-completing-read-1: Added (not laxp) guard for first branch of main if. +;; bmkp-crosshairs-highlight: Assign a priority. Make the cmd a no-op for Emacs 20-21. +;; bmkp-choose-navlist-*, bmkp-navlist-bmenu-list, bmkp-jump-in-navlist*, +;; bmkp-cycle(-this-buffer*): +;; Set bmkp-current-nav-bookmark to bookmark, not to its name. +;; bmkp-update-autonamed-bookmark: Do not set bmkp-current-nav-bookmark to the name. +;; Call bmkp-refresh-menu-list even if menu list is not displayed. +;; Pass the bookmark name to bmkp-refresh-menu-list. +;; Return the updated BOOKMARK. +;; bmkp-refresh-menu-list: Set window point also. +;; bmkp-goto-position: +;; Added BOOKMARK arg. When bmkp-save-new-location-flag, update BOOKMARK. Return indicator. +;; bmkp-create-varlist-bookmark: Call bookmark-set with INTERACTIVEP arg. +;; bmkp-cycle(-this-buffer*): Added STARTOVERP arg. Pass OTHER-WINDOW, STARTOVERP to bmkp-cycle-1. +;; bmkp-cycle-1: Added STARTOVERP arg. If non-nil pop-up-frames, then inhibit showing annotation. +;; Use region only if bmkp-use-region value is cycling-too. +;; Use eq for *-list-position test. If *-list-position returns nil, then reset. +;; Use save-selected-window, unlesl OTHER-WINDOW. +;; bmkp-(next|previous)-bookmark(-this-buffer|-w32): Added STARTOVERP arg. C-u: start over at 1. +;; Bind highlight cmds: *-map: h,H,u,U,C-u,=,C-up|down. *-bmenu-*map: H+,H>+,H>H,HH,HS,H>U,HU. +;; *-jump-map: h. Bind TS in *-bmenu-*map. +;; Add bmkp-occur-create-autonamed-bookmarks to occur-mode-map as C-c b. +;; Menus: Added Highlight, Toggle Option. Added light to Jump To, Show, Mark, mouse. Reorder. +;; 2010/06/23 dadams +;; Split the change log off from file bookmark+-doc.el to new file bookmark+-chg.el. +;; 2010/06/21 dadams +;; Renamed: bmkp-toggle-autoname-bookmark-set/delete to bmkp-toggle-autonamed-bookmark-set/delete, +;; bmkp-autonamed-bookmarks-alist-only to bmkp-autonamed-this-buffer-alist-only, +;; bmkp-bookmark-autoname-p to bmkp-autonamed-bookmark-for-buffer-p, +;; Added: bmkp-autonamed-alist-only, bmkp-non-autonamed-alist-only, bmkp-autonamed-bookmark-p, +;; bmkp-completing-read-1: Use DEFAULT as default. Use just (not lax) - no non-t. +;; Use DEFAULT if empty input only if DEFAULT is non-nil. +;; bmkp-choose-navlist-of-type: Added pseudo-type "any". +;; bmkp-specific-buffers-alist-only: Exclude desktop etc. bookmarks. +;; bmkp-update-autonamed-bookmark: Arg can be a bookmark (not just name). +;; 2010/06/19 dadams +;; RENAMED bookmarkp* TO bmkp*. ***** THIS IS AN INCOMPATIBLE CHANGE ****** +;; +;; If you have existing customizations, or if you have bookmarks that have the (internal) tag +;; "bmkp-jump", then YOU MUST REPLACE occurrences of "bookmarkp" by "bmkp" EVERYWHERE. This +;; includes replacing occurrences in (1) your bookmarks file (bookmark-default-file), (2) your +;; state file (bmkp-bmenu-state-file), and (3) your command file (bmkp-bmenu-commands-file). +;; +;; Changed *-bmenu-w32-open-select binding to M-o from M-v. +;; 2010/06/11 dadams +;; Wrap all (require '* nil t) in condition-case. +;; 2010/06/07 dadams +;; Fix deskstop bookmarks for Emacs < 22. Protect: +;; *-release-lock with fboundp, *-buffer-args-list with boundp, *-dir with Emacs version #, +;; 2010/05/30 dadams +;; Added: bookmarkp-(next|previous)-bookmark-w32(-repeat). Bound to C-x p (next|prior). +;; 2010/05/29 dadams +;; *-bmenu-list, *-choose-navlist-from-bookmark-list, *-bmenu-define(-full-snapshot)-command, +;; *-save-menu-list-state, -make-bookmark-list-record: +;; Add/restore bookmarkp-bmenu-filter-pattern to/from state. +;; *-jump-bookmark-list: Set bookmarkp-latest-bookmark-alist to bookmark-alist. +;; Reordered Bookmark menu and added items: +;; Set Bookmark, Delete Autonamed Bookmark, Delete All Autonamed Bookmarks Here, +;; Delete Bookmarks Here, Delete Bookmark, Rename Bookmark, Bookmark List for This Buffer, +;; Bookmark List for Navlist, Set Navlist to Bookmarks of Type, +;; Set Navlist from Bookmark-List Bookmark, Insert Bookmark Contents, Insert Bookmark Location. +;; Added to Bookmark+ menu: Set Navlist *. +;; Added to bookmarkp-bmenu-jump-menu: In Navigation List. +;; Added :enable entries for menu items. +;; Updated bookmark-bmenu-mode doc string for cycling, navlist, and options. +;; Corrected bindings of bookmarkp-jump-in-navlist(-other-window). +;; 2010/05/26 dadams +;; Added: +;; bookmarkp-choose-navlist-(from-bookmark-list|of-type), bookmarkp-crosshairs-highlight, +;; bookmarkp-cycle(-this-buffer)(-other-window), bookmarkp-delete-bookmarks, +;; bookmarkp-jump-in-navlist(-other-window), bookmarkp-navlist-bmenu-list, +;; bookmarkp-(next|previous)-bookmark(-this-buffer)(-repeat), +;; bookmarkp-toggle-autoname-bookmark-set/delete, bookmarkp-autoname-bookmark(-function), +;; bookmarkp-autonamed-bookmarks-alist-only, bookmarkp-autoname-format, +;; bookmarkp-bookmark-autoname-p, bookmarkp-crosshairs-flag, +;; bookmarkp-this-buffer-cycle-sort-comparer, bookmarkp-current-bookmark-list-state, +;; bookmarkp-cycle-1, bookmarkp-list-position, bookmarkp-position-cp, +;; bookmarkp-current-nav-bookmark, bookmarkp-cycle-this-buffer-buff, bookmarkp-nav-alist, +;; bookmarkp-update-autonamed-bookmark, bookmarkp-delete-all-autonamed-for-this-buffer. +;; Bound: +;; bookmarkp-choose-navlist-from-bookmark-list, bookmark-insert-location, +;; bookmarkp-navlist-bmenu-list, bookmarkp-choose-navlist-of-type, bookmarkp-delete-bookmarks, +;; bookmarkp-toggle-autoname-bookmark-set/delete, bookmarkp-jump-in-navlist(-other-window), +;; bookmarkp-(next|previous)-bookmark(-this-buffer)-repeat. +;; bookmark--jump-via: Update the name and position of an autonamed bookmark. +;; 2010/05/22 dadams +;; *-this-buffer-p: Return nil for bookmarks not really associated with a buffer. +;; *-default-handler, *-goto-position: Forgot comma to eval file-name when no-such-file error. +;; *-show-annotation: Bind buffer-read-only to nil for updating. +;; 2010/05/19 dadams +;; Added: bookmarkp-this-buffer-bmenu-list. Bound to `C-x p .'. +;; menu-bar-bookmark-map: +;; Added bookmarkp-this-buffer-bmenu-list. Added separators. +;; Added vanilla items edit, write, load, to impose order. Renamed item edit. +;; 2010/05/16 dadams +;; bookmark-set: Quoted history arg. Thx to S. Nemec. +;; bookmarkp-bmenu-define-full-snapshot-command: Use quote comma, not quote, for *-specific-*. +;; 2010/05/15 dadams +;; Replace *same-(buffer|file)-jump* by *specific-(buffers|files)-jump*: read multiple buff/files. +;; Renamed: *same-(buffer|file)* to *-last-specific-(buffer|file)* for pred, alist, and var. +;; Renamed: *same-(buffer|file)* to *specific-(buffer|file)* for hist, *types*, mark/show cmds. +;; Renamed: *-selected-buffers-alist* to *-specific-buffers-alist*. +;; Added: *-specific-files-alist*, *-(all|some)-tags(-regexp)-alist-only. +;; *-completing-read-(buffer|file)-name: Use (buffer|file)-name-history, not *-same-*-history. +;; *-read-tags-completing: Rewrote to correctly handle cons and string tags, error handling, etc. +;; *-bmenu-(add|remove)-tags-*-marked: Error handling. +;; *(all|some)-tags(-regexp)-jump*: Use *-(all|some)-tags(-regexp)-alist-only. +;; 2010/05/11 dadams +;; Added: bookmarkp-bmenu-mark-same-(buffer|file)-bookmarks, bookmarkp-this-(buffer|file)-p, +;; bookmarkp-this-(buffer|file)-alist-only, bookmarkp-bmenu-show-only-same-(buffer|file), +;; bookmarkp-completing-read-(buffer|file)-name, bookmarkp-same-(buffer|file)-history, +;; bookmarkp-(same|this)-(buffer|file)-alist-only, bookmarkp-last-same-(buffer|file), +;; bookmarkp-(same|this)-(buffer|file)-jump(-other-window), bookmarkp-(buffer|file)-names, +;; bookmarkp-same-(buffer|file)-as-last-p, bookmarkp-other-window-pop-to-flag, +;; bookmarkp-select-buffer-other-window. +;; Use bookmarkp-select-buffer-other-window instead of switch-to-buffer-other-window everywhere. +;; Bound = (b|f) (M|S), C-x j (=|.) (b|f) to (same|current)-(buffer|file) commands. +;; *-types-alist: Handle same-(buffer|file) too. +;; *-bmenu-list, *-bmenu-define-full-snapshot-command, *-save-menu-list-state: +;; Handle bookmarkp-last-same-(buffer|file) as part of state. +;; 2010/05/05 dadams +;; bookmarkp-create-varlist-bookmark, bookmarkp-make-varlist-record: +;; Added optional arg BUFFER-NAME. +;; bookmark-alist: Corrected doc string wrt BUFFER-NAME and region context strings. +;; 2010/05/04 dadams +;; Added: bookmarkp-create-varlist-bookmark. +;; bookmarkp-jump-varlist: If bookmark's buffer doesn't exist, use current buffer and show msg. +;; 2010/04/24 adams +;; Added: bookmarkp-bmenu-show-only-varlists, bookmarkp-set-restrictions-bookmark, +;; bookmarkp-set-varlist-bookmark, bookmarkp-varlist-jump, bookmarkp-varlist, +;; bookmarkp-jump-varlist, bookmarkp-make-varlist-record, bookmarkp-printable-p, +;; bookmarkp-printable-vars+vals, bookmarkp-read-variables-completing, +;; bookmarkp-read-variable, bookmarkp-varlist-alist-only, bookmarkp-varlist-bookmark-p, +;; bookmarkp-varlist-history. +;; Bound bookmarkp-bmenu-show-only-varlists to V S, bookmarkp-varlist-jump to C-x j v (and menu). +;; *-types-alist: Added bookmarkp-varlist-history. +;; *-bmenu-mode-status-help, *-bmenu-propertize-item, *-describe-bookmark: Handle varlist bmks. +;; *-bmenu-w32-open-select: Changed binding to M-v from V. +;; *-bmenu-mode: Updated doc string. +;; 2010/04/17 dadams +;; bookmark-set: Numeric prefix arg means use all bookmarks as completion candidates. +;; Simplified the prompt. +;; bookmarkp-completing-read-1: +;; Use icicle-transform-multi-completion in icicle-delete-candidate-object +;; Ensure loaded before byte-compile (put a require after provide). +;; Move bookmarkp-replace-regexp-in-string before macro bookmarkp-define-sort-command (uses it). +;; bookmarkp-bmenu-w32-open-with-mouse, bookmarkp-bmenu-mouse-3-menu: +;; Use with-current-buffer, not save-excursion of set-buffer. +;; bookmarkp-make-dired-record, bookmarkp-jump-dired: Use dolist, not mapcar (just side effect). +;; bookmarkp-(some|all)-tags-jump(-other-window): Removed extraneous arg in error call. +;; 2010/04/16 dadams +;; Added: bookmarkp-completing-read-1, bookmarkp-completing-read-lax, +;; bookmarkp-selected-buffers-alist-only. +;; bookmark-set: Use bookmark-completing-read-lax w/ buffer's bookmarks, not read-from-minibuffer. +;; bookmark-completing-read: Define using bookmarkp-completing-read-1. +;; 2010/04/09 dadams +;; bookmarkp-edit-bookmark: Update dired-directory property along with filename property. +;; 2010/03/28 dadams +;; bookmarkp-goto-position: Don't funcall bookmarkp-jump-display-function if it is nil. +;; 2010/03/28 dadams +;; bookmark-default-handler: Don't funcall bookmarkp-jump-display-function if it is nil. +;; 2010/03/27 dadams +;; Changed the customization group from bookmarkp to bookmark-plus. +;; Moved doc and change history from bookmark+.el to this new file, bookmark+-doc.el. +;; bookmarkp-commentary-button: Use bookmark+-doc.el, not bookmark+.el. +;; 2010/03/17 dadams +;; Added: bookmarkp-toggle-bookmark-set-refreshes, bookmarkp-refresh-latest-bookmark-list, +;; bookmarkp-after-set-hook. +;; 2010/03/16 dadams +;; Fixed parens placement (typo) for last change to define *-jump-woman for Emacs 20. +;; 2010/03/11 dadams +;; Define bookmarkp-jump-woman also for Emacs 20 (just raise an error). +;; *-show-annotation: Typo: bookmark -> bmk-name. +;; 2010/03/10 dadams +;; Added: bookmarkp-bookmark-creation-cp, bookmarkp-bmenu-sort-by-creation-time (bind: s0, menu). +;; *-make-record-default: Add entry: created. +;; *-describe-bookmark: Add creation time to description. +;; 2010/03/03 dadams +;; *-sort-and-remove-dups: Do not set bookmarkp-sorted-alist to the result. +;; *-bmenu-list-1: Set bookmarkp-sorted-alist to the result of calling *-sort-and-remove-dups. +;; 2010/03/02 dadams +;; Added: bookmarkp-sorted-alist. +;; *-bmenu-list-1: Use bookmarkp-sorted-alist. +;; *-sort-and-remove-dups: Set bookmarkp-sorted-alist to the result. +;; All *-cp (and hence *-define-file-sort-predicate): +;; Accept bookmark names as args, in addition to bookmarks. +;; bookmark-alpha-p: Don't use bookmarkp-make-plain-predicate, to avoid infinite recursion. +;; 2010/02/28 dadams +;; Added: bookmarkp-send-bug-report. +;; bookmarkp-bmenu-mode-status-help: Rewrote to provide only Bookmark+ help. Added help buttons. +;; Fixed Commentary typos. +;; 2010/02/26 dadams +;; Added: bookmarkp-desktop-change-dir, bookmarkp-desktop-kill, bookmarkp-desktop-delete. +;; *-jump-desktop: Call *-desktop-change-dir. +;; *-read-bookmark-for-type: Added optional arg ACTION. +;; 2010/02/24 dadams +;; *-bmenu-list: Handle case null last-bookmark-file (due to old file format). Thx to Seb Luque. +;; *-make-record-default: protect dired-buffers with boundp. Thx to Janek Schwarz. +;; 2010/02/16 dadams +;; bookmarkp-define-sort-command: Add msg suffix about repeating. +;; bookmarkp-msg-about-sort-order: Added optional arg SUFFIX-MSG. +;; 2010/02/15 dadams +;; Added: bookmark-bmenu-switch-other-window (redefinition for Emacs 20-22). +;; *-bmenu-mode: Added redefinition, instead of advising. +;; *-send-edited-annotation, *-relocate, *-rename, *-bmenu-refresh-menu-list, +;; *-remove(-all)-tags, *-add-tags: +;; Refresh the menu list, to pick up changes. +;; *-refresh-menu-list: Added optional arg BOOKMARK: go to it. +;; Do not bind bookmark-bmenu-relocate unless it's defined. +;; *-handler-cp: Respect case-fold-search. +;; 2010/02/14 dadams +;; Renamed bookmark-bmenu-list-1 to bookmarkp-bmenu-list-1. +;; Added faces: bookmarkp-(a|t|>|D)-mark, bookmarkp-heading (don't use bookmark-menu-heading). +;; Added redefinitions: bookmark-send-edited-annotation, bookmark(-bmenu)-show-annotation, +;; bookmark-show-all-annotations. +;; *-bmenu-mark, *-bmenu-delete, *-bmenu-list-1: Add faces to marks. +;; *-bmenu-list-1 and everywhere: Get rid of "% " before menu-list title. +;; *-bmenu-list-1: Use "a", not "*", as annotation mark. +;; Add "t" mark for tags. Add an extra space before bookmark name. +;; *-bmenu-marks-width: change value from 2 to 4, for the tags column and the extra space. +;; 2010/02/13 dadams +;; Added: bookmarkp-desktop-history, +;; bookmarkp-desktop-jump (bound to C-x j K; added to menu), +;; bookmarkp-bookmark-list-jump (bound to C-x j B; added to menu), +;; bookmarkp-bookmark-list-alist-only, bookmarkp-bookmark-list-history. +;; *-types-alist: Added entries for desktops and bookmark-lists. +;; *-describe-bookmark: Added optional arg, to show full (internal) info. +;; Bind it to ? in bookmark-map. +;; *-jump-bookmark-list: Pop to the bookmark-list (to show it). +;; *-bmenu-mark-w3m-bookmarks: Typo: wrong predicate. +;; *(-bmenu)-remove-all-tags: Raise error if no tags to remove. +;; *-bmenu-remove-all-tags: Require confirmation if interactive. +;; *-bmenu-remove-tags: Added optional arg MSGP. +;; Menus: Added "..." as needed. +;; *-bmenu-mouse-3-menu: Guard bookmark-bmenu-relocate with fboundp. +;; 2010/02/12 dadams +;; Added: bookmarkp-bmenu-define-jump-marked-command. Bound to M-c and added to menu. +;; Changed bookmarkp-toggle-saving-bookmark-file binding to M-~ (M-s conflicts w isearch-multi). +;; Updated bookmark-bmenu-mode doc string. +;; 2010/02/11 dadams +;; Added: bookmarkp-types-alist, +;; bookmarkp-(dired|gnus|info|man|region|w3m|(non-|local-|remote-)file)-history. +;; bookmark-completing-read: Added optional HIST arg. +;; *-(relocate|rename|insert(-location)): Added bookmark default for interactive use. +;; *-jump-dired: Handle bookmarkp-jump-display-function. +;; *-read-bookmark-for-type: Added optional HIST arg. +;; *-jump-to-type(-other-window), +;; *-(dired|file|gnus|info|man|region|w3m|(local-|non-|remote-)file)-jump*(-other-window): +;; Use type-specific history var. +;; 2010/02/09 dadams +;; Added: bookmarkp-get-tag-value. +;; bookmark--jump-via: Handle special bookmark tag bookmarkp-jump. +;; 2010/02/08 dadams +;; Renamed: bookmarkp-bmenu-dired-marked-local to bookmarkp-bmenu-dired-marked. +;; bookmarkp-bmenu-dired-marked: Handle remote bookmarks if Emacs > 23.1. +;; Support tags with values. +;; Added: bookmarkp-tag-name, bookmarkp-full-tag, bookmarkp(-bmenu)-set-tag-value. +;; Renamed variable (not fn) bookmarkp-tags-list to bookmarkp-tags-alist. +;; Use bookmarkp-full-tag everywhere for tag completion. +;; *-has-tag-p: Use assoc-default, not member. +;; *-read-tag(s)-completing: CANDIDATE-TAGS is now an alist. +;; *-list-all-tags: Added optional arg FULLP (prefix arg). +;; *-tags-list: Added optional arg NAMES-ONLY-P. +;; *-(add|remove|rename)-tags: Use copy-alist, not copy-sequence. Alist, not list, membership. +;; *-rename-tag: Raise error if no tag with old name. +;; *-bmenu-mark-bookmarks-tagged-regexp, *-regexp-filtered-tags-alist-only, *-describe-bookmark, +;; *-(all|some)-tags-regexp-jump(-other-window): +;; Use bookmarkp-tag-name. +;; *-bmenu-mark/unmark-bookmarks-tagged-(all|some)/(none|not-all), *-define-tags-sort-command: +;; Use assoc-default, not member. +;; Added: bookmarkp-bmenu-add-tags, bookmarkp-bmenu-remove(-all)-tags. +;; *-bmenu-mouse-3-menu: Use bookmarkp-bmenu-add-tags, bookmarkp-bmenu-remove(-all)-tags. +;; Added bookmarkp-bmenu-set-tag-value. +;; *-bmenu-mark-bookmarks-satisfying: Made it a command (interactive). +;; 2010/02/07 dadams +;; *-write-file: Corrected handling of ALT-MSG. +;; Cleanup. +;; *-remove-tags: Don't call *-get-tags twice. +;; *-bmenu-(un)mark-bookmarks-tagged(-not)-(all|none|some): +;; Don't duplicate what bookmarkp-read-tags-completing does. +;; *-add-tags, *-remove-tags(-from-all): TAGS arg must be a list from the beginning. +;; *-remove-tags-from-all, *-rename-tag: Use bookmark-all-names - don't mapcar car over alist. +;; *-all-tags-regexp-jump: Corrected to use same pred as *-all-tags-regexp-jump-other-window. +;; *-(some|all)-tags-jump(-other-window): Use bookmarkp-has-tag-p - don't repeat the definition. +;; *-read-tag(s)-completing: Removed unnecessary or. +;; 2010/02/06 dadams +;; *-write-file, *-empty-file: Corrected handling of ALT-MSG. +;; 2010/02/05 dadams +;; Added: bookmarkp-same-file-p, bookmarkp-empty-file. +;; Bound bookmarkp-empty-file to C-x p 0, and added it to menus. +;; *-bmenu-list, *-switch-bookmark-file: Use bookmarkp-same-file-p. +;; bookmark-write-file: Added optional ALT-MSG arg. +;; 2010/02/04 dadams +;; Added: bookmarkp-bmenu-omit, bookmarkp-list-all-tags. Added to mouse-3 menu, Tags menus. +;; 2010/02/01 dadams +;; Added: bookmarkp-current-bookmark-file, bookmarkp-switch-bookmark-file, +;; (redefinition of) bookmark-load, (redefinition of) bookmark-save, +;; bookmarkp-toggle-saving-bookmark-file, bookmarkp-last-save-flag-value. +;; *-bmenu-list: Restore bookmarkp-current-bookmark-file if appropriate. +;; *-bmenu-mode-status-help: Show bookmarkp-current-bookmark-file. +;; *-bmenu-define-full-snapshot-command, *-save-menu-list-state: +;; Save bookmarkp-current-bookmark-file. +;; Bound bookmarkp-switch-bookmark-file to L and C-x r L. Added both load commands to both menus. +;; *-toggle-saving-menu-list-state: Changed binding to M-l. Error if init value is nil. +;; Bound *-toggle-saving-bookmark-file to M-s and added to menu. +;; Added bookmark-write to bookmarkp-bmenu-menubar-menu (Save As). +;; bookmarkp-bmenu-menubar-menu: Added :help strings everywhere. +;; bookmarkp-bmenu-mode-status-help: Added face legend. +;; 2010/01/31 dadams +;; Added: bookmarkp-tags-list, bookmarkp-read-tag-completing, bookmarkp-use-w32-browser-p, +;; bookmarkp-bmenu-w32-open(-select|-with-mouse). Bind *-w32* to M-RET, V, M-mouse-2. +;; *-default-handler: Call w32-browser if bookmarkp-use-w32-browser-p. +;; *-bmenu-unomit-marked: Don't try to return to original position (duh). +;; *-bmenu-goto-bookmark-named: Use eobp as loop condition. Call bookmark-bmenu-ensure-position. +;; *-read-tags-completing: +;; Added arg UPDATE-TAGS-LIST-P. Call bookmark-maybe-load-default-file. +;; Use bookmarkp-tags-list if CANDIDATE-TAGS is nil. Update that var if UPDATE-TAGS-LIST-P. +;; *-(add|remove)-tags: Added arg NO-CACHE-UPDATE-P. If nil, call bookmarkp-tags-list. +;; *-remove-tags-from-all, *-rename-tag, *-bmenu-(add|remove)-tags-(to|from)-marked: +;; Call bookmarkp-tags-list. +;; *-remove-tags-from-all: Pass nil as tags arg to bookmarkp-read-tags-completing. +;; *-rename-tag: Use bookmarkp-read-tag-completing, not read-string. +;; 2010/01/29 dadams +;; bookmarkp-describe-bookmark: Handle desktop bookmarks specifically. +;; Added: bookmarkp-menu-popup-max-length. +;; bookmark-completing-read: Use bookmarkp-menu-popup-max-length. +;; bookmarkp-bmenu-state-file: Added missing default value for const. +;; Don't add jump-other entry to menu-bar-bookmark-map (just use Jump To submenu). +;; 2010/01/28 dadams +;; bookmarkp-(all|some)-tags(-regexp)-jump(-other-window): Error if no bookmarks with the tags. +;; bookmarkp-(all|some)-tags-jump(-other-window): Handle case where user enters no tags. +;; Use :advertised-binding property for bookmark-jump(-other-window). +;; Added: bookmarkp-bmenu-jump-menu. +;; Added bookmarkp-bmenu-jump-menu to menu-bar-bookmark-map and bookmarkp-bmenu-menubar-menu. +;; 2010/01/27 dadams +;; Added: bookmarkp-every, bookmarkp-(all|some)-tags(-regexp)-jump(-other-window). +;; 2010/01/26 dadams +;; Added: bookmarkp-bmenu-dired-marked-local. Bound to M-d >. +;; 2010/01/23 dadams +;; Added: bookmarkp-handler-cp, bookmarkp-desktop-no-save-vars, bookmarkp-set-desktop-bookmark, +;; bookmarkp-make-desktop-record, bookmarkp-jump-desktop, bookmarkp-desktop-read, +;; bookmarkp-desktop-alist-only, bookmarkp-desktop-bookmark-p, +;; bookmarkp-bmenu-mark-desktop-bookmarks, bookmarkp-bmenu-show-only-desktops, +;; face bookmarkp-desktop. +;; bookmarkp-bmenu-sort-by-bookmark-type: Add bookmarkp-handler-cp to the list (last). +;; bookmarkp-bmenu-propertize-item: Add face bookmarkp-desktop for desktop bookmarks. +;; Bound: bookmarkp-set-desktop-bookmark to C-x p K, C-x r K, +;; bookmarkp-bmenu-mark-desktop-bookmarks to K M (and Mark menu), +;; bookmarkp-bmenu-show-only-desktops to K S (and Show menu). +;; bookmark-bmenu-mode doc string: Updated for new commands. +;; Added autoload cookies for all defcustoms. +;; 2010/01/20 dadams +;; Added: bookmarkp-bmenu-mode-status-help. Bound to C-h m, ?. +;; 2010/01/19 dadams +;; bookmarkp-remote-file-bookmark-p: Include remote Dired bookmarks. Thx to Simon Harrison. +;; Added: bookmarkp-describe-bookmark-internals, bookmarkp-bmenu-describe-this+move-(down|up), +;; defalias for list-bookmarks. +;; bookmarkp-describe-bookmark: Reformatted help output. Added more info about Dired bookmarks. +;; bookmarkp-bmenu-describe-this-bookmark: +;; C-u calls bookmarkp-describe-bookmark-internals. Bound also to C-h C-RET. +;; 2010/01/18 dadams +;; Added: bookmarkp-dired-subdirs. +;; bookmarkp-make-dired-record, bookmarkp-jump-dired: Handle inserted and hidden dirs. +;; bookmarkp-jump-dired: Use expand-file-name, not concat. +;; 2010/01/17 dadams +;; Added: +;; bookmarkp-jump(-other-window)-map, bookmarkp-jump-1, bookmark-all-names (redefined), +;; bookmarkp-read-bookmark-for-type, bookmarkp-dired-jump-current(-other-window), +;; bookmarkp-(dired|(local-|remote-|non-)file|gnus|info|man|region|w3m)-jump(-other-window), +;; bookmarkp-jump-to-type(-other-window). +;; bookmark-jump(-other-window): Use bookmarkp-jump-1. +;; bookmark-completing-read: Added optional args ALIST and PRED. +;; bookmarkp-default-bookmark-name: Added optional arg ALIST. +;; 2010/01/14 dadams +;; bookmark-bmenu-surreptitiously-rebuild-list: Put back save-excursion & save-window-excursion. +;; 2010/01/02 dadams +;; Renamed *-bmenu-check-position to *-bmenu-ensure-position, per Emacs 23.2. Added defalias. +;; 2010/01/01 dadams +;; *-bmenu-(un)mark, *-bmenu-other-window, *-bmenu-rename: Call bookmark-bmenu-check-position. +;; *-bmenu-delete: Don't call bookmark-bmenu-check-position again at end. +;; *-bmenu-edit-bookmark: Call bookmark-bmenu-check-position at beginning, not end. +;; 2009/12/30 dadams +;; Added: bookmarkp-bmenu-header-lines, bookmarkp-bmenu-marks-width. Use everywhere. +;; 2009/12/29 dadams +;; Added: bookmarkp-make-bookmark-list-record, bookmarkp-jump-bookmark-list, face +;; bookmarkp-bookmark-list. +;; *-bmenu-propertize-item: Highlight bookmark-list bookmarks. +;; *-bmenu-refresh-menu-list: Set bookmarkp-latest-bookmark-alist to refreshed list. +;; Face *-local-directory: Made dark background version the inverse of light. +;; *-bmenu-list-1: Use eq, not equal, test for bookmarkp-omitted-alist-only as filter fn. +;; *-bmenu-define(-full-snapshot)-command: Include bookmarkp-bmenu-omitted-list in saved state. +;; 2009/12/26 dadams +;; Added: bookmarkp-bmenu-omitted-list, bookmarkp-bmenu-show-only-omitted, bookmarkp-unomit-all, +;; bookmarkp-bmenu-omit/unomit-marked, bookmarkp-bmenu-(un-)omit-marked, +;; bookmarkp-omitted-alist-only. +;; Bind *-bmenu-omit/unomit-marked, *-bmenu-show-only-omitted, *-unomit-all to O>,OS,OU. +;; Added omit/un-omit stuff to Bookmark+ menu. +;; bookmarkp-remove-assoc-dups, bookmarkp-sort-and-remove-dups: Added optional arg OMIT. +;; bookmark-delete: Update bookmarkp-bmenu-omitted-list. +;; bookmarkp-save-menu-list-state, bookmark-bmenu-list: +;; Save/restore bookmarkp-bmenu-omitted-list as part of state. +;; bookmark-bmenu-list-1: Treat omitted list when bookmarkp-omitted-alist-only. +;; bookmarkp-marked-bookmark-p: Arg can now be a bookmark (or a bookmark name). +;; bookmarkp-bmenu-unmark-all: Start by going forward 2 lines, not 1, if user hit RET. +;; bookmarkp-bmenu-make-sequence-from-marked: +;; Added optional arg DONT-OMIT-P. If nil, omit marked bookmarks. +;; If the seq bookmark already exists, prompt to add to it or replace it. +;; Go to the new bookmark in the menu list. +;; 2009/12/15 dadams +;; Added: bookmarkp-sequence-jump-display-function, bookmarkp-sequence, bookmarkp-function, +;; bookmarkp-bmenu-make-sequence-from-marked, bookmarkp-jump-sequence, +;; bookmarkp-sequence-bookmark-p, bookmarkp-make-function-bookmark, +;; bookmarkp-jump-function, bookmarkp-function-bookmark-p. +;; bookmarkp-describe-bookmark: Update for sequence and function bookmarks. +;; bookmark-bmenu-list: Use condition-case when read from bookmarkp-bmenu-state-file. +;; Bind emacs-lisp-mode-hook to nil. +;; bookmark-bmenu-surreptitiously-rebuild-list: Use save-current-buffer. +;; bookmarkp-bmenu-propertize-item: Add faces to function and sequence bookmarks. +;; bookmarkp-bmenu-menubar-menu: Add *-make-sequence-*-from-marked, *-make-function-bookmark. +;; bookmark--jump-via: Call *-record-visit with BATCH arg, to preserver point in menu list. +;; bookmark-bmenu-list-1: fit-frame only if buffer is *Bookmark List*. +;; 2009/12/13 dadams +;; *-alist-only: Call bookmark-maybe-load-default-file. +;; 2009/12/11 dadams +;; Added: bookmarkp-list-defuns-in-commands-file, bookmarkp-remove-dups. +;; 2009/12/06 dadams +;; Added: bookmarkp-bmenu-mouse-3-menu (bound to mouse-3), +;; bookmarkp-bmenu-(menubar|define-command|sort|show|tags|mark)-menu. +;; bookmark-bmenu-delete: Remove newly flagged bookmark from bookmarkp-bookmark-marked-list. +;; bookmarkp-define-tags-sort-command: Save macroexpanded definition in +;; bookmarkp-bmenu-commands-file. +;; 2009/12/04 dadams +;; Added: bookmarkp-bmenu-define-full-snapshot-command (bound to C), +;; bookmarkp-define-tags-sort-command. +;; bookmarkp-bmenu-mark-bookmarks-tagged-regexp: Removed extra forward-line if we mark line. +;; 2009/12/03 dadams +;; Added: bookmarkp-bmenu-define-command (bound to c), bookmarkp-bmenu-commands-file. +;; bookmark-bmenu-list: Read bookmarkp-bmenu-commands-file. +;; bookmarkp-sort-and-remove-dups: Bug fix - return the list even when null sort function. +;; 2009/11/01 dadams +;; Added: *-bmenu-check-position (redefinition), bmkext-jump-* defaliases. +;; *-(w3m|man|gnus)-bookmark-p: Recognize the aliases. +;; *-jump-man: Bind Man-notify-method. +;; *-bmenu-goto-bookmark-named: Check the text property, instead of searching. +;; *-bmenu-bookmark: Wrap in condition-case. +;; 2009/10/31 dadams +;; Added: bookmark-bmenu-list-1. bookmarkp-toggle-saving-menu-list-state (C-t), +;; bookmarkp-bmenu-state-file, bookmarkp-bmenu-first-time-p, +;; bookmarkp-last-bmenu-(bookmark|state-file), bookmark-exit-hook-internal +;; (redefinition), bookmarkp-save-menu-list-state. +;; bookmark-bmenu-list: Restore menu-list state if appropriate. Call bookmark-bmenu-list-1. +;; bookmarkp-bmenu-quit: If *-bmenu-state-file is non-nil, save the state. +;; bookmark-write-file: Use case, not cond. +;; bookmark-set: Use command name as default for man-page bookmark name. +;; bookmark-delete: Update bookmarkp-latest-bookmark-alist. +;; 2009/10/28 dadams +;; Renamed: bookmarkp-bookmark-marked-p to bookmarkp-marked-bookmark-p +;; bookmarkp-bmenu-sort-by-gnus-thread to bookmarkp-bmenu-sort-by-Gnus-thread. +;; Added: bookmarkp-man, bookmarkp-make-(wo)man-record, bookmarkp-jump-(wo)man, +;; bookmarkp-man-bookmark-p, bookmarkp-bmenu-mark-man-bookmarks, +;; bookmarkp-bmenu-show-only-man-pages, bookmarkp-man-alist-only. +;; *-bmenu-propertize-item: Handle (wo)man bookmarks. Use bookmarkp-info-bookmark-p. +;; *-regexp-filtered-*: Use bookmarkp-remove-if-not. +;; *-write-file: Remove text properties from file name also. +;; *-regexp-filtered-(tags|(bookmark|file)-name)-alist-only: Use *-remove-if-not. +;; 2009/10/26 dadams +;; Added: bookmarkp-bmenu-mark-*-bookmarks, bmenu-mark-bookmarks-satisfying. +;; Bound those and *-show-only-* accordingly. +;; bookmarkp-file-alist-only: Redefined to just use *-file-bookmark-p. +;; 2009/10/25 dadams +;; bookmarkp-bmenu-propertize-item: Put bookmark name on line as text property. +;; bookmark-bmenu-bookmark: Get bookmark name from text property bookmarkp-bookmark-name. +;; Removed: bookmarkp-latest-sorted-alist. +;; bookmark-bmenu-list: Use bookmarkp-bmenu-title only if defined. +;; 2009/10/21 dadams +;; Added: bookmarkp-barf-if-not-in-menu-list. Use in place of its body. +;; Added: bookmarkp-bmenu-mark-bookmarks-tagged-regexp. Bound to T m %. +;; Added: bookmarkp-record-visit. Use in *--jump-via. Replaces next two removals. +;; Removed: bookmarkp-add-or-update-time, bookmarkp-increment-visits. +;; Renamed: *-record-(end|front|rear)-context(-region)-string'. +;; New names: bookmarkp-(end-)position-(pre|post)-context(-region). +;; *-bmenu-describe-this-bookmark: Added *-barf-if-not-in-menu-list. +;; *-bmenu-(un)mark-all, *-bmenu-regexp-mark, *-bmenu-toggle-marks: +;; Removed with-current-buffer. +;; 2009/10/20 dadams +;; Added: bookmarkp-bmenu-filter-function, bookmarkp-bmenu-title. +;; Removed: bookmarkp-bmenu-called-from-inside-p. +;; *-bmenu-list: +;; Removed TITLE arg. Get title from bookmarkp-bmenu-title or default. +;; Use interactive-p and absence of menu list, not *-bmenu-called-from-inside-p, as the +;; criterion for removing marks. Fixes bugs such as bookmark creation removing marks. +;; *-define-sort-command, *-bmenu-execute-deletions, *-increment-visits, +;; *-add-or-update-time, *-bmenu-show-only-*, *-bmenu-show-all, +;; *-bmenu-refresh-menu-list, *-bmenu-toggle-show-only-(un)marked, +;; *-bmenu-filter-alist-by-regexp, *-bmenu-reverse(-multi-sort)-order, +;; *-bmenu-change-sort-order: +;; Do not bind or set *-called-from-inside-p. +;; *-bmenu-show-only-*, *-bmenu-show-all, *-bmenu-filter-alist-by-regexp: +;; Set *-bmenu-filter-function, *-bmenu-title. +;; *-bmenu-show-all: +;; Set *-latest-bookmark-alist to bookmark-alist. +;; *-bmenu-refresh-menu-list: Fix so that it in fact refreshes. +;; Do not use *-bmenu-surreptitiously-rebuild-list and *-bmenu-check-position. +;; Bind bookmark-alist to last alist (filtered or not), and call *-bmenu-list. +;; *-bmenu-surreptitiously-rebuild-list: +;; Do not use save*-excursion. Do not get current title and pass it to *-bmenu-list. +;; *-file-alist-only: +;; Removed optional arg. We have *-local-file-alist-only for that. +;; *-regexp-filtered-alist-only, *-bmenu-filter-alist-by-regexp: +;; Remove REGEXP arg - use bookmarkp-bmenu-filter-pattern. +;; *-bmenu-filter-incrementally: +;; Raise error if not in *Bookmark List*. +;; Use just bookmarkp-bmenu-filter-alist-by-regexp in timer - pass no regexp arg. +;; Added: bookmarkp-some, *-bmenu-filter-(file-name|tags)-incrementally, +;; *-bmenu-filter-alist-by-(file-name|tags)-regexp, +;; *-regexp-filtered-(file-name|tags)-alist-only. +;; Renamed: *-bmenu-filter-incrementally to *-bmenu-filter-bookmark-name-incrementally, +;; *-bmenu-filter-alist-by-regexp to *-bmenu-filter-alist-by-bookmark-name-regexp, +;; *-regexp-filtered-alist-only to *-regexp-filtered-bookmark-name-alist-only. +;; Bound these commands to P B, P F, and P T. Updated bookmark-bmenu-mode doc string. +;; 2009/10/18 dadams +;; Added: *-bmenu-filter-(incrementally|delay|prompt|pattern|timer|alist-by-regexp), +;; *-bmenu-read-filter-input, *-regexp-filtered-alist-only, +;; *-bmenu-cancel-incremental-filtering. +;; *-bmenu-execute-deletions: Don't update menu list if this is a no-op. +;; Updated Commentary. +;; Thx to Thierry Volpiatto. +;; Added: *-marked-cp, *-bmenu-sort-marked-before-unmarked. Bound to s >. +;; *-define-sort-command: Use copy-sequence for default value. +;; 2009/10/17 dadams +;; Added: *-read-tags-completing, *-set-union, *-tag-history, *-describe-bookmark, +;; *-bmenu-describe-this-bookmark. Bound *-bmenu-describe-this-bookmark to C-h RET. +;; Use *-read-tags-completing instead of *-read-tags. +;; *-sort-orders-for-cycling-alist: Use copy-sequence. +;; *-bmenu-change-sort-order: Use member, not memq. +;; *-get-bookmark: Handle case of non-string, non-cons. Document NOERROR in doc string. +;; *-bmenu-execute-deletions: Fix so marks aren't removed if when delete. Thx to Thierry. +;; Convert recorded time to an Emacs time spec: +;; *-make-record-default, -add-or-update-time: Use current-time, not bookmark-float-time. +;; *-get-visit-time: Convert a deprecated time entry to an Emacs time spec. +;; *-bookmark-last-access-cp: Convert recorded time to a number for comparison. +;; Added: *-bmenu-show-filenames (redef of vanilla: put props on whole line, fit frame). +;; Removed: old-bookmark-insert-location. +;; *-insert-location: Do not call original. Redefined: do not add text properties. +;; *-bmenu-list, *-bmenu-hide-filenames: Put properties on line up to max width. +;; *-bmenu-goto-bookmark-named: Allow trailing whitespace, since we use the whole line now. +;; *-bmenu-list: Use pop-to-buffer, not switch-to-buffer. Use do-list, not mapcar. +;; *-bmenu-hide-filenames: fit-frame-if-one-window. +;; *-bmenu-propertize-item: Better help-echo text. +;; Updated bookmark-alist doc string to mention visits, time, and tags entries. +;; 2009/10/16 dadams +;; Added tags feature. +;; Added: *-(get|read)-tags, *-has-tag-p, *-remove(-all)-tags(-from-all), +;; *-bmenu-remove-tags-from-marked, *-add-tags(-to-marked), *-rename-tag, +;; *-bmenu-(un)mark-bookmarks-tagged-(all|none|some|not-all), +;; *-bmenu-mark/unmark-bookmarks-tagged-(all/none|some/not-all). +;; Bound to prefix key T. +;; *-bmenu-mode: Updated doc string. +;; Added: bookmarkp-default-bookmark-name. Use as default instead of *-current-bookmark. +;; Renamed: *-maybe-save-bookmark to *-maybe-save-bookmarks. +;; Menu-list commands: Raise an error if command is used outside the menu list. +;; 2009/10/15 dadams +;; Added: *-bmenu-(search|query-replace)-marked-bookmarks-regexp. Bound to M-a, M-q. +;; Renamed: *-non-marked-bookmarks-only to *-unmarked-bookmarks-only, +;; *-bookmark-marked-alist to *-bmenu-marked-bookmarks. +;; *-increment-visits, *-add-or-update-time: +;; Set *-bmenu-called-from-inside-p to t, so we don't remove marks. +;; Redefined *-bmenu-bookmark to get name from *-latest-sorted-alist. Thx to Thierry V. +;; *-bmenu-surreptitiously-rebuild-list, *-bmenu-list: +;; Removed optional arg DONT-TOGGLE-FILENAMES-P. +;; *-bmenu-execute-deletions, *-bmenu-toggle-show-only-(un)marked, *-bmenu-(un)mark-all, +;; *-bmenu-regexp-mark, *-bmenu-toggle-marks: +;; Do not bother with *-bmenu-toggle-filenames and rebuilding the menu list. +;; 2009/10/14 dadams +;; Added: *-bmenu-delete (redefinition), *-isearch-bookmarks, +;; *-bmenu-isearch(-marked)-bookmarks(-regexp), *-isearch-next-bookmark-buffer. +;; Bound multi-isearch commands to M-s a C(-M)-s. +;; 2009/10/13 dadams +;; Added: *-make-dired-record, *-jump-dired, *-dired-bookmark-p, *-dired-alist-only, +;; *-bmenu-show-only-dired. Bound *-bmenu-show-only-dired to M-d. +;; bookmarkp-file-bookmark-p: Include bookmarks that have the Dired handler. +;; Moved *-sort-orders-for-cycling-alist defcustoms after *-define-sort-command calls. +;; Call bookmarkp-msg-about-sort-order only when interactive. +;; *-add-or-update-time, *-increment-visits: Do not save each time we access a bookmark. +;; Updated doc string of bookmark-alist and Commentary. +;; 2009/10/09 dadams +;; Added: bookmarkp-bmenu-delete-marked. Bound it to D. +;; bookmarkp-sort-orders-for-cycling-alist. +;; Renamed: bookmarkp-sort-functions-alist to bookmarkp-sort-orders-alist, +;; bookmarkp-sort-function to bookmarkp-sort-comparer. +;; bookmark-bmenu-execute-deletions: Added optional arg, for *-bmenu-delete-marked. +;; *-sort-function: Changed default value to sorting by bookmark type (`s k'). +;; *-bmenu-change-sort-order: Use *-sort-orders-for-cycling-alist, not all sort orders. +;; Updated Commentary and doc string (bookmark-bmenu-mode). +;; 2009/10/08 dadams +;; Added: *-bmenu-sort-by-(w3m-url|gnus-thread), *-(gnus|w3m)-cp, *-cp-not, +;; *-local-file-(accessed|updated)-more-recently-cp, *-bmenu-sort-by-bookmark-type. +;; Renamed: *-bmenu-sort-by(-last)-file-(size|type|access|update) to +;; *-bmenu-sort-by(-last)-local-file-(size|typeaccess|update), +;; *-file-visited-more-recently-cp to *-local-file-accessed-more-recently-cp, +;; *-file-(size|type)-cp to *-local-file-(size|type)-cp. +;; Removed: *-file-(device|gid(-chg)|inode|last-(access|update|status-change)|links|modes +;; |uid)-cp. +;; Bound *-bmenu-sort-by-bookmark-type to `s k'. +;; *-define-file-sort-predicate: Use *-file-bookmark-p, not *-local-file-bookmark-p. +;; *-msg-about-sort-order: Added optional arg PREFIX-ARG. Use in: *-show-(all|only-*). +;; 2009/10/07 dadams +;; Renamed: *-bmenu-sort-by-last-visit-time to *-bmenu-sort-by-last-bookmark-access, +;; *-bmenu-sort-by-visit-frequency to *-bmenu-sort-by-bookmark-visit-frequency, +;; *-visited-more-recently-cp to *-bookmark-last-access-cp. +;; 2009/10/06 dadams +;; Added: bookmarkp-msg-about-sort-order. +;; bookmark-completing-read: Simple sort when use menu-bar menu. +;; 2009/10/05 dadams +;; Added: *-make-plain-predicate, *-reverse-multi-sort-order, *-multi-sort, +;; *-define-file-sort-predicate, *-bmenu-sort-by-file-*, *-file-attribute-*-cp, +;; and aliases *-file-*-cp, *-current-sort-order. +;; Redefined sorting to allow multi-predicates: +;; Redefined: *-sort-function, *-sort-and-remove-dups, *-define-sort-command, +;; *-sort-functions-alist. +;; Bound keys with `s f' prefix to file-sorting commands +;; *-current-sort-order: Use rassoc instead of rassq now. +;; Swap keys s and S. S is now bookmark-bmenu-save. s is not the sorting prefix key. +;; bookmark-bmenu-mode: Mention S key explicitly here (even though it is also +;; mentioned in the vanilla part of the doc string). +;; 2009/10/04 dadams +;; *-bmenu-change-sort-order-repeat: Require repeat.el. +;; Renamed: bookmarkp-current-sec-time to bookmarkp-float-time. +;; *-float-time: Added arg, so it's the same as float-time (for Emacs 20). +;; Bind *-reverse-sort-order to `S R'. +;; *-remote-file-bookmark-p: Removed extra rem-file in last and. +;; *-non-file-bookmark-p: Ensure it's not a remote file, before calling file-exists-p. +;; 2009/10/03 dadams +;; Added: bookmarkp-file-remote-p, bookmarkp-buffer (face). +;; bookmarkp-non-file (face): Changed to gray. +;; *-default-handler, *-bmenu-propertize-item, *-(info|file)-bookmark-p: +;; Support Emacs 20-21 Info-node bookmarks. +;; bookmarkp-bmenu-propertize-item: Use different face for existing buffers. +;; Use bookmarkp-non-file-filename. +;; bookmarkp-non-file-bookmark-p: Include buffer bookmarks for nonexistent buffers. +;; bookmarkp-remote-file-bookmark-p: Use bookmarkp-file-remote-p. +;; bookmark-handle-bookmark: +;; Redefine for all Emacs versions. Handle buffer (non-file) bookmarks. +;; Reordered some function definitions. +;; 2009/10/02 dadams +;; Added: bookmarkp-bmenu-goto-bookmark-named, bookmarkp-latest-sorted-alist. +;; *-sort-and-remove-dups: Set *-latest-sorted-alist (not used yet). +;; *-define-sort-command, *-bmenu-change-sort-order, *-reverse-sort-order: +;; Bind *-bmenu-called-from-inside-p to t, to prevent losing marks. +;; Restore cursor position to same bookmark after sorting - use *-goto-bookmark-named. +;; *-bmenu-surreptitiously-rebuild-list, *-bmenu-list: Added arg DONT-TOGGLE-FILENAMES-P. +;; *-bmenu-execute-deletions, *-bmenu-toggle-show-only-(un)marked: +;; Call *-surreptitiously-* with arg DONT-TOGGLE-FILENAMES-P. +;; *-bmenu-hide-filenames: Simplify - don't get to position by searching backward. +;; *-handle-region-default: Use forward-line, not goto-line. +;; Thx to Thierry V. +;; 2009/10/01 dadams +;; Added: bookmarkp-some-unmarked-p. +;; Renamed: *-bmenu-toggle-show-only- to *-bmenu-show-only-, +;; *-bmenu-called-from-inside-flag to *-bmenu-called-from-inside-p. +;; bookmarkp-some-marked-p: Do not test bookmarkp-bookmark-marked-alist. +;; Arg must be required (explicit). Changed calls accordingly. +;; bookmark-bmenu-mode: Cleaned up doc string. +;; bookmark-bmenu-((un)mark|rename|edit-*|toggle-marks|surreptitiously-rebuild-list), +;; bookmarkp-root-or-sudo-logged-p, bookmarkp-jump-w3m-(new-session|only-one-tab), +;; bookmarkp-some-marked-p: +;; Inline let vars used only once. +;; bookmarkp-bmenu-toggle-show-only-marked: +;; Test bookmarkp-some-unmarked-p, not bookmarkp-some-marked-p, +;; and include *-before-hide-unmarked in the test. +;; bookmarkp-bmenu(-toggle)-show-only-*: Display status message. +;; bookmarkp-bmenu-toggle-show-only-(un)marked: Fit frame. +;; bookmark-prop-set: Fixed, so it handles old bookmark format also. +;; 2009/10/01 Thierry Volpiatto +;; Removed: bookmarkp-bmenu-restore-marks. +;; bookmark-bmenu-list: +;; Do the mark restoration in line, at the same time as the annotation * restoration. +;; Simplify use of START and END. +;; 2009/09/30 dadams +;; bookmarkp-bmenu-regexp-mark: Remove binding of bookmark-alist. +;; bookmark-bmenu-(un)mark, bookmarkp-bmenu-edit-bookmark (remove first call only), +;; bookmark-bmenu-other-window, bookmark-bmenu-rename, bookmarkp-bmenu-restore-marks: +;; Remove bookmark-bmenu-check-position (done by bookmark-bmenu-bookmark anyway). +;; bookmark-insert-location: Fix interactive spec for Emacs < 22. +;; bookmark-location: Return "" instead of raising error, if no location found. +;; bookmarkp-current-sec-time: Move the let: do not call current-time unless we need to. +;; bookmarkp-bmenu-unmark-all: forward-line only 1, not 2. Thx to Thierry. +;; bookmark-bmenu-mode: Updated doc string - bindings and mention options. +;; bookmarkp-bmenu-propertize-item: For buffer, check also against " - no file -". +;; 2009/09/29 dadams +;; bookmark-bmenu-unmark: Use delete, not remove. +;; Removed: bookmark-bmenu-check-position, bookmarkp-maybe-sort. +;; Added: bookmarkp-sort-and-remove-dups, bookmarkp-remove-assoc-dups, +;; bookmarkp-face-prop, bookmarkp-bad-bookmark, bookmark-menu-heading (Emacs 20,21), +;; bookmark-bmenu-bookmark (redefinition). +;; *-bmenu-toggle-show-only-*: Do not call-interactively. +;; bookmarkp-bmenu-(un)mark-all: +;; Handle bookmark-bmenu-toggle-filenames (wrapper). +;; Remove bookmark-bmenu-check-position - just ensure within menu list. +;; bookmarkp-bmenu-mark-all: Move save-excursion so it applies to all movements. +;; Message stating number marked. +;; bookmarkp-bmenu-unmark-all: Use with-current-buffer ensure in menu list. +;; Use bookmark-bmenu-unmark. +;; Fixed U bindings for bookmarkp-bmenu-unmark-all. +;; bookmarkp-bmenu-regexp-mark: +;; Remove bookmark-bmenu-check-position - just ensure in menu list. +;; bookmarkp-bmenu-toggle-marks: Use forward-line 2, to ensure in menu list. +;; Message stating number marked. +;; bookmark-bmenu-list, bookmarkp-bmenu-propertize-item: Use bookmarkp-face-prop. +;; bookmark-bmenu-list: Don't start applying the faces until column 2. +;; Removed key bindings in bookmark-map for *-toggle-show-only-*. +;; Redefined faces, esp. for a light background. +;; Use font-lock-face or face property, depending on Emacs version. +;; +;; 2009-06-09 to 2009-09-27 Thierry Volpiatto and dadams +;; New features, as follows. +;; See also the change log at +;; http://mercurial.intuxication.org/hg/bookmark-icicle-region/. +;; 2090-09-27 Rewrote sorting and unmarking code. (+ Updates to doc, names.) +;; Unmarking is now like Dired & query-replace. +;; Sorting is via one sort function; sort predicates do all the sorting. +;; Can now cycle sort orders with S S S... +;; Sort cmds now cycle among normal, reverse, off. +;; Add: *-define-sort-command (macro), *-assoc-delete-all, *-upcase, +;; *-get-visits-count, *-get-visit-time, *-sort-functions-alist. +;; Remove docstring from defalias (for Emacs 20). +;; 2009-09-26 Fix *-bmenu-mode doc (defadvice). +;; 2009-09-25 *-bmenu-edit, *-bmenu-sort-1: Fix bmk retrieval code. +;; Redefine *-bmenu-unmark. Add: *-bmenu-toggle-marks. +;; Bind *-bmenu-unmark-all-bookmarks to M-DEL. Reorder code. +;; Rename: *-bmenu-unmark-all-(bookmarks|(delete|mark)-flag)', +;; *-bmenu-unmark-all-bookmarks-1. +;; Change sort predicates in defalias. Rename bmk entry visit to visits. +;; Remove: *-bmenu-show-number-of-visit. +;; 2009-09-22 Rewrote sorting code. Renamed unmarking fns. +;; 2009-09-21 Rename mark/unmark cmds to have -bmenu. +;; Add: *-bmenu-called-from-inside-flag - set it in (un)hide marks fns. +;; 2009-09-20 *-write-file: Remove text properties before saving. +;; Remove all marks only in current display. +;; 2009-09-19 *-current-sec-time: Protect with fboundp for Emacs 20. +;; *-bmenu-sort-1: Add msg showing sort method. +;; Change key S-A to S-S (A is annotations). +;; 2009-09-18 Improve sorting by visit frequency. Always increment when jump. +;; Fix increment visit fn. Allow sorting by last visited. +;; When visit values are equal, sort with string-lessp. +;; Add TIME bookmark-alist entry. *-make-record-default: Add time entry. +;; Fix: bad parens, errors in sorting predicate. Rename fns. +;; Use single fn to sort using diff methods. +;; Add: *-bmenu-refresh-alist (bind to g). +;; 2009-09-16 Add: *-toggle-sorting-by-most-visited, *-reset-visit-flag, +;; *-bmenu-show-number-of-visit. +;; Redefine *-prop-set. Improve *-toggle-sorting-by-most-visited. +;; Add auto-doc to header. *-bmenu-mode: Add missing key. +;; Update menu-list after jumping. +;; Increment save counter when jump with visit flag. +;; 2009-09-15 Record number of visits. Added sorting by most visits. +;; 2009-09-14 Add doc string. Update defadvice doc string wrt keys. +;; 2009-09-12 Add: fns to mark all, unmark D or > or all, *-bmenu-reset-alist. +;; Fix keymap (Emacs 20). *-unmark-all-bookmarks1: Move the save-excursion. +;; 2009-09-11 Add: *-bmenu-check-position (redef to improve performance), +;; *-unmark-all-bookmarks, *-current-list-have-marked-p, +;; *-bookmark-marked-p, *-(non-)marked-bookmarks-only. +;; *-bmenu-hide-unmarked: Add toggling. Restore lost fn. +;; Reorder code. Bind cmds in *-bmenu-mode-map. +;; *-bmenu-hide-marked: Do not hide if no marked in current filter. +;; Improve: *-bmenu-hide(-not)-marked-bookmark, (un)hide marked fns. +;; 2009-09-10 Fix *--restore-all-mark, *-bmenu-regexp-mark. +;; *-bmenu-list: Add *-restore-all-mark. +;; *-bmenu-mark: Push marked bmk to marked list. +;; Add: bookmarkp-bookmark-marked-list, *-bmenu-quit. +;; 2009-09-09 *-maybe-sort-alist: Use copy-sequence. +;; So remove fixes for *-rename, *-edit-bookmark. +;; *-yank, *-rename', *-set: Fix yanking. +;; Remove non-file bmks from file-only list. +;; Add: *-bmenu-list-only-non-file-bookmarks, *-maybe-message (Emacs 20), +;; *-bmenu-mark-bookmark-matching-regexp, *-bmenu-hide-marked-bookmark, +;; *-bmenu-hide-not-marked-bookmark, *-bmenu-mark (redefinition). +;; *-write-file: Improve performance. +;; *-non-file-alist-only: Remove unused def. +;; Fix: hide marked/unmarked with toggle-filenames, keymap for Emacs 20. +;; Improve comments, doc strings. +;; *-bmenu-mark-bookmark-matching-regexp: Fix while loop. +;; 2009-09-08 bookmark-store: Remove duplicate setq of *-current-bookmark. +;; 2009-09-07 Reorganize (reorder), add comments, improve doc strings. +;; Change binding of *-bmenu-relocate from R to M-r. +;; 2009-09-06 bookmark-rename: Redefine with new arg BATCH. +;; *-bmenu-rename: Go to new pos, not old. +;; *-edit-bookmark, bookmark-rename: Fix display update for Emacs 20. +;; 2009-09-05 Add: *-edit-bookmark, *-bmenu-edit-bookmark, *-maybe-save-bookmark. +;; 2009-09-04 Require cl. Allow RET in Emacs 20. Add doc string. +;; *-fix-bookmark-alist-and-save: +;; 2009-09-03 Fix *-fix-bookmark-alist-and-save: +;; Use error, not message. Change value for setcdr. +;; Do not use push with non-var (cl). +;; bookmark-delete: +;; Redefine, to fix vanilla bug: increment count even when batch. +;; *-non-file-name: Change to - no file -. *-bmenu-list: Add arg FILTER-ON. +;; *-bmenu-execute-deletions: Use delete, not remove. +;; Add: *-replace-regexp-in-string. +;; bookmark-set: Fix *-yank-point for region case. Fix bad parens. +;; 2009-09-02 Add: *-non-file-filename. *-fix-bookmark-alist-and-save: Fix msg. +;; Require cl (gensym). *-at-bol/eol' -> line-*-position (for Emacs 20). +;; bookmark-delete: increment *-count if batch arg (fixes vanilla bug). +;; Redefine *-bmenu-execute-deletions, +;; *-bmenu-surreptitiously-rebuild-list. +;; Update current filtered display - do not reload & display all bmks. +;; Add redefinitions of *-bmenu-rename', *-yank-word to fix vanilla bugs: +;; *-bmenu-rename: Do not call *-bmenu-list twice. +;; *-yank-word: Do not insert whitespace. +;; Rename *-last-bookmark-alist-in-use to *-latest-bookmark-alist. +;; 2009-09-01 Fix: Loading of new doc for bookmark-alist (add vacuous defvar). +;; *-bmenu-(list|hide-filenames): start -> end, end -> start. +;; Removed extraneous quote mark that caused problems. +;; Save only if condition-case exits OK. +;; 2009-08-31 Fixes: Test for non-file bmk. Filename for Gnus bmks. +;; Compatibility of bookmark-alist with vanilla Emacs. +;; Require info.el and ffap.el when needed. +;; Add: *-line-number-at-pos (for Emacs 20), +;; *-bmenu-other-window (redefinition). +;; Rename *-propertize-bookmark-list to *-propertize-bmenu-item. +;; 2009-08-30 Fix: Increment *-alist-modification-count when relocate region, +;; and maybe save. +;; Move code adding properties to bookmarks out of *-bmenu-list. +;; mapc -> mapcar. *-bmenu-hide-filenames: Redefine. +;; 2009-08-29 Remove refresh code. +;; 2009-08-27 Added: *-local-directory-bookmark-p, *-local-file-alist-only, +;; *-non-file-alist-only. +;; *-file-bookmark-p: Redefined to exclude bmks with handlers. +;; Renamed fns and faces. +;; 2009-08-25 Fit frame after display menu list. +;; Refresh list when toggle filename visibility. +;; 2009-08-24 Fix: *-bmenu-list for remote files, bookmark-set, *-remote-file-bookmark-p. +;; Ensure arg to file-remote-p is not nil. +;; Recenter region only if it is visible. +;; 2009-08-23 Remove old *-location. *-bmenu-list: Add isw3m. +;; bookmark-set: +;; Redefine for older Emacs. Use a default prompt for gnus, w3m. +;; Use *-name-length-max for title when region is active. +;; Ensure bookmark is on one line. +;; 2009-08-22 Try to handle tramp ftp files. +;; Do not fail if bookmark has empty filename entry. +;; Show region end pos using exchange-point-and-mark. +;; 2009-08-21 Remove all cl stuff (list*, loop, etc.). Add *-remove-if(-not). +;; Remove compile-time require of cl. +;; Add predicates *-(region|gnus|w3m|info|(remote-|local-)file)-bookmark-p. +;; Redefine alist-only functions to optimize and use new preds. +;; 2009-08-20 *--jump-via: Fix to show relocated region before ask whether to save. +;; *-relocate-region: Fix ar-str. Rename a var. Add: *-region-activated-p. +;; Revert chgs. +;; 2009-08-19 Update/fix commentary: bookmark-alist, linkd. +;; *-default-handler, *-handle-region-default: +;; Get bmk record from name only once. +;; *-save-new-region-location: Move t inside progn. +;; 2009-08-16 Use prefix bookmarkp where appropriate. +;; 2009-08-15 Improve comments, doc strings. Rename fns, vars. +;; Add :group with prefix bookmarkp. +;; 2009-08-09 Fix doc strings. +;; 2009-08-08 bookmark-set: Update doc string. Show keys in C-h m. +;; 2009-08-07 *-jump: Fix to jump in same window (thx to Henry Atting). +;; *-at-bol/eol' -> line-*-position. +;; 2009-08-01 bookmark-store: Fix for Emacs 20. +;; 2009-07-27 Ensure we start on an empty w3m buffer. Add: *-w3m-allow-multi-tabs. +;; 2009-07-24 *-bmenu-mode-map: Define some new keys. +;; 2009-07-23 *-bmenu-list: Add path to file in help-echo. +;; 2009-07-19 Fix title underline. Highlight bookmark if root logged with tramp. +;; Add face for sudo. +;; 2009-07-18 Add: filter functions, option for bookmark-bmenu-list. +;; Remove toggle region. +;; *-bmenu-list-only-files-entries: Add prefix arg to show remote. +;; 2009-07-14 Add a forgotten test. +;; 2009-07-13 Fix errors. Give pos in msg even if no search. +;; *-from-bob/eob: Fixed like old strict. +;; Remove *-relocate-region-(method|from-limits). +;; Remove unused code in record fns. Add: *-relocate-region-function. +;; 2009-07-12 Do not pass args to relocation routines. Remove use of flet. +;; Use skip-chars-*ward. Use forward-line, not beginning-of-line. +;; Remove save-excursion around message. Correct typo f(ree var BMK). +;; 2009-07-11 Fix *-relocate-region-strict. Rename fns, adjust defcustom. +;; Save relocated region after pushing mark. Add comments. +;; 2009-07-10 New retrieve fn. Add looking-* fns. +;; 2009-07-08 Simplify record fns. Add doc strings. Add: *-save-relocated-position. +;; Fix: updating when relocate (wrt new record fns), string closing, +;; free vars, parens, names. +;; 2009-07-06 Fix: *-bmenu-list wrt windows, Info colors. +;; 2009-07-04 Rename fns to record, vars, args of retrieve fns. Big changes, fixes. +;; 2009-07-01 Fix comments. *-retrieve-region-strict: improve when out of context. +;; 2009-06-30 Fix: free vars, *-retrieve-region, provide (name). +;; 2009-06-29 Fix: w3m handler, file name for non-file, *-simple-retrieve-position. +;; Add: *-retrieve-region-strict. +;; 2009-06-28 Add: *-retrieve-region-method-is, *-retrieve-region-lax, +;; fns to retrieve regions. +;; Use buffer again, not buffer-name. +;; 2009-06-27 Fix wrong-type error no such file. Renamed faces. Add: *-prop-set. +;; Load gnus at compile time. Protect tramp-file-name-regexp with boundp. +;; 2009-06-25 Fixes for older Emacs compatibility. +;; 2009-06-24 Improve *-default-handler. +;; Add: *-always-save-relocated-position, *-prop-get. +;; 2009-06-23 Use search-regexp, not re-search-regexp. Add Gnus bmks. Add doc. +;; Fix *-bmenu-list. +;; 2009-06-21 Fix: *-default-handler for Info. Improve doc strings, commentary. +;; Fixes to be compatible with Emacs 20-22. +;; Use defcustom for *-list-only-regions-flag. +;; *jump: Put prefix arg in interactive spec. Use buffer-name, not buffer. +;; Remove require of Tramp and inline Tramp fns. +;; Remove tests for display-(color|mouse)-p. +;; w3m-bookmark-(jump|make-record): require w3m. +;; 2009-06-20 Update context strings when relocate. +;; Fix: bookmark-get-*: search from point-min. +;; 2009-06-19 Fix: *-make-record-default, *-toggle-use-only-regions, *-default-handler, +;; bookmarking Dired. +;; Handle 4 positions in *-default-handler. +;; 2009-06-17 Fix: case where some bookmarked text was removed, *-use-region. +;; 2009-06-15 Fix *-region-alist-only, *-get-buffername, *-location, +;; non-file (buffer) bookmarks. +;; Support w3m similar to Info. +;; 2009-06-14 Fix bookmark+version, region relocation. Info support. Error handling. +;; 2009-06-13 Fix: *-list-only-regions, *-region-handler, *-make-record, keymap, faces. +;; Put region & info handling in *-default-handler, not separate handlers. +;; Merge *-make-record-region to *-make-record-default. +;; *-jump now negates *-use-region if prefix arg. Raise error if bad bmk. +;; 2009-06-12 Add: *-get-endposition, *-region-alist-only-names. +;; Add filter to show only region bookmarks. +;; Faces for menu list. Change region color. +;; 2009-06-11 Add: *-region-search-size, *-get-buffername, *-use-region. +;; Redefine *-handle-bookmark, *-jump, to fit bookmark-use-region. +;; Add condtions to bookmark-make-record. Support w3m. Support t command. +;; 2009-06-10 Fix search regexp. Fix region in Info. Save bookmark if region moves. +;; 2009-06-09 Added: bookmark-make-record(-region), bookmark-region-handler. +;; Relocation. +;; 2009/05/25 dadams +;; Added redefinition of bookmark-get-bookmark-record. +;; 2008/10/16 dadams +;; bookmark-jump-other-window: Don't define it for Emacs 23+ (not needed). +;; 2008/04/04 dadams +;; bookmark-jump-other-window: Updated wrt Emacs 22.2. +;; 2007/10/07 dadams +;; Added: bookmark-completing-read, bookmark-delete, bookmark-insert(-location), +;; bookmark-jump, bookmark-relocate, bookmark-rename. +;; bookmark-jump-other-window: Use new bookmark-completing-read. +;; 2007/07/13 dadams +;; Replaced Emacs version tests to reflect Emacs 22 release. +;; 2006/03/08 dadams +;; bookmark-jump-other-window: Handle nil arg. +;; 2005/05/17 dadams +;; Updated to work with Emacs 22.x. +;; 2004/11/20 dadams +;; Refined to deal with Emacs 21 < 21.3.50 (soon to be 22.x) +;; 2004/10/26 dadams +;; Different menu-bar command, depending on Emacs version. +;; 2004/09/21 dadams +;; Only define bookmark-menu-jump-other-window if < Emacs 22. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; You need not load this file. It contains only documentation. + +(provide 'bookmark+-chg) ; Not used. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-chg.el ends here + diff --git a/auto-install/bookmark+-doc.el b/auto-install/bookmark+-doc.el new file mode 100644 index 0000000..37a68a7 --- /dev/null +++ b/auto-install/bookmark+-doc.el @@ -0,0 +1,2591 @@ +;;; bookmark+-doc.el - Documentation for package Bookmark+. +;; +;; Filename: bookmark+-doc.el +;; Description: Documentation for package Bookmark+ +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Created: Fri Sep 15 07:58:41 2000 +;; Last-Updated: Sun Aug 7 14:14:44 2011 (-0700) +;; By: dradams +;; Update #: 13841 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-doc.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, +;; info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Documentation for the Bookmark+ package, which provides +;; extensions to standard library `bookmark.el'. +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other required code (non-bmenu) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only - this file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation includes how to byte-compile and install +;; Bookmark+. It is also available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if put you this +;; library, `bookmark+-doc.el', in your `load-path'.) +;; +;; More description below. +;; +;; +;; ****** NOTE ****** +;; +;; On 2010-06-18, I changed the prefix used by package Bookmark+ +;; from `bookmarkp-' to `bmkp-'. THIS IS AN INCOMPATIBLE CHANGE. +;; I apologize for the inconvenience, but the new prefix is +;; preferable for a number of reasons, including easier +;; distinction from standard `bookmark.el' names. +;; +;; This change means that YOU MUST MANUALLY REPLACE ALL +;; OCCURRENCES of `bookmarkp-' by `bmkp-' in the following +;; places, if you used Bookmark+ prior to this change: +;; +;; 1. In your init file (`~/.emacs') or your `custom-file', if +;; you have one. This is needed if you customized any +;; Bookmark+ features. +;; +;; 2. In your default bookmark file, `bookmark-default-file' +;; (`.emacs.bmk'), and in any other bookmark files you might +;; have. +;; +;; 3. In your `*Bookmark List*' state file, +;; `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el'). +;; +;; 4. In your `*Bookmark List*' commands file, +;; `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'), +;; if you have one. +;; +;; You can do this editing in a virgin Emacs session (`emacs +;; -Q'), that is, without loading Bookmark+. +;; +;; Alternatively, you can do this editing in an Emacs session +;; where Bookmark+ has been loaded, but in that case you must +;; TURN OFF AUTOMATIC SAVING of both your default bookmark file +;; and your `*Bookmark List*' state file. Otherwise, when you +;; quit Emacs your manually edits will be overwritten. +;; +;; To turn off this automatic saving, you can use `M-~' and `M-l' +;; in buffer `*Bookmark List*' (commands +;; `bmkp-toggle-saving-bookmark-file' and +;; `bmkp-toggle-saving-menu-list-state' - they are also in the +;; `Bookmark+' menu). +;; +;; +;; Again, sorry for this inconvenience. + +;;(@> "Index") +;; +;; Index +;; ----- +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Documentation") +;; (@> "Installing Bookmark+") +;; (@> "Bookmark+ Features") +;; (@> "Different Types of Jump Commands") +;; (@> "Bookmark Tags") +;; (@> "Bookmark Tags Can Have Values") +;; (@> "Function, Sequence, and Variable-List Bookmarks") +;; (@> "Editing Bookmarks") +;; (@> "Bookmark-List Views - Saving and Restoring State") +;; (@> "Quitting Saves the Bookmark-List State") +;; (@> "State-Restoring Commands and Bookmarks") +;; (@> "Bookmarking without Visiting the Target") +;; (@> "Bookmarking a File or a URL") +;; (@> "Autofile Bookmarks") +;; (@> "Bookmarking the Marked Files in Dired") +;; (@> "Bookmarking Compilation, Grep, and Occur Hits") +;; (@> "Bookmarking Files That You Cannot Visit") +;; (@> "Opening Bookmarks Using Windows File Associations") +;; (@> "Using Multiple Bookmark Files") +;; (@> "Bookmark-File Bookmarks") +;; (@> "The Bookmark List (Display)") +;; (@> "Tag Commands and Keys") +;; (@> "Tags: Sets of Bookmarks") +;; (@> "Open Dired for the Marked File Bookmarks") +;; (@> "Marking and Unmarking Bookmarks") +;; (@> "Filtering Bookmarks (Hiding and Showing)") +;; (@> "Only Visible Bookmarks Are Affected") +;; (@> "Omitting Bookmarks from Display") +;; (@> "Sorting Bookmarks") +;; (@> "Bookmarks for Specific Files or Buffers") +;; (@> "Cycling, Navigation List, Autonaming") +;; (@> "The Bookmark Navigation List") +;; (@> "Cycling the Navigation List") +;; (@> "Cycling Dynamic Sets of Bookmarks") +;; (@> "Cycling in the Current Buffer") +;; (@> "Autonamed Bookmarks - Easy Come Easy Go") +;; (@> "Highlighting Bookmark Locations") +;; (@> "Defining How to Highlight") +;; (@> "Highlighting On Demand") +;; (@> "Highlighting Automatically") +;; (@> "Using Highlighted Bookmarks") +;; (@> "Use Bookmark+ with Icicles") +;; (@> "If you use Emacs 20 and Also a More Recent Version") +;; (@> "Bookmark Compatibility with Vanilla Emacs (`bookmark.el')") +;; (@> "New Bookmark Structure") + +;;(@* "Documentation") +;; +;; Documentation +;; ------------- +;; +;;(@* "Installing Bookmark+") +;; ** Installing Bookmark+ ** +;; +;; The main Bookmark+ library is `bookmark+.el'. The other required +;; libraries are `bookmark+-mac.el', `bookmark+-bmu.el', +;; `bookmark+-1.el', and `bookmark+-key.el'. If you want to be able +;; to highlight bookmarks then you will also need library +;; `bookmark+-lit.el'. I recommend that you byte-compile all of the +;; libraries, after loading the source files (in particular, load +;; `bookmark+-mac.el'). +;; +;; Put the directory of these libraries in your `load-path' and add +;; this to your init file (~/.emacs): +;; +;; (require 'bookmark+) +;; +;; That will load all of the Bookmark+ libraries. If you do not care +;; about bookmark highlighting then simply do not put +;; `bookmark+-lit.el' in your `load-path'. +;; +;; By default (see option `bmkp-crosshairs-flag'), when you visit a +;; bookmark that has no region it is highlighted temporarily using +;; crosshairs, for easy recognition. (This temporary highlighting is +;; independent of the highlighting provided by `bookmark+-lit.el'.) +;; +;; For this optional crosshairs feature you also need library +;; `crosshairs.el', which in turn requires libraries `col-highlight', +;; `hl-line', `hl-line+', and `vline'. Library `hl-line' comes with +;; vanilla Emacs. The others are available from the Emacs Wiki web +;; site: http://www.emacswiki.org/. You also need Emacs 22 or later +;; for this feature. + +;;(@* "Bookmark+ Features") +;; ** Bookmark+ Features ** +;; +;; Here is an overview of some of the features that Bookmark+ +;; provides. Some of these are detailed in other sections, below. +;; +;; * Richer bookmarks. They record more. They are more accurate. +;; +;; - You can tag bookmarks, a la del.icio.us. In effect, tags +;; define bookmark sets. A bookmark can have any number of +;; tags, and multiple bookmarks can have the same tag. You can +;; sort, show/hide, or mark bookmarks based on their tags. +;; +;; - Bookmark+ tags can be more than just names. They can be +;; full-fledged user-defined attributes, with Emacs-Lisp objects +;; as their values. +;; +;; - You can have multiple bookmarks with the same name. This is +;; particularly useful for autofile bookmarks, which are +;; bookmarks that have the same name as their target files. +;; They give you the effect of using files themselves as +;; bookmarks. In particular, they let you, in effect, tag +;; files. See (@> "Autofile Bookmarks") and +;; (@> "Tagging Files"). +;; +;; (In vanilla Emacs you can also, in theory, have multiple +;; bookmarks with the same name. But you cannot really use them +;; in any practical way. Vanilla Emacs cannot distinguish among +;; them: the most recent one shadows all others with the same +;; name.) +;; +;; - Bookmarks record the number of times you have visited them +;; and the time of the last visit. You can sort, show/hide, or +;; mark bookmarks based on this info. +;; +;; - You can combine bookmarks, to make composite, or sequence, +;; bookmarks. Invoking a sequence bookmark invokes each of its +;; component bookmarks in turn. A component bookmark can itself +;; be a sequence bookmark. +;; +;; - You can bookmark a region of text, not just a position. When +;; you jump to a bookmark that records a region, the region is +;; activated (see option `bmkp-use-region'). (Region activation +;; is not supported for Gnus bookmarks.) +;; +;; - Bookmarks are relocated better than for vanilla Emacs when +;; the contextual text changes. +;; +;; * Additional types of bookmarks. +;; +;; - Autofile bookmarks. You can bookmark a file without visiting +;; it or naming the bookmark. The bookmark name is the same as +;; the file name (non-directory part). You can have multiple +;; such bookmarks with the same name, to bookmark files with the +;; same name but in different directories. +;; +;; - Dired bookmarks. You can bookmark a Dired buffer, recording +;; and restoring its `ls' switches, which files are marked, +;; which subdirectories are inserted, and which (sub)directories +;; are hidden. +;; +;; - Bookmark-list bookmarks. You can bookmark the current state +;; of buffer `*Bookmark List*' - a list of bookmarks. Jumping +;; to such a bookmark restores the recorded sort order, filter, +;; title, and omit list. See (@> "Omitting Bookmarks from Display"). +;; +;; - Bookmark-file bookmarks. You can bookmark a bookmark file. +;; Jumping to such a bookmark loads the bookmarks in the file. +;; See (@> "Bookmark-File Bookmarks"). +;; +;; - Desktop bookmarks. You can bookmark the current Emacs +;; desktop, as defined by library `desktop.el' - use command +;; `bmkp-set-desktop-bookmark' (`C-x p K'). You can "jump" to +;; (that is, restore) a saved desktop. A desktop includes: +;; +;; - Some global variables. To exclude variables normally +;; saved, see option `bmkp-desktop-no-save-vars'. +;; - The current set of buffers and their associated files. +;; For each: its mode, point, mark, & some local variables. +;; +;; - Gnus bookmarks. You can bookmark a Gnus article, a URL, a +;; PDF file (DocView), a UNIX manual page (from the output of +;; Emacs command `man' or `woman'), an image, or a piece of +;; music. +;; +;; - Non-file (buffer) bookmarks. You can bookmark a buffer that +;; is not associated with a file. +;; +;; - Function bookmarks. A bookmark can represent a Lisp +;; function, which is invoked when you "jump" to the bookmark. +;; +;; - Sequence (composite) bookmarks. A bookmark can represent a +;; sequence of other bookmarks. +;; +;; - Lisp variable bookmarks. A bookmark can represent a set of +;; variables and their values. +;; +;; In particular, note that you can use the following kinds of +;; bookmarks to quickly switch among different projects (sets of +;; bookmarks): Dired, bookmark-list, bookmark-file, and desktop +;; bookmarks. +;; +;; * Additional ways to bookmark. +;; +;; - You can bookmark the file or URL named at point (or any other +;; file or URL), without first visiting it. +;; +;; - You can bookmark the targets of the hits in a compilation +;; buffer or an `occur' buffer, without first visiting them. +;; +;; - You can bookmark all of the marked files in Dired at once. +;; +;; * Extensive menus. +;; +;; - In the `*Bookmark List*' display, a `mouse-3' popup menu has +;; actions for the individual bookmark that you point to when +;; you click the mouse. +;; +;; - In the `*Bookmark List*' display, a complete menu-bar menu, +;; `Bookmark+', is available. The same menu is available on +;; `C-mouse-3'. It has submenus `Jump To', `Mark', `Omit', +;; `Show', `Sort', `Tags', `Highlight' (needs library +;; `bookmark+-lit.el), and `Define Command'. +;; +;; - The vanilla `Bookmarks' menu, which is typically a submenu of +;; the menu-bar `Edit' menu, is modified by adding several items +;; from the `Bookmark+' menu, including submenus `Jump To', +;; `Tags', and `Highlight'. +;; +;; * Improvements for the bookmark list. +;; +;; This is buffer `*Bookmark List*', aka the bookmark "menu list" +;; (a misnomer), which you display using `C-x r l'. See +;; (@> "The Bookmark List (Display)"). +;; +;; - The last display state is saved (by default), and is restored +;; the next time you show the list. (Tip: Use the bookmark list +;; as your "Home" page at Emacs startup.) +;; +;; - You can save the current bookmark-list state at any time and +;; return to it later. There are a few ways to do this, +;; including bookmarking the list itself. +;; See (@> "Bookmark-List Views - Saving and Restoring State"). +;; +;; - Marking/unmarking is enhanced. It is similar to Dired's. +;; +;; - You can easily mark or show different classes of bookmarks. +;; +;; - Faces distinguish bookmarks by type. +;; +;; - You can sort bookmarks in many ways. You can easily define +;; your own sort orders, even complex ones. +;; +;; - You can regexp-search (`M-a') or query-replace (`M-q') the +;; targets (destination file or buffers) of the marked +;; bookmarks, in the current bookmark-list sort order. For +;; Emacs 23 and later, you can even search incrementally (`M-s a +;; C-s', or `M-s a C-M-s' for regexp). +;; +;; - You can use `M-d >' to open Dired for just the local file +;; bookmarks that are marked (`>'). +;; +;; - If you use Emacs on Microsoft Windows, you can open bookmarks +;; according to Windows file associations. (You will also need +;; library `w32-browser.el'.) +;; +;; - You can use (lax) completion when you set a bookmark using +;; `bookmark-set' (`C-x r m'), choosing from existing bookmarks +;; for the same buffer. This makes it easy to update a nearby +;; bookmark (e.g. relocate it). With a numeric prefix argument +;; (or if there are no bookmarks for the buffer), you can choose +;; from all bookmarks. +;; +;; - You can edit a bookmark: its name and file name/location, its +;; tags, or its complete defining internal Lisp record. +;; +;; * Multiple bookmark files. +;; +;; - Although vanilla Emacs lets you load different bookmark +;; files, this feature is not well supported, if not +;; contradictory. With Bookmark+ you can easily (a) switch +;; among alternative bookmark files or (b) load multiple files +;; into the same session, accumulating their bookmark +;; definitions. The last file you used is the default, so it is +;; easy to go back and forth between two bookmark files. +;; See (@> "Using Multiple Bookmark Files"). +;; +;; * Type-specific jump commands. +;; +;; - When you want to jump to a bookmark of a specific type +;; (e.g. Dired), you can use a command that offers only such +;; bookmarks as completion candidates. +;; +;; * Dedicated keymaps as prefix keys. +;; +;; - Prefix `C-x p' is used for bookmark keys, in general. The +;; vanilla keys on prefix `C-x r' are still available also, but +;; that prefix is shared with register commands, making it less +;; convenient for bookmarks. Using `C-x p' lets you focus on +;; bookmarks. +;; +;; - Prefix `C-x p c' is for setting various kinds of bookmarks. +;; +;; - Prefixes `C-x j' and `C-x 4 j' (for other-window) are used +;; for bookmark jump commands. Again, a dedicated prefix key +;; helps you focus on one kind of action (jumping). +;; +;; All of these prefix keys correspond to prefix-map variables, so +;; you need not use these particular prefixes. You can bind these +;; maps to any prefix keys you want. These are the maps, together +;; with their predefined bindings. (Note that the keymap for +;; setting bookmarks is bound to a prefix in `bookmark-map'.) +;; +;; `bookmark-map' - `C-x p' +;; `bmkp-set-map' - `C-x p c' +;; `bmkp-jump-map' - `C-x j' +;; `bmkp-jump-other-window-map' - `C-x 4 j' +;; +;; In addition, mode-specific bookmarking commands are bound in +;; some other modes: Occur, Compilation (including Grep), +;; Buffer-menu, Gnus, Info, Man, Woman, W3M, and Dired (if you use +;; Dired+). These keys let you set or jump to bookmarks specific +;; to the modes. +;; +;; * Helpful help. +;; +;; - Information about individual bookmarks. +;; +;; . Anywhere in Emacs, `C-x p ?' (command +;; `bmkp-describe-bookmark') describes any bookmark. With a +;; prefix argument, it shows you the full information that +;; defines it (internal form). +;; +;; . In the bookmark list, `C-h RET' (or `C-h C-RET') describes +;; the bookmark under the cursor. The description is as +;; complete as possible - for example, for an image-file +;; bookmark the complete EXIF image metadata is shown. (This +;; is only for Emacs 22 and later, and only if you have +;; command-line tool `exiftool' installed. See standard Emacs +;; library `image-dired.el' for more information about +;; `exiftool'.) +;; +;; And again, a prefix arg (`C-u C-h RET') means show the full +;; (internal) bookmark information. +;; +;; - General Bookmark+ documentation. +;; +;; . Anywhere in Emacs, `M-x bmkp-bmenu-mode-status-help' shows +;; detailed information about the current state of the +;; bookmark list. Click button `Doc in Commentary' or button +;; `Doc on the Web' to access the complete documentation. +;; +;; (Use button `Customize' to customize all '''Bookmark+''' +;; faces and options.) +;; +;; . In the bookmark list, `?' and `C-h m' are the same as `M-x +;; bmkp-bmenu-mode-status-help'. (`C-h m' in the bookmark +;; list does not show you info about minor modes. If you want +;; that, use `M-x describe-mode'.) +;; +;; . In the `bookmark-plus' group customization buffer (`M-x +;; customize-group bookmark-plus'), click button `Commentary'. +;; +;; . From the Emacs-Wiki Web site, +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; * Jump-destination highlighting. +;; +;; - When you jump to a bookmark, the destination (position) is +;; highlighted temporarily using crosshairs, to make it stand +;; out. Option `bmkp-crosshairs-flag' controls this, and this +;; feature is available only if you also use library +;; `crosshairs.el'. +;; +;; * Visual bookmarks (highlighting). +;; +;; - You can highlight the locations of bookmarks, either +;; automatically or on demand. You control what kind of +;; highlighting, if any, is used for which bookmarks. This +;; feature requires that you have library `bookmark+-lit.el' in +;; your `load-path' (it will then be loaded by `bookmark+.el). +;; +;; * Synergy with Icicles. +;; +;; - Icicles works with Bookmark+ to provide enhanced bookmark +;; jumping (visiting), setting, and help. It gives you a +;; bookmark browser. See (@> "Use Bookmark+ with Icicles") and +;; http://www.emacswiki.org/cgi-bin/wiki/Icicles. + +;;(@* "Different Types of Jump Commands") +;; ** Different Types of Jump Commands ** +;; +;; When you jump to a bookmark, you can use completion to specify the +;; bookmark name. `bookmark-jump' and `bookmark-jump-other-window', +;; bound to `C-x j j' and `C-x 4 j j', are general commands. Their +;; completion candidates include all of your bookmarks. With +;; Bookmark+ you can easily have a large number of bookmarks. +;; +;; To provide more specificity, Bookmark+ provides many different +;; bookmark jump commands. If you want to jump to a bookmark of a +;; specific type, such as Info, you can use a Bookmark+ command that +;; is specific to bookmarks of that type: only those bookmarks are +;; completion candidates. +;; +;; There are thus type-specific commands: `bmkp-dired-jump', +;; `bmkp-info-jump', and so on, bound to `C-x j d', `C-x j i', and so +;; on. There are also commands to jump to bookmarks for the current +;; buffer or for particular buffers or files +;; (see (@> "Bookmarks for Specific Files or Buffers")). +;; +;; All bookmark jump commands are bound to keys that have the prefix +;; `C-x j'. There is an other-window version of most jump commands, +;; and it is bound to the same key as the same-window command, except +;; the prefix is `C-x 4 j', not `C-x j'. For instance, +;; `bmkp-dired-jump-other-window' is bound to `C-x 4 j d'. +;; +;; More precisely, the bookmark jump commands are on the prefix maps +;; `bmkp-jump-map' and `bmkp-jump-other-window-map', which have the +;; default bindings `C-x j' and `C-x 4 j'. You can bind these maps +;; to any keys you like. +;; +;; If you do not remember the different type-specfic bindings, you +;; can use commands `bmkp-jump-to-type' and +;; `bmkp-jump-to-type-other-window' (`C-x j :' and `C-x 4 j :'). +;; They work for any type, prompting you first for the type, then for +;; a bookmark of that type (only). +;; +;; There are several commands for jumping to a bookmark with tags. +;; The completion candidates can be those bookmarks that have all +;; tags in a given set, some tags in a given set, all tags matching a +;; regexp, or some tags matching a regexp. You are prompted for the +;; set of tags or the regexp to match. +;; +;; These commands all have the prefix key `C-x j t'. The suffix key +;; is `*' for "all" and `+' for "some". The regexp-matching commands +;; precede the suffix key with `%'. For example, `C-x j t % +' jumps +;; to a bookmark you choose that has one or more tags that match the +;; regexp you input. +;; +;; There are some type-specific jump commands for bookmarks with +;; tags. The key sequences for these include a key that indicates +;; the bookmark type, after the `t' indicating tags. For example, +;; commands for jumping to a file or directory bookmark having +;; certain tags use the prefix `C-x j t f' (`f' for file). Similar +;; commands for autofile bookmarks have prefix `C-x j t a' (`a' for +;; autofile). +;; +;; For example, `C-x j t f % *' jumps to a file or directory bookmark +;; you choose, where all of its tags match a regexp, and `C-x j t a +;; +' finds a file tagged with at least one of the tags you input. +;; The autofile "jump" commands are really `find-file' commands: they +;; read a file name using `read-file-name' - see (@> "Autofile Bookmarks"). +;; +;; Bookmark names are global. File names are not; that is, the +;; non-directory portion is not. Suppose you have two similar +;; directories with some like-named files, perhaps tagged in similar +;; ways. Imagine image files of your vacations organized in +;; different directories by year. It is sometimes useful to narrow +;; your focus to the file bookmarks in one directory. +;; +;; Commands such as `bmkp-file-this-dir-jump' (`C-x j C-f') offer as +;; completion candidates only bookmarks for files and subdirs in the +;; current directory (`default-directory'). For tags, there are +;; equivalent commands. For example, `C-x j t C-f % *' is the same +;; as `C-x j t f % *', but the destinations are limited to files in +;; the current directory. All of the "this-dir" file jump commands +;; are bound to the same keys as the general file jump commands, but +;; with `C-f' instead of `f'. +;; +;; Remember that Bookmark+ collects lots of commands on only a few +;; predefined prefix keys, primarily as a mnemonic device. Nothing +;; requires you to use the long key sequence `C-x j t f % *' to visit +;; a file that has a given set of tags. It is expected that you will +;; bind short key sequences to commands that you use often. +;; +;; The `C-x j' and `C-x 4 j' bindings are global. In addition, in +;; some modes `j' is bound to the corresponding type-specific jump +;; command. For example, in Info mode, `j' is bound to +;; `bmkp-info-jump'. (Dired is an exception here: `J' is used +;; instead of `j', since `j' is already taken for `dired-goto-file'.) +;; These commands are also added to the mode's menu-bar menu. +;; +;; In Dired mode, `C-j' is bound to a special Dired-specific jump +;; command, `bmkp-dired-this-dir-jump', whose destinations all use +;; the current directory (`default-directory'). The aim of `C-j' is +;; not to change directories but to change to a different set of +;; Dired markings, switches, inserted subdirectories, or hidden +;; subdirectories for the same Dired directory. +;; +;; In addition to the predefined bookmark types, which you can use as +;; described above, you can define a "type"-specific jump command for +;; any set of bookmarks. That is, you can use any specific set of +;; bookmarks as the completion candidates for a new jump command. +;; Such a set is really only a pseudo-type: the actual bookmarks can +;; each be of any type. +;; +;; You could use this feature, for example, to define a jump command +;; for the bookmarks that belong to a given project. +;; +;; One way to define such a command is to first mark the bookmarks +;; that you want to be the completion candidates, then use `M-c' +;; (command `bmkp-bmenu-define-jump-marked-command') in the bookmark +;; list. +;; +;; The `*Bookmark List*' display defines a set of bookmarks, even +;; without markings. So does each bookmark of type bookmark list, +;; that is, a bookmark corresponding to a particular `*Bookmark +;; List*' display state - see +;; (@> "State-Restoring Commands and Bookmarks"). +;; +;; You can capture the set of bookmarks corresponding to a `*Bookmark +;; List*' display for use in navigation, that is, as the current +;; "navigation list". Navigation here includes jumping and cycling +;; - see (@> "Cycling, Navigation List, Autonaming"). +;; +;; To capture in the navigation list the bookmarks corresponding to +;; either the current `*Bookmark List*' display or a bookmark-list +;; bookmark, use `C-x p B', which is bound to command +;; `bmkp-choose-navlist-from-bookmark-list'. To then jump to a +;; bookmark from such a navigation list, use `C-x j N' or `C-x 4 j N' +;; (`bmkp-jump-in-navlist' or `bmkp-jump-in-navlist-other-window'). + +;;(@* "Bookmark Tags") +;; ** Bookmark Tags ** +;; +;; With Bookmark+ you can bookmark many kinds of Emacs object. +;; Bookmarks record locations - that is their primary purpose. They +;; can also record annotations: general free-text descriptions of +;; your choosing. +;; +;; Bookmark+ bookmarks can also be tagged, as a way to organize them, +;; which also means as a way to organize the objects that are +;; bookmarked. +;; +;; By "tagging" and "tag" in this context is meant associating +;; keywords or other text with an object, typically in order to +;; classify or characterize it. Tags are metadata about an object. +;; This notion of tagging is sometimes called "delicious" tagging +;; after the Web site www.delicious.com that popularized it +;; (`http://en.wikipedia.org/wiki/Delicious_(website)'). +;; +;; Be aware that there is another notion of "tag" associated with +;; Emacs: that involving Emacs tags files, which record the locations +;; of function, variable, etc. definitions in source files. There is +;; no relation between the two notions of "tag". +;; +;; A bookmark tag is a string (or a cons whose car is a string - see +;; (@> "Bookmark Tags Can Have Values")). You can add as many tags +;; as you like to any bookmark, and multiple bookmarks can have the +;; same tag(s). In fact, that's the whole idea behind using them for +;; organizing. +;; +;; This feature is unrelated to the fact that bookmarks record +;; locations and are useful for navigating. You can, if you want, +;; use bookmarks to tag files in various ways purely for purposes of +;; organizing them (e.g. into projects), whether or not you ever use +;; the bookmarks as a way to visit them. +;; +;; For example, if you use Dired+ (library `dired+.el'), then you can +;; use `M-b' (`diredp-do-bookmark') in Dired to create an autofile +;; bookmark for each of the marked files in the Dired buffer. Even +;; if you never use those bookmarks for navigating to the files, you +;; can use them with tags to organize the files and thus operate on +;; subsets of them. +;; +;; By default, you create bookmarks without tags and add tags to them +;; later. If you prefer, you can customize option +;; `bmkp-prompt-for-tags-flag' to non-nil so that you are prompted to +;; add tags immediately whenever you set (create) a bookmark. There +;; are also some commands, such as `bmkp-tag-a-file' (`C-x p t + a') +;; and `bmkp-untag-a-file' (`C-x p t - a'), that always prompt for +;; tags to add or remove. (In general, the key `a' is used in key +;; sequences for autofile bookmarks.) +;; +;; When you are prompted to enter a tag, you type some text then hit +;; `RET'. If you want to include a newline character in the tag +;; itself, use `C-q C-j' (`C-j' is the newline character). You can +;; use `C-q' this way to enter any character. If you do use complex +;; strings as tags then you might prefer to simply edit a bookmark's +;; tags in a separate buffer. You can do that using `C-x p t e' (or +;; `T e' in the bookmark-list display). +;; +;; To make tags more useful, Bookmark+ provides *lots* of commands: +;; commands for adding, removing, copying, pasting, and renaming +;; tags; commands for jumping to bookmarks with particular sets of +;; tags; and commands for marking or unmarking (in buffer `*Bookmark +;; List*') bookmarks that are tagged in various ways. +;; +;; Most commands pertaining to tags are by default on prefix key `C-x +;; p t' - use `C-x p t C-h' to see them. In buffer `*Bookmark +;; List*', commands pertaining to tags are on prefix key `T' - use `T +;; C-h' to see them. +;; +;; When combined with other Bookmark+ commands (e.g. search, +;; query-replace) that apply to the marked bookmarks in the +;; `*Bookmark List*' window, you can really do quite a lot using +;; bookmark tags. Use your imagination! +;; +;; See Also: +;; +;; * (@> "Bookmarking the Marked Files in Dired") +;; * (@> "Opening Bookmarks Using Windows File Associations") +;; * (@> "Tag Commands and Keys") + +;;(@* "Bookmark Tags Can Have Values") +;; ** Bookmark Tags Can Have Values ** +;; +;; Bookmark tags are simply names (strings) when you create them. +;; Nearly all of the predefined operations that use tags use these +;; names: sorting, marking, jumping, and so on. But you can in fact +;; add an associated value to any tag. This means that a tag can act +;; just like an object attribute or property: it can be a name/value +;; pair. +;; +;; To add a value to a tag that has none, or to change the current +;; value of a tag, you use command `bmkp-set-tag-value', which is +;; bound to `T v' in the bookmark list and bound to `C-x p t v' +;; globally. You are prompted for the bookmark, the tag, and the new +;; value. +;; +;; A tag value can be a number, symbol, string, list, vector, and so +;; on. It can be as complex as you like. It can be any Emacs-Lisp +;; object that has read syntax, that is, that is readable by the Lisp +;; reader. (Everything that is saved as part of a bookmark must be +;; readable; otherwise, your bookmark file could not be read +;; (loaded).) +;; +;; Because tag values can be pretty much anything, you are pretty +;; much on your own when it comes to making use of them. Bookmark+ +;; does not provide predefined functions for using tag values. In +;; general, tag values are something you will use with home-grown +;; Lisp code for your own purposes. +;; +;; However, you can easily make some interactive use of tag values +;; with little effort. You can, for example, define a predicate that +;; tests whether a bookmark has a tag value that satisfies some +;; property (e.g. is a number greater than 3.14159265358979), and +;; then you can use command `bmkp-bmenu-mark-bookmarks-satisfying' to +;; mark those bookmarks. +;; +;; Tags that have the prefix "bmkp-" are reserved - do not name your +;; own tags using this prefix. +;; +;; Currently, "bmkp-jump" is the only predefined bookmark tag. You +;; can give this tag a value that is a function - it is called +;; whenever the tagged bookmark is visited. Any Lisp-readable +;; function value is allowed: a symbol or a lambda expression. +;; +;; For example, to display `Hello!' when a bookmark is visited you +;; can use this: +;; +;; T v bookmark-jump RET (lambda () (message "Hello!")) +;; +;; The function that is the value of a "bmkp-jump" tag is called just +;; after the the standard hook `bookmark-after-jump-hook' is invoked. +;; You can use this tag to invoke functions that are specific to +;; individual bookmarks; bookmarks can thus have their own, extra +;; jump functions. + +;;(@* "Function, Sequence, and Variable-List Bookmarks") +;; ** Function, Sequence, and Variable-List Bookmarks ** +;; +;; Bookmarks are typically thought of only as recorded locations. +;; Invoking a bookmark, called "jumping" to it, traditionally means +;; just visiting its location. Bookmark+ looks at bookmarks in a +;; more general way than that. A bookmark is a shortcut of some +;; kind - nothing more. +;; +;; A given type of bookmark is defined by its handler function, which +;; really could do anything you like. We've already seen the +;; examples of region bookmarks, which restore the active region, and +;; Dired bookmarks, which restore a set of Dired markings, switches, +;; inserted subdirectories, and hidden (sub)directories. +;; +;; A "function bookmark" simply invokes some function - any function. +;; You can, for instance, define a window or frame configuration and +;; record that as a bookmark. Then jump to the bookmark to switch +;; contexts. (You can also bookmark a desktop and jump to that.) +;; +;; Function bookmarks might not seem too interesting, since we have +;; other ways of invoking functions in Emacs. But the other features +;; of Bookmark+ combine with this feature. You can, for instance, +;; tag such bookmarks. +;; +;; And you can combine them, invoking the functions sequentially. +;; This is just a particular case of using a "sequence bookmark", +;; which simply records a sequence of bookmarks. The bookmarks in a +;; sequence can be of any kind, including other sequence bookmarks. +;; +;; Command `bmkp-make-function-bookmark' creates a function bookmark +;; - you give it a function symbol or a lambda expression. Command +;; `bmkp-bmenu-make-sequence-from-marked' creates a sequence from the +;; marked bookmarks in the bookmark list, in their current order. +;; +;; A variable-list bookmark saves and restores the values of a set of +;; variables. Command `bmkp-set-variable-list-bookmark' prompts you +;; for the variables to include in the list and then sets the +;; bookmark. Command `bmkp-jump-variable-list' (`C-x j v') restores +;; the recorded variable values for the bookmark's buffer. You can +;; also create variable-list bookmarks non-interactively, using +;; function `bmkp-create-variable-list-bookmark'. +;; +;; If you use library `wide-n.el', then you can move among multiple +;; restrictions (narrowings) in a buffer. The restrictions are +;; stored in buffer-local variable `wide-n-restrictions'. Command +;; `bmkp-set-restrictions-bookmark' bookmarks this value for the +;; current buffer. Jumping to such a bookmark restores the saved +;; ring/stack of restrictions. + +;;(@* "Editing Bookmarks") +;; ** Editing Bookmarks ** +;; +;; In vanilla Emacs, you can use `e' in the bookmark list display to +;; edit the annotation associated with a bookmark. And you can use +;; `r' to rename a bookmark. But that is all. There is no easy way +;; to really edit a bookmark. +;; +;; With Bookmark+, in addition to `e' and `r', you can use `E' in the +;; bookmark list, or `C-x p E' anywhere, to edit the bookmark name +;; and the target file name (bookmarked location). You are prompted +;; for the new names. +;; +;; If you use a prefix argument (`C-u E' in the bookmark list or `C-u +;; C-x p E' elsewhere), then you can edit the complete internal +;; bookmark record - the Lisp definition. This is the same internal +;; definition that you see when you use `C-u C-h RET' in the bookmark +;; list. +;; +;; Use `C-c C-c' when you are done editing the bookmark record, to +;; save your changes. The number of visits and the time last visited +;; for the bookmark are updated automatically (unless you use a +;; prefix argument: `C-u C-c C-c'). +;; +;; When you use `C-c C-c', Bookmark+ does a quick check to see if it +;; recognizes the bookmark type as valid. This is not a complete +;; bookmark validity check, but it can help to let you know if you +;; make an editing mistake that renders the bookmark record invalid. +;; +;; In that case, you are asked whether you want to save the changes +;; anyway. Remember that you can use `undo' to reverse particular +;; changes or simply kill the edit buffer to abandon all changes. +;; +;; In a similar way, you can use `T e' in the bookmark list or `C-x p +;; t e' elsewhere, to edit a bookmark's tags. + +;;(@* "Bookmark-List Views - Saving and Restoring State") +;; ** Bookmark-List Views - Saving and Restoring State ** +;; +;; The bookmark list (buffer `*Bookmark List*') provides a view into +;; the set of bookmarks. You can mark, sort, and hide (filter, omit) +;; bookmarks - see (@> "The Bookmark List (Display)"). The state of +;; the displayed bookmark list can thus change. +;; +;; At different times, and in different contexts, different views can +;; be useful. Bookmark+ lets you save the current state of the +;; displayed list and later restore it. There are a couple of +;; different ways to do this. +;; +;; +;;(@* "Quitting Saves the Bookmark-List State") +;; *** Quitting Saves the Bookmark-List State *** +;; +;; If option `bmkp-bmenu-state-file' is non-nil, which it is by +;; default, then Bookmark+ remembers the last state of the bookmark +;; list when you quit it or you quit Emacs, and it restores that +;; state when you show the list again (which could be in the next +;; Emacs session). You can think of this feature as your "Home" page +;; for bookmarks, giving you a stepping stone to the files and +;; directories you use most. +;; +;; If, for example, when you quit the bookmark list you are showing +;; only bookmarks to Info nodes and UNIX manual pages, sorted in a +;; particular way, and with some of them marked for particular +;; processing, then the next time you open the list the same state is +;; restored: the same set of bookmarks is shown, in the same order, +;; with the same markings. +;; +;; You can turn off this automatic bookmark-list display state +;; saving, if you want, by customizing option `bmkp-bmenu-state-file' +;; to nil. And you can toggle this option at any time, using `M-l' +;; in the bookmark list (command +;; `bmkp-toggle-saving-menu-list-state'). In particular, if you want +;; your next visit to the bookmark list to start out with a +;; previously recorded state instead of the current state, just hit +;; `M-l' before quitting the bookmark list. +;; +;; +;;(@* "State-Restoring Commands and Bookmarks") +;; *** State-Restoring Commands and Bookmarks *** +;; +;; In addition to automatically saving/restoring the final +;; bookmark-list display state, you can save this state at any time, +;; any number of times, for later restoration. This gives you the +;; ability to create multiple persistent views of your bookmarks. +;; +;; There are two ways to do this: +;; +;; * Create a bookmark for the `*Bookmark List*' buffer itself: a +;; bookmark-list bookmark. +;; +;; * Define a command that restores the bookmark-list state. +;; +;; When you use `C-x r m' (`bookmark-set') in buffer `*Bookmark +;; List*' to create a bookmark-list bookmark, the current sort order, +;; filter, regexp pattern, title, and omit list are saved as part of +;; the bookmark. (These concepts are described below - see +;; (@> "Bookmark List (Display)").) Jumping to such a bookmark +;; restores all of these. +;; +;; Alternatively, you can define a command that does the same thing, +;; but without creating another bookmark - use `c' +;; (`bmkp-bmenu-define-command') in the bookmark list to do this. +;; You are prompted for the name of the new command. Use the command +;; anytime (including in another Emacs session) to restore the +;; bookmark list. +;; +;; Define any number of such commands for the views you use. The +;; file for saving the definitions (see option +;; `bmkp-bmenu-commands-file') is never overwritten, so you can also +;; add other code to it manually, if you want. The file is read the +;; first time the bookmark list is displayed in a given Emacs +;; session. +;; +;; The state that is saved and restored using a bookmark-list +;; bookmark or a command defined using `c' is only a partial state. +;; The current set of markings and some other information are not +;; saved, in order to save disk space and save/restore time. +;; +;; Sometimes, however, you really want to save the entire +;; bookmark-list state, creating a full snapshot. You can use `C' +;; (`bmkp-bmenu-define-full-snapshot-command') to do that. This +;; defines a command that restores the bookmark list completely. +;; That is the same thing that happens automatically (by default) +;; whenever you quit the bookmark list (or Emacs), but defining +;; snapshot commands lets you have multiple saved states and switch +;; to them at will. +;; +;; Be aware, however, that full-snapshot command definitions can be +;; quite large, since they each contain a copy of the current +;; bookmark list and any accessory lists (hidden and marked bookmarks +;; etc.). +;; +;; Whether you use `c' or `C' to define a state-restoring command or +;; you create a bookmark-list bookmark, you can create a sequence +;; bookmark that combines such bookmark-list restoration with +;; activation of other bookmarks. (To include a state-restoring +;; command in a sequence, you need to first create a function +;; bookmark that uses the command, and then include that bookmark in +;; the sequence.) + +;;(@* "Bookmarking without Visiting the Target") +;; ** Bookmarking without Visiting the Target ** +;; +;; There are several use cases for bookmarking a target without first +;; visiting it: +;; +;; 1. In an Emacs buffer you come across a reference or a link to a +;; file or a URL. You bookmark the target without bothering to +;; visit it first. You do not really care which position in the +;; file is bookmarked. +;; +;; 2. In Dired, you mark certain files and then bookmark all (each) +;; of them, in one operation. +;; +;; 3. As a special case of #1 and #2, you bookmark a file that you +;; cannot visit in Emacs (in the sense of editing it in a buffer) +;; - for example, a music file. "Jumping" to the bookmark +;; performs an operation appropriate to the file - for example, +;; playing music. +;; +;; 4. In a compilation buffer (e.g. `*grep*', `*compile*') or an +;; occur or multi-occur buffer (`*Occur*'), you bookmark one or +;; more of the hits. Such a bookmark takes you to the appropriate +;; position in the target file or buffer. +;; +;; +;;(@* "Bookmarking a File or a URL") +;; *** Bookmarking a File or a URL *** +;; +;; You can use commands `bmkp-file-target-set' and +;; `bmkp-url-target-set', bound by default to `C-x p c f' and `C-x p +;; c u', to bookmark any file or URL. Completion is available, the +;; default file name or URL being determined by the text at point. +;; In addition to the file or URL, you are prompted for the bookmark +;; name. (In general, the keys `f' and `u' are used in key sequences +;; for file and URL bookmarks, respectively.) +;; +;; +;;(@* "Autofile Bookmarks") +;; *** Autofile Bookmarks *** +;; +;; Autofile bookmarking represents a special case of bookmarking a +;; file without visiting it. For an autofile bookmark you need not +;; provide the bookmark name - you specify only the file to bookmark. +;; You can create a new autofile bookmark, or set an existing one, +;; using `bmkp-bookmark-a-file' (aka `bmkp-autofile-set'), which is +;; bound by default to `C-x p c a'. (In general, the key `a' is used +;; in key sequences for autofile bookmarks.) +;; +;; If user option `bmkp-propertize-bookmark-names-flag' is non-nil, +;; which it is by default with Emacs 21 and later, then you can have +;; multiple bookmarks with the same name. This is important for +;; autofile bookmarks because the bookmark name is only the +;; non-directory part of the file name. This Bookmark+ feature lets +;; you have different autofile bookmarks for files of the same name +;; in different directories. +;; +;; Because an autofile bookmark name is the same as its +;; (non-directory) file name, you can define and use file-visiting +;; commands where the file name is read using `read-file-name' with a +;; predicate that tests various bookmark fields. +;; +;; For example, by default (for Emacs 21 or later), you can use `C-x +;; j a' or `C-x 4 j a' to visit an autofile bookmark. These keys are +;; bound to `bmkp-find-file' and `bmkp-find-file-other-window', +;; respectively (which are also known as `bmkp-autofile-jump' and +;; `bmkp-autofile-jump-other-window'). +;; +;; Similarly, you can use prefix key `C-x j t a' followed by the +;; usual tags-command suffix keys (e.g. `+', `% *') to visit a file +;; or directory (that is, jump to an autofile bookmark) that is +;; tagged in a particular way. See (@> "Tagging Files"). All of the +;; autofile "jump" commands are really `find-file' commands: they +;; read a file name using `read-file-name', letting you navigate up +;; and down the file hierarchy. +;; +;; In addition to the single autofile bookmark you can create for a +;; given absolute file location, you can of course create additional +;; bookmarks to the same file, using different bookmark names. Among +;; other things, this lets you tag the same file in different ways. +;; +;; +;;(@* "Bookmarking the Marked Files in Dired") +;; *** Bookmarking the Marked Files in Dired *** +;; +;; If you use Dired+ (library `dired+.el'), then you can bookmark all +;; of the marked files in a Dired buffer at once, as autofiles, even +;; if you normally do not or cannot visit those files in Emacs. +;; These keys are available in Dired: +;; +;; `M-b' - Bookmark each marked file +;; `C-M-S-b' (aka `C-M-B') - Bookmark each marked file in a +;; bookmark-file that you specify +;; `C-M-b' - Bookmark each marked file in a +;; bookmark-file you specify, and create +;; a bookmark for that bookmark-file +;; +;; Each of these commands bookmarks each of the marked files as an +;; autofile. By default, the bookmark file used for the latter two +;; commands is in the current directory. +;; +;; If you use multiple `C-u' as a prefix arg for these commands, then +;; you can bookmark all of the files in Dired, regardless of +;; markings, as follows: +;; +;; `C-u C-u' - Use all files in Dired, except directories +;; `C-u C-u C-u' - Use all files and dirs, except `.' and `..' +;; `C-u C-u C-u C-u' - Use all files and all directories +;; +;; `C-M-b' not only bookmarks each of the marked files, it also +;; creates a bookmark-file bookmark for that set of bookmarks. See +;; (@> "Bookmark-File Bookmarks"), below. +;; +;; You can later "jump" to that bookmark to load its set of +;; bookmarks. If you use `C-u' when you jump to it, then you switch +;; bookmark files, so that `C-x r l' displays only the bookmarks +;; created from the marked files. Without `C-u', jumping to the +;; bookmark-file bookmark simply loads its bookmarks into the current +;; set of bookmarks. +;; +;; +;;(@* "Bookmarking Compilation, Grep, and Occur Hits") +;; *** Bookmarking Compilation, Grep, and Occur Hits *** +;; +;; In a similar way, you can bookmark the file or buffer positions of +;; selected hits in a compilation buffer (including `*grep*') or an +;; `occur' or `multi-occur' buffer. +;; +;; `C-c C-b' in such a buffer bookmarks the target of the hit at +;; point. `C-c C-M-b' bookmarks the target of each hit in the +;; buffer. +;; +;; `C-c C-M-b' in these buffers is thus similar to `M-b' in a Dired +;; buffer. Unlike Dired, however, there is no way to mark such hits. +;; Every hit is bookmarked. +;; +;; Nevertheless, you can get the same effect. Just use `C-x C-q' to +;; make the buffer writable (e.g. temporarily), and then remove any +;; hits that you do not want to bookmark. You can remove hits anyway +;; you like, including by `C-k' and by regexp (`M-x flush-lines' or +;; `M-x keep-lines'). +;; +;; See also: (@> "Autonamed Bookmarks - Easy Come Easy Go"), +;; bookmarking occur hits using autonamed bookmarks. +;; +;; +;;(@* "Bookmarking Files That You Cannot Visit") +;; *** Bookmarking Files That You Cannot Visit *** +;; +;; There are lots of files that you use that you never visit, but +;; that you might like to keep track of or access in other ways +;; besides opening them in Emacs: music files, image files, whatever. +;; +;; You can define a new kind of bookmark for any file type you are +;; interested in, implementing a bookmark handler for it that +;; performs the appropriate action on it when you "jump" to it. That +;; action needs to be expressible using an Emacs function, but it +;; need not have anything to do with visiting the file in Emacs. +;; +;; When you bookmark a target file that Emacs recognizes as an image +;; or sound file, an appropriate handler is used automatically. +;; +;; After you create individual bookmarks for, say, music or image +;; files, you can use `P B' in the bookmark-list display to show only +;; those bookmarks, and then use `C-x r m' to bookmark that state of +;; the bookmark-list. +;; +;; That bookmark-list bookmark in effect becomes a music playlist or +;; an image library or slideshow. Jump to it anytime you want to +;; listen to that set of music pieces or view those images. And you +;; can use `C-x p B' and then `C-x p next' to cycle among the music +;; pieces or images (slideshow). (See (@> "Cycling the Navigation List").) +;; +;; Together with the use of bookmark tags, this gives you a handy way +;; to organize and access objects of any kind. See (@> "Bookmark Tags"). +;; +;; You use option `bmkp-default-handler-associations' to control +;; which operation (bookmark handler) to use for which file type. +;; This is a set of associations (an alist) with key a regexp +;; matching a file name and with value a Lisp sexp that evaluates to +;; either a shell command (a string) or an Emacs function (a symbol +;; or lambda form). +;; +;; The handler for the bookmark created invokes the shell command or +;; the Emacs function with the file name as argument. +;; +;; Here is an example option value: +;; +;; (("\\.ps$" . "gsview32.exe") +;; ("\\.html?$" . browse-url)) +;; +;; This value creates a bookmark that, when you jump to it, invokes +;; shell command `gsview32.exe' on the bookmark's target file if it +;; is PostScript (extension `.ps'), and invokes Emacs Lisp function +;; `browse-url' on the file if it is HTML (extension `.htm' or +;; `.html'). +;; +;; The default value of `bmkp-default-handler-associations' is taken +;; from the value of option `dired-guess-shell-alist-user' (from +;; Dired X). +;; +;; If no matching file association is found in +;; `bmkp-default-handler-associations', and if option +;; `bmkp-guess-default-handler-for-file-flag' is non-nil (it is nil +;; by default), then Bookmark+ will guess a shell command to use in +;; the handler. It does this by matching the file name against +;; `dired-guess-shell-alist-default' (also from Dired X). In Emacs +;; 23+, if it finds no shell command that way then it guesses one +;; based on mailcap entries. +;; +;; +;;(@* "Opening Bookmarks Using Windows File Associations") +;; *** Opening Bookmarks Using Windows File Associations *** +;; +;; If you use Microsoft Windows there is no need to define new +;; bookmark types and handlers, if the action you want is the one +;; that Windows associates with the file. You already have a set of +;; file/program associations, and Bookmark+ recognizes these as +;; alternative handlers. +;; +;; You can thus take advantage of Windows file associations to open +;; bookmarks for files of all kinds. To do this, you also need +;; library `w32-browser.el'. In the bookmark list, the following +;; keys are bound to commands that open bookmarks using the +;; associated Windows `Open' applications: +;; +;; `M-RET' - `bmkp-bmenu-w32-open' +;; `M-mouse-2' - `bmkp-bmenu-w32-open-with-mouse' +;; `M-o' - `bmkp-bmenu-w32-open-select' +;; +;; Windows file associations are always available to you, in addition +;; to any other file associations that you define using +;; `bmkp-default-handler-associations' (see +;; (@> "Bookmarking Files That You Cannot Visit")). +;; +;; You can thus have two different programs associated with the same +;; kind of file. Your MS Windows file association for PostScript +;; might, for example, use Adobe Distiller to create a PDF file from +;; PostScript, while your `bmkp-default-handler-associations' +;; association for PostScript might use GhostView to display it +;; directly. + +;;(@* "Tagging Files") +;; ** Tagging Files ** +;; +;; Section (@> "Tags: Sets of Bookmarks") covers bookmark tags, which +;; are persistent metadata that you define to help you organize +;; bookmarks into meaningful sets. +;; +;; Section (@> "Autofile Bookmarks") describes autofile bookmarks, +;; which, in effect, let you treat files generally as if they were +;; bookmarks. You can choose a file to visit or act on by its name +;; and location, but also by its bookmark metadata. +;; +;; In particular, you can tag a file - that is, specify tags for its +;; associated autofile bookmark. And you can then visit a file that +;; has a given set of tags. Bookmark+ provides file commands that +;; automatically create and manipulate autofile bookmarks, that is, +;; bookmarks that have the same name as the files they tag. +;; +;; Command `bmkp-tag-a-file' (aka `bmkp-autofile-add-tags'), bound by +;; default to `C-x p t + a', prompts you for a set of tags and a file +;; location, and creates or sets the corresponding autofile bookmark. +;; Command `bmkp-untag-a-file' (aka `bmkp-autofile-remove-tags'), +;; bound by default to `C-x p t - a', similarly lets you remove +;; specified tags from a file. +;; +;; If you also use library Icicles, then you can act on multiple +;; files during the same command (a "multi-command"). You can thus +;; all at once tag a set of files the same way, or act on a set of +;; files that are tagged similarly. +;; +;; If you also use library Dired+ (`dired+.el') then you can use +;; `C-+' to add tags to the marked files and `C--' to remove tags +;; from them. You can use `C-M-+' and `C-M--' to do the same thing +;; for the current file. You can also use items from the Dired menus +;; to do these things. +;; +;; Bookmark+ provides two kinds of command for visiting files +;; associated with bookmarks that have tags. +;; +;; The first kind uses bookmarks directly: you choose a bookmark +;; name, not a file name, but the candidates are only file and +;; directory bookmarks. These commands have the prefix `bmkp-file-'. +;; +;; As a special case, commands with the prefix `bmkp-file-this-dir-' +;; limit the choices to bookmarks for files and subdirectories of the +;; current directory. By default, the commands across all +;; directories are on prefix key `C-x 4 j t f' and those for the +;; current directory only are on prefix key `C-x j t C-f'. See +;; (@> "Different Types of Jump Commands") for more about these +;; commands. +;; +;; The second kind of command is for visiting tagged files, that is, +;; autofile bookmarks. These commands are available only for Emacs +;; 21 and later (because they use `read-file-name' with a PREDICATE +;; argument, not available for Emacs 20). The candidates are file +;; names, not bookmark names. These commands have the prefix +;; `bmkp-find-file-', and by default they are on the prefix key `C-x +;; j t a'. (In general, the keys `f' and `a' are used in key +;; sequences for file and autofile bookmarks, respectively.) +;; +;; For example: +;; +;; `C-x j t f % +' is `bmkp-file-some-tags-regexp-jump' +;; `C-x j t C-f % +' is `bmkp-file-this-dir-some-tags-regexp-jump' +;; `C-x j t a % +' is `bmkp-find-file-some-tags-regexp' +;; +;; * The first of these visits any file bookmark that has at least +;; one tag among the tags you specify, and you choose among +;; bookmark names. The files can be in any directories. +;; +;; * The second is similar to the first, but only bookmarks for files +;; in the current directory are candidates. +;; +;; * The third is similar regarding tags, but it uses +;; `read-file-name', so you can browse among all files, up and down +;; the file hierarchy. The candidates are file names, not bookmark +;; names. +;; +;; If you use Icicles, there are similar sets of commands, but they +;; all let you act on multiple files at the same time +;; (multi-commands). For example, you can delete (or byte-compile +;; or...) a set of files according to their tags. +;; +;; Remember that you can create multiple bookmarks for the same file, +;; providing them with different sets of tags. (Only one of the +;; bookmarks is the autofile bookmark.) +;; +;; You can also use multiple bookmark files (the files that record +;; bookmarks). Different projects can thus have different tags for +;; the same sets of files, even using just autofile bookmarks. See +;; (@> "Using Multiple Bookmark Files"). +;; +;; A file bookmark can have any number of tags, and multiple file +;; bookmarks can have the same tag. You can sort, show/hide, or mark +;; files based on their tags. + +;;(@* "Using Multiple Bookmark Files") +;; ** Using Multiple Bookmark Files ** +;; +;; Bookmark-list views (see +;; (@> "Bookmark-List Views - Saving and Restoring State")) provide +;; one way to switch among various sets of bookmarks that you use. +;; But that feature affects only the bookmarks that you see displayed +;; in buffer `*Bookmark List*', not the actual set of available +;; bookmarks. +;; +;; The bookmarks available to you are defined in a bookmark file. By +;; default, they are stored in the file named by option +;; `bookmark-default-file' (`~/.emacs.bmk', by default). You do not +;; need to load or save this file manually; Emacs does that for you +;; automatically. +;; +;; But you can also have extra, alternative bookmark files if you +;; want, and at any time you can change the bookmark file that is +;; current. To do that, use `C-x p L' (uppercase `L'), which is +;; bound to command `bmkp-switch-bookmark-file'. +;; +;; Having multiple bookmark files gives you an added degree of +;; flexibility. You can see which file is current at any time by +;; using `?' or `C-h m' in the buffer `*Bookmark List*' (or anywhere +;; else using `M-x bmkp-bmenu-mode-status-help'). +;; +;; When you switch to another bookmark file, the default file to +;; switch to is the last bookmark file you used (in the same +;; session). So it is trivial to toggle back and forth between two +;; bookmark files: just hit `RET' to accept the default. +;; +;; When bookmarks are saved automatically, or when you save them +;; using `bookmark-save' (`S' in the bookmark list or `C-x p s' +;; globally) and you don't use a prefix argument, they are saved in +;; the current bookmark file. +;; +;; You can turn off the automatic saving of the current bookmark +;; file, by customizing option `bookmark-save-flag' to nil. And you +;; can toggle this option at any time, using `M-~' in the bookmark +;; list (command `bmkp-toggle-saving-bookmark-file'). +;; +;; Besides using multiple bookmark files as *alternatives*, you can +;; combine them, using them as component bookmark subsets (like +;; modules). To do that, use command `C-x p l' (lowercase `l'), +;; which is bound to `bookmark-load', and do not use a prefix +;; argument. (Using a prefix argument with `C-x p l' is the same as +;; using `C-x p L': it switches bookmark files.) Here too the +;; default is the name of the last bookmark file that you used. +;; +;; To create additional bookmark files, to use either as alternatives +;; or as components, you can either copy an existing bookmark file or +;; use `bmkp-empty-file' (`C-x p 0') to create a new, empty bookmark +;; file. If you use `C-x p 0' with an existing bookmark file, then +;; its bookmarks are all deleted - it is emptied. +;; +;; Instead of simply copying a bookmark file, you can use +;; `bookmark-save' with a prefix argument, or use `bookmark-write' +;; (bound to `C-x p w'), to save the currently defined bookmarks to a +;; different bookmark file. +;; +;; However a bookmark file was created, you can switch to it and then +;; add or delete bookmarks selectively, to change its content. +;; Remember that you can delete bookmarks from the current set using +;; command `bookmark-delete' (`C-x p d') or, in the bookmark list, +;; using `d' plus `x' or marking then `D'. +;; +;; +;;(@* "Bookmark-File Bookmarks") +;; *** Bookmark-File Bookmarks *** +;; +;; A bookmark file is an excellent, persistent way to represent a set +;; of bookmarks. In particular, it can represent a project or a +;; project component. Switch among bookmark files to access +;; different projects. Load project components as you need them. +;; +;; You can load a bookmark file using `C-x p L' (switch) or `C-x p l' +;; (accumulate). As a convenience, you can also load a bookmark file +;; by jumping to a bookmark-file bookmark. +;; +;; You use command `bmkp-set-bookmark-file-bookmark', bound to `C-x p +;; x', to create a bookmark-file bookmark. Jumping to such a +;; bookmark just loads the bookmark file that it records. With `C-u' +;; (e.g. `C-u C-x p j project-foo'), jumping switches bookmark files. +;; Without `C-u' it accumulates the loaded bookmarks. +;; +;; A bookmark-file bookmark is not only an added convenience. You +;; can also use it in combination with other Bookmark+ features, such +;; as tagging. +;; +;; As a shortcut, in Dired (if you use library Dired+), `C-M-b' +;; creates a bookmark-file bookmark. The bookmark file that it +;; records contains autofile bookmarks to each of the files that was +;; marked in Dired at the time it was created. Jumping to that +;; bookmark-file bookmark makes those (marked) files available as +;; bookmarks. See also +;; (@> "Use Dired to Bookmark Files without Visiting Them"). +;; +;; Note that the bookmark file in which a bookmark-file bookmark is +;; recorded is not the same as the bookmark file recorded in that +;; bookmark. +;; +;; For example, when you use `C-M-b' in Dired, the bookmark-file for +;; the marked files is, by default, file `.emacs.bmk' in the Dired +;; directory. So if you are in directory `/foo/bar' the default +;; bookmark file for the marked files is `/foo/bar/.emacs.bmk'. But +;; the new bookmark-file bookmark created is recorded in the current +;; bookmark file, whatever that might be (e.g. `~/.emacs.bmk'). + +;;(@* "The Bookmark List (Display)") +;; ** The Bookmark List (Display) ** +;; +;; Bookmark+ enhances the bookmark list (aka the bookmark "menu +;; list", a misnomer) that is displayed in buffer `*Bookmark List*' +;; when you use `C-x r l' (command `bookmark-bmenu-list'). +;; +;; Bookmarks are highlighted to indicate their type. You can mark and +;; unmark bookmarks, show or hide bookmarks of particular types, and +;; more. Bookmarks that have tags are marked with a `t'. Bookmarks +;; that have an annotation are marked with an `a' (not with a `*' as +;; in vanilla `bookmark.el'). Bookmarks that have bookmark-highlight +;; override settings (see (@> "Defining How to Highlight")) are +;; marked with a one-character pink background. +;; +;; Use `?' or `C-h m' in buffer `*Bookmark List*' for more +;; information about the bookmark list, including the following: +;; +;; * The current status of sorting, filtering, and marking. +;; +;; * A legend for the faces used for different bookmark types. +;; +;; +;;(@* "Tag Commands and Keys") +;; *** Tag Commands and Keys *** +;; +;; There are lots of tag-related bookmark commands, and most are +;; bound to keys in buffer `*Bookmark List*' as well as to other keys +;; outside it. How can you keep the commands straight or remember +;; their keys? +;; +;; In the bookmark list display, tags-command keys begin with prefix +;; key `T'. Elsewhere, they begin with prefix key `C-x p t' (or `C-x +;; j t', for jump commands - see (@> "Different Types of Jump Commands")). +;; +;; `C-h m' (or `?') is your friend, of course. Likewise `T C-h' and +;; `C-x p t C-h'. Beyond that, the tag-related keys that are more +;; than two keystrokes are organized as follows: +;; +;; They all have the prefix key `T'. +;; +;; `m' means mark +;; `u' means unmark +;; `>' stands for the marked bookmarks +;; `*' means AND (set intersection; all) +;; `+' means OR (set union; some/any) +;; `~' means NOT (set complement) +;; +;; The key `T m *', for instance, marks (`m') the bookmarks that are +;; tagged with all (`*' = AND) of a given set of tags. It prompts you +;; for one or more tags that the bookmarks must have, and it marks +;; all bookmarks that have all of the tags you enter. +;; +;; The key `T u ~ +' unmarks (`u') the bookmarks that do not (`~') +;; have any (`+' = OR) of the tags you specify. And so on. +;; +;; The marking and unmarking commands for tags compare the tags a +;; bookmark has with tags that you enter. Any bookmarks that have no +;; tags are ignored - they are neither marked nor unmarked by these +;; commands. +;; +;; `+' and `-' can also mean add and remove tags, respectively, and +;; `>' stands for the marked bookmarks. So `T > +' adds (`+') one or +;; more tags to each of the marked (`>') bookmarks. +;; +;; In general, the tag-related commands let you enter a set of tags, +;; one at a time. Thus, instead of having a command that adds a +;; single tag to the current bookmark, you have a command that adds +;; any number of tags to it. To add just a single tag, hit `RET' +;; twice: once to enter the tag, and once again to indicate that it +;; is the last (i.e., the only) one. +;; +;; If you just hit `RET' immediately, specifying an empty set of +;; tags, then each of the commands does something appropriate. For +;; `T m *', for instance, an empty list of tags means to mark (only) +;; the bookmarks that have any tags at all. +;; +;; Finally, for the marking/unmarking tags commands, a prefix +;; argument flips the sense of the command, in this way: +;; +;; "some are" -> "some are NOT", i.e., "not all are" (and vice versa) +;; "all are" -> "all are NOT", i.e., "none are" (and vice versa) +;; +;; In other words: +;; +;; C-u T m * = T m ~ + (all are NOT = not some are) +;; C-u T m ~ + = T m * (not some are NOT = all are) +;; C-u T m + = T m ~ * (some are NOT = not all are) +;; C-u T m ~ * = T m + (not all are NOT = some are) +;; +;; You'll figure it out ;-). +;; +;; Other important keys pertaining to tags (the keys in parentheses +;; work in any buffer, not just buffer `*Bookmark List*'): +;; +;; * `C-h RET' (`C-x p ?') shows you the tags that belong to a +;; bookmark. With a prefix argument it shows you the full internal +;; form of the tags, that is, the name+value pairs. +;; +;; * `T e' (`C-x p t e') lets you edit a bookmark's tags. +;; +;; * `T l' (`C-x p t l') lists all tags currently known to Emacs +;; (across all bookmarks). +;; +;; * `T +' (`C-x p t + b') adds some tags to a bookmark. +;; `T -' (`C-x p t - b') removes some tags from a bookmark. +;; `T 0' (`C-x p t 0) removes all tags from a bookmark. +;; `T d' (`C-x p t d) removes a set of tags from all bookmarks. +;; +;; In the bookmark list display you can also sort bookmarks according +;; to how they are tagged, even in complex ways. See +;; (@> "Sorting Bookmarks"). +;; +;; +;;(@* "Tags: Sets of Bookmarks") +;; *** Tags: Sets of Bookmarks *** +;; +;; The best way to think about tags is as names of sets. All +;; bookmarks tagged `blue' constitute the bookmark set named `blue'. +;; +;; The bookmarks visible in the bookmark list at any time also +;; constitute an unnamed set. Likewise, the marked bookmarks and the +;; unmarked bookmarks are unnamed sets. Bookmark+ is all about +;; helping you act on sets of Emacs objects. Bookmarks are named, +;; persistent pointers to objects such as files and file sets. +;; Bookmark tags are named, persistent sets of bookmarks (and hence +;; of their target objects). +;; +;; The marking commands make it easy to combine sets as unions or +;; intersections. And you can give the result a name for quick +;; access later, just by adding a new tag. in other words, do the +;; set-definition work only once, and name the result. +;; +;; How would you tag as `Java IDE Projects' the bookmarks that are +;; already tagged both `Java' and `ide'? +;; +;; 1. `T m * Java RET ide RET RET', to mark them. +;; 2. `T > + Java IDE Projects RET RET, to tag them. +;; +;; How would you sort your bookmarks, to show all those tagged both +;; `blue' and `moon' first? +;; +;; 1. `T m * blue RET moon RET RET', to mark them. +;; 2. `s >' to sort the marked bookmarks first +;; (see (@> "Sorting Bookmarks"), below). +;; +;; If you wanted to show only the marked bookmarks, instead of +;; sorting to put them first in the list, you would use `>' +;; instead of `s >'. +;; +;; How would you query-replace the set of files that are tagged with +;; any of the tags `alpha', `beta', and `gamma', but are not tagged +;; `blue' or `moon'? +;; +;; 1. `F S', to show only the file bookmarks. +;; 2. `T m + alpha RET beta RET gamma RET RET', to mark the +;; bookmarks that have at least one of those tags. +;; 3. `T u + blue RET moon RET RET', to unmark those that are +;; tagged `blue' or `moon'. +;; 4. `M-q' to query-replace the marked files. +;; +;; If that were a set of files that you used often, then you would +;; name the set by giving the files a new tag. +;; +;; The point is that bookmarks, and bookmark tags in particular, let +;; you define and manipulate sets of Emacs objects. It doesn't +;; matter how you define such a set: regexp matching (marking, +;; filtering), by object type, by tag combinations... Sets need not +;; be named to act on them, but you can provide them with persistent +;; names (tags) to avoid redefining them over and over. Manipulation +;; of bookmarked objects includes visiting, searching, and +;; query-replacing. And you can define your own bookmark types +;; (using bookmark handlers) and associated manipulations. +;; +;; +;;(@* "Open Dired for the Marked File Bookmarks") +;; *** Open Dired for the Marked File Bookmarks *** +;; +;; You've seen that the bookmark list has many features that are +;; similar to Dired features. But Dired is specialized for files and +;; directories, and it has many more features for manipulating them. +;; The bookmark list is not intended to replace Dired. +;; +;; You can, however, use the bookmark list to take advantage of +;; arbitrary Dired features for file and directory bookmarks. +;; Command `bmkp-bmenu-dired-marked' (`M-d >') weds Bookmark+'s +;; set-defining and set-manipulating features (tagging, marking, +;; filtering etc.) to Dired's file-manipulating features. +;; +;; `M-d >' opens a Dired buffer that is specialized for just the +;; files and directories whose bookmarks are marked in the bookmark +;; list. (Other marked bookmarks are ignored by the command.) The +;; files and directories can be located anywhere; they need not be in +;; the same directory. They are listed in Dired using absolute file +;; names. +;; +;; (In Emacs versions prior to release 23.2, only local files and +;; directories can be handled, due to Emacs bug #5478. In such +;; versions, remote-file bookmarks are ignored by `M-d >'.) +;; +;; This Bookmark+ feature makes sets of files and directories +;; immediately amenable to all of the operations provided by Dired. +;; +;; It is particularly useful in conjunction with tags. Use bookmark +;; tags and marks to define a possibly complex set of file and +;; directory bookmarks. Then hit `M-d >' to list them in a Dired +;; buffer. Then use any Dired commands you want to act on any of +;; them. +;; +;; For example, to compress bookmarked files that are tagged with +;; both `blue' and `moon': +;; +;; 1. Mark them using `T m * blue RET moon RET RET'. +;; 2. Open Dired for them using `M-d >'. +;; 3. Mark them in Dired, then compress them using `Z'. +;; +;; Since tags are persistent, Bookmark+ gives you a good way to +;; define an arbitrary set of files as a project and then open them +;; in Dired at any time to operate on them. +;; +;; If you use Dired+ (library `dired+.el'), then a similar feature is +;; available for the marked files and directories: You can use +;; `C-M-*' in Dired to open a separate Dired buffer for them only. +;; You can of course then bookmark that resulting Dired buffer, if +;; you like. +;; +;; If you use Icicles, then whenever you use a command that reads a +;; file (or directory) name, you can use `M-|' during file-name +;; completion to open Dired on the currently matching set of file +;; names. That is, this is the same kind of special Dired buffer +;; that is provided for file and directory bookmarks by `M-d >' in +;; the bookmark list. +;; +;; +;;(@* "Marking and Unmarking Bookmarks") +;; *** Marking and Unmarking Bookmarks *** +;; +;; Bookmark+ enhances the marking and unmarking of bookmarks in the +;; bookmark list in several ways. These enhancements are similar to +;; features offered by Dired and Dired-X. You can use: +;; +;; * `% m' to mark the bookmarks that match a regexp. The entire +;; line in the bookmark list is checked for a match, that is, both +;; the bookmark name and the file name, if shown. +;; +;; * `M-DEL' (or `U') to unmark all bookmarks, or all that are marked +;; `>', or all that are flagged `D' for deletion. +;; +;; * `t' to toggle (swap) the marked and unmarked bookmarks: those +;; that are marked become unmarked, and vice versa. +;; +;; * `>' to show only the marked bookmarks or `<' to show only the +;; unmarked bookmarks. Repeat to show them all again. +;; +;; * `F M', `I M' etc. to mark only the file bookmarks, Info +;; bookmarks etc. (The first key here is the same as the +;; corresponding filter key, e.g. `F' for files - see next topic.) +;; +;; +;;(@* "Filtering Bookmarks (Hiding and Showing)") +;; *** Filtering Bookmarks (Hiding and Showing) *** +;; +;; You can hide and show different sets of bookmarks in the bookmark +;; list. There are commands to show only bookmarks of a particular +;; type - e.g. `I S' to show only Info bookmarks. These are, in +;; effect, shortcuts for first marking those bookmarks and then +;; showing only the marked bookmarks (and then unmarking). For +;; example, `F S' is a shortcut for `F M >' (and then `U RET'). +;; +;; You can also filter to show only the bookmarks that match a given +;; regexp. There are two ways to do this: +;; +;; * Use `P B' (for "pattern", "bookmark") and type a regexp. The +;; bookmarks are filtered incrementally, as you type. Only the +;; bookmark name is matched (not the file name). Hit any +;; non-inserting key, such as `RET', to finish defining the +;; pattern. +;; +;; Similarly, hit `P F' for bookmarks whose file names match a +;; regexp, `P A' for bookmarks whose annotations match a regexp, +;; and `P T' for bookmarks with one or more tags that match a +;; regexp. See (@> "Bookmark Tags"), above, for information about +;; tags. +;; +;; * Just as in Dired, use `% m' to mark the bookmarks that match a +;; regexp. Then use `>' to show only the marked bookmarks. See +;; (@> "Marking and Unmarking Bookmarks"), above. +;; +;; This method has the advantage that you can show the complement, +;; the bookmarks that do *not* match the regexp, by using `<' +;; instead of `>'. It also has the advantage that matching checks +;; the combination of bookmark name and file name (use `M-t' to +;; toggle showing file names). +;; +;; +;;(@* "Only Visible Bookmarks Are Affected") +;; *** Only Visible Bookmarks Are Affected *** +;; +;; Commands that operate on the current bookmark or on the marked or +;; the unmarked bookmarks act only on bookmarks that are displayed +;; (not hidden). This includes the commands that mark or unmark +;; bookmarks. This means that you can easily define any given set of +;; bookmarks. +;; +;; For example: +;; +;; Use `F S' to show only bookmarks associated with files. +;; Use `% m' to mark those that match a particular regexp. +;; Use `R S' to show only bookmarks that have regions. +;; Use `m' to mark some of those region bookmarks individually. +;; Use `.' to show all bookmarks. +;; Use `t' to swap marked and unmarked (so unmarked are now marked) +;; Use `D' to delete all of the marked bookmarks (after confirming) +;; +;; Together, steps 1-7 delete all file bookmarks that match the +;; regexp and all region bookmarks that you selectively marked. +;; +;; +;;(@* "Omitting Bookmarks from Display") +;; *** Omitting Bookmarks from Display *** +;; +;; In sections (@> "Marking and Unmarking Bookmarks") and +;; (@> "Filtering Bookmarks (Hiding and Showing)") you learned how +;; to hide and show bookmarks in the bookmark list. This section is +;; about a different kind of hiding, called "omitting". +;; +;; Omitted bookmarks are not shown in the bookmark list, no matter +;; what filtering is used. The only way to show omitted bookmarks is +;; to show all of them and only them, using `O S', which is bound to +;; command `bmkp-bmenu-show-only-omitted'. +;; +;; Omitted bookmarks are still available even if they are not shown, +;; and you can still jump to them (e.g. using `C-x r b'). You just +;; don't see them in the bookmark list. And that's the reason for +;; this feature: to hide those bookmarks that you don't care to see. +;; +;; One use for this feature is to hide the component bookmarks that +;; make up a sequence bookmark (see +;; (@> "Function, Sequence, and Variable-List Bookmarks")). The +;; default behavior when you create a sequence bookmark is in fact to +;; omit its component bookmarks from the displayed list. +;; +;; You can omit any bookmarks by marking them and then using `O >' +;; (`bmkp-bmenu-omit/unomit-marked'). If you are looking at the +;; omitted bookmarks (after using `O S'), then `O >' un-omits the +;; bookmarks marked there. Think of two complementary spaces: the +;; normal bookmark list and the omitted bookmark list. When you use +;; `O >', the marked bookmarks that are currently shown are moved to +;; the opposite space. +;; +;; You can un-omit all of the omitted bookmarks at once, using `O U' +;; (`bmkp-unomit-all'). You can also call this command from outside +;; the bookmark-list display. +;; +;; +;;(@* "Sorting Bookmarks") +;; *** Sorting Bookmarks *** +;; +;; Filtering hides certain kinds of bookmarks. Sometimes, you want +;; to see bookmarks of various kinds, but you want them to be grouped +;; or sorted in different ways, for easy recognition, comparison, and +;; access. +;; +;; Bookmarks shown in the bookmark list are sorted using the current +;; value of option `bmkp-sort-comparer'. (If that is nil, they are +;; unsorted, which means they appear in reverse chronological order +;; of their creation.) +;; +;; You can use `s s'... (repeat hitting the `s' key) to cycle among +;; the various sort orders possible, updating the display +;; accordingly. By default, you cycle among all available sort +;; orders, but you can shorten the cycling list by customizing option +;; `bmkp-sort-orders-for-cycling-alist'. +;; +;; You can also change directly to one of the main sort orders +;; (without cycling) using `s n', `s f n', etc. - use `C-h m' or `?' +;; for more info. +;; +;; You can reverse the current sort direction (ascending/descending) +;; using `s r'. Also, repeating any of the main sort-order commands +;; (e.g. `s n') cycles among that order, the reverse, and unsorted. +;; +;; For a complex sort, which involves composing several sorting +;; conditions, you can also use `s C-r' to reverse the order of +;; bookmark sorting groups or the order within each group (depending +;; on whether `s r' is also used). Be aware that this can be a bit +;; unintuitive. If it does not do what you expect or want, or if it +;; confuses you, then don't use it ;-). (`s C-r' has no noticeable +;; effect on simple sorting.) +;; +;; Remember that you can combine sorting with filtering different +;; sets of bookmarks - bookmarks of different kinds (e.g. Info) or +;; bookmarks that are marked or unmarked. +;; +;; Finally, you can easily define your own sorting commands and sort +;; orders. See macro `bmkp-define-sort-command' and the +;; documentation for option `bmkp-sort-comparer'. (Bookmark+ uses +;; option `bmkp-sort-comparer'; it *ignores* vanilla Emacs option +;; `bookmark-sort-flag'.) +;; +;; Of particular note is that you can interactively define commands +;; that sort by a given list of tags - you use keys `T s' (command +;; `bmkp-define-tags-sort-command') to do that. You are prompted for +;; the tags to sort by. Bookmarks are sorted first according to +;; whether they are tagged with the first tag, then the second tag, +;; and so on. Otherwise, sorting is by bookmark name. +;; +;; The tags you specify are used, in order, in the name of the new +;; command. For example, if you enter tags `alpha', `beta', and +;; `gamma', in that order, then the sorting command created is +;; `bmkp-bmenu-sort-alpha-beta-gamma'. The new command is saved in +;; your bookmark commands file (`bmkp-bmenu-commands-file'). +;; +;; Note that because you can add a new tag to all bookmarks that have +;; some given set of tags, you can use that single (new) tag to +;; represent the entire tag set. Sorting by that tag is then the +;; same as sorting by the tag set. You can of course use overlapping +;; sets in the composite sort command. You can, for example, sort +;; first according to tag `tag1', which represents the set of tags +;; `alpha', `beta', `gamma', `delta', and then sort according to tag +;; `tag2', which represents the set of tags `beta', `delta'. +;; +;; See also (@> "Use Bookmark+ with Icicles") - the same technique is +;; used in Icicles for sorting bookmarks as completion candidates. + +;;(@* "Bookmarks for Specific Files or Buffers") +;; ** Bookmarks for Specific Files or Buffers ** +;; +;; A bookmark typically records a position or a region in a file or +;; buffer. Sometimes you are interested in accessing or examining +;; only the bookmarks for particular files or buffers. For example, +;; you might want to navigate among the bookmarks for the current +;; buffer. Or you might want to search the regions recorded in the +;; bookmarks for a particular file. +;; +;; For a bookmark, the recorded file and buffer name differ in that +;; the file name is absolute. Bookmarks for buffer `foo.el' include +;; all files named `foo.el', whereas bookmarks for file +;; `/project1/lisp/foo.el' include only the files in that one +;; directory. +;; +;; Bookmark+ provides some commands to handle these use cases. The +;; keys bound to these commands use `f' for file and `b' for buffer. +;; In the bookmark-list display, the following keys affect the +;; bookmarks for a particular file or buffer whose name you provide +;; (with completion). +;; +;; * `= f M' and `= b M' - mark +;; * `= f S' and `= b S' - show (only) +;; +;; For navigation, the following keys jump to bookmarks for +;; particular files or buffers. (Use `C-x 4 j' for other-window.) +;; +;; * `C-x j .' - current buffer +;; * `C-x j = f' and `C-x j = b' - specified file(s) or buffer(s) +;; +;; For the `=' keys you are prompted for one or more file names or +;; buffer names. +;; +;; Finally, because the bookmarks in the current buffer can be of +;; particular interest, `C-x p .' opens the bookmark-list display for +;; only those bookmarks. + +;;(@* "Cycling, Navigation List, Autonaming") +;; ** "Cycling, Navigation List, Autonaming" ** +;; +;; Using completion to jump to a bookmark is handy. It lets you +;; choose a bookmark by its name and gives you direct ("random") +;; access to it. +;; +;; Sometimes, however, you don't much care what a bookmark is named, +;; and you want to cycle quickly among relatively few, related +;; bookmarks. Obviously, the smaller the number of bookmarks in the +;; set, the more convenient cycling is - with many bookmarks cycling +;; can become tedious. +;; +;; An analogy: If your TV has lots of channels, then the channel +;; up/down buttons on the remote control are not so useful: 32, 33, +;; 34, ..., 79! Unless the channel you want happens to be near the +;; current channel, cycling around a huge ring of channels is not the +;; way to go. And just because your TV receives lots of channels +;; does not mean that you watch them all or that you are equally +;; interested in them all. +;; +;; Some TV remote controls have a feature that mitigates this +;; problem. You can define a ring of favorite channels, and there +;; are two additional buttons that let you cycle forward and backward +;; around the ring, skipping the channels in between. The number of +;; favorites is relatively small, so cycling is not tedious. More +;; importantly, all of the channels in the ring are ones you are +;; interested in. +;; +;; Extend this idea to allow for assigning different sets of channels +;; to the favorites ring at different times: choose the ring you want +;; at any time: sports, music, films, science, art, history, and so +;; on. Add the possibility of sorting those sets in various ways, to +;; further facilitate cycling, and you arrive at the idea behind the +;; Bookmark+ navigation list. +;; +;; Another analogy is a music playlist. You can use Bookmark+ as a +;; simple music player by bookmarking music files. Similarly, you +;; can use Bookmark+ to create slideshows by bookmarking image files. +;; Cycle the navigation list to move through the slide show. +;; +;; If you use MS Windows, you can take advantage of your existing +;; file associations to open your bookmarks using the appropriate +;; program - no need to define a new bookmark type and handler. See +;; (@> "Bookmarking Files That You Cannot Visit"). +;; +;; Note: The default value of option `bmkp-use-region' is `t', not +;; `cycling-too', which means that when you cycle to a bookmark its +;; recorded region (if any) is not activated. This is probably what +;; you want most of the time. Cycling is a repetitive action, and if +;; you cycle to a bookmark with no recorded region then an already +;; active region is just extended. Customize the value to +;; `cycling-too' if you prefer that behavior. +;; +;; +;;(@* "The Bookmark Navigation List") +;; *** "The Bookmark Navigation List *** +;; +;; Bookmark+ is all about letting you define and manipulate sets of +;; bookmarks. When a bookmark set can be used for cycling (as well +;; as jumping) it is called the "navigation list" or "navlist", for +;; short. +;; +;; In other words, Bookmark+ lets you cycle among any set of +;; bookmarks. When you cycle, it is the set that currently +;; constitutes the navigation list that is cycled. +;; +;; Here are two ways to define the navigation list: +;; +;; * `C-x p :' (`bmkp-choose-navlist-of-type') - As the set of all +;; bookmarks of a certain type (`any' or empty input means use all +;; bookmarks). +;; +;; * `C-x p B' (`bmkp-choose-navlist-from-bookmark-list') - As the +;; set of all bookmarks corresponding to a bookmark-list bookmark, +;; that is the bookmarks corresponding to a given recorded state of +;; buffer `*Bookmark List*'. +;; +;; Each of these lets you choose a set of bookmarks using completion. +;; For `C-x p :' you are prompted for the type of bookmark +;; (e.g. `dired'). +;; +;; For `C-x p B' you are prompted for the name of a bookmark-list +;; bookmark that you created. But you can also choose the candidate +;; `CURRENT *Bookmark List*' to capture the bookmarks that would be +;; shown currently in the `*Bookmark List*' (even if the list is not +;; displayed now). See (@> "State-Restoring Commands and Bookmarks") +;; for information about bookmark-list bookmarks. +;; +;; If you do not define the navigation list before you start cycling, +;; it is automatically defined as follows: +;; +;; * If you cycle using a current-buffer cycling key such as `C-x p +;; down' (see (@> "Cycling in the Current Buffer")) then the +;; bookmarks in the current buffer are used as the navlist. +;; +;; * Otherwise, a snapshot is taken of the the bookmarks currently in +;; the global bookmark list (the value of variable +;; `bookmark-alist') as the navlist. +;; +;; However the navlist is defined, it is important to remember this: +;; it is a static snapshot of some set of bookmarks taken at a given +;; time. Subsequent changes to the bookmark list that was copied are +;; not reflected in the navlist. If you add a bookmark it will not +;; be among those cycled. But see also +;; (@> "Cycling Dynamic Sets of Bookmarks") for how to cycle dynamic +;; sets. +;; +;; You can update the navlist at any time by taking another snapshot +;; of the same bookmark list you used for the last snapshot. For the +;; global bookmark list just use `C-x p : RET'. (You can of course +;; bind that action to a shorter key sequence if you like.) +;; +;; Besides cycling among the bookmarks of the navlist (see next), +;; once you have defined the navigation list you can use `C-x j N' or +;; `C-x 4 j N' to jump to its bookmarks, as mentioned in section +;; (@> "Different Types of Jump Commands"). +;; +;; Note that just because you might have used `C-x p B' to define the +;; navlist using a particular bookmark-list bookmark or the current +;; `*Bookmark List*' state, that does not mean that the `*Bookmark +;; List*' state at any given time necessarily reflects the navlist +;; bookmarks. The two are separate. You can, however, open the +;; `*Bookmark List*' so that it reflects the bookmarks currently in +;; the navigation list, using `C-x p N' (`bmkp-navlist-bmenu-list'). +;; +;; +;;(@* "Cycling the Navigation List") +;; *** "Cycling the Navigation List" *** +;; +;; So you choose a navigation list. How do you then cycle among its +;; bookmarks? +;; +;; Commands `bmkp-next-bookmark' and `bmkp-previous-bookmark' cycle +;; to the next and previous bookmark in the navigation list (with +;; wraparound). +;; +;; You can bind these to any keys you like, but it's obviously better +;; to choose keys that are easily repeatable (e.g. by holding them +;; pressed). Some people who are used to using MS Visual Studio +;; might want to use `f2' and `S-f2' to cycle forward and backward. +;; +;; Bookmark+ does not define such key bindings, but you can. What it +;; does is define repeatable keys on the `bookmark-map' keymap, which +;; has prefix `C-x p'. To do this it binds similar commands that can +;; be repeated by simply repeating the key-sequence suffix. These +;; are the keys: +;; +;; Forward: `C-x p f', `C-x p C-f', `C-x p right' +;; Backward: `C-x p b', `C-x p C-b', `C-x p left' +;; +;; (If you use an Emacs version prior to Emacs 22, you cannot use +;; this prefix-key repeatable feature.) +;; +;; In addition, if you use MS Windows then you can invoke the Windows +;; `Open' action on each bookmark when you cycle, to act on its file +;; using the program associated with the file type. This lets you +;; play music or display images in a playlist or slideshow fashion. +;; These are the keys to do that: +;; +;; Forward: `C-x p next' (PageDown key) +;; Backward: `C-x p prior' (PageUp key) +;; +;; Being able to cycle among an arbitrary set of bookmarks is the +;; most important feature of Bookmark+ cycling. The other important +;; feature is that if the navigation list is defined by `*Bookmark +;; List*' then the characteristics of that bookmark display are +;; respected for navigation. Only the bookmarks visible in +;; `*Bookmark List*' are included, and the `*Bookmark List*' sort +;; order is used for navigation. +;; +;; So you can not only choose any set of bookmarks for cycling at any +;; given time, you can also cycle among them in an order you choose. +;; For example, if in the bookmark list display (`C-x r l') you show +;; only those file bookmarks that belong to a given project, and you +;; have them sorted by file size, then cycling moves among only those +;; files, in file-size order. +;; +;; This is a main reason you will want to define bookmark-list +;; bookmarks, which record a specific set of bookmarks and their sort +;; order: to later choose given sets in different contexts for +;; cycling. +;; +;; +;;(@* "Cycling Dynamic Sets of Bookmarks") +;; *** "Cycling Dynamic Sets of Bookmarks" *** +;; +;; The fact that the navlist is a static snapshot is a useful +;; feature, but sometimes you might want to cycle among a particular +;; dynamic set of bookmarks, that is, to have cycling take changes to +;; the bookmark set into account automatically. For that, Bookmark+ +;; provides separate cycling commands for most types of bookmark. +;; +;; By default, these different kinds of cycling commands are not +;; bound to any keys, with the exception of the commands for cycling +;; the current buffer. This exception includes cycling all bookmarks +;; for the current buffer (see (@> "Cycling in the Current Buffer") +;; and cycling only the highlighted bookmarks for the current buffer +;; (see (@> "Using Highlighted Bookmarks")). Keys `C-x p down' and +;; `C-x p C-down' are defined for these two kinds of current-buffer +;; cycling. +;; +;; If you often want to cycle among the bookmarks of some other +;; particular kind (e.g. only the autonamed bookmarks), then you can +;; bind the relevant commands +;; (e.g. `bmkp-next-autonamed-bookmark-repeat', +;; `bmkp-previous-autonamed-bookmark-repeat') to handy keys. +;; Otherwise, you can just use the cycling commands without binding +;; them. +;; +;; +;;(@* "Cycling in the Current Buffer") +;; *** "Cycling in the Current Buffer" *** +;; +;; You can navigate the bookmarks in the current buffer by cycling as +;; well as jumping. It is convenient to have dedicated keys for +;; this, separate from the keys to cycle the navigation list. The +;; following keys are defined, corresponding to commands +;; `bmkp-next-bookmark-this-buffer-repeat' and +;; `bmkp-previous-bookmark-this-buffer-repeat': +;; +;; Next: `C-x p n', `C-x p C-n', `C-x p down' +;; Previous: `C-x p p', `C-x p C-p', `C-x p up' +;; +;; Starting with Emacs 23.3 (Emacs fix for bug #6256), you can also +;; use the mouse wheel to cycle: `C-x p' then just rotate the wheel. +;; +;; Again, you can bind any keys you want to these commands +;; (e.g. `f2', `S-f2'). If you do not need to use a prefix key, then +;; bind commands `bmkp-next-bookmark-this-buffer' and +;; `bmkp-previous-bookmark-this-buffer' (no -repeat). +;; +;; You can also cycle among just the highlighted bookmarks in the +;; current buffer - see (@> "Using Highlighted Bookmarks"). +;; +;; Current-buffer cycling (all bookmarks or only the highlighted +;; ones) is dynamic: the current set of bookmarks is cycled, not a +;; static snapshot. The navlist is automatically updated to the +;; current dynamic set each time you cycle. This is different from +;; the usual cycling of the navlist, where it is taken as a static +;; snapshot - see (@> "The Bookmark Navigation List"). +;; +;; By default, you cycle the current-buffer bookmarks in order of +;; their positions in the buffer, top to bottom. If you want a +;; different order, you can customize option +;; `bmkp-this-buffer-cycle-sort-comparer'. +;; +;; Alternatively, you can use `C-x p .' to display the `*Bookmark +;; List*' with only the current buffer's bookmarks, sort them there, +;; and then use `C-x p B' to set the navigation list to `CURRENT +;; *Bookmark List*'. In that case, you use the navlist cycling keys +;; (e.g. `C-x p f', not `C-x p n'), and the cycled set is a static +;; snapshot. +;; +;; +;;(@* "Autonamed Bookmarks - Easy Come Easy Go") +;; *** "Autonamed Bookmarks - Easy Come Easy Go" *** +;; +;; Sometimes it is convenient to quickly create and delete bookmarks +;; whose names you don't really care about. That is the purpose of +;; "autonamed" bookmarks. An autonamed bookmark has a simple name +;; provided automatically, and it does not record any region +;; information - it records only a position. It is nevertheless an +;; ordinary, persistent bookmark. +;; +;; `C-x p RET' creates a bookmark at point without prompting you for +;; the name. It is named using the current buffer name preceded by +;; the position in the buffer. For example, the autonamed bookmark +;; in buffer `foo.el' at position 58356 is `000058356 foo.el'. +;; +;; (You can customize the format of autonamed bookmarks using options +;; `bmkp-autoname-bookmark-function' and `bmkp-autoname-format'.) +;; +;; When you jump to any bookmark, the actual destination can differ +;; from the recorded position, because the buffer text might have +;; changed. In that case, the position you jump to has been +;; automatically relocated using the recorded bookmark context (some +;; buffer text surrounding the original position). +;; +;; If option `bmkp-save-new-location-flag' is non-nil then, after +;; jumping, the recorded position of the bookmark is automatically +;; updated to reflect the new location jumped to. This is true for +;; any bookmark. +;; +;; In the case of an autonamed bookmark, the bookmark name reflects +;; the recorded position when you create it. And when you jump to +;; it, both the name and the recorded position are updated to reflect +;; the jump destination. So jumping to an autonamed bookmark keeps +;; its persistent record in sync with the buffer location. +;; +;; You will thus notice that the names of autonamed bookmarks can +;; change as you visit them (e.g. cycling). The bookmarks are +;; automatically repositioned following their recorded contexts, and +;; their names reflect that repositioning. +;; +;; `C-x p RET' is `bmkp-toggle-autonamed-bookmark-set/delete', and it +;; does double duty. If an autonamed bookmark is under the cursor, +;; then `C-x p RET' deletes it. Easy creation, easy deletion. +;; Because of this toggle behavior, there is at most one autonamed +;; bookmark at any given buffer position. +;; +;; `C-x p RET' has a third use: With a prefix argument, it prompts +;; you to confirm the deletion of *all* autonamed bookmarks for the +;; current buffer. +;; +;; (You can also use `C-x p delete' (that's the `delete' key), bound +;; to `bmkp-delete-bookmarks', to delete individual bookmarks under +;; the cursor or all bookmarks in the buffer. This is not limited to +;; autonamed bookmarks.) +;; +;; In addition to `C-x p RET', you can create autonamed bookmarks +;; using these commands: +;; +;; * `bmkp-set-autonamed-bookmark-at-line' - At a line beginning +;; * `bmkp-set-autonamed-regexp-buffer' - At buffer matches +;; * `bmkp-set-autonamed-regexp-region' - At region matches +;; * `bmkp-occur-create-autonamed-bookmarks' (`C-c b' in *Occur*) - +;; At `occur' and `multi-occur' hits +;; +;; Autonamed bookmarks are normal bookmarks. In particular, they are +;; persisted. If you do not care to persist them, you can ensure +;; that they are automatically deleted by adding +;; `bmkp-delete-autonamed-this-buffer-no-confirm' to +;; `kill-buffer-hook' and `bmkp-delete-autonamed-no-confirm' to +;; `kill-emacs-hook': +;; +;; (add-hook 'kill-buffer-hook +;; 'bmkp-delete-autonamed-this-buffer-no-confirm) +;; (add-hook 'kill-emacs-hook +;; 'bmkp-delete-autonamed-no-confirm) + +;;(@* "Highlighting Bookmark Locations") +;; ** Highlighting Bookmark Locations ** +;; +;; You can highlight the location (destination) of a bookmark. For +;; this feature you need library `bookmark+-lit.el' in addition to +;; the other Bookmark+ libraries. +;; +;; You might never want to highlight a bookmark, or you might want to +;; highlight most or even all bookmarks, or your use of highlighting +;; might fall somewhere between. It depends on what kind of +;; bookmarks you have and how you use them. Bookmark+ lets you +;; choose. By default, no bookmarks are highlighted. + +;;(@* "Defining How to Highlight") +;; ** Defining How to Highlight ** +;; +;; By default, autonamed bookmarks are highlighted differently from +;; non-autonamed bookmarks. Bookmark highlighting uses a style and a +;; face. The available styles are these: +;; +;; * Line - Highlight line of the bookmark position +;; * Position - Highlight character at bookmark position +;; * Line Beginning - Highlight first character on line +;; * Left Fringe - Highlight only the left fringe +;; * Left Fringe + Line - Highlight the left fringe and the line +;; * Right Fringe - Highlight only the right fringe +;; * Right Fringe + Line - Highlight the right fringe and the line +;; +;; You can customize the default styles and faces to use for +;; autonamed and non-autonamed bookmarks. You can also customize the +;; fringe bitmaps to use. +;; +;; * `bmkp-light-autonamed' (face) +;; * `bmkp-light-non-autonamed' (face) +;; * `bmkp-light-style-autonamed' (option) +;; * `bmkp-light-style-non-autonamed' (option) +;; * `bmkp-light-left-fringe-bitmap' (option) +;; * `bmkp-light-right-fringe-bitmap' (option) +;; +;; In addition to the default highlighting, which you can customize, +;; you can set the highlighting for individual bookmarks and +;; particular sets of bookmarks (overriding their default +;; highlighting). These individual settings are saved as part of the +;; bookmarks themselves. +;; +;; In the bookmark list (buffer `*Bookmark List*'): +;; +;; * `H +' - Set the highlighting for this line's bookmark +;; * `H > +' - Set the highlighting for the marked bookmarks +;; +;; Globally, you can use `M-x bmkp-set-lighting-for-bookmark' to set +;; the highlighting for a given bookmark. +;; +;; Each of these commands prompts you (with completion) for the style +;; and face to set, as well as for a condition that controls whether +;; to highlight. Each of these is optional - just hit `RET' (empty +;; input) at its prompt to skip setting it. +;; +;; The condition is an Emacs-Lisp sexp that is evaluated whenever an +;; attempt is made to highlight the bookmark. Any resulting value +;; except `:no-light' highlights the bookmark. The sexp can refer to +;; the variables `this-bookmark' and `this-bookmark-name', whose +;; values are the bookmark to be highlighted and its name, +;; respectively. +;; +;; So, for example, if you wanted to be prompted each time before +;; highlighting a certain bookmark you might set its highlighting +;; condition to a sexp such as this: +;; +;; (or (y-or-n-p (format "Highlight `%s' " this-bookmark-name)) +;; :no-light) +;; +;; If you hit `n' at the prompt then `:no-light' is returned and the +;; bookmark is not highlighted. +;; +;; In the bookmark-list display, a pink-background, one-character +;; highlight is used next to each bookmark that has a highlight +;; override wrt the default. You can see what that override setting +;; is by using `C-u C-h RET' - look for the `lighting' entry in the +;; bookmark definition. +;; +;; +;;(@* "Highlighting On Demand") +;; *** Highlighting On Demand *** +;; +;; You can highlight or unhighlight a bookmark or a set of bookmarks +;; on demand. +;; +;; In the bookmark list (buffer `*Bookmark List*'): +;; +;; * `H H', `H U' - Highlight, unhighlight this line's bookmark +;; +;; * `H > H', `H > U' - Highlight, unhighlight the marked bookmarks +;; +;; Globally: +;; +;; * `C-x p C-u' - Unhighlight a highlighted bookmark at +;; point or on the same line (in that order) +;; +;; * `C-x p h', `C-x p u' - Highlight, unhighlight a bookmark in the +;; current buffer (with completion). +;; +;; * `C-x p H', `C-x p U' - Highlight, unhighlight bookmarks: +;; +;; With plain `C-u': all bookmarks +;; +;; With `C-u C-u': navigation-list bookmarks +;; +;; Otherwise, bookmarks in current buffer: +;; No prefix arg: all bookmarks +;; Prefix arg > 0: autonamed bookmarks +;; < 0: non-autonamed bookmarks +;; +;; The default bookmark for `C-x p u' is the same bookmark that is +;; unhighlighted by `C-x p C-u': a (highlighted) bookmark at point +;; (preferably) or on the same line. The latter key binding just +;; saves you having to hit `RET' to pick the default. +;; +;; When you use `C-x p h', you can use a prefix argument to override +;; both the default highlighting and any highlighting that is +;; recorded for the bookmark itself. You are prompted for the style +;; or face to use: +;; +;; * Negative arg: prompted for style +;; * Non-negative arg: prompted for face +;; * Plain `C-u': prompted for style and face +;; +;; +;;(@* "Highlighting Automatically") +;; *** Highlighting Automatically *** +;; +;; You can also highlight automatically, whenever you set (create) a +;; bookmark or jump to one. This is controlled by these options: +;; +;; * `bmkp-auto-light-when-set' +;; * `bmkp-auto-light-when-jump' +;; +;; You can choose any of these values for either option: +;; +;; * Autonamed bookmark +;; * Non-autonamed bookmark +;; * Any bookmark +;; * Autonamed bookmarks in buffer +;; * Non-autonamed bookmarks in buffer +;; * All bookmarks in buffer +;; * None (no automatic highlighting) - the default +;; +;; The first three values highlight only the bookmark being set or +;; jumped to. + +;;(@* "Using Highlighted Bookmarks") +;; ** Using Highlighted Bookmarks ** +;; +;; Once you have highlighted bookmarks, what can you do with them? +;; Obviously, the highlighting can help you distinguish and find +;; bookmarks visually. But highlighting also serves as yet another +;; way to define sets: the highlighted vs unhighlighted bookmarks. +;; +;; Any command that operates on a set of bookmarks can be applied to +;; one or the other of these two sets. Bookmark+ defines only a few +;; such operations, but you can easily define others. +;; +;; In addition to such specific commands, you can also apply general +;; operations to the highlighted or unhighlighted bookmarks, using +;; the bookmark-list display (`*Bookmark List*'). `H S' shows only +;; the bookmarks that are currently highlighted, and `H M' marks +;; them. You can then perform any of the available bookmark-list +;; operations on them. +;; +;; Globally, you can use these keys: +;; +;; * `C-x p =' - List the bookmarks that are +;; highlighted at point. With a +;; prefix arg, show the full data. +;; +;; * `C-x j h', `C-x 4 j h' - Jump to a highlighted bookmark. +;; Only highlighted bookmarks are +;; completion candidates. +;; +;; * `C-x p C-down', `C-x p C-up' - Cycle to the next and previous +;; highlighted bookmark. + +;;(@* "Use Bookmark+ with Icicles") +;; ** Use Bookmark+ with Icicles ** +;; +;; Icicles (http://www.emacswiki.org/cgi-bin/wiki/Icicles) enhances +;; your use of Bookmark+ in several ways. +;; +;; When jumping to a bookmark, you can narrow the completion +;; candidates to bookmarks of a particular type (e.g. Info, using +;; `C-M-i'; remote, using `C-M-@'; region, using `C-M-r'). You can +;; narrow again (and again), to another bookmark type, to get the +;; intersection (e.g. remote Info bookmarks that define a region). +;; +;; You can also narrow against different bookmark-name patterns +;; (e.g. regexps) - so-called "progressive completion". And take the +;; complement (e.g., bookmarks whose names do not match +;; `foo.*2010.*bar'). (This is not special to bookmarks; it is +;; standard Icicles practice.) +;; +;; In Icicle mode, several of the Bookmark+ keys are remapped to +;; corresponding Icicles multi-commands. A bookmark jump key thus +;; becomes a bookmarks browser. For example, `C-x j d' browses among +;; any number of Dired bookmarks. +;; +;; A single key can set a bookmark or visit bookmarks. This key is +;; whatever command `bookmark-set' would normally be bound to - +;; e.g. `C-x r m'. A prefix arg controls what it does. If negative +;; (`M--'), jump to (browse) bookmarks. Otherwise, set a bookmark, +;; as follows: +;; +;; * Numeric prefix arg (non-negative): No prompt. Use the buffer +;; name plus the text of the region (if active) or the current line +;; as the bookmark name. Quickest way to set a bookmark. +;; +;; * No prefix arg (as usual): Prompt for bookmark name. But if the +;; region is active, use the buffer name plus the region text as +;; the default name. +;; +;; * Plain `C-u' (as usual): Prompt for name; no bookmark overwrite. +;; +;; During completion of a bookmark name, many features of the +;; bookmark-list display (see (@> "The Bookmark List (Display)")) are +;; available on the fly. Buffer `*Completions*' acts like a dynamic +;; version of `*Bookmark List*': +;; +;; * Candidates are highlighted in the `*Completions*' window +;; according to their bookmark type. +;; +;; * Candidates are Icicles multi-completions with up to three parts: +;; +;; a. the bookmark name +;; b. the bookmark file or buffer name +;; c. any tags +;; +;; You can match any or all of the parts. For example, you can +;; match bookmarks that have tags by typing this regexp: +;; +;; C-M-j . * C-M-j S-TAB +;; +;; Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string', +;; the string used to join the parts. This regexp says, "match the +;; completion candidates that have all three parts (two join +;; strings)", hence some tags. +;; +;; You can turn off the use of multi-completion candidates for +;; subsequent commands, so only bookmark names are used, by hitting +;; `M-m' in the minibuffer. You can think of this as similar to +;; using `M-t' in `*Bookmark List*' to toggle showing file names. +;; You can make not showing files and tags the default behavior by +;; customizing `icicle-show-multi-completion-flag'. +;; +;; * You can sort completion candidates using the Bookmark+ sort +;; orders. Use `C-,' to cycle among sort orders. +;; +;; * You can use Icicles candidate-help keys (`C-M-RET', `C-M-down', +;; etc.) to get detailed information about the current bookmark +;; candidate. `C-u C-M-RET' shows the complete, internal info +;; defining the bookmark. And without doing anything, summary info +;; about the current candidate is available in the mode line of +;; buffer `*Completions*'. +;; +;; * You can use Icicles candidate-action keys (`C-RET', `C-mouse-2', +;; `C-down', etc.) to visit any number of bookmarks. For example, +;; holding down `C-down' cycles among the current bookmark +;; candidates, opening each in turn. +;; +;; * You can use `S-delete' to delete the bookmark named by the +;; current candidate. You can delete any number of bookmarks this +;; way, during a single invocation of a bookmark command. +;; +;; * You can define Icicles sets of bookmarks, persistent or not, and +;; act on their members in various ways. + +;;(@* "If you use Emacs 20 and Also a More Recent Version") +;; ** If you use Emacs 20 and Also a More Recent Version ** +;; +;; This section pertains to you *ONLY* in the rare case that you use +;; both Emacs 20 and a later version, and you share the same bookmark +;; file or bookmark-list display state file between the versions. +;; +;; By default starting with Emacs 21, Bookmark+ uses bookmark names +;; that are propertized with the full bookmark information, in order +;; to let you use multiple bookmarks with the same bookmark name. An +;; example of this is having two autofile bookmarks for files with +;; the same name in different directories. +;; +;; When you save the bookmark list (`bookmark-alist') or a full +;; snapshot of the bookmark-list display state (e.g., using command +;; `bmkp-bmenu-define-full-snapshot-command'), these propertized +;; names are saved. +;; +;; However, Emacs 20 cannot read a serialized version of the bookmark +;; list if it has such propertized names (the property value is a +;; list that contains the propertized string, hence circular) - it +;; will raise a read error. To avoid this, when Bookmark+ in Emacs +;; 20 saves bookmarks or a full snapshot of the bookmark-list display +;; state, it unpropertizes the bookmark names. You can read the +;; resulting files in any Emacs version. +;; +;; But if you happen to save bookmark information using a later +;; version of Emacs (e.g. Emacs 23) and you then read that recorded +;; state using Emacs 20, the read will fail. If this happens then +;; you will need to re-save the affected file(s) using a later Emacs +;; version. In the later Emacs version: +;; +;; 1. `M-x set-variable bmkp-propertize-bookmark-names-flag nil', +;; to stop using propertized bookmark names. +;; 2. `C-x r l' to display the bookmark list. +;; 3. `g', to refresh the display. +;; 4. `S' to save the bookmark list. +;; 5. `M-x bmkp-save-menu-list-state', to save the display state. +;; +;; You will now be able to use your bookmarks in Emacs 20 again. +;; +;; If you will often be going back and forth between Emacs 20 and a +;; later version, then you may prefer to simply turn off the use of +;; propertized bookmark names, to avoid the hassle mentioned above. +;; You can do that by customizing user option +;; `bmkp-propertize-bookmark-names-flag' to nil. +;; +;; Be aware, however, that if you do that you will not be able to +;; take full advantage of Bookmark+ features such as autofile +;; bookmarks, which require the ability to have multiple bookmarks +;; with the same name. See (@> "Autofile Bookmarks"). + +;;(@* "Bookmark Compatibility with Vanilla Emacs (`bookmark.el')") +;; ** Bookmark Compatibility with Vanilla Emacs (`bookmark.el') ** +;; +;; Bookmark+ is generally compatible with GNU Emacs versions 20 +;; through 23. +;; +;; 1. All bookmarks created using any version of vanilla Emacs +;; (library `bookmark.el') continue to work with Bookmark+. +;; +;; 2. All bookmarks created using Bookmark+ will work with all Emacs +;; versions (20-23), provided you use Bookmark+ to access them. +;; +;; 3. Most bookmarks created using Bookmark+ will not interfere with +;; the behavior of vanilla Emacs, versions 21-23. The new +;; bookmark types are simply ignored by vanilla Emacs. For +;; example: +;; +;; - A bookmark with a region is treated like a simple position +;; bookmark: the destination is the region start position. +;; +;; - A Gnus bookmark does not work; it is simply ignored. +;; +;; However, there are two cases in which Bookmark+ bookmarks will +;; raise an error in vanilla Emacs: +;; +;; * You cannot use non-file (e.g. buffer-only) bookmarks with any +;; version of vanilla Emacs. +;; +;; * You cannot use any bookmarks created using Bookmark+ with +;; vanilla Emacs 20. +;; +;; The Emacs bookmark data structure has changed from version to +;; version. Bookmark+ always creates bookmarks that have the most +;; recent structure (Emacs 23). As is the case for any bookmarks +;; that have the Emacs 23 structure, these bookmarks will not work +;; in vanilla Emacs 20 (that is, without Bookmark+). +;; +;; Bottom line: Use `bookmark+.el' to access bookmarks created using +;; `bookmark+.el'. + +;;(@* "New Bookmark Structure") +;; ** New Bookmark Structure ** +;; +;; The bookmark data structure, variable `bookmark-alist', has been +;; enhanced to support new bookmark types. For a description of this +;; enhanced structure, use `C-h v bookmark-alist'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; You need not load this file. It contains only documentation. + +(provide 'bookmark+-doc) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-doc.el ends here + diff --git a/auto-install/bookmark+-key.el b/auto-install/bookmark+-key.el new file mode 100644 index 0000000..5999f3e --- /dev/null +++ b/auto-install/bookmark+-key.el @@ -0,0 +1,881 @@ +;;; bookmark+-key.el --- Bookmark+ key and menu bindings. +;; +;; Filename: bookmark+-key.el +;; Description: Bookmark+ key and menu bindings. +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2010-2011, Drew Adams, all rights reserved. +;; Created: Fri Apr 1 15:34:50 2011 (-0700) +;; Version: +;; Last-Updated: Mon Apr 25 06:54:55 2011 (-0700) +;; By: dradams +;; Update #: 256 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-key.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other (non-bmenu) required code +;; `bookmark+-key.el' - key and menu bindings (this file) +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) +;; +;; +;; Internal variables defined here: +;; +;; `bmkp-find-file-menu', `bmkp-highlight-menu', `bmkp-jump-map', +;; `bmkp-jump-menu', `bmkp-options-menu', +;; `bmkp-jump-other-window-map', `bmkp-jump-tags-menu', +;; `bmkp-set-map', `bmkp-tags-map', `bmkp-tags-menu'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; *This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;; + +;; Quiet the byte-compiler + +(defvar bmkp-bmenu-menubar-menu) ; Defined in `bookmark+-bmu.el'. +(defvar bmkp-crosshairs-flag) ; Defined in `bookmark+-1.el'. +(defvar bmkp-prompt-for-tags-flag) ; Defined in `bookmark+-1.el'. +(defvar bmkp-save-new-location-flag) ; Defined in `bookmark+-1.el'. +(defvar diredp-menu-bar-subdir-menu) ; Defined in `dired+.el'. +(defvar gnus-summary-mode-map) ; Defined in `gnus-sum.el'. +(defvar Info-mode-map) ; Defined in `info.el'. +(defvar Info-mode-menu) ; Defined in `info.el'. +(defvar Man-mode-map) ; Defined in `man.el'. +(defvar mouse-wheel-down-event) ; Defined in `mwheel.el'. +(defvar mouse-wheel-up-event) ; Defined in `mwheel.el'. +(defvar w3m-minor-mode-map) ; Defined in `w3m.el'. +(defvar w3m-mode-map) ; Defined in `w3m.el'. +(defvar woman-menu) ; Defined in `woman.el'. +(defvar woman-mode-map) ; Defined in `woman.el'. + +;;(@* "Keymaps") +;;; Keymaps ---------------------------------------------------------- + +;; `bookmark-map' + +(define-key ctl-x-map "p" bookmark-map) +(define-key ctl-x-map "pj" 'bookmark-jump-other-window) +(define-key ctl-x-map "rK" 'bmkp-set-desktop-bookmark) +(define-key bookmark-map "0" 'bmkp-empty-file) +(define-key bookmark-map "B" 'bmkp-choose-navlist-from-bookmark-list) +(define-key bookmark-map "E" 'bmkp-edit-bookmark) +(define-key bookmark-map "I" 'bookmark-insert-location) ; The original in `bookmark.el' was `f'. +(define-key bookmark-map "K" 'bmkp-set-desktop-bookmark) +(define-key bookmark-map "L" 'bmkp-switch-bookmark-file) +(define-key bookmark-map "N" 'bmkp-navlist-bmenu-list) +(define-key bookmark-map "o" 'bookmark-jump-other-window) +(define-key bookmark-map "q" 'bookmark-jump-other-window) +(define-key bookmark-map "x" 'bmkp-set-bookmark-file-bookmark) +(when (featurep 'bookmark+-lit) + (define-key bookmark-map "h" 'bmkp-light-bookmark-this-buffer) + (define-key bookmark-map "H" 'bmkp-light-bookmarks) + (define-key bookmark-map "u" 'bmkp-unlight-bookmark-this-buffer) + (define-key bookmark-map "U" 'bmkp-unlight-bookmarks) + (define-key bookmark-map "\C-u" 'bmkp-unlight-bookmark-here) + (define-key bookmark-map "=" 'bmkp-bookmarks-lighted-at-point)) +(define-key bookmark-map "." 'bmkp-this-buffer-bmenu-list) +(define-key bookmark-map "?" 'bmkp-describe-bookmark) +(define-key bookmark-map ":" 'bmkp-choose-navlist-of-type) +(define-key bookmark-map "\r" 'bmkp-toggle-autonamed-bookmark-set/delete) +(define-key bookmark-map [delete] 'bmkp-delete-bookmarks) + +;; If you use Emacs before Emacs 22, then you will want to bind the commands +;; whose names do *not* end in `-repeat' to keys that are easily repeatable. +;; For example, you might want to bind `bmkp-next-bookmark-this-buffer' +;; (not `bmkp-next-bookmark-this-buffer-repeat') to a key such as [f2]. +;; +(when (> emacs-major-version 21) + (define-key bookmark-map [down] 'bmkp-next-bookmark-this-buffer-repeat) + (define-key bookmark-map "n" 'bmkp-next-bookmark-this-buffer-repeat) + (define-key bookmark-map "\C-n" 'bmkp-next-bookmark-this-buffer-repeat) + + ;; This requires the fix for Emacs bug #6256, which is in Emacs 23.3 (presumably). + ;; For older Emacs versions you can bind the wheel event to `bmkp-next-bookmark-this-buffer' + ;; in the global map. IOW, prior to Emacs 23.3 a mouse event won't work with `repeat'. + (when (and (boundp 'mouse-wheel-up-event) + (or (> emacs-major-version 23) + (and (= emacs-major-version 23) (> emacs-minor-version 2)))) + (define-key bookmark-map (vector (list mouse-wheel-up-event)) + 'bmkp-next-bookmark-this-buffer-repeat)) + (define-key bookmark-map [up] 'bmkp-previous-bookmark-this-buffer-repeat) + (define-key bookmark-map "p" 'bmkp-previous-bookmark-this-buffer-repeat) + (define-key bookmark-map "\C-p" 'bmkp-previous-bookmark-this-buffer-repeat) + + ;; This requires the fix for Emacs bug #6256, which is in Emacs 23.3 (presumably). + ;; For older Emacs versions you can bind the wheel event to `bmkp-previous-bookmark-this-buffer' + ;; in the global map. IOW, prior to Emacs 23.3 a mouse event won't work with `repeat'. + (when (and (boundp 'mouse-wheel-down-event) + (or (> emacs-major-version 23) + (and (= emacs-major-version 23) (> emacs-minor-version 2)))) + (define-key bookmark-map (vector (list mouse-wheel-down-event)) + 'bmkp-previous-bookmark-this-buffer-repeat)) + (define-key bookmark-map [right] 'bmkp-next-bookmark-repeat) + (define-key bookmark-map "f" 'bmkp-next-bookmark-repeat) + (define-key bookmark-map "\C-f" 'bmkp-next-bookmark-repeat) + (define-key bookmark-map [left] 'bmkp-previous-bookmark-repeat) + (define-key bookmark-map "b" 'bmkp-previous-bookmark-repeat) + (define-key bookmark-map "\C-b" 'bmkp-previous-bookmark-repeat) + (define-key bookmark-map [next] 'bmkp-next-bookmark-w32-repeat) + (define-key bookmark-map [prior] 'bmkp-previous-bookmark-w32-repeat) + (when (featurep 'bookmark+-lit) + (define-key bookmark-map [C-down] 'bmkp-next-lighted-this-buffer-repeat) + (define-key bookmark-map [C-up] 'bmkp-previous-lighted-this-buffer-repeat))) + + +;; `bmkp-set-map': prefix `C-x p c' + +(defvar bmkp-set-map nil "Keymap containing bindings for bookmark set commands.") + +(define-prefix-command 'bmkp-set-map) +(define-key bookmark-map "c" bmkp-set-map) ; `C-x p c' for create + +(define-key bmkp-set-map "a" 'bmkp-autofile-set) ; `C-x p c a' +(define-key bmkp-set-map "f" 'bmkp-file-target-set) ; `C-x p c f' +(define-key bmkp-set-map "K" 'bmkp-set-desktop-bookmark) ; `C-x p c K' +(define-key bmkp-set-map "m" 'bookmark-set) ; `C-x p c m' +(define-key bmkp-set-map "u" 'bmkp-url-target-set) ; `C-x p c u' +(define-key bmkp-set-map "x" 'bmkp-set-bookmark-file-bookmark) ; `C-x p c x' +(define-key bmkp-set-map "\r" 'bmkp-toggle-autonamed-bookmark-set/delete) ; `C-x p c RET' + + +;; Add set commands to other keymaps: occur, compilation: `C-c C-b', `C-c C-M-b', `C-c C-M-B'. +;; See `dired+.el' for Dired bookmarking keys, which are different. + +(add-hook 'occur-mode-hook + #'(lambda () + (unless (lookup-key occur-mode-map "\C-c\C-b") + (define-key occur-mode-map "\C-c\C-b" 'bmkp-occur-target-set)) + (unless (lookup-key occur-mode-map "\C-c\C-\M-b") + (define-key occur-mode-map "\C-c\C-\M-b" 'bmkp-occur-target-set-all)) + (unless (lookup-key occur-mode-map [(control ?c) (control meta shift ?b)]) + (define-key occur-mode-map [(control ?c) (control meta shift ?b)] + 'bmkp-occur-create-autonamed-bookmarks)))) + +(add-hook 'compilation-mode-hook + #'(lambda () + (unless (lookup-key occur-mode-map "\C-c\C-b") + (define-key occur-mode-map "\C-c\C-b" 'bmkp-compilation-target-set)) + (unless (lookup-key occur-mode-map "\C-c\C-\M-b") + (define-key occur-mode-map "\C-c\C-\M-b" 'bmkp-compilation-target-set-all)))) + +(add-hook 'compilation-minor-mode-hook + #'(lambda () + (unless (lookup-key occur-mode-map "\C-c\C-b") + (define-key occur-mode-map "\C-c\C-b" 'bmkp-compilation-target-set)) + (unless (lookup-key occur-mode-map "\C-c\C-\M-b") + (define-key occur-mode-map "\C-c\C-\M-b" 'bmkp-compilation-target-set-all)))) + + +;; `bmkp-tags-map': prefix `C-x p t' + +(defvar bmkp-tags-map nil "Keymap containing bindings for bookmark tag commands.") + +(define-prefix-command 'bmkp-tags-map) +(define-key bookmark-map "t" bmkp-tags-map) ; `C-x p t' for tags + +(define-key bmkp-tags-map "0" 'bmkp-remove-all-tags) ; `C-x p t 0' +(define-key bmkp-tags-map "+" nil) ; For Emacs 20 +(define-key bmkp-tags-map "+b" 'bmkp-add-tags) ; `C-x p t + b' +(define-key bmkp-tags-map "-b" 'bmkp-remove-tags) ; `C-x p t - b' +(define-key bmkp-tags-map "+a" 'bmkp-tag-a-file) ; `C-x p t + a' +(define-key bmkp-tags-map "-a" 'bmkp-untag-a-file) ; `C-x p t - a' +(define-key bmkp-tags-map "c" 'bmkp-copy-tags) ; `C-x p t c' +(define-key bmkp-tags-map "d" 'bmkp-remove-tags-from-all) ; `C-x p t d' +(define-key bmkp-tags-map "e" 'bmkp-edit-tags) ; `C-x p t e' +(define-key bmkp-tags-map "l" 'bmkp-list-all-tags) ; `C-x p t l' +(define-key bmkp-tags-map "p" 'bmkp-paste-add-tags) ; `C-x p t p' +(define-key bmkp-tags-map "q" 'bmkp-paste-replace-tags) ; `C-x p t q' +(define-key bmkp-tags-map "r" 'bmkp-rename-tag) ; `C-x p t r' +(define-key bmkp-tags-map "v" 'bmkp-set-tag-value) ; `C-x p t v' +(define-key bmkp-tags-map "V" 'bmkp-set-tag-value-for-navlist) ; `C-x p t V' +(define-key bmkp-tags-map "\M-w" 'bmkp-copy-tags) ; `C-x p t M-w' +(define-key bmkp-tags-map "\C-y" 'bmkp-paste-add-tags) ; `C-x p t C-y' + + +;; `bmkp-jump-map' and `bmkp-jump-other-window-map': prefixes `C-x j' and `C-x 4 j' + +(defvar bmkp-jump-map nil "Keymap containing bindings for bookmark jump commands.") + +(defvar bmkp-jump-other-window-map nil + "Keymap containing bindings for bookmark jump other-window commands.") + +(define-prefix-command 'bmkp-jump-map) +(define-prefix-command 'bmkp-jump-other-window-map) +(define-key ctl-x-map "j" bmkp-jump-map) +(define-key ctl-x-4-map "j" bmkp-jump-other-window-map) + +(define-key bmkp-jump-map "." 'bmkp-this-buffer-jump) ; `C-x j .' +(define-key bmkp-jump-other-window-map "." 'bmkp-this-buffer-jump-other-window) ; `C-x 4 j .' +(define-key bmkp-jump-map "#" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "#" nil) ; For Emacs 20 +(define-key bmkp-jump-map "##" 'bmkp-autonamed-jump) ; `C-x j # #' +(define-key bmkp-jump-other-window-map "##" 'bmkp-autonamed-jump-other-window) ; `C-x 4 j # #' +(define-key bmkp-jump-map "#." 'bmkp-autonamed-this-buffer-jump) ; `C-x j # .' +(define-key bmkp-jump-other-window-map "#." + 'bmkp-autonamed-this-buffer-jump-other-window) ; `C-x 4 j # .' +(define-key bmkp-jump-map "=" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "=" nil) ; For Emacs 20 +(define-key bmkp-jump-map "=b" 'bmkp-specific-buffers-jump) ; `C-x j = b' +(define-key bmkp-jump-other-window-map "=b" 'bmkp-specific-buffers-jump-other-window) ; `C-x 4 j = b' +(define-key bmkp-jump-map "=f" 'bmkp-specific-files-jump) ; `C-x j = f' +(define-key bmkp-jump-other-window-map "=f" 'bmkp-specific-files-jump-other-window) ; `C-x 4 j = f' +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (define-key bmkp-jump-map "a" 'bmkp-find-file) ; `C-x j a' + (define-key bmkp-jump-other-window-map "a" 'bmkp-find-file-other-window)) ; `C-x 4 j a' +(define-key bmkp-jump-map "b" 'bmkp-non-file-jump) ; `C-x j b' +(define-key bmkp-jump-other-window-map "b" 'bmkp-non-file-jump-other-window) ; `C-x 4 j b' +(define-key bmkp-jump-map "B" 'bmkp-bookmark-list-jump) ; `C-x j B' +(define-key bmkp-jump-other-window-map "B" 'bmkp-bookmark-list-jump) ; SAME +(define-key bmkp-jump-map "d" 'bmkp-dired-jump) ; `C-x j d' +(define-key bmkp-jump-other-window-map "d" 'bmkp-dired-jump-other-window) ; `C-x 4 j d' +(define-key bmkp-jump-map "\C-d" 'bmkp-dired-this-dir-jump) ; `C-x j C-d' +(define-key bmkp-jump-other-window-map "\C-d" 'bmkp-dired-this-dir-jump-other-window) ; `C-x 4 j C-d' +(define-key bmkp-jump-map "f" 'bmkp-file-jump) ; `C-x j f' +(define-key bmkp-jump-other-window-map "f" 'bmkp-file-jump-other-window) ; `C-x 4 j f' +(define-key bmkp-jump-map "\C-f" 'bmkp-file-this-dir-jump) ; `C-x j C-f' +(define-key bmkp-jump-other-window-map "\C-f" 'bmkp-file-this-dir-jump-other-window) ; `C-x 4 j C-f' +(define-key bmkp-jump-map "g" 'bmkp-gnus-jump) ; `C-x j g' +(define-key bmkp-jump-other-window-map "g" 'bmkp-gnus-jump-other-window) ; `C-x 4 j g' +(define-key bmkp-jump-map "h" 'bmkp-lighted-jump) ; `C-x j h' +(define-key bmkp-jump-other-window-map "h" 'bmkp-lighted-jump-other-window) ; `C-x 4 j h' +(define-key bmkp-jump-map "i" 'bmkp-info-jump) ; `C-x j i' +(define-key bmkp-jump-other-window-map "i" 'bmkp-info-jump-other-window) ; `C-x 4 j i' +(define-key bmkp-jump-map "j" 'bookmark-jump) ; `C-x j j' +(put 'bookmark-jump :advertised-binding "\C-xjj") + +(define-key bmkp-jump-other-window-map "j" 'bookmark-jump-other-window) ; `C-x 4 j j' +(put 'bookmark-jump-other-window :advertised-binding "\C-x4jj") +(put 'jump-other :advertised-binding "\C-x4jj") + +(define-key bmkp-jump-map "K" 'bmkp-desktop-jump) ; `C-x j K' +(define-key bmkp-jump-other-window-map "K" 'bmkp-desktop-jump) ; SAME +(define-key bmkp-jump-map "l" 'bmkp-local-file-jump) ; `C-x j l' +(define-key bmkp-jump-other-window-map "l" 'bmkp-local-file-jump-other-window) ; `C-x 4 j l' +(define-key bmkp-jump-map "m" 'bmkp-man-jump) ; `C-x j m' +(define-key bmkp-jump-other-window-map "m" 'bmkp-man-jump-other-window) ; `C-x 4 j m' +(define-key bmkp-jump-map "n" 'bmkp-remote-file-jump) ; `C-x j n' ("_n_etwork") +(define-key bmkp-jump-other-window-map "n" 'bmkp-remote-file-jump-other-window) ; `C-x 4 j n' +(define-key bmkp-jump-map "N" 'bmkp-jump-in-navlist) ; `C-x j N' +(define-key bmkp-jump-other-window-map "N" 'bmkp-jump-in-navlist-other-window) ; `C-x 4 j N' +(define-key bmkp-jump-map "r" 'bmkp-region-jump) ; `C-x j r' +(define-key bmkp-jump-other-window-map "r" 'bmkp-region-jump-other-window) ; `C-x 4 j r' + +(define-key bmkp-jump-map "t" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "t" nil) ; For Emacs 20 +(define-key bmkp-jump-map "t*" 'bmkp-all-tags-jump) ; `C-x j t *' +(define-key bmkp-jump-other-window-map "t*" 'bmkp-all-tags-jump-other-window) ; `C-x 4 j t *' +(define-key bmkp-jump-map "t+" 'bmkp-some-tags-jump) ; `C-x j t +' +(define-key bmkp-jump-other-window-map "t+" 'bmkp-some-tags-jump-other-window) ; `C-x 4 j t +' +(define-key bmkp-jump-map "t%" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "t%" nil) ; For Emacs 20 +(define-key bmkp-jump-map "t%*" 'bmkp-all-tags-regexp-jump) ; `C-x j t % *' +(define-key bmkp-jump-other-window-map "t%*" + 'bmkp-all-tags-regexp-jump-other-window) ; `C-x 4 j t % *' +(define-key bmkp-jump-map "t%+" 'bmkp-some-tags-regexp-jump) ; `C-x j t % +' +(define-key bmkp-jump-other-window-map "t%+" + 'bmkp-some-tags-regexp-jump-other-window) ; `C-x 4 j t % +' + +(when (> emacs-major-version 21) ; Needs `read-file-name' with a PREDICATE arg. + (define-key bmkp-jump-map "ta*" 'bmkp-find-file-all-tags) ; `C-x j t a *' + (define-key bmkp-jump-other-window-map "ta*" 'bmkp-find-file-all-tags-other-window) ; `C-x 4 j t a *' + (define-key bmkp-jump-map "ta+" 'bmkp-find-file-some-tags) ; `C-x j t a +' + (define-key bmkp-jump-other-window-map "ta+" + 'bmkp-find-file-some-tags-other-window) ; `C-x 4 j t a +' + (define-key bmkp-jump-map "ta%*" 'bmkp-find-file-all-tags-regexp) ; `C-x j t a % *' + (define-key bmkp-jump-other-window-map "ta%*" + 'bmkp-find-file-all-tags-regexp-other-window) ; `C-x 4 j t a % *' + (define-key bmkp-jump-map "ta%+" 'bmkp-find-file-some-tags-regexp) ; `C-x j t a % +' + (define-key bmkp-jump-other-window-map "ta%+" + 'bmkp-find-file-some-tags-regexp-other-window)) ; `C-x 4 j t a % +' + +(define-key bmkp-jump-map "tf" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "tf" nil) ; For Emacs 20 +(define-key bmkp-jump-map "tf*" 'bmkp-file-all-tags-jump) ; `C-x j t f *' +(define-key bmkp-jump-other-window-map "tf*" 'bmkp-file-all-tags-jump-other-window) ; `C-x 4 j t f *' +(define-key bmkp-jump-map "tf+" 'bmkp-file-some-tags-jump) ; `C-x j t f +' +(define-key bmkp-jump-other-window-map "tf+" 'bmkp-file-some-tags-jump-other-window) ; `C-x 4 j t f +' +(define-key bmkp-jump-map "tf%" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "tf%" nil) ; For Emacs 20 +(define-key bmkp-jump-map "tf%*" 'bmkp-file-all-tags-regexp-jump) ; `C-x j t f % *' +(define-key bmkp-jump-other-window-map "tf%*" + 'bmkp-file-all-tags-regexp-jump-other-window) ; `C-x 4 j t f % *' +(define-key bmkp-jump-map "tf%+" 'bmkp-file-some-tags-regexp-jump) ; `C-x j t f % +' +(define-key bmkp-jump-other-window-map "tf%+" + 'bmkp-file-some-tags-regexp-jump-other-window) ; `C-x 4 j t f % +' + +(define-key bmkp-jump-map "t\C-f" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "t\C-f" nil) ; For Emacs 20 +(define-key bmkp-jump-map "t\C-f*" 'bmkp-file-this-dir-all-tags-jump) ; `C-x j t C-f *' +(define-key bmkp-jump-other-window-map "t\C-f*" + 'bmkp-file-this-dir-all-tags-jump-other-window) ; `C-x 4 j t C-f *' +(define-key bmkp-jump-map "t\C-f+" 'bmkp-file-this-dir-some-tags-jump) ; `C-x j t C-f +' +(define-key bmkp-jump-other-window-map "t\C-f+" + 'bmkp-file-this-dir-some-tags-jump-other-window) ; `C-x 4 j t C-f +' +(define-key bmkp-jump-map "t\C-f%" nil) ; For Emacs 20 +(define-key bmkp-jump-other-window-map "t\C-f%" nil) ; For Emacs 20 +(define-key bmkp-jump-map "t\C-f%*" + 'bmkp-file-this-dir-all-tags-regexp-jump) ; `C-x j t C-f % *' +(define-key bmkp-jump-other-window-map "t\C-f%*" + 'bmkp-file-this-dir-all-tags-regexp-jump-other-window) ; `C-x 4 j t C-f % *' +(define-key bmkp-jump-map "t\C-f%+" + 'bmkp-file-this-dir-some-tags-regexp-jump) ; `C-x j t C-f % +' +(define-key bmkp-jump-other-window-map "t\C-f%+" + 'bmkp-file-this-dir-some-tags-regexp-jump-other-window) ; `C-x 4 j t C-f % +' + +(define-key bmkp-jump-map "u" 'bmkp-url-jump) ; `C-x j u' +(define-key bmkp-jump-other-window-map "u" 'bmkp-url-jump-other-window) ; `C-x 4 j u' +(define-key bmkp-jump-map "v" 'bmkp-variable-list-jump) ; `C-x j v' +(define-key bmkp-jump-map "w" 'bmkp-w3m-jump) ; `C-x j w' +(define-key bmkp-jump-other-window-map "w" 'bmkp-w3m-jump-other-window) ; `C-x 4 j w' +(define-key bmkp-jump-map "x" 'bmkp-bookmark-file-jump) ; `C-x j x' +(define-key bmkp-jump-map ":" 'bmkp-jump-to-type) ; `C-x j :' +(define-key bmkp-jump-other-window-map ":" 'bmkp-jump-to-type-other-window) ; `C-x 4 j :' + +;; Add jump commands to other keymaps: Buffer-menu, Dired, Gnus, Info, Man, Woman, W3M. +(add-hook 'buffer-menu-mode-hook + #'(lambda () (unless (lookup-key Buffer-menu-mode-map "j") + (define-key Buffer-menu-mode-map "j" 'bmkp-non-file-jump)))) +(add-hook 'dired-mode-hook + #'(lambda () + (let ((now (lookup-key dired-mode-map "J"))) + ;; Uppercase, since `j' is `dired-goto-file'. + (unless (and now (not (eq now 'undefined))) ; `dired+.el' uses `undefined'. + (define-key dired-mode-map "J" 'bmkp-dired-jump)) + (setq now (lookup-key dired-mode-map "\C-j")) + (unless (and now (not (eq now 'undefined))) ; `dired+.el' uses `undefined'. + (define-key dired-mode-map "\C-j" 'bmkp-dired-this-dir-jump))) + (let ((map dired-mode-map) + (sep '(menu-bar subdir separator-bmkp)) + (bdj '(menu-bar subdir bmkp-dired-jump)) + (bdjc '(menu-bar subdir bmkp-dired-this-dir-jump))) + (when (boundp 'diredp-menu-bar-subdir-menu) ; In `dired+el'. + (setq map diredp-menu-bar-subdir-menu + sep (cddr sep) + bdj (cddr bdj) + bdjc (cddr bdjc))) + (define-key map (apply #'vector sep) '("--")) + (define-key map (apply #'vector bdj) + '(menu-item "Jump to a Dired Bookmark" bmkp-dired-jump + :help "Jump to a bookmarked Dired buffer")) + (define-key map (apply #'vector bdjc) + '(menu-item "Show This Dir Using a Bookmark" bmkp-dired-this-dir-jump + :help "Use a bookmarked version of this directory"))))) +(add-hook 'gnus-summary-mode-hook + #'(lambda () (unless (lookup-key gnus-summary-mode-map "j") + (define-key gnus-summary-mode-map "j" 'bmkp-gnus-jump)))) +(add-hook 'Info-mode-hook + #'(lambda () + (unless (lookup-key Info-mode-map "j") + (define-key Info-mode-map "j" 'bmkp-info-jump)) + (define-key-after Info-mode-menu [bmkp-info-jump] + '(menu-item "Jump to an Info Bookmark" bmkp-info-jump + :help "Jump to a bookmarked Info node") + 'Go\ to\ Node\.\.\.))) ; Used by `info(+).el' - corresponds to `Info-goto-node'. +(add-hook 'Man-mode-hook + #'(lambda () (unless (lookup-key Man-mode-map "j") + (define-key Man-mode-map "j" 'bmkp-man-jump)))) +(add-hook 'woman-mode-hook + #'(lambda () + (unless (lookup-key woman-mode-map "j") (define-key woman-mode-map "j" 'bmkp-man-jump)) + (when (boundp 'woman-menu) + (define-key-after woman-menu [bmkp-man-jump] + '(menu-item "Jump to a `man'-page Bookmark" bmkp-man-jump + :help "Jump to a bookmarked `man' page") + 'WoMan\.\.\.)))) ; Used by `woman.el' - corresponds to command `woman'. +(add-hook 'w3m-minor-mode-hook + #'(lambda () (unless (lookup-key w3m-minor-mode-map "j") + (define-key w3m-minor-mode-map "j" 'bmkp-w3m-jump)))) +(add-hook 'w3m-mode-hook + #'(lambda () (unless (lookup-key w3m-mode-map "j") + (define-key w3m-mode-map "j" 'bmkp-w3m-jump)))) + + +;;; Vanilla Emacs `Bookmarks' menu (see also [jump] from `Bookmark+' menu, below). + +(define-key-after menu-bar-bookmark-map [separator-set] '("--") 'jump) +(define-key-after menu-bar-bookmark-map [set] + '(menu-item "Set Bookmark..." (lambda () (interactive) (call-interactively #'bookmark-set)) + :help "Set a bookmark at point") + 'separator-set) +(define-key-after menu-bar-bookmark-map [bmkp-autofile-set] + '(menu-item "Set Autofile Bookmark..." bmkp-autofile-set + :help "Set and automatically name a bookmark for a given file") + 'set) +(define-key-after menu-bar-bookmark-map [bmkp-file-target-set] + '(menu-item "Set Bookmark for File..." bmkp-file-target-set + :help "Set a bookmark with a given name for a given file") + 'bmkp-autofile-set) +(define-key-after menu-bar-bookmark-map [bmkp-url-target-set] + '(menu-item "Set Bookmark for URL..." bmkp-url-target-set + :help "Set a bookmark for a given URL") + 'bmkp-file-target-set) +(define-key-after menu-bar-bookmark-map [bmkp-set-desktop-bookmark] + '(menu-item "Set Bookmark for Desktop" bmkp-set-desktop-bookmark + :help "Save the current desktop as a bookmark") + 'bmkp-url-target-set) +(define-key-after menu-bar-bookmark-map [bmkp-set-bookmark-file-bookmark] + '(menu-item "Set Bookmark for Bookmark File..." bmkp-set-bookmark-file-bookmark + :help "Set a bookmark that loads a bookmark file when jumped to") + 'bmkp-set-desktop-bookmark) +(define-key-after menu-bar-bookmark-map [bmkp-toggle-autoname-bookmark-set] + '(menu-item "Set Autonamed Bookmark" bmkp-toggle-autonamed-bookmark-set/delete + :help "Set an autonamed bookmark at point" + :visible (not (bookmark-get-bookmark (funcall bmkp-autoname-bookmark-function (point)) + 'noerror))) + 'bmkp-set-bookmark-file-bookmark) +(define-key-after menu-bar-bookmark-map [separator-delete] '("--") 'bmkp-toggle-autoname-bookmark-set) +(define-key-after menu-bar-bookmark-map [bmkp-toggle-autoname-bookmark-delete] + '(menu-item "Delete Autonamed Bookmark" bmkp-toggle-autonamed-bookmark-set/delete + :help "Delete the autonamed bookmark at point" + :visible (bookmark-get-bookmark (funcall bmkp-autoname-bookmark-function (point)) + 'noerror)) + 'bmkp-set-bookmark-file-bookmark) +(define-key-after menu-bar-bookmark-map [bmkp-delete-all-autonamed-for-this-buffer] + '(menu-item "Delete All Autonamed Bookmarks Here..." + bmkp-delete-all-autonamed-for-this-buffer + :help "Delete all autonamed bookmarks for the current buffer" + :enable (mapcar #'bookmark-name-from-full-record (bmkp-autonamed-this-buffer-alist-only))) + 'bmkp-toggle-autonamed-bookmark-set/delete) +(define-key-after menu-bar-bookmark-map [bmkp-delete-bookmarks] + '(menu-item "Delete Bookmarks Here..." bmkp-delete-bookmarks + :help "Delete some bookmarks at point or, with `C-u', all bookmarks in the buffer" + :enable (mapcar #'bookmark-name-from-full-record (bmkp-this-buffer-alist-only))) + 'bmkp-delete-all-autonamed-for-this-buffer) +(define-key-after menu-bar-bookmark-map [delete] + '(menu-item "Delete Bookmark..." bookmark-delete + :help "Delete the bookmark you choose by name" :enable bookmark-alist) + 'bmkp-delete-bookmarks) +(define-key-after menu-bar-bookmark-map [rename] + '(menu-item "Rename Bookmark..." bookmark-rename + :help "Rename the bookmark you choose by name" :enable bookmark-alist) + 'delete) +(define-key-after menu-bar-bookmark-map [bmkp-purge-notags-autofiles] + '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles + :help "Delete all autofile bookmarks that have no tags" :enable bookmark-alist) + 'rename) + +(define-key-after menu-bar-bookmark-map [separator-0] '("--") 'bmkp-purge-notags-autofiles) +(define-key-after menu-bar-bookmark-map [edit] + '(menu-item "Show Bookmark List" bookmark-bmenu-list + :help "Open the list of bookmarks in buffer `*Bookmark List*'") + 'separator-0) +(define-key-after menu-bar-bookmark-map [bmkp-this-buffer-bmenu-list] + '(menu-item "Show Bookmark List for This Buffer" bmkp-this-buffer-bmenu-list + :help "Open `*Bookmark List*' for the bookmarks in the current buffer (only)" + :enable (mapcar #'bookmark-name-from-full-record (bmkp-this-buffer-alist-only))) + 'edit) +(define-key-after menu-bar-bookmark-map [bmkp-navlist-bmenu-list] + '(menu-item "Show Bookmark List for Navlist" bmkp-navlist-bmenu-list + :help "Open `*Bookmark List*' for bookmarks in navlist (only)" + :enable bmkp-nav-alist) + 'bmkp-this-buffer-bmenu-list) + +(define-key-after menu-bar-bookmark-map [separator-2] '("--") 'bmkp-navlist-bmenu-list) +(define-key-after menu-bar-bookmark-map [bmkp-choose-navlist-of-type] + '(menu-item "Set Navlist to Bookmarks of Type..." bmkp-choose-navlist-of-type + :help "Set the navigation list to the bookmarks of a certain type") + 'separator-2) +(define-key-after menu-bar-bookmark-map [bmkp-choose-navlist-from-bookmark-list] + '(menu-item "Set Navlist from Bookmark-List Bookmark..." bmkp-choose-navlist-from-bookmark-list + :help "Set the navigation list from a bookmark-list bookmark") + 'bmkp-choose-navlist-of-type) +(define-key-after menu-bar-bookmark-map [bmkp-list-defuns-in-commands-file] + '(menu-item "List User-Defined Bookmark Commands" bmkp-list-defuns-in-commands-file + :help "List the functions defined in `bmkp-bmenu-commands-file'" + :enable (and bmkp-bmenu-commands-file (file-readable-p bmkp-bmenu-commands-file))) + 'bmkp-choose-navlist-from-bookmark-list) +(define-key-after menu-bar-bookmark-map [bmkp-make-function-bookmark] + '(menu-item "New Function Bookmark..." bmkp-make-function-bookmark + :help "Create a bookmark that will invoke FUNCTION when \"jumped\" to") + 'bmkp-list-defuns-in-commands-file) + +(define-key-after menu-bar-bookmark-map [insert] + '(menu-item "Insert Bookmark Contents..." bookmark-insert :help "Insert bookmarked text") + 'bmkp-make-function-bookmark) +(define-key-after menu-bar-bookmark-map [locate] + '(menu-item "Insert Bookmark Location..." bookmark-locate ; Alias for `bookmark-insert-location'. + :help "Insert a bookmark's file or buffer name") + 'insert) + +(define-key-after menu-bar-bookmark-map [separator-3] '("--") 'locate) +(define-key-after menu-bar-bookmark-map [save] + '(menu-item "Save Bookmarks" bookmark-save :help "Save currently defined bookmarks") + 'separator-3) +(define-key-after menu-bar-bookmark-map [write] + '(menu-item "Save Bookmarks As..." bookmark-write + :help "Write current bookmarks to a bookmark file") + 'save) +(define-key-after menu-bar-bookmark-map [bmkp-empty-file] + '(menu-item "New (Empty) Bookmark File..." bmkp-empty-file + :help "Create a new, empty bookmark file, or empty an existing bookmark file") + 'write) +(define-key-after menu-bar-bookmark-map [load] + '(menu-item "Add Bookmarks from File..." bookmark-load + :help "Load additional bookmarks from a bookmark file") + 'bmkp-empty-file) +(define-key-after menu-bar-bookmark-map [load-read-only] + '(menu-item "Switch to Bookmark File..." bmkp-switch-bookmark-file + :help "Switch to a different bookmark file, *replacing* the current set of bookmarks") + 'load) + + +;; `bmkp-highlight-menu' of `Bookmarks' menu + +(when (featurep 'bookmark+-lit) + (defvar bmkp-highlight-menu (make-sparse-keymap) + "`Highlight' submenu for menu-bar `Bookmarks' menu.") + (define-key menu-bar-bookmark-map [highlight] (cons "Highlight" bmkp-highlight-menu)) + + (define-key bmkp-highlight-menu [bmkp-unlight-bookmarks] + '(menu-item "Unhighlight All" bmkp-unlight-bookmarks + :help "Unhighlight all bookmarks (everywhere).")) + (define-key bmkp-highlight-menu [bmkp-unlight-this-buffer] + '(menu-item "Unhighlight All in Buffer" bmkp-unlight-this-buffer + :help "Unhighlight all bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-unlight-non-autonamed-this-buffer] + '(menu-item "Unhighlight All Non-Autonamed in Buffer" bmkp-unlight-non-autonamed-this-buffer + :help "Unhighlight all non-autonamed bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-unlight-autonamed-this-buffer] + '(menu-item "Unhighlight All Autonamed in Buffer" bmkp-unlight-autonamed-this-buffer + :help "Unhighlight all autonamed bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-unlight-bookmark] + '(menu-item "Unhighlight One..." bmkp-unlight-bookmark + :help "Unhighlight a bookmark.")) + (define-key bmkp-highlight-menu [bmkp-unlight-bookmark-this-buffer] + '(menu-item "Unhighlight One in Buffer..." bmkp-unlight-bookmark-this-buffer + :help "Unhighlight a bookmark in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-unlight-bookmark-here] + '(menu-item "Unhighlight This One" bmkp-unlight-bookmark-here + :help "Unhighlight a bookmark at point or on its line.")) + (define-key bmkp-highlight-menu [separator-1] '("--")) + (define-key bmkp-highlight-menu [bmkp-light-bookmarks-in-region] + '(menu-item "Highlight All in Region" bmkp-light-bookmarks-in-region + :help "Highlight all bookmarks in the region.")) + (define-key bmkp-highlight-menu [bmkp-light-this-buffer] + '(menu-item "Highlight All in Buffer" bmkp-light-this-buffer + :help "Highlight all bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-light-non-autonamed-this-buffer] + '(menu-item "Highlight All Non-Autonamed in Buffer" bmkp-light-non-autonamed-this-buffer + :help "Highlight all non-autonamed bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-light-autonamed-this-buffer] + '(menu-item "Highlight All Autonamed in Buffer" bmkp-light-autonamed-this-buffer + :help "Highlight all autonamed bookmarks in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-light-navlist-bookmarks] + '(menu-item "Highlight All in Navigation List" bmkp-light-navlist-bookmarks + :help "Highlight all bookmarks in the navigation list.")) + (define-key bmkp-highlight-menu [bmkp-light-bookmark-this-buffer] + '(menu-item "Highlight One in Buffer..." bmkp-light-bookmark-this-buffer + :help "Highlight a bookmark in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-light-bookmark] + '(menu-item "Highlight One..." bmkp-light-bookmark + :help "Highlight a bookmark.")) + (define-key bmkp-highlight-menu [separator-0] '("--")) + (define-key bmkp-highlight-menu [bmkp-next-lighted-this-buffer] + '(menu-item "Next in Buffer" bmkp-next-lighted-this-buffer + :help "Cycle to the next highlighted bookmark in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-previous-lighted-this-buffer] + '(menu-item "Previous in Buffer" bmkp-previous-lighted-this-buffer + :help "Cycle to the previous highlighted bookmark in this buffer.")) + (define-key bmkp-highlight-menu [bmkp-bookmarks-lighted-at-point] + '(menu-item "List Highlighted at Point" bmkp-bookmarks-lighted-at-point + :help "List the bookmarks at point that are highlighted.")) + (define-key bmkp-highlight-menu [bmkp-set-lighting-for-bookmark] + '(menu-item "Set Highlighting for One..." bmkp-set-lighting-for-bookmark + :help "Set individual highlighting for a bookmark."))) + + +;; `bmkp-options-menu' of `Bookmarks' menu + +(defvar bmkp-options-menu (make-sparse-keymap) + "`Toggle Option' submenu for menu-bar `Bookmarks' menu.") +(define-key menu-bar-bookmark-map [options] (cons "Toggle Option" bmkp-options-menu)) + +(define-key bmkp-options-menu [bmkp-crosshairs-flag] + (bmkp-menu-bar-make-toggle bmkp-crosshairs-flag bmkp-crosshairs-flag + "Highlight Jump using Crosshairs" + "Crosshairs highlighting is %s" + "Temporarily highlight visited bookmarks using crosshairs")) +(define-key bmkp-options-menu [bmkp-save-new-location-flag] + (bmkp-menu-bar-make-toggle bmkp-save-new-location-flag bmkp-save-new-location-flag + "Save after Relocating" + "Saving relocated bookmarks is %s" + "Save a bookmark after automatically relocating it")) +(define-key bmkp-options-menu [bmkp-prompt-for-tags-flag] + (bmkp-menu-bar-make-toggle bmkp-prompt-for-tags-flag bmkp-prompt-for-tags-flag + "Prompt for Tags when Setting" + "Prompting for tags when setting a bookmark is %s" + "Prompt for tags when setting a bookmark interactively")) + +;; `bmkp-tags-menu' of `Bookmarks' menu + +(defvar bmkp-tags-menu (make-sparse-keymap) + "`Tags' submenu for menu-bar `Bookmarks' menu.") +(define-key menu-bar-bookmark-map [tags] (cons "Tags" bmkp-tags-menu)) + +(define-key bmkp-tags-menu [bmkp-list-all-tags] + '(menu-item "List All Tags" bmkp-list-all-tags :help "List all tags used for any bookmarks")) +(define-key bmkp-tags-menu [bmkp-purge-notags-autofiles] + '(menu-item "Purge Autofiles with No Tags..." bmkp-purge-notags-autofiles + :help "Delete all autofile bookmarks that have no tags")) +(define-key bmkp-tags-menu [bmkp-untag-a-file] + '(menu-item "Untag a File (Remove Some)..." bmkp-untag-a-file + :help "Remove some tags from autofile bookmark for a file")) +(define-key bmkp-tags-menu [bmkp-tag-a-file] + '(menu-item "Tag a File (Add Some)..." bmkp-tag-a-file + :help "Add some tags to the autofile bookmark for a file")) +(define-key bmkp-tags-menu [bmkp-rename-tag] + '(menu-item "Rename Tag..." bmkp-rename-tag :help "Rename a tag in all bookmarks")) +(define-key bmkp-tags-menu [bmkp-set-tag-value] + '(menu-item "Set Tag Value..." bmkp-set-tag-value :help "Set the tag value for a given bookmark")) +(define-key bmkp-tags-menu [bmkp-remove-tags-from-all] + '(menu-item "Remove Some Tags from All..." bmkp-remove-tags-from-all + :help "Remove a set of tags from all bookmarks")) +(define-key bmkp-tags-menu [bmkp-remove-tags] + '(menu-item "Remove Some Tags..." bmkp-remove-tags :help "Remove a set of tags from a bookmark")) +(define-key bmkp-tags-menu [bmkp-add-tags] + '(menu-item "Add Some Tags..." bmkp-add-tags :help "Add a set of tags to a bookmark")) +(define-key bmkp-tags-menu [bmkp-paste-replace-tags] + '(menu-item "Paste Tags (Replace)..." bmkp-paste-replace-tags + :help "Replace tags for a bookmark with tags copied from another")) +(define-key bmkp-tags-menu [bmkp-paste-add-tags] + '(menu-item "Paste Tags (Add)..." bmkp-paste-add-tags + :help "Add tags to a bookmark that were previously copied from another")) +(define-key bmkp-tags-menu [bmkp-copy-tags] + '(menu-item "Copy Tags..." bmkp-copy-tags + :help "Copy the tags from a bookmark, so you can paste them to another")) + +;; `bmkp-jump-menu' of `Bookmarks' menu + +(defvar bmkp-jump-menu (make-sparse-keymap) + "`Jump To' submenu for menu-bar `Bookmarks' menu.") +;; Add jump menu to vanilla Emacs `Bookmarks' menu and remove the two jump commands already there. +(define-key menu-bar-bookmark-map [jump] nil) +(define-key menu-bar-bookmark-map [jump-other] nil) +(define-key menu-bar-bookmark-map [bmkp-jump] (cons "Jump To" bmkp-jump-menu)) + +;; `Jump To': Add jump menu also to the `Bookmark+' menu, and remove the two jump commands there. +(define-key bmkp-bmenu-menubar-menu [jump] (cons "Jump To" bmkp-jump-menu)) + +(define-key bmkp-jump-menu [bmkp-autonamed-this-buffer-jump] + '(menu-item "Autonamed for This Buffer..." bmkp-autonamed-this-buffer-jump + :help "Jump to an autonamed bookmark in this buffer")) +(define-key bmkp-jump-menu [bmkp-autonamed-jump-other-window] + '(menu-item "Autonamed..." bmkp-autonamed-jump-other-window + :help "Jump to an autonamed bookmark")) +(define-key bmkp-jump-menu [bmkp-specific-files-jump-other-window] + '(menu-item "For Specific Files..." bmkp-specific-files-jump-other-window + :help "Jump to a bookmark for specific files")) +(define-key bmkp-jump-menu [bmkp-specific-buffers-jump-other-window] + '(menu-item "For Specific Buffers..." bmkp-specific-buffers-jump-other-window + :help "Jump to a bookmark for specific buffers")) +(define-key bmkp-jump-menu [bmkp-this-buffer-jump] + '(menu-item "For This Buffer..." bmkp-this-buffer-jump + :help "Jump to a bookmark for the current buffer" + :enable (mapcar #'bookmark-name-from-full-record (bmkp-this-buffer-alist-only)))) +(when (featurep 'bookmark+-lit) + (define-key bmkp-jump-menu [bmkp-lighted-jump-other-window] + '(menu-item "Highlighted..." bmkp-lighted-jump-other-window + :help "Jump to a highlighted bookmark" + :enable (bmkp-lighted-alist-only)))) +(define-key bmkp-jump-menu [bmkp-jump-in-navlist-other-window] + '(menu-item "In Navigation List..." bmkp-jump-in-navlist-other-window + :help "Jump to a bookmark that is in the navigation list" :enable bmkp-nav-alist)) +(define-key bmkp-jump-menu [jump-sep0] '("--")) +(define-key bmkp-jump-menu [bmkp-url-jump-other-window] + '(menu-item "URL..." bmkp-url-jump-other-window :help "Jump to a URL bookmark" + :enable (bmkp-url-alist-only))) +(define-key bmkp-jump-menu [bmkp-gnus-jump-other-window] + '(menu-item "Gnus..." bmkp-gnus-jump-other-window :help "Jump to a Gnus bookmark" + :enable (bmkp-gnus-alist-only))) +(define-key bmkp-jump-menu [bmkp-man-jump-other-window] + '(menu-item "Man Page..." bmkp-man-jump-other-window :help "Jump to a `man'-page bookmark" + :enable (bmkp-man-alist-only))) +(define-key bmkp-jump-menu [bmkp-info-jump-other-window] + '(menu-item "Info Node..." bmkp-info-jump-other-window :help "Jump to an Info bookmark" + :enable (bmkp-info-alist-only))) +(define-key bmkp-jump-menu [bmkp-non-file-jump-other-window] + '(menu-item "Buffer (Non-File)..." bmkp-non-file-jump-other-window + :help "Jump to a non-file (buffer) bookmark" :enable (bmkp-non-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-region-jump-other-window] + '(menu-item "Region..." bmkp-region-jump-other-window + :help "Jump to a bookmark that defines the active region" :enable (bmkp-region-alist-only))) +(define-key bmkp-jump-menu [bmkp-remote-file-jump-other-window] + '(menu-item "Remote File..." bmkp-remote-file-jump-other-window + :help "Jump to a remote file or directory bookmark" :enable (bmkp-remote-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-local-file-jump-other-window] + '(menu-item "Local File..." bmkp-local-file-jump-other-window + :help "Jump to a local file or directory bookmark" :enable (bmkp-local-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-file-this-dir-jump-other-window] + '(menu-item "File in This Dir..." bmkp-file-this-dir-jump-other-window + :help "Jump to a bookmark for a file or subdirectory in the `default-directory'." + :enable (bmkp-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-file-jump-other-window] + '(menu-item "File..." bmkp-file-jump-other-window :help "Jump to a file or directory bookmark" + :enable (bmkp-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-dired-this-dir-jump-other-window] + '(menu-item "Dired for This Dir..." bmkp-dired-this-dir-jump-other-window + :help "Jump to a Dired bookmark for `default-directory', restoring recorded state" + :enable (bmkp-dired-alist-only))) +(define-key bmkp-jump-menu [bmkp-dired-jump-other-window] + '(menu-item "Dired..." bmkp-dired-jump-other-window + :help "Jump to a Dired bookmark, restoring the recorded Dired state" + :enable (bmkp-dired-alist-only))) +(define-key bmkp-jump-menu [bmkp-variable-list-jump] + '(menu-item "Variable List..." bmkp-variable-list-jump :help "Jump to a variable-list bookmark" + :enable (bmkp-variable-list-alist-only))) +(define-key bmkp-jump-menu [bmkp-bookmark-file-jump] + '(menu-item "Bookmark File..." bmkp-bookmark-file-jump + :help "Jump to (load) a bookmark-file bookmark" :enable (bmkp-bookmark-file-alist-only))) +(define-key bmkp-jump-menu [bmkp-bookmark-list-jump] + '(menu-item "Bookmark List..." bmkp-bookmark-list-jump :help "Jump to a bookmark-list bookmark" + :enable (bmkp-bookmark-list-alist-only))) +(define-key bmkp-jump-menu [bmkp-desktop-jump] + '(menu-item "Desktop..." bmkp-desktop-jump :help "Jump to a desktop bookmark" + :enable (bmkp-desktop-alist-only))) +(define-key bmkp-jump-menu [bmkp-jump-to-type-other-window] + '(menu-item "Of Type..." bmkp-jump-to-type-other-window + :help "Jump to a bookmark of a type that you specify")) + +(defvar bmkp-jump-tags-menu (make-sparse-keymap) + "`With Tags' submenu for `Jump To' submenu of `Bookmarks' menu.") +(define-key bmkp-jump-menu [bmkp-tags] (cons "With Tags" bmkp-jump-tags-menu)) +(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-all-tags-regexp-jump-other-window] + '(menu-item "File in This Dir, All Tags Matching Regexp..." + bmkp-file-this-dir-all-tags-regexp-jump-other-window + :help "Jump to a file bookmark in this dir where each tag matches a regexp")) +(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-some-tags-regexp-jump-other-window] + '(menu-item "File in This Dir, Any Tag Matching Regexp..." + bmkp-file-this-dir-some-tags-regexp-jump-other-window + :help "Jump to a file bookmark in this dir where at least one tag matches a regexp")) +(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-all-tags-jump-other-window] + '(menu-item "File in This Dir, All Tags in Set..." bmkp-file-this-dir-all-tags-jump-other-window + :help "Jump to a file bookmark in this dir that has all of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-file-this-dir-some-tags-jump-other-window] + '(menu-item "File in This Dir, Any Tag in Set..." bmkp-file-this-dir-some-tags-jump-other-window + :help "Jump to a file bookmark in this dir that has some of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [jump-sep4] '("--")) +(define-key bmkp-jump-tags-menu [bmkp-file-all-tags-regexp-jump-other-window] + '(menu-item "File, All Tags Matching Regexp..." bmkp-file-all-tags-regexp-jump-other-window + :help "Jump to a file or dir bookmark where each tag matches a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-file-some-tags-regexp-jump-other-window] + '(menu-item "File, Any Tag Matching Regexp..." bmkp-file-some-tags-regexp-jump-other-window + :help "Jump to a file or dir bookmark where at least one tag matches a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-file-all-tags-jump-other-window] + '(menu-item "File, All Tags in Set..." bmkp-file-all-tags-jump-other-window + :help "Jump to a file or dir bookmark that has all of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-file-some-tags-jump-other-window] + '(menu-item "File, Any Tag in Set..." bmkp-file-some-tags-jump-other-window + :help "Jump to a file or dir bookmark that has some of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [jump-sep3] '("--")) +(define-key bmkp-jump-tags-menu [bmkp-find-file-all-tags-regexp-other-window] + '(menu-item "Autofile, All Tags Matching Regexp..." bmkp-find-file-all-tags-regexp-other-window + :help "Jump to a file or dir bookmark where each tag matches a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-find-file-some-tags-regexp-other-window] + '(menu-item "Autofile, Any Tag Matching Regexp..." bmkp-find-file-some-tags-regexp-other-window + :help "Jump to a file or dir bookmark where at least one tag matches a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-find-file-all-tags-other-window] + '(menu-item "Autofile, All Tags in Set..." bmkp-find-file-all-tags-other-window + :help "Jump to a file or dir bookmark that has all of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-find-file-some-tags-other-window] + '(menu-item "Autofile, Any Tag in Set..." bmkp-find-file-some-tags-other-window + :help "Jump to a file or dir bookmark that has some of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [jump-sep2] '("--")) +(define-key bmkp-jump-tags-menu [bmkp-all-tags-regexp-jump-other-window] + '(menu-item "All Tags Matching Regexp..." bmkp-all-tags-regexp-jump-other-window + :help "Jump to a bookmark that has each tag matching a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-some-tags-regexp-jump-other-window] + '(menu-item "Any Tag Matching Regexp..." bmkp-some-tags-regexp-jump-other-window + :help "Jump to a bookmark that has at least one tag matching a regexp that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-all-tags-jump-other-window] + '(menu-item "All Tags in Set..." bmkp-all-tags-jump-other-window + :help "Jump to a bookmark that has all of a set of tags that you enter")) +(define-key bmkp-jump-tags-menu [bmkp-some-tags-jump-other-window] + '(menu-item "Any Tag in Set..." bmkp-some-tags-jump-other-window + :help "Jump to a bookmark that has some of a set of tags that you enter")) +(define-key bmkp-jump-menu [bookmark-jump-other-window] + '(menu-item "Any in Other Window..." bookmark-jump-other-window + :help "Jump to a bookmark of any type, in another window")) +(define-key bmkp-jump-menu [bookmark-jump] + '(menu-item "Any..." bookmark-jump :help "Jump to a bookmark of any type, in this window")) + +;; `bmkp-find-file-menu' submenu of `File' menu +(defvar bmkp-find-file-menu (make-sparse-keymap) + "`Bookmarked File' submenu for menu-bar `File' menu.") +(define-key menu-bar-file-menu [bmkp-find-file] + (list 'menu-item "Bookmarked File" bmkp-find-file-menu)) +(define-key bmkp-find-file-menu [bmkp-find-file-all-tags-regexp-other-window] + '(menu-item "All Tags Matching Regexp..." bmkp-find-file-all-tags-regexp-other-window + :help "Visit a file or dir where each tag matches a regexp that you enter")) +(define-key bmkp-find-file-menu [bmkp-find-file-some-tags-regexp-other-window] + '(menu-item "Any Tag Matching Regexp..." bmkp-find-file-some-tags-regexp-other-window + :help "Jump to a file or dir bookmark where at least one tag matches a regexp that you enter")) +(define-key bmkp-find-file-menu [bmkp-find-file-all-tags-other-window] + '(menu-item "All Tags in Set..." bmkp-find-file-all-tags-other-window + :help "Visit a file or dir that has all of a set of tags that you enter")) +(define-key bmkp-find-file-menu [bmkp-find-file-some-tags-other-window] + '(menu-item "Any Tag in Set..." bmkp-find-file-some-tags-other-window + :help "Visit a file or dir that has some of a set of tags that you enter")) +(define-key bmkp-find-file-menu [bmkp-find-file-other-window] + '(menu-item "File..." bmkp-find-file-other-window + :help "Visit a bookmarked file or directory: an autofile bookmark.")) + +;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-key) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-key.el ends here diff --git a/auto-install/bookmark+-lit.el b/auto-install/bookmark+-lit.el new file mode 100644 index 0000000..a28610e --- /dev/null +++ b/auto-install/bookmark+-lit.el @@ -0,0 +1,1331 @@ +;;; bookmark+-lit.el --- Bookmark highlighting for Bookmark+. +;; +;; Filename: bookmark+-lit.el +;; Description: Bookmark highlighting for Bookmark+. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2010-2111, Drew Adams, all rights reserved. +;; Created: Wed Jun 23 07:49:32 2010 (-0700) +;; Last-Updated: Tue Aug 9 10:27:52 2011 (-0700) +;; By: dradams +;; Update #: 737 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-lit.el +;; Keywords: bookmarks, highlighting, bookmark+ +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `pp', `pp+'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Bookmark highlighting for Bookmark+ (library `bookmark+.el'). +;; +;; The Bookmark+ libraries are: +;; +;; `bookmark+.el' - main code library +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - code for highlighting bookmarks (this file) +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' +;; `bookmark+-1.el' - other required code (non-bmenu) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; This library (`bookmark+-lit.el') is a Bookmark+ option. If you +;; want to use it then load it before loading `bookmark+.el', so +;; that its commands can be bound to keys and menu items. +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) + +;;(@> "Index") +;; +;; Index +;; ----- +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Things Defined Here") +;; (@> "Faces (Customizable)") +;; (@> "User Options (Customizable)") +;; (@> "Internal Variables") +;; (@> "Functions") +;; (@> "Menu-List (`*-bmenu-*') Commands") +;; (@> "General Highlight Commands") +;; (@> "Other Functions") + +;;(@* "Things Defined Here") +;; +;; Things Defined Here +;; ------------------- +;; +;; Commands defined here: +;; +;; +;; `bmkp-bmenu-light', `bmkp-bmenu-light-marked', +;; `bmkp-bmenu-set-lighting', `bmkp-bmenu-set-lighting-for-marked', +;; `bmkp-bmenu-show-only-lighted', `bmkp-bmenu-unlight', +;; `bmkp-bmenu-unlight-marked', `bmkp-bookmarks-lighted-at-point', +;; `bmkp-cycle-lighted-this-buffer', +;; `bmkp-cycle-lighted-this-buffer-other-window', +;; `bmkp-light-autonamed-this-buffer', `bmkp-light-bookmark', +;; `bmkp-light-bookmark-this-buffer', `bmkp-light-bookmarks', +;; `bmkp-light-bookmarks-in-region', +;; `bmkp-light-navlist-bookmarks', +;; `bmkp-light-non-autonamed-this-buffer', +;; `bmkp-light-this-buffer', `bmkp-lighted-jump', +;; `bmkp-lighted-jump-other-window', +;; `bmkp-next-lighted-this-buffer', +;; `bmkp-next-lighted-this-buffer-repeat', +;; `bmkp-previous-lighted-this-buffer', +;; `bmkp-previous-lighted-this-buffer-repeat', +;; `bmkp-set-lighting-for-bookmark', +;; `bmkp-set-lighting-for-buffer', +;; `bmkp-set-lighting-for-this-buffer', +;; `bmkp-unlight-autonamed-this-buffer', `bmkp-unlight-bookmark', +;; `bmkp-unlight-bookmark-here', +;; `bmkp-unlight-bookmark-this-buffer', `bmkp-unlight-bookmarks', +;; `bmkp-unlight-non-autonamed-this-buffer', +;; `bmkp-unlight-this-buffer'. +;; +;; User options defined here: +;; +;; `bmkp-auto-light-relocate-when-jump-flag', +;; `bmkp-auto-light-when-jump', `bmkp-auto-light-when-set', +;; `bmkp-light-left-fringe-bitmap' (Emacs 22+), +;; `bmkp-light-priorities', `bmkp-light-right-fringe-bitmap' (Emacs +;; 22+), `bmkp-light-style-autonamed', +;; `bmkp-light-style-non-autonamed', `bmkp-light-threshold'. +;; +;; Faces defined here: +;; +;; `bmkp-light-autonamed', `bmkp-light-fringe-autonamed' (Emacs +;; 22+), `bmkp-light-fringe-non-autonamed' (Emacs 22+), +;; `bmkp-light-mark', `bmkp-light-non-autonamed'. +;; +;; Non-interactive functions defined here: +;; +;; `bmkp-a-bookmark-lighted-at-pos', +;; `bmkp-a-bookmark-lighted-on-this-line', +;; `bmkp-bookmark-overlay-p', `bmkp-default-lighted', +;; `bmkp-fringe-string' (Emacs 22+), `bmkp-get-lighting', +;; `bmkp-lighted-p', `bmkp-light-face', `bmkp-light-style', +;; `bmkp-light-style-choices', `bmkp-light-when', +;; `bmkp-lighted-alist-only', `bmkp-lighting-attribute', +;; `bmkp-lighting-face', `bmkp-lighting-style', +;; `bmkp-lighting-when', `bmkp-make/move-fringe' (Emacs 22+), +;; `bmkp-make/move-overlay-of-style', `bmkp-number-lighted', +;; `bmkp-overlay-of-bookmark', `bmkp-read-set-lighting-args', +;; `bmkp-set-lighting-for-bookmarks', +;; `bmkp-this-buffer-lighted-alist-only'. +;; +;; Internal variables defined here: +;; +;; `bmkp-autonamed-overlays', `bmkp-light-styles-alist', +;; `bmkp-non-autonamed-overlays'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(eval-when-compile (require 'cl)) ;; case + +(require 'bookmark) +;; bookmark-alist, bookmark-bmenu-bookmark, bookmark-completing-read, +;; bookmark-get-bookmark, bookmark-get-position, +;; bookmark-handle-bookmark, bookmark-maybe-load-default-file, +;; bookmark-name-from-full-record, bookmark-name-from-record, bookmark-prop-get, +;; bookmark-prop-set + +;;; Fix incompatibility introduced by gratuitous Emacs name change. +(cond ((and (fboundp 'bookmark-name-from-record) (not (fboundp 'bookmark-name-from-full-record))) + (defalias 'bookmark-name-from-full-record 'bookmark-name-from-record)) + ((and (fboundp 'bookmark-name-from-full-record) (not (fboundp 'bookmark-name-from-record))) + (defalias 'bookmark-name-from-record 'bookmark-name-from-full-record))) + +;; (eval-when-compile (require 'bookmark+-bmu)) +;; bmkp-bmenu-barf-if-not-in-menu-list, bmkp-bmenu-filter-function, +;; bmkp-bmenu-title + +;; (eval-when-compile (require 'bookmark+-1)) +;; bmkp-autonamed-bookmark-p, bmkp-autonamed-this-buffer-alist-only, +;; bmkp-autoname-format, bmkp-current-nav-bookmark, +;; bmkp-current-sort-order, bmkp-cycle-1, bmkp-default-bookmark-name, +;; bmkp-function-bookmark-p, bmkp-get-buffer-name, bmkp-jump-1, +;; bmkp-latest-bookmark-alist, bmkp-marked-bookmarks-only, +;; bmkp-msg-about-sort-order, bmkp-nav-alist, bmkp-refresh-menu-list, +;; bmkp-remove-if, bmkp-remove-if-not, bmkp-repeat-command, +;; bmkp-sequence-bookmark-p, bmkp-sort-omit, +;; bmkp-specific-buffers-alist-only, bmkp-this-buffer-alist-only, +;; bmkp-this-buffer-cycle-sort-comparer, bmkp-this-buffer-p + +(require 'pp+ nil t) ;; pp-read-expression-map + +;;;;;;;;;;;;;;;;;;;;;;; + +;; Quiet the byte-compiler +(defvar bmkp-light-left-fringe-bitmap) ; Defined in this file for Emacs 22+. +(defvar bmkp-light-right-fringe-bitmap) ; Defined in this file for Emacs 22+. +(defvar fringe-bitmaps) ; Built-in for Emacs 22+. + + +;;(@* "Faces (Customizable)") +;;; Faces (Customizable) --------------------------------------------- + +(defface bmkp-light-autonamed + '((((background dark)) (:background "#00004AA652F1")) ; a dark cyan + (t (:background "misty rose"))) ; a light pink + "*Face used to highlight an autonamed bookmark (except in the fringe)." + :group 'bookmark-plus :group 'faces) + +(when (fboundp 'fringe-columns) + (defface bmkp-light-fringe-autonamed + '((((background dark)) (:background "#B19E6A64B19E")) ; a dark magenta + (t (:background "#691DC8A2691D"))) ; a medium green + "*Face used to highlight an autonamed bookmark in the fringe." + :group 'bookmark-plus :group 'faces) + (defface bmkp-light-fringe-non-autonamed + '((((background dark)) (:background "#691DC8A2691D")) ; a medium green + (t (:foreground "Black" :background "Plum"))) ; a light magenta + "*Face used to highlight a non-autonamed bookmark in the fringe." + :group 'bookmark-plus :group 'faces)) + +(defface bmkp-light-mark '((t (:background "Plum"))) + "*Face used to mark highlighted bookmarks in the bookmark list. +This face must be combinable with face `bmkp-t-mark'." + :group 'bookmark-plus :group 'faces) + +(defface bmkp-light-non-autonamed + '((((background dark)) (:background "#B19E6A64B19E")) ; a dark magenta + (t (:background "DarkSeaGreen1"))) ; a light green + "*Face used to highlight a non-autonamed bookmark (except in the fringe)." + :group 'bookmark-plus :group 'faces) + +;;(@* "User Options (Customizable)") +;;; User Options (Customizable) -------------------------------------- + +;;;###autoload +(defcustom bmkp-auto-light-relocate-when-jump-flag t + "*Non-nil means highlight the relocated, instead of the recorded, position. +This has an effect only when the highlighting style for the bookmark +is `point'." + :type 'boolean :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-auto-light-when-jump nil + "*Which bookmarks to automatically highlight when jumped to." + :type '(choice + (const :tag "Autonamed bookmark" autonamed-bookmark) + (const :tag "Non-autonamed bookmark" non-autonamed-bookmark) + (const :tag "Any bookmark" any-bookmark) + (const :tag "Autonamed bookmarks in buffer" autonamed-in-buffer) + (const :tag "Non-autonamed bookmarks in buffer" non-autonamed-in-buffer) + (const :tag "All bookmarks in buffer" all-in-buffer) + (const :tag "None (no automatic highlighting)" nil)) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-auto-light-when-set nil + "*Which bookmarks to automatically highlight when set." + :type '(choice + (const :tag "Autonamed bookmark" autonamed-bookmark) + (const :tag "Non-autonamed bookmark" non-autonamed-bookmark) + (const :tag "Any bookmark" any-bookmark) + (const :tag "Autonamed bookmarks in buffer" autonamed-in-buffer) + (const :tag "Non-autonamed bookmarks in buffer" non-autonamed-in-buffer) + (const :tag "All bookmarks in buffer" all-in-buffer) + (const :tag "None (no automatic highlighting)" nil)) + :group 'bookmark-plus) + +;;;###autoload +(defcustom bmkp-light-priorities '((bmkp-autonamed-overlays . 160) + (bmkp-non-autonamed-overlays . 150)) + "*Priorities of bookmark highlighting overlay types. +As an idea, `ediff' uses 100+, `isearch' uses 1001." + :group 'bookmark-plus :type '(alist :key-type symbol :value-type integer)) + +;; Not used for Emacs 20-21. +(when (fboundp 'fringe-columns) + (defcustom bmkp-light-left-fringe-bitmap 'left-triangle + "*Symbol for the left fringe bitmap to use to highlight a bookmark. +This option is not used for Emacs versions before Emacs 22." + :type (cons 'choice (mapcar (lambda (bb) (list 'const bb)) fringe-bitmaps)) + :group 'bookmark-plus) + + ;; Not used for Emacs 20-21. + (defcustom bmkp-light-right-fringe-bitmap 'right-triangle + "*Symbol for the right fringe bitmap to use to highlight a bookmark. +This option is not used for Emacs versions before Emacs 22." + :type (cons 'choice (mapcar (lambda (bb) (list 'const bb)) fringe-bitmaps)) + :group 'bookmark-plus)) + +;; Must be before any options that use it. +(defvar bmkp-light-styles-alist (append '(("Line Beginning" . bol) + ("Position" . point) + ("Line" . line) + ("None" . none)) + (and (fboundp 'fringe-columns) + '(("Left Fringe" . lfringe) + ("Right Fringe" . rfringe) + ("Left Fringe + Line" . line+lfringe) + ("Right Fringe + Line" . line+rfringe)))) + "Alist of highlighting styles. Key: string description. Value: symbol.") + +;; Must be before options that use it. +(defun bmkp-light-style-choices () + "Return custom `:type' used for bookmark highlighting style choices." + (cons 'choice + (mapcar (lambda (xx) (list 'const :tag (car xx) (cdr xx))) bmkp-light-styles-alist))) + +;;;###autoload +(defcustom bmkp-light-style-autonamed (if (not (fboundp 'fringe-columns)) ; Emacs 20-21. + 'line + 'line+lfringe) + "*Default highlight style for autonamed bookmarks." + :group 'bookmark-plus :type (bmkp-light-style-choices)) + +;;;###autoload +(defcustom bmkp-light-style-non-autonamed (if (not (fboundp 'fringe-columns)) ; Emacs 20-21. + 'line + 'line+rfringe) + "*Default highlight style for non-autonamed bookmarks." + :group 'bookmark-plus :type (bmkp-light-style-choices)) + +;;;###autoload +(defcustom bmkp-light-threshold 100000 + "*Maximum number of bookmarks to highlight." + :type 'integer :group 'bookmark-plus) + +;;(@* "Internal Variables") +;;; Internal Variables ----------------------------------------------- + +(defvar bmkp-autonamed-overlays nil + "Overlays used to highlight autonamed bookmarks.") + +(defvar bmkp-non-autonamed-overlays nil + "Overlays used to highlight non-autonamed bookmarks.") + +;;(@* "Functions") +;;; Functions -------------------------------------------------------- + + +;;(@* "Menu-List (`*-bmenu-*') Commands") +;; *** Menu-List (`*-bmenu-*') Commands *** + +;;;###autoload +(defun bmkp-bmenu-show-only-lighted () ; `H S' in bookmark list + "Display a list of highlighted bookmarks (only)." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (setq bmkp-bmenu-filter-function 'bmkp-lighted-alist-only + bmkp-bmenu-title "Highlighted Bookmarks") + (let ((bookmark-alist (funcall bmkp-bmenu-filter-function))) + (setq bmkp-latest-bookmark-alist bookmark-alist) + (bookmark-bmenu-list 'filteredp)) + (when (interactive-p) + (bmkp-msg-about-sort-order (bmkp-current-sort-order) "Only highlighted bookmarks are shown"))) + +;;;###autoload +(defun bmkp-bmenu-light () ; `H H' in bookmark list + "Highlight the location of this line's bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-light-bookmark (bookmark-bmenu-bookmark) nil nil 'MSG)) + +;;;###autoload +(defun bmkp-bmenu-light-marked (&optional parg msgp) ; `H > H' in bookmark list + "Highlight the marked bookmarks." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when msgp (message "Highlighting marked bookmarks...")) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (dolist (bmk marked) (bmkp-light-bookmark bmk))) + (when msgp (message "Highlighting marked bookmarks...done"))) + +;;;###autoload +(defun bmkp-bmenu-unlight () ; `H U' in bookmark list + "Highlight the location of this line's bookmark." + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-unlight-bookmark (bookmark-bmenu-bookmark) 'NOERROR)) + +;;;###autoload +(defun bmkp-bmenu-unlight-marked (&optional parg msgp) ; `H > U' in bookmark list + "Unhighlight the marked bookmarks." + (interactive (list 'MSG)) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when msgp (message "Unhighlighting marked bookmarks...")) + (let ((marked (bmkp-marked-bookmarks-only))) + (unless marked (error "No marked bookmarks")) + (dolist (bmk marked) (bmkp-unlight-bookmark bmk t))) + (when msgp (message "Unhighlighting marked bookmarks...done"))) + +;;;###autoload +(defun bmkp-bmenu-set-lighting (style face when &optional msgp) ; `H +' in bookmark list + "Set the `lighting' property for this line's bookmark. +You are prompted for the highlight style, face, and condition (when)." + (interactive + (let* ((bmk (bookmark-bmenu-bookmark)) + (bmk-style (bmkp-lighting-style bmk)) + (bmk-face (bmkp-lighting-face bmk)) + (bmk-when (bmkp-lighting-when bmk))) + (append (bmkp-read-set-lighting-args + (and bmk-style (format "%s" (car (rassq bmk-style bmkp-light-styles-alist)))) + (and bmk-face (format "%S" bmk-face)) + (and bmk-when (format "%S" bmk-when))) + '(MSG)))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (bmkp-set-lighting-for-bookmark (bookmark-bmenu-bookmark) style face when 'MSG)) + +;;;###autoload +(defun bmkp-bmenu-set-lighting-for-marked (style face when &optional msgp) ; `H > +' in bookmark list + "Set the `lighting' property for the marked bookmarks. +You are prompted for the highlight style, face, and condition (when)." + (interactive (append (bmkp-read-set-lighting-args) '(MSG))) + (bmkp-bmenu-barf-if-not-in-menu-list) + (when msgp (message "Setting highlighting...")) + (let ((marked (bmkp-marked-bookmarks-only)) + (curr-bmk (bookmark-bmenu-bookmark))) + (unless marked (error "No marked bookmarks")) + (dolist (bmk marked) + (if (or face style when) + (bookmark-prop-set bmk 'lighting + `(,@(and face (not (eq face 'auto)) `(:face ,face)) + ,@(and style (not (eq style 'none)) `(:style ,style)) + ,@(and when (not (eq when 'auto)) `(:when ,when)))) + (bookmark-prop-set bmk 'lighting nil))) + (when (get-buffer-create "*Bookmark List*") (bmkp-refresh-menu-list curr-bmk))) + (when msgp (message "Setting highlighting...done"))) + + +;;(@* "General Highlight Commands") +;; *** General Highlight Commands *** + +;;;###autoload +(defun bmkp-bookmarks-lighted-at-point (&optional position fullp msgp) ; `C-x p =' + "Return a list of the bookmarks highlighted at point. +With no prefix arg, return the bookmark names. +With a prefix arg, return the full bookmark data. +Interactively, display the info. +Non-interactively, use the bookmarks at POSITION (default: point)." + (interactive (list (point) current-prefix-arg 'MSG)) + (unless position (setq position (point))) + (let ((bmks ()) + bmk) + (dolist (ov (overlays-at position)) + (when (setq bmk (overlay-get ov 'bookmark)) + (push (if fullp (bookmark-get-bookmark bmk) bmk) bmks))) + (if (not fullp) + (when msgp (message "%s" bmks)) + (setq bmks (mapcar #'bookmark-get-bookmark bmks)) + (when msgp (pp-eval-expression 'bmks))) + bmks)) + +;;;###autoload +(defun bmkp-lighted-jump (bookmark-name &optional use-region-p) ; `C-x j h' + "Jump to a highlighted bookmark. +This is a specialization of `bookmark-jump' - see that, in particular +for info about using a prefix argument." + (interactive + (let ((alist (bmkp-lighted-alist-only))) + (unless alist (error "No highlighted bookmarks")) + (list (bookmark-completing-read "Jump to highlighted bookmark" nil alist) current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'switch-to-buffer use-region-p)) + +;;;###autoload +(defun bmkp-lighted-jump-other-window (bookmark-name &optional use-region-p) ; `C-x 4 j h' + "Jump to a highlighted bookmark in another window. +See `bmkp-lighted-jump'." + (interactive + (let ((alist (bmkp-lighted-alist-only))) + (unless alist (error "No highlighted bookmarks")) + (list (bookmark-completing-read "Jump to highlighted bookmark in another window" nil alist) + current-prefix-arg))) + (bmkp-jump-1 bookmark-name 'bmkp-select-buffer-other-window use-region-p)) + +;;;###autoload +(defun bmkp-unlight-bookmark (bookmark &optional noerrorp msgp) + "Unhighlight BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record." + (interactive + (let ((lighted-bmks (bmkp-lighted-alist-only))) + (unless lighted-bmks (error "No highlighted bookmarks")) + (list (bookmark-completing-read "UNhighlight bookmark" (bmkp-default-lighted) lighted-bmks) + nil + 'MSG))) + (let* ((bmk (bookmark-get-bookmark bookmark 'noerror)) + (bmk-name (bookmark-name-from-full-record bmk)) + (autonamedp (bmkp-autonamed-bookmark-p bmk))) + (when bmk ; Skip bad bookmark, but not already highlighted bookmark. + (unless (or noerrorp (bmkp-lighted-p bmk-name)) + (error "Bookmark `%s' is not highlighted" bmk-name)) + (dolist (ov (if autonamedp bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + (when (equal bmk-name (overlay-get ov 'bookmark)) (delete-overlay ov)))) + (when msgp (message "UNhighlighted bookmark `%s'" bmk-name)))) + +;;;###autoload +(defun bmkp-unlight-bookmark-here (&optional noerrorp msgp) ; `C-x p C-u' + "Unhighlight a bookmark at point or the same line (in that order)." + (interactive (list nil 'MSG)) + (let ((bmk (or (bmkp-a-bookmark-lighted-at-pos) (bmkp-a-bookmark-lighted-on-this-line)))) + (unless bmk (error "No highlighted bookmark on this line")) + (bmkp-unlight-bookmark bmk noerrorp msgp))) + +;;;###autoload +(defun bmkp-unlight-bookmark-this-buffer (bookmark &optional noerrorp msgp) ; `C-x p u' + "Unhighlight a BOOKMARK in this buffer. +BOOKMARK is a bookmark name or a bookmark record. +With a prefix arg, choose from all bookmarks, not just those in this +buffer." + (interactive + (let ((lighted-bmks (if current-prefix-arg + (bmkp-lighted-alist-only) + (bmkp-this-buffer-lighted-alist-only))) + (msg-suffix (if current-prefix-arg "" " in this buffer"))) + (unless lighted-bmks (error "No highlighted bookmarks%s" msg-suffix)) + (list (bookmark-completing-read (format "UNhighlight bookmark%s in this buffer" msg-suffix) + (bmkp-default-lighted) + lighted-bmks) + nil + 'MSG))) + (bmkp-unlight-bookmark bookmark noerrorp msgp)) + +;;;###autoload +(defun bmkp-unlight-bookmarks (&optional overlays-symbols this-buffer-p msgp) ; `C-x p U' + "Unhighlight bookmarks. +A prefix argument determines which bookmarks to unhighlight: + none - Current buffer, all bookmarks. + >= 0 - Current buffer, autonamed bookmarks only. + < 0 - Current buffer, non-autonamed bookmarks only. + C-u - All buffers (all bookmarks)." + (interactive (list (cond ((or (not current-prefix-arg) (consp current-prefix-arg)) + '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + ((natnump current-prefix-arg) '(bmkp-autonamed-overlays)) + (current-prefix-arg '(bmkp-non-autonamed-overlays))) + (or (not current-prefix-arg) (atom current-prefix-arg)) + 'MSG)) + (unless overlays-symbols + (setq overlays-symbols '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))) + (let ((count 0) + (count-auto 0) + (count-non-auto 0) + (this-buf (current-buffer))) + (dolist (ov-symb overlays-symbols) + (dolist (ov (symbol-value ov-symb)) + (let ((ov-buf (overlay-buffer ov))) + (when (and ov-buf (or (not this-buffer-p) (eq ov-buf this-buf))) + (when (eq 'bmkp-autonamed-overlays ov-symb) + (setq count-auto (1+ count-auto) + count (1+ count))) + (when (eq 'bmkp-non-autonamed-overlays ov-symb) + (setq count-non-auto (1+ count-non-auto) + count (1+ count))) + (delete-overlay ov))))) + (when msgp (message "UNhighlighted %d bookmarks %s: %d autonamed, %d other" + count (if this-buffer-p "in this buffer" "(all buffers)") + count-auto count-non-auto)))) + +;;;###autoload +(defun bmkp-unlight-autonamed-this-buffer (&optional everywherep) + "Unhighlight autonamed bookmarks. +No prefix arg: unhighlight them only in the current buffer. +Prefix arg, unhighlight them everywhere." + (interactive "P") + (bmkp-unlight-bookmarks '(bmkp-autonamed-overlays) (not everywherep))) + +;;;###autoload +(defun bmkp-unlight-non-autonamed-this-buffer (&optional everywherep) + "Unhighlight non-autonamed bookmarks. +No prefix arg: unhighlight them only in the current buffer. +Prefix arg, unhighlight them everywhere." + (interactive "P") + (bmkp-unlight-bookmarks '(bmkp-non-autonamed-overlays) (not everywherep))) + +;;;###autoload +(defun bmkp-unlight-this-buffer () + "Unhighlight all bookmarks in the current buffer." + (interactive) + (bmkp-unlight-bookmarks)) + +;;;###autoload +(defun bmkp-set-lighting-for-bookmark (bookmark-name style face when &optional msgp light-now-p) + "Set the `lighting' property for bookmark BOOKMARK-NAME. +You are prompted for the bookmark, highlight style, face, and condition. +With a prefix argument, do not highlight now. + +Non-interactively: +STYLE, FACE, and WHEN are as for a bookmark's `lighting' property + entries, or nil if no such entry. +Non-nil MSGP means display a highlighting progress message. +Non-nil LIGHT-NOW-P means apply the highlighting now." + (interactive + (let* ((bmk (bookmark-completing-read "Highlight bookmark" + (or (bmkp-default-lighted) + (bmkp-default-bookmark-name)))) + (bmk-style (bmkp-lighting-style bmk)) + (bmk-face (bmkp-lighting-face bmk)) + (bmk-when (bmkp-lighting-when bmk))) + (append (list bmk) + (bmkp-read-set-lighting-args + (and bmk-style (format "%s" (car (rassq bmk-style bmkp-light-styles-alist)))) + (and bmk-face (format "%S" bmk-face)) + (and bmk-when (format "%S" bmk-when))) + (list 'MSGP (not current-prefix-arg))))) + (when msgp (message "Setting highlighting...")) + (if (or face style when) + (bookmark-prop-set bookmark-name + 'lighting `(,@(and face (not (eq face 'auto)) `(:face ,face)) + ,@(and style (not (eq style 'none)) `(:style ,style)) + ,@(and when (not (eq when 'auto)) `(:when ,when)))) + (bookmark-prop-set bookmark-name 'lighting nil)) + (when (get-buffer-create "*Bookmark List*") (bmkp-refresh-menu-list bookmark-name)) + (when msgp (message "Setting highlighting...done")) + (when light-now-p (bmkp-light-bookmark bookmark-name nil nil msgp))) ; This msg is more informative. + +;;;###autoload +(defun bmkp-set-lighting-for-buffer (buffer style face when &optional msgp light-now-p) + "Set the `lighting' property for each of the bookmarks for BUFFER. +You are prompted for the highlight style, face, and condition (when). +With a prefix argument, do not highlight now. + +Non-interactively: +STYLE, FACE, and WHEN are as for a bookmark's `lighting' property + entries, or nil if no such entry. +Non-nil MSGP means display a highlighting progress message. +Non-nil LIGHT-NOW-P means apply the highlighting now." + (interactive (append (list (bmkp-completing-read-buffer-name)) + (bmkp-read-set-lighting-args) + (list 'MSGP (not current-prefix-arg)))) + (bmkp-set-lighting-for-bookmarks + (let ((bmkp-last-specific-buffer buffer)) (bmkp-last-specific-buffer-alist-only)) + style face when msgp light-now-p)) + +;;;###autoload +(defun bmkp-set-lighting-for-this-buffer (style face when &optional msgp light-now-p) + "Set the `lighting' property for each of the bookmarks for this buffer. +You are prompted for the highlight style, face, and condition (when). +With a prefix argument, do not highlight now. + +Non-interactively: +STYLE, FACE, and WHEN are as for a bookmark's `lighting' property + entries, or nil if no such entry. +Non-nil MSGP means display a highlighting progress message. +Non-nil LIGHT-NOW-P means apply the highlighting now." + (interactive (append (bmkp-read-set-lighting-args) (list 'MSGP (not current-prefix-arg)))) + (bmkp-set-lighting-for-bookmarks (bmkp-this-buffer-alist-only) style face when msgp light-now-p)) + +(defun bmkp-set-lighting-for-bookmarks (alist style face when &optional msgp light-now-p) + "Set the `lighting' property for each of the bookmarks in ALIST. +STYLE, FACE, and WHEN are as for a bookmark's `lighting' property + entries, or nil if no such entry. +Non-nil MSGP means display a highlighting progress message. +Non-nil LIGHT-NOW-P means apply the highlighting now." + (when msgp (message "Setting highlighting...")) + (dolist (bmk alist) (bmkp-set-lighting-for-bookmark bmk style face when)) ; No MSGP arg here. + (when msgp (message "Setting highlighting...done")) + (when light-now-p (bmkp-light-bookmarks alist nil msgp))) ; Do separately so we get its message. + +;;;###autoload +(defun bmkp-light-bookmark (bookmark &optional style face msgp pointp) + "Highlight BOOKMARK. +With a prefix arg you are prompted for the style and/or face to use: + Plain prefix arg (`C-u'): prompt for both style and face. + Numeric non-negative arg: prompt for face. + Numeric negative arg: prompt for style. + +Non-interactively: + BOOKMARK is a bookmark name or a bookmark record. + STYLE and FACE override the defaults. + POINT-P non-nil means highlight point rather than the recorded + bookmark `position." + (interactive + (let* ((bmk (bookmark-completing-read "Highlight bookmark" (bmkp-default-bookmark-name))) + (sty (and current-prefix-arg (or (consp current-prefix-arg) + (<= (prefix-numeric-value current-prefix-arg) 0)) + (cdr (assoc (let ((completion-ignore-case t)) + (completing-read + "Style: " bmkp-light-styles-alist nil t nil nil + (and (bmkp-lighting-style bmk) + (format "%s" (car (rassq (bmkp-lighting-style bmk) + bmkp-light-styles-alist)))))) + bmkp-light-styles-alist)))) + (fac (and current-prefix-arg (or (consp current-prefix-arg) + (natnump (prefix-numeric-value current-prefix-arg))) + (not (member sty '(lfringe rfringe none))) ; No face possible for these. + (condition-case nil ; Emacs 22+ accepts a default. + (read-face-name "Face: " (format "%S" (bmkp-lighting-face bmk))) + (wrong-number-of-arguments (read-face-name "Face: ")))))) + (list bmk sty fac 'MSG))) + (let* ((bmkp-use-region nil) ; Inhibit region handling. + (bmk (bookmark-get-bookmark bookmark (not msgp))) ; Error if interactive. + (bmk-name (bookmark-name-from-full-record bmk)) + (pos (bookmark-get-position bmk)) + (buf (and bmk (bmkp-get-buffer-name bmk))) + (autonamedp (bmkp-autonamed-bookmark-p bmk)) + (styl (or style (and bmk (bmkp-light-style bmk)))) + (fac (or face (and bmk (not (member styl '(lfringe rfringe none))) + (bmkp-light-face bmk)))) + (passes-when-p (and bmk (or face style ; Always highlight if changed face or style. + (bmkp-light-when bmk)))) + (nb-lit (bmkp-number-lighted)) + bmk-ov) + (catch 'bmkp-light-bookmark + (when bmk ; Just skip bad bookmark if not interactive. + (cond ((setq bmk-ov (bmkp-overlay-of-bookmark bmk)) + (if (not (or style face)) + (when msgp ; No-op batch. + (error "Already highlighted - use prefix arg to change")) + (when style (bmkp-make/move-overlay-of-style style pos autonamedp bmk-ov)) + (when (and face (not (memq styl '(lfringe rfringe none)))) + (overlay-put bmk-ov 'face face))) + (when msgp (message "%sighlighted bookmark `%s'" (if bmk-ov "H" "UNh") bmk-name))) + (passes-when-p + (save-excursion + + ;; See note in comments of `bmkp-light-bookmarks' - same considerations here. + ;; (let ((bmkp-jump-display-function nil)) (bookmark-handle-bookmark bmk)) + ;; + (with-current-buffer (or (and buf (get-buffer buf)) (current-buffer)) + + ;; POINTP is non-nil when `bmkp-light-bookmark' is called from + ;; `bookmark--jump-via'. + (when (and pointp bmkp-auto-light-relocate-when-jump-flag) + (setq pos (point))) + (when (and pos (< pos (point-max))) + (let ((ov (bmkp-make/move-overlay-of-style styl pos autonamedp))) + (when ov ; nil means `none' style. + (let ((ovs (if autonamedp + 'bmkp-autonamed-overlays + 'bmkp-non-autonamed-overlays))) + (push ov (symbol-value ovs))) + (when (and (not (bmkp-lighted-p bmk)) + (> (setq nb-lit (1+ nb-lit)) bmkp-light-threshold)) + (setq nb-lit (1- nb-lit)) + (throw 'bmkp-light-bookmark bmk)) + (overlay-put ov 'priority + (or (cdr (assoc (if autonamedp + 'bmkp-autonamed-overlays + 'bmkp-non-autonamed-overlays) + bmkp-light-priorities)) + (apply #'min (mapcar #'cdr bmkp-light-priorities)))) + (unless (memq styl '(lfringe rfringe none)) (overlay-put ov 'face fac)) + (overlay-put ov 'evaporate t) + (overlay-put ov 'category 'bookmark-plus) + (overlay-put ov 'bookmark bmk-name)) + (when msgp + (message "%sighlighted bookmark `%s'" (if ov "H" "UNh") bmk-name))))))) + (t + (when msgp (message "Bookmark's condition canceled highlighting")))))))) + +;;;###autoload +(defun bmkp-light-bookmark-this-buffer (bookmark &optional style face msgp) ; `C-x p h' + "Highlight a BOOKMARK in the current buffer. +With a prefix arg you are prompted for the style and/or face to use: + Plain prefix arg (`C-u'): prompt for both style and face. + Numeric non-negative arg: prompt for face. + Numeric negative arg: prompt for style. +See `bmkp-light-boookmark' for argument descriptions." + (interactive + (let* ((bmk (bookmark-completing-read "Highlight bookmark" nil (bmkp-this-buffer-alist-only))) + (sty (and current-prefix-arg (or (consp current-prefix-arg) + (<= (prefix-numeric-value current-prefix-arg) 0)) + (cdr (assoc (let ((completion-ignore-case t)) + (completing-read + "Style: " bmkp-light-styles-alist nil t nil nil + (and (bmkp-lighting-style bmk) + (format "%s" (car (rassq (bmkp-lighting-style bmk) + bmkp-light-styles-alist)))))) + bmkp-light-styles-alist)))) + (fac (and current-prefix-arg (or (consp current-prefix-arg) + (natnump (prefix-numeric-value current-prefix-arg))) + (not (member sty '(lfringe rfringe none))) ; No face possible for these. + (condition-case nil ; Emacs 22+ accepts a default. + (read-face-name "Face: " (format "%S" (bmkp-lighting-face bmk))) + (wrong-number-of-arguments (read-face-name "Face: ")))))) + (list bmk sty fac 'MSG))) + (bmkp-light-bookmark bookmark style face msgp)) + +;;;###autoload +(defun bmkp-light-bookmarks (&optional alist overlays-symbols msgp) ; `C-x p H' + "Highlight bookmarks. +A prefix argument determines which bookmarks to highlight: + none - Current buffer, all bookmarks. + = 0 - Current buffer, highlighted bookmarks only (rehighlight). + > 0 - Current buffer, autonamed bookmarks only. + < 0 - Current buffer, non-autonamed bookmarks only. + C-u - All buffers (all bookmarks) - after confirmation. + C-u C-u - Navlist (all bookmarks). + +Non-interactively, ALIST is the alist of bookmarks to highlight." + (interactive + (list (cond ((not current-prefix-arg) (bmkp-this-buffer-alist-only)) + ((consp current-prefix-arg) (if (> (prefix-numeric-value current-prefix-arg) 4) + bmkp-nav-alist + (unless + (y-or-n-p + "Confirm highlighting bookmarks in ALL buffers ") + (error "Canceled highlighting")) + (bmkp-specific-buffers-alist-only + (mapcar #'buffer-name (buffer-list))))) + ((> current-prefix-arg 0) (bmkp-autonamed-this-buffer-alist-only)) + ((< current-prefix-arg 0) (bmkp-remove-if #'bmkp-autonamed-bookmark-p + (bmkp-this-buffer-alist-only))) + ((= current-prefix-arg 0) (bmkp-this-buffer-lighted-alist-only))) + (cond ((or (not current-prefix-arg) (consp current-prefix-arg)) + '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + ((natnump current-prefix-arg) '(bmkp-autonamed-overlays)) + (current-prefix-arg '(bmkp-non-autonamed-overlays))) + 'MSG)) + (unless overlays-symbols + (setq overlays-symbols '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))) + (let ((bmkp-use-region nil) ; Inhibit region handling. + (total 0) + (nb-auto 0) + (nb-non-auto 0) + (new-auto 0) + (new-non-auto 0) + (nb-lit (bmkp-number-lighted)) + bmk bmk-name autonamedp face style pos buf bmk-ov passes-when-p) + (catch 'bmkp-light-bookmarks + (dolist (bookmark alist) + (setq bmk (bookmark-get-bookmark bookmark 'noerror) + bmk-name (and bmk (bookmark-name-from-full-record bmk)) + autonamedp (bmkp-autonamed-bookmark-p bmk-name) + face (and bmk (bmkp-light-face bmk)) + style (and bmk (bmkp-light-style bmk)) + bmk-ov (bmkp-overlay-of-bookmark bmk) + passes-when-p (and bmk (or bmk-ov ; Always highlight if already highlighted. + (bmkp-light-when bmk)))) + (when (and bmk passes-when-p) ; Skip bad bookmark and respect `:when' (unless highlighted). + (setq pos (bookmark-get-position bmk) + buf (bmkp-get-buffer-name bmk)) + (save-excursion + ;; An alternative here would be to call the handler at let it do the highlighting. + ;; In that case, we would need at least to bind the display function to nil while + ;; handling, so we don't also do the jump. In particular, we don't want to pop to + ;; the bookmark in a new window or frame. + ;; Calling the handler would be good for some cases, such as Info, where the + ;; highlighting is not really specific to the buffer but to a narrowed part of it. + ;; + ;; (let ((bmkp-jump-display-function nil)) (bookmark-handle-bookmark bmk)) + ;; + ;; But calling the handler is in general the wrong thing. We don't want highlighting + ;; all Dired bookmarks in a given directory to also do all the file marking and + ;; subdir hiding associated with each of the bookmarks. So we do just the + ;; highlighting, no handling, putting the code in side `with-current-buffer'. + (with-current-buffer (or (and buf (get-buffer buf)) (current-buffer)) + (when (and pos (< pos (point-max))) + (dolist (ov-symb overlays-symbols) + (when (or (and (eq 'bmkp-autonamed-overlays ov-symb) autonamedp) + (and (eq 'bmkp-non-autonamed-overlays ov-symb) (not autonamedp))) + (let ((ov (bmkp-make/move-overlay-of-style style pos autonamedp bmk-ov))) + (when ov ; nil means `none' style. + (set ov-symb (cons ov (symbol-value ov-symb))) + (when (eq 'bmkp-autonamed-overlays ov-symb) + (unless bmk-ov (setq new-auto (1+ new-auto))) + (setq nb-auto (1+ nb-auto))) + (when (eq 'bmkp-non-autonamed-overlays ov-symb) + (unless bmk-ov (setq new-non-auto (1+ new-non-auto))) + (setq nb-non-auto (1+ nb-non-auto))) + (when (and (not bmk-ov) (> (setq nb-lit (1+ nb-lit)) bmkp-light-threshold)) + (setq nb-lit (1- nb-lit)) + (throw 'bmkp-light-bookmarks bmk)) + (setq total (1+ total)) + (overlay-put ov 'priority ; > ediff's 100+, < isearch-overlay's 1001. + (or (cdr (assoc ov-symb bmkp-light-priorities)) + (apply #'min (mapcar #'cdr bmkp-light-priorities)))) + (unless (memq style '(lfringe rfringe none)) (overlay-put ov 'face face)) + (overlay-put ov 'evaporate t) + (overlay-put ov 'category 'bookmark-plus) + (overlay-put ov 'bookmark bmk-name))))))))))) + (when msgp (message "%s New: %d auto + %d other, Total: %d auto + %d other = %d" + (if (consp current-prefix-arg) + (if (> (prefix-numeric-value current-prefix-arg) 4) + "[Navlist]" + "[All buffers]") + "[This buffer]") + new-auto new-non-auto nb-auto nb-non-auto total)))) + +;;;###autoload +(defun bmkp-light-navlist-bookmarks (&optional overlays-symbols msgp) + "Highlight bookmarks in the navigation list. +No prefix arg: all bookmarks. +Prefix arg >= 0: autonamed bookmarks only. +Prefix arg < 0: non-autonamed bookmarks only." + (interactive + (list (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays)) + (current-prefix-arg '(bmkp-non-autonamed-overlays))) + 'MSG)) + (bmkp-light-bookmarks bmkp-nav-alist overlays-symbols msgp)) + +;;;###autoload +(defun bmkp-light-this-buffer (&optional overlays-symbols msgp) + "Highlight bookmarks in the current buffer. +No prefix arg: all bookmarks. +Prefix arg >= 0: autonamed bookmarks only. +Prefix arg < 0: non-autonamed bookmarks only." + (interactive + (list (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays)) + (current-prefix-arg '(bmkp-non-autonamed-overlays))) + 'MSG)) + (bmkp-light-bookmarks (bmkp-this-buffer-alist-only) overlays-symbols msgp)) + +;;;###autoload +(defun bmkp-light-bookmarks-in-region (start end &optional overlays-symbols msgp) + "Highlight bookmarks in the region. +No prefix arg: all bookmarks. +Prefix arg >= 0: autonamed bookmarks only. +Prefix arg < 0: non-autonamed bookmarks only." + (interactive + (list (region-beginning) + (region-end) + (cond ((not current-prefix-arg) '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays)) + ((natnump (prefix-numeric-value current-prefix-arg)) '(bmkp-autonamed-overlays)) + (current-prefix-arg '(bmkp-non-autonamed-overlays))) + 'MSG)) + (bmkp-light-bookmarks (bmkp-remove-if-not (lambda (bmk) (let ((pos (bookmark-get-position bmk))) + (and (>= pos start) (<= pos end)))) + (bmkp-this-buffer-alist-only)) + overlays-symbols msgp)) + +;;;###autoload +(defun bmkp-light-autonamed-this-buffer (&optional msgp) + "Highlight all autonamed bookmarks." + (interactive (list 'MSG)) + (bmkp-light-bookmarks (bmkp-autonamed-this-buffer-alist-only) '(bmkp-autonamed-overlays) msgp)) + +;;;###autoload +(defun bmkp-light-non-autonamed-this-buffer (&optional msgp) + "Highlight all non-autonamed bookmarks." + (interactive (list 'MSG)) + (bmkp-light-bookmarks (bmkp-remove-if #'bmkp-autonamed-bookmark-p (bmkp-this-buffer-alist-only)) + '(bmkp-non-autonamed-overlays) msgp)) + +;;;###autoload +(defun bmkp-cycle-lighted-this-buffer (increment &optional other-window startoverp) + "Cycle through highlighted bookmarks in this buffer by INCREMENT. +Positive INCREMENT cycles forward. Negative INCREMENT cycles backward. +Interactively, the prefix arg determines INCREMENT: + Plain `C-u': 1 + otherwise: the numeric prefix arg value + +To change the sort order, you can filter the `*Bookmark List*' to show +only highlighted bookmarks for this buffer, sort the bookmarks there, +and use `\\[bmkp-choose-navlist-from-bookmark-list]', choosing `CURRENT *Bookmark List*' as the +navigation list. + +Then you can cycle the bookmarks using `bookmark-cycle' +\(`\\[bmkp-next-bookmark-repeat]' etc.), instead of `bookmark-cycle-lighted-this-buffer'. + +In Lisp code: + Non-nil OTHER-WINDOW means jump to the bookmark in another window. + Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the + first bookmark in the navlist." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) nil startovr))) + (bookmark-maybe-load-default-file) + (let ((bmkp-sort-comparer bmkp-this-buffer-cycle-sort-comparer)) + (setq bmkp-nav-alist (bmkp-sort-omit (bmkp-this-buffer-lighted-alist-only)))) + (unless bmkp-nav-alist (error "No lighted bookmarks for cycling")) + (unless (and bmkp-current-nav-bookmark (not startoverp) + (bookmark-get-bookmark bmkp-current-nav-bookmark 'NOERROR) + (bmkp-this-buffer-p bmkp-current-nav-bookmark)) ; Exclude desktops etc. + (setq bmkp-current-nav-bookmark (car bmkp-nav-alist))) + (if (bmkp-cycle-1 increment other-window startoverp) + (unless (or (bmkp-sequence-bookmark-p bmkp-current-nav-bookmark) + (bmkp-function-bookmark-p bmkp-current-nav-bookmark)) + (message "Position: %9d, Bookmark: `%s'" (point) (bookmark-name-from-full-record + bmkp-current-nav-bookmark))) + (message "Invalid bookmark: `%s'" (bookmark-name-from-full-record bmkp-current-nav-bookmark)))) + +;;;###autoload +(defun bmkp-cycle-lighted-this-buffer-other-window (increment &optional startoverp) + "Same as `bmkp-cycle-lighted-this-buffer' but uses another window." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-lighted-this-buffer increment 'OTHER-WINDOW startoverp)) + +;;;###autoload +(defun bmkp-next-lighted-this-buffer (n &optional startoverp) ; Repeatable key, e.g. `S-f2' + "Jump to the Nth-next highlighted bookmark in the current buffer. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one. +See also `bmkp-cycle-lighted-this-buffer'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-lighted-this-buffer n nil startoverp)) + +;;;###autoload +(defun bmkp-previous-lighted-this-buffer (n &optional startoverp) ; Repeatable key, e.g. `f2' + "Jump to the Nth-previous highlighted bookmark in the current buffer. +See `bmkp-next-lighted-this-buffer'." + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (bmkp-cycle-lighted-this-buffer (- n) nil startoverp)) + +;;;###autoload +(defun bmkp-next-lighted-this-buffer-repeat (arg) ; `C-x p C-down' + "Jump to the Nth next highlighted bookmark in the current buffer. +This is a repeatable version of `bmkp-next-bookmark-this-buffer'. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one (and no repeat)." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-next-lighted-this-buffer)) + +;;;###autoload +(defun bmkp-previous-lighted-this-buffer-repeat (arg) ; `C-x p C-up' + "Jump to the Nth previous highlighted bookmark in the current buffer. +See `bmkp-next-lighted-this-buffer-repeat'." + (interactive "P") + (require 'repeat) + (bmkp-repeat-command 'bmkp-previous-lighted-this-buffer)) + + +;;(@* "Other Functions") +;; *** Other Functions *** + +(defun bmkp-light-face (bookmark) + "Return the face to use to highlight BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Returns: + nil if BOOKMARK is not a valid bookmark; + the `:face' specified by BOOKMARK's `lighting' property, if any; + `bmkp-light-autonamed' if BOOKMARK is an autonamed bookmark; + or `bmkp-light-non-autonamed' otherwise." + (setq bookmark (bookmark-get-bookmark bookmark 'noerror)) + (or (bmkp-lighting-face bookmark) + (and bookmark (if (string-match (format bmkp-autoname-format ".*") + (bookmark-name-from-full-record bookmark)) + 'bmkp-light-autonamed + 'bmkp-light-non-autonamed)))) + +(defun bmkp-light-style (bookmark) + "Return the style to use to highlight BOOKMARK. +BOOKMARK is a bookmark name or a bookmark record. +Returns: + nil if BOOKMARK is not a valid bookmark; + the `:style' specified by BOOKMARK's `lighting' property, if any; + the value of `bmkp-light-style-autonamed' if autonamed; + or the value of `bmkp-light-style-non-autonamed' otherwise." + (setq bookmark (bookmark-get-bookmark bookmark 'noerror)) + (or (bmkp-lighting-style bookmark) + (and bookmark (if (string-match (format bmkp-autoname-format ".*") + (bookmark-name-from-full-record bookmark)) + bmkp-light-style-autonamed + bmkp-light-style-non-autonamed)))) + +(defun bmkp-light-when (bookmark) + "Return non-nil if BOOKMARK should be highlighted. +BOOKMARK's `:when' condition is used to determine this. +BOOKMARK is a bookmark name or a bookmark record." + (setq bookmark (bookmark-get-bookmark bookmark 'noerror)) + (let ((this-bookmark bookmark) + (this-bookmark-name (bookmark-name-from-full-record bookmark)) + (when-sexp (bmkp-lighting-when bookmark))) + (not (eq :no-light (eval when-sexp))))) + +(defun bmkp-lighting-face (bookmark) + "`:face' specified by BOOKMARK's `lighting', or nil if no `:face' entry. +BOOKMARK is a bookmark name or a bookmark record. + +The `:face' entry is the face (a symbol) used to highlight BOOKMARK. +Alternatively, it can be `auto' or nil, which both mean the same as +having no `:face' entry: do not override automatic face choice." + (bmkp-lighting-attribute bookmark :face)) + +(defun bmkp-lighting-style (bookmark) + "`:style' specified by BOOKMARK's `lighting', or nil if no `:style' entry. +BOOKMARK is a bookmark name or a bookmark record. + +The `:style' entry is the style used to highlight BOOKMARK. +It is a value acceptable for `bmkp-light-style-non-autonamed'. +Alternatively, it can be `auto' or nil, which both mean the same as +having no `:style' entry: do not override automatic style choice." + (bmkp-lighting-attribute bookmark :style)) + +(defun bmkp-lighting-when (bookmark) + "`:when' specified by BOOKMARK's `lighting', or nil if no `:when' entry. +BOOKMARK is a bookmark name or a bookmark record. + +The `:when' entry is a sexp that is eval'd when you try to highlight +BOOKMARK. If the result is the symbol `:no-light', then do not +highlight. Otherwise, highlight. (Note that highlighting happens if +the value is nil or there is no `:when' entry.)" + (bmkp-lighting-attribute bookmark :when)) + +(defun bmkp-lighting-attribute (bookmark attribute) + "ATTRIBUTE specified by BOOKMARK's `lighting', or nil if no such attribute. +BOOKMARK is a bookmark name or a bookmark record. +ATTRIBUTE is `:style' or `:face'." + (setq bookmark (bookmark-get-bookmark bookmark 'noerror)) + (let* ((lighting (and bookmark (bmkp-get-lighting bookmark))) + (attr (and (consp lighting) (plist-get lighting attribute)))) + (when (and (eq 'auto attr) (not (eq :when attribute))) (setq attr nil)) + attr)) + +(defun bmkp-get-lighting (bookmark) + "Return the `lighting' property list for BOOKMARK. +This is the cdr of the `lighting' entry (i.e. with `lighting' removed). +BOOKMARK is a bookmark name or a bookmark record." + (bookmark-prop-get bookmark 'lighting)) + +(defun bmkp-bookmark-overlay-p (overlay) + "Return non-nil if OVERLAY is a bookmark overlay." + (and (overlayp overlay) (overlay-get overlay 'bookmark))) + +(defun bmkp-default-lighted () + "Return a highlighted bookmark at point or on this line, or nil if none. +For Emacs 23+, if there is a highlighted bookmark at point, return a + list of all such." + (or (if (> emacs-major-version 22) + (bmkp-bookmarks-lighted-at-point) + (bmkp-a-bookmark-lighted-at-pos)) + (bmkp-a-bookmark-lighted-on-this-line))) + +(defun bmkp-a-bookmark-lighted-on-this-line (&optional fullp msgp) + "Return a bookmark highlighted on the current line or nil if none. +The search for a highlighted bookmark moves left to bol from point, + then right to eol from point. +Return the bookmark name or, if FULLP non-nil, the full bookmark data." + (let ((pos (point)) + (bol (1+ (line-beginning-position))) + (eol (1- (line-end-position))) + bmk) + (catch 'bmkp-a-bookmark-lighted-on-this-line + (while (>= pos bol) + (when (setq bmk (bmkp-a-bookmark-lighted-at-pos pos)) + (throw 'bmkp-a-bookmark-lighted-on-this-line bmk)) + (setq pos (1- pos))) + (while (<= pos eol) + (when (setq bmk (bmkp-a-bookmark-lighted-at-pos pos)) + (throw 'bmkp-a-bookmark-lighted-on-this-line bmk)) + (setq pos (1+ pos))) + nil) + (when (and bmk fullp) (setq bmk (bookmark-get-bookmark bmk))) + bmk)) + +(defun bmkp-a-bookmark-lighted-at-pos (&optional position fullp) + "Return a bookmark highlighted at POSITION or nil if none. +POSITION defaults to point. +Return the bookmark name or, if FULLP non-nil, the full bookmark data." + (unless position (setq position (point))) + (let (bmk) + (catch 'bmkp-a-bookmark-lighted-at-pos + (dolist (ov (overlays-at position)) + (when (setq bmk (overlay-get ov 'bookmark)) + (throw 'bmkp-a-bookmark-lighted-at-pos bmk))) + nil) + (when (and bmk fullp) (setq bmk (bookmark-get-bookmark bmk))) + bmk)) + +(defun bmkp-read-set-lighting-args (&optional default-style default-face default-when) + "Read args STYLE, FACE, and WHEN for commands that set `lighting' prop. +Optional args are the default values (strings) for reading new values." + (let* ((icicle-unpropertize-completion-result-flag t) + (style (cdr (assoc (let ((completion-ignore-case t)) + (completing-read "Style: " bmkp-light-styles-alist + nil t nil nil default-style)) + bmkp-light-styles-alist))) + (face (and (not (member style '(lfringe rfringe none))) ; No face possible for these. + (y-or-n-p "Change face? ") ; Allow nil, for `auto'. + (condition-case nil ; Emacs 22+ accepts a default. + (read-face-name "Face: " default-face) + (wrong-number-of-arguments (read-face-name "Face: "))))) + (when-cands `(("auto" . nil) + ("conditionally (read sexp)") + ("never" . :no-light))) + (when (completing-read "When: " when-cands nil t nil nil + (if default-when "conditionally (read sexp)" "auto"))) + (evald (if (string-match "^con" when) + (read-from-minibuffer "Highlight when (sexp): " nil + (if (boundp 'pp-read-expression-map) + pp-read-expression-map + read-expression-map) + t 'read-expression-history default-when) + (cdr (assoc when when-cands))))) + (list style face evald))) + +(defun bmkp-lighted-alist-only () + "`bookmark-alist', with only highlighted bookmarks. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (bmkp-lighted-p bmk)) bookmark-alist)) + +(defun bmkp-this-buffer-lighted-alist-only () + "`bookmark-alist', with only highlighted bookmarks for current buffer. +A new list is returned (no side effects)." + (bookmark-maybe-load-default-file) + (bmkp-remove-if-not (lambda (bmk) (and (bmkp-this-buffer-p bmk) (bmkp-lighted-p bmk))) + bookmark-alist)) + +(defun bmkp-number-lighted (&optional overlays-symbols) + "Number of bookmarks highlighted." + (unless overlays-symbols + (setq overlays-symbols '(bmkp-autonamed-overlays bmkp-non-autonamed-overlays))) + (let ((count 0)) + (dolist (ov-symb overlays-symbols) + (dolist (ov (symbol-value ov-symb)) (when (overlay-buffer ov) (setq count (1+ count))))) + count)) + +(defalias 'bmkp-lighted-p 'bmkp-overlay-of-bookmark) +(defun bmkp-overlay-of-bookmark (bookmark &optional overlays) + "Return the overlay for BOOKMARK in OVERLAYS, or nil if none. +BOOKMARK is a bookmark name or a bookmark record. +Optional arg OVERLAYS is the list of overlays to check. +If nil, check overlays for both autonamed and non-autonamed bookmarks." + (setq bookmark (bookmark-get-bookmark bookmark 'noerror)) + (and bookmark ; Return nil for a bad bookmark. + (setq bookmark (bookmark-name-from-full-record bookmark)) + (catch 'bmkp-overlay-of-bookmark + (dolist (ov (if overlays + (apply #'append (mapcar #'symbol-value overlays)) + (append bmkp-autonamed-overlays bmkp-non-autonamed-overlays))) + (when (and (overlay-buffer ov) (equal bookmark (overlay-get ov 'bookmark))) + (throw 'bmkp-overlay-of-bookmark ov))) + nil))) + +(defun bmkp-make/move-overlay-of-style (style pos autonamedp &optional overlay) + "Return a bookmark overlay of STYLE at bookmark position POS. +AUTONAMEDP non-nil means the bookmark is autonamed. +If OVERLAY is non-nil it is the overlay to use - change to STYLE. + Otherwise, create a new overlay. +If STYLE is `none' then: + If OVERLAY is non-nil, delete it. + Return nil." + (let ((ov overlay)) + (when (and (< emacs-major-version 22) (not (rassq style bmkp-light-styles-alist))) + (message "Fringe styles not supported before Emacs 22 - changing to `line' style") + (setq style 'line)) + (case style + (line (if (not ov) + (setq ov (save-excursion + (make-overlay + (progn (goto-char pos) (line-beginning-position 1)) + (progn (goto-char pos) (line-beginning-position 2))))) + (overlay-put ov 'before-string nil) ; Remove any fringe highlighting. + (save-excursion + (move-overlay ov + (progn (goto-char pos) (line-beginning-position 1)) + (progn (goto-char pos) (line-beginning-position 2)))))) + (lfringe (setq ov (bmkp-make/move-fringe 'left pos autonamedp ov))) + (rfringe (setq ov (bmkp-make/move-fringe 'right pos autonamedp ov))) + (line+lfringe (setq ov (bmkp-make/move-fringe 'left pos autonamedp ov 'LINEP))) + (line+rfringe (setq ov (bmkp-make/move-fringe 'right pos autonamedp ov 'LINEP))) + (bol (if (not ov) + (setq ov (save-excursion (goto-char pos) + (make-overlay (line-beginning-position) + (1+ (line-beginning-position))))) + (overlay-put ov 'before-string nil) ; Remove any fringe highlighting. + (save-excursion (goto-char pos) + (move-overlay ov (line-beginning-position) + (1+ (line-beginning-position)))))) + (point (if (not ov) + (setq ov (make-overlay pos (1+ pos))) + (overlay-put ov 'before-string nil) ; Remove any fringe highlighting. + (move-overlay ov pos (1+ pos)))) + (none (when ov (delete-overlay ov)) (setq ov nil))) + ov)) + +;; Not used for Emacs 20-21. +(defun bmkp-make/move-fringe (side pos autonamedp &optional overlay linep) + "Return an overlay that uses the fringe. +If SIDE is `right' then use the right fringe, otherwise left. +POS is the overlay position. +AUTONAMEDP: non-nil means use face `bmkp-light-fringe-autonamed'. + nil means use face `bmkp-light-fringe-non-autonamed'. +If OVERLAY is non-nil it is the overlay to use. + Otherwise, create a new overlay. +Non-nil LINEP means also highlight the line containing POS." + (unless (> emacs-major-version 21) (error "Fringe styles not supported before Emacs 22")) + (let ((ov overlay)) + (if ov + (save-excursion (move-overlay overlay (progn (goto-char pos) + (goto-char (line-beginning-position))) + (1+ (point)))) + (setq ov (save-excursion (make-overlay (progn (goto-char pos) + (goto-char (line-beginning-position))) + (1+ (point)))))) + (overlay-put ov 'before-string (bmkp-fringe-string side autonamedp)) + (if linep + (move-overlay ov (save-excursion (goto-char pos) (line-beginning-position 1)) + (save-excursion (goto-char pos) (line-beginning-position 2))) + (overlay-put ov 'face nil)) ; Remove any non-fringe highlighting. + ov)) + +;; Not used for Emacs 20-21. +(defun bmkp-fringe-string (side autonamedp) + "Return a fringe string for a bookmark overlay. +If SIDE is `right' then use the right fringe, otherwise left. +AUTONAMEDP: non-nil means use face `bmkp-light-fringe-autonamed'. + nil means use face `bmkp-light-fringe-non-autonamed'." + (unless (> emacs-major-version 21) (error "Fringe styles not supported before Emacs 22")) + (let ((fringe-string (copy-sequence (if autonamedp "*AUTO*" "*NONAUTO*")))) + (put-text-property 0 (length fringe-string) + 'display (if (eq side 'right) + (list 'right-fringe + bmkp-light-right-fringe-bitmap + (if autonamedp + 'bmkp-light-fringe-autonamed + 'bmkp-light-fringe-non-autonamed)) + (list 'left-fringe + bmkp-light-left-fringe-bitmap + (if autonamedp + 'bmkp-light-fringe-autonamed + 'bmkp-light-fringe-non-autonamed))) + fringe-string) + fringe-string)) + +;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-lit) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-lit.el ends here diff --git a/auto-install/bookmark+-mac.el b/auto-install/bookmark+-mac.el new file mode 100644 index 0000000..4dc0386 --- /dev/null +++ b/auto-install/bookmark+-mac.el @@ -0,0 +1,373 @@ +;;; bookmark+-mac.el --- Macros for Bookmark+. +;; +;; Filename: bookmark+-mac.el +;; Description: Macros for Bookmark+. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Created: Sun Aug 15 11:12:30 2010 (-0700) +;; Last-Updated: Fri Apr 1 16:24:04 2011 (-0700) +;; By: dradams +;; Update #: 78 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+-mac.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `pp'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Macros for Bookmark+. +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library +;; `bookmark+-mac.el' - Lisp macros (this file) +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other (non-bmenu) required code +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) + +;;(@> "Index") +;; +;; If you have library `linkd.el' and Emacs 22 or later, load +;; `linkd.el' and turn on `linkd-mode' now. It lets you easily +;; navigate around the sections of this doc. Linkd mode will +;; highlight this Index, as well as the cross-references and section +;; headings throughout this file. You can get `linkd.el' here: +;; http://dto.freeshell.org/notebook/Linkd.html. +;; +;; (@> "Things Defined Here") +;; (@> "Functions") +;; (@> "Macros") + +;;(@* "Things Defined Here") +;; +;; Things Defined Here +;; ------------------- +;; +;; Macros defined here: +;; +;; `bmkp-define-cycle-command', +;; `bmkp-define-next+prev-cycle-commands', +;; `bmkp-define-sort-command', `bmkp-define-file-sort-predicate', +;; `bmkp-menu-bar-make-toggle'. +;; +;; Non-interactive functions defined here: +;; +;; `bmkp-assoc-delete-all', `bmkp-replace-regexp-in-string'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(require 'bookmark) +;; bookmark-bmenu-bookmark, bookmark-bmenu-ensure-position, +;; bookmark-bmenu-surreptitiously-rebuild-list, bookmark-get-bookmark, +;; bookmark-get-filename + +;; (eval-when-compile (require 'bookmark+-bmu)) +;; bmkp-bmenu-barf-if-not-in-menu-list, +;; bmkp-bmenu-goto-bookmark-named, bmkp-sort-orders-alist + +;; (eval-when-compile (require 'bookmark+-1)) +;; bmkp-file-bookmark-p, bmkp-float-time, bmkp-local-file-bookmark-p, +;; bmkp-msg-about-sort-order, bmkp-reverse-sort-p, bmkp-sort-comparer + +;;(@* "Functions") + +;;; Functions -------------------------------------------------------- + +;;; These functions are general functions. They are here because they are used in macro +;;; `bmkp-define-sort-command'. That macro is in this file because it is used only to create +;;; bmenu commands. + +;; Used in `bmkp-define-sort-command'. +(defun bmkp-assoc-delete-all (key alist) + "Delete from ALIST all elements whose car is `equal' to KEY. +Return the modified alist. +Elements of ALIST that are not conses are ignored." + (while (and (consp (car alist)) (equal (car (car alist)) key)) (setq alist (cdr alist))) + (let ((tail alist) + tail-cdr) + (while (setq tail-cdr (cdr tail)) + (if (and (consp (car tail-cdr)) (equal (car (car tail-cdr)) key)) + (setcdr tail (cdr tail-cdr)) + (setq tail tail-cdr)))) + alist) + +;; Used in `bmkp-define-sort-command'. +(defun bmkp-replace-regexp-in-string (regexp rep string &optional fixedcase literal subexp start) + "Replace all matches for REGEXP with REP in STRING and return STRING." + (if (fboundp 'replace-regexp-in-string) ; Emacs > 20. + (replace-regexp-in-string regexp rep string fixedcase literal subexp start) + (if (string-match regexp string) (replace-match rep nil nil string) string))) ; Emacs 20 + +;;(@* "Macros") + +;;; Macros ----------------------------------------------------------- + +;;;###autoload +(defmacro bmkp-define-cycle-command (type &optional otherp) + "Define a cycling command for bookmarks of type TYPE. +Non-nil OTHERP means define a command that cycles in another window." + `(defun ,(intern (format "bmkp-cycle-%s%s" type (if otherp "-other-window" ""))) + (increment &optional startoverp) + ,(if otherp + (format "Same as `bmkp-cycle-%s', but use other window." type) + (format "Cycle through %s bookmarks by INCREMENT (default: 1). +Positive INCREMENT cycles forward. Negative INCREMENT cycles backward. +Interactively, the prefix arg determines INCREMENT: + Plain `C-u': 1 + otherwise: the numeric prefix arg value + +Plain `C-u' also means start over at first bookmark. + +In Lisp code: + Non-nil STARTOVERP means reset `bmkp-current-nav-bookmark' to the + first bookmark in the navlist." type)) + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) + startovr))) + (let ((bmkp-nav-alist (bmkp-sort-and-remove-dups + (,(intern (format "bmkp-%s-alist-only" type)))))) + (bmkp-cycle increment ,otherp startoverp)))) + +;;;###autoload +(defmacro bmkp-define-next+prev-cycle-commands (type) + "Define `next' and `previous' commands for bookmarks of type TYPE." + `(progn + ;; `next' command. + (defun ,(intern (format "bmkp-next-%s-bookmark" type)) (n &optional startoverp) + ,(format "Jump to the Nth-next %s bookmark. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one. +See also `bmkp-cycle-%s'." type type) + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (,(intern (format "bmkp-cycle-%s" type)) n startoverp)) + + ;; `previous' command. + (defun ,(intern (format "bmkp-previous-%s-bookmark" type)) (n &optional startoverp) + ,(format "Jump to the Nth-previous %s bookmark. +See `bmkp-next-%s-bookmark'." type type) + (interactive (let ((startovr (consp current-prefix-arg))) + (list (if startovr 1 (prefix-numeric-value current-prefix-arg)) startovr))) + (,(intern (format "bmkp-cycle-%s" type)) (- n) startoverp)) + + ;; `next' repeating command. + (defun ,(intern (format "bmkp-next-%s-bookmark-repeat" type)) (arg) + ,(format "Jump to the Nth-next %s bookmark. +This is a repeatable version of `bmkp-next-%s-bookmark'. +N defaults to 1, meaning the next one. +Plain `C-u' means start over at the first one (and no repeat)." type type) + (interactive "P") + (require 'repeat) + (bmkp-repeat-command ',(intern (format "bmkp-next-%s-bookmark" type)))) + + ;; `previous repeating command. + (defun ,(intern (format "bmkp-previous-%s-bookmark-repeat" type)) (arg) + ,(format "Jump to the Nth-previous %s bookmark. +See `bmkp-next-%s-bookmark-repeat'." type type) + (interactive "P") + (require 'repeat) + (bmkp-repeat-command ',(intern (format "bmkp-previous-%s-bookmark" type)))))) + +;;;###autoload +(defmacro bmkp-define-sort-command (sort-order comparer doc-string) + "Define a command to sort bookmarks in the bookmark list by SORT-ORDER. +SORT-ORDER is a short string or symbol describing the sorting method. +Examples: \"by last access time\", \"by bookmark name\". + +The new command is named by replacing any spaces in SORT-ORDER with +hyphens (`-') and then adding the prefix `bmkp-bmenu-sort-'. Example: +`bmkp-bmenu-sort-by-bookmark-name', for SORT-ORDER `by bookmark name'. + +COMPARER compares two bookmarks, returning non-nil if and only if the +first bookmark sorts before the second. It must be acceptable as a +value of `bmkp-sort-comparer'. That is, it is either nil, a +predicate, or a list ((PRED...) FINAL-PRED). See the doc for +`bmkp-sort-comparer'. + +DOC-STRING is the doc string of the new command." + (unless (stringp sort-order) (setq sort-order (symbol-name sort-order))) + (let ((command (intern (concat "bmkp-bmenu-sort-" (bmkp-replace-regexp-in-string + "\\s-+" "-" sort-order))))) + `(progn + (setq bmkp-sort-orders-alist (bmkp-assoc-delete-all ,sort-order (copy-sequence + bmkp-sort-orders-alist))) + (push (cons ,sort-order ',comparer) bmkp-sort-orders-alist) + (defun ,command () + ,(concat doc-string "\nRepeating this command cycles among normal sort, reversed \ +sort, and unsorted.") + (interactive) + (bmkp-bmenu-barf-if-not-in-menu-list) + (cond (;; Not this sort order - make it this sort order. + (not (equal bmkp-sort-comparer ',comparer)) + (setq bmkp-sort-comparer ',comparer + bmkp-reverse-sort-p nil)) + (;; This sort order reversed. Change to unsorted. + bmkp-reverse-sort-p + (setq bmkp-sort-comparer nil)) + (t;; This sort order - reverse it. + (setq bmkp-reverse-sort-p t))) + (message "Sorting...") + (bookmark-bmenu-ensure-position) + (let ((current-bmk (bookmark-bmenu-bookmark))) + (bookmark-bmenu-surreptitiously-rebuild-list) + (bmkp-bmenu-goto-bookmark-named current-bmk)) ; Put cursor back on right line. + (when (interactive-p) + (bmkp-msg-about-sort-order + ,sort-order + nil + (cond ((and (not bmkp-reverse-sort-p) + (equal bmkp-sort-comparer ',comparer)) "(Repeat: reverse)") + ((equal bmkp-sort-comparer ',comparer) "(Repeat: unsorted)") + (t "(Repeat: sort)")))))))) + +;;;###autoload +(defmacro bmkp-define-file-sort-predicate (att-nb) + "Define a predicate for sorting bookmarks by file attribute ATT-NB. +See function `file-attributes' for the meanings of the various file +attribute numbers. + +String attribute values sort alphabetically; numerical values sort +numerically; nil sorts before t. + +For ATT-NB 0 (file type), a file sorts before a symlink, which sorts +before a directory. + +For ATT-NB 2 or 3 (uid, gid), a numerical value sorts before a string +value. + +A bookmark that has file attributes sorts before a bookmark that does +not. A file bookmark sorts before a non-file bookmark. Only local +files are tested for attributes - remote-file bookmarks are treated +here like non-file bookmarks." + `(defun ,(intern (format "bmkp-file-attribute-%d-cp" att-nb)) (b1 b2) + ,(format "Sort file bookmarks by attribute %d. +B1 and B2 are bookmarks or bookmark names. +Sort bookmarks with file attributes before those without attributes +Sort file bookmarks before non-file bookmarks. +Treat remote file bookmarks like non-file bookmarks." + att-nb) + (setq b1 (bookmark-get-bookmark b1)) + (setq b2 (bookmark-get-bookmark b2)) + (let (a1 a2) + (cond (;; Both are file bookmarks. + (and (bmkp-file-bookmark-p b1) (bmkp-file-bookmark-p b2)) + (setq a1 (file-attributes (bookmark-get-filename b1)) + a2 (file-attributes (bookmark-get-filename b2))) + (cond (;; Both have attributes. + (and a1 a2) + (setq a1 (nth ,att-nb a1) + a2 (nth ,att-nb a2)) + ;; Convert times and maybe inode number to floats. + ;; The inode conversion is kludgy, but is probably OK in practice. + (when (consp a1) (setq a1 (bmkp-float-time a1))) + (when (consp a2) (setq a2 (bmkp-float-time a2))) + (cond (;; (1) links, (2) maybe uid, (3) maybe gid, (4, 5, 6) times + ;; (7) size, (10) inode, (11) device. + (numberp a1) + (cond ((< a1 a2) '(t)) + ((> a1 a2) '(nil)) + (t nil))) + ((= 0 ,att-nb) ; (0) file (nil) < symlink (string) < dir (t) + (cond ((and a2 (not a1)) '(t)) ; file vs (symlink or dir) + ((and a1 (not a2)) '(nil)) + ((and (eq t a2) (not (eq t a1))) '(t)) ; symlink vs dir + ((and (eq t a1) (not (eq t a2))) '(t)) + ((and (stringp a1) (stringp a2)) + (if (string< a1 a2) '(t) '(nil))) + (t nil))) + ((stringp a1) ; (2, 3) string uid/gid, (8) modes + (cond ((string< a1 a2) '(t)) + ((string< a2 a1) '(nil)) + (t nil))) + ((eq ,att-nb 9) ; (9) gid would change if re-created. nil < t + (cond ((and a2 (not a1)) '(t)) + ((and a1 (not a2)) '(nil)) + (t nil))))) + (;; First has attributes, but not second. + a1 + '(t)) + (;; Second has attributes, but not first. + a2 + '(nil)) + (;; Neither has attributes. + t + nil))) + (;; First is a file, second is not. + (bmkp-local-file-bookmark-p b1) + '(t)) + (;; Second is a file, first is not. + (bmkp-local-file-bookmark-p b2) + '(nil)) + (t;; Neither is a file. + nil))))) + +;;;###autoload +(defmacro bmkp-menu-bar-make-toggle (name variable doc message help &rest body) + "Return a valid `menu-bar-make-toggle' call in Emacs 20 or later. +NAME is the name of the toggle command to define. +VARIABLE is the variable to set. +DOC is the menu-item name. +MESSAGE is the toggle message, minus status. +HELP is `:help' string. +BODY is the function body to use. If present, it is responsible for +setting the variable and displaying a status message (not MESSAGE)." + (if (< emacs-major-version 21) + `(menu-bar-make-toggle ,name ,variable ,doc ,message ,@body) + `(menu-bar-make-toggle ,name ,variable ,doc ,message ,help ,@body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+-mac) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+-mac.el ends here diff --git a/auto-install/bookmark+.el b/auto-install/bookmark+.el new file mode 100644 index 0000000..4e08c47 --- /dev/null +++ b/auto-install/bookmark+.el @@ -0,0 +1,163 @@ +;;; bookmark+.el --- Bookmark+: extensions to standard library `bookmark.el'. +;; +;; Filename: bookmark+.el +;; Description: Bookmark+: extensions to standard library `bookmark.el'. +;; Author: Drew Adams, Thierry Volpiatto +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2000-2011, Drew Adams, all rights reserved. +;; Copyright (C) 2009, Thierry Volpiatto, all rights reserved. +;; Created: Fri Sep 15 07:58:41 2000 +;; Last-Updated: Mon Aug 1 08:59:18 2011 (-0700) +;; By: dradams +;; Update #: 14963 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/bookmark+.el +;; Keywords: bookmarks, bookmark+, placeholders, annotations, search, info, url, w3m, gnus +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `bookmark', `bookmark+-1', `bookmark+-bmu', `bookmark+-key', +;; `bookmark+-lit', `bookmark+-mac', `dired', `dired-aux', +;; `dired-x', `ffap', `pp', `pp+'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Bookmark+: extensions to standard library `bookmark.el'. +;; +;; The Bookmark+ libraries are these: +;; +;; `bookmark+.el' - main (driver) library (this file) +;; `bookmark+-mac.el' - Lisp macros +;; `bookmark+-lit.el' - (optional) code for highlighting bookmarks +;; `bookmark+-bmu.el' - code for the `*Bookmark List*' (bmenu) +;; `bookmark+-1.el' - other required code (non-bmenu) +;; `bookmark+-key.el' - key and menu bindings +;; +;; `bookmark+-doc.el' - documentation (comment-only file) +;; `bookmark+-chg.el' - change log (comment-only file) +;; +;; The documentation (in `bookmark+-doc.el') includes how to +;; byte-compile and install Bookmark+. The documentation is also +;; available in these ways: +;; +;; 1. From the bookmark list (`C-x r l'): +;; Use `?' to show the current bookmark-list status and general +;; help, then click link `Doc in Commentary' or link `Doc on the +;; Web'. +;; +;; 2. From the Emacs-Wiki Web site: +;; http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus. +;; +;; 3. From the Bookmark+ group customization buffer: +;; `M-x customize-group bookmark-plus', then click link +;; `Commentary'. +;; +;; (The commentary links in #1 and #3 work only if you have library +;; `bookmark+-doc.el' in your `load-path'.) +;; +;; +;; ****** NOTE ****** +;; +;; On 2010-06-18, I changed the prefix used by package Bookmark+ +;; from `bookmarkp-' to `bmkp-'. THIS IS AN INCOMPATIBLE CHANGE. +;; I apologize for the inconvenience, but the new prefix is +;; preferable for a number of reasons, including easier +;; distinction from standard `bookmark.el' names. +;; +;; This change means that YOU MUST MANUALLY REPLACE ALL +;; OCCURRENCES of `bookmarkp-' by `bmkp-' in the following +;; places, if you used Bookmark+ prior to this change: +;; +;; 1. In your init file (`~/.emacs') or your `custom-file', if +;; you have one. This is needed if you customized any +;; Bookmark+ features. +;; +;; 2. In your default bookmark file, `bookmark-default-file' +;; (`.emacs.bmk'), and in any other bookmark files you might +;; have. +;; +;; 3. In your `*Bookmark List*' state file, +;; `bmkp-bmenu-state-file' (`~/.emacs-bmk-bmenu-state.el'). +;; +;; 4. In your `*Bookmark List*' commands file, +;; `bmkp-bmenu-commands-file' (`~/.emacs-bmk-bmenu-commands.el'), +;; if you have one. +;; +;; You can do this editing in a virgin Emacs session (`emacs +;; -Q'), that is, without loading Bookmark+. +;; +;; Alternatively, you can do this editing in an Emacs session +;; where Bookmark+ has been loaded, but in that case you must +;; TURN OFF AUTOMATIC SAVING of both your default bookmark file +;; and your `*Bookmark List*' state file. Otherwise, when you +;; quit Emacs your manually edits will be overwritten. +;; +;; To turn off this automatic saving, you can use `M-~' and `M-l' +;; in buffer `*Bookmark List*' (commands +;; `bmkp-toggle-saving-bookmark-file' and +;; `bmkp-toggle-saving-menu-list-state' - they are also in the +;; `Bookmark+' menu). +;; +;; +;; Again, sorry for this inconvenience. +;; +;; +;; Commands defined here: +;; +;; `bmkp-version'. +;; +;; Internal variables defined here: +;; +;; `bmkp-version-number'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;; + +(require 'bookmark) ; Vanilla Emacs. +(require 'bookmark+-mac) ; Lisp macros. +(require 'bookmark+-lit nil t) ; Optional (soft require) - no error if not found. If you do + ; not want to use `bookmark+-lit.el' then simply do not put + ; it in your `load-path'. +(require 'bookmark+-bmu) ; `*Bookmark List*' stuff. +(require 'bookmark+-1) ; Rest of Bookmark+ required stuff, except keys & menus. +(require 'bookmark+-key) ; Keys & menus. + +;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(defconst bmkp-version-number "3.2.2") + +;;;###autoload +(defun bmkp-version () + "Show version number of library `bookmark+.el'." + (interactive) + (message "Bookmark+, version %s" bmkp-version-number)) + +;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'bookmark+) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; bookmark+.el ends here diff --git a/auto-install/col-highlight.el b/auto-install/col-highlight.el new file mode 100644 index 0000000..1a46600 --- /dev/null +++ b/auto-install/col-highlight.el @@ -0,0 +1,317 @@ +;;; col-highlight.el --- Highlight the current column. +;; +;; Filename: col-highlight.el +;; Description: Highlight the current column. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2006-2011, Drew Adams, all rights reserved. +;; Created: Fri Sep 08 11:06:35 2006 +;; Version: 22.0 +;; Last-Updated: Mon Jan 3 19:55:33 2011 (-0800) +;; By: dradams +;; Update #: 320 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/col-highlight.el +;; Keywords: faces, frames, emulation, highlight, cursor, accessibility +;; Compatibility: GNU Emacs: 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `vline'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library highlights the current column. When you move the +;; cursor, the highlighting follows (tracks the cursor), as long as +;; the highlighting stays on. +;; +;; Command `column-highlight-mode' toggles this highlighting on and +;; off. +;; +;; If you use `column-highlight-mode' twice in succession (I bind it +;; to `C-+'), you can flash the highlighting to show you the current +;; column temporarily. An alternative way to flash-highlight is to +;; use command `flash-column-highlight' (once). It shows the +;; highlighting for just a second or two (see option +;; `col-highlight-period'). +;; +;; You can also have current-column highlighting come on +;; automatically, when Emacs is idle. Command +;; `toggle-highlight-column-when-idle' toggles this mode. Command +;; `col-highlight-set-interval' changes the number of idle seconds to +;; wait before highlighting. +;; +;; +;; To use this file, you must also have library `vline.el'. +;; Put this in your Emacs init file (~/.emacs): +;; +;; (require 'col-highlight) ; Load this file (and `vline') +;; +;; If you want to turn on continual current-column highlighting by +;; default, then add this to your init file: +;; +;; (column-highlight-mode 1) +;; +;; If you want to turn on automatic idle highlighting of the current +;; column, then add this to your init file: +;; +;; (toggle-highlight-column-when-idle 1) +;; +;; If you want to use a different wait interval, before idle +;; highlighting begins, then set it in your init file using +;; `col-highlight-set-interval': +;; +;; (col-highlight-set-interval 6) ; Wait 6 idle secs. +;; +;; Note that `column-highlight-mode' is intentionally a global minor +;; mode. If you want a local minor mode, so that highlighting +;; affects only a particular buffer, you can use `vline-mode' (in +;; `vline.el'). +;; +;; +;; See also: +;; +;; * Library `hl-line+.el', which offers the same functionality, but +;; for the current line instead of the current column. +;; +;; * Library `crosshairs.el', which combines the features of +;; `col-highlight.el' and `hl-line+.el', providing a crosshair +;; highlighting effect. It requires `col-highlight.el' and +;; `hl-line+.el'. +;; +;; * Library `cursor-chg.el' or library `oneonone.el', to change the +;; cursor type when Emacs is idle. +;; +;; User options defined here: +;; +;; `col-highlight-period', `column-highlight-mode', +;; `col-highlight-vline-face-flag'. +;; +;; Faces defined here: +;; +;; `col-highlight'. +;; +;; Commands defined here: +;; +;; `col-highlight-flash', `col-highlight-set-interval', +;; `col-highlight-toggle-when-idle', `column-highlight-mode', +;; `flash-column-highlight', `toggle-highlight-column-when-idle'. +;; +;; Non-interactive functions defined here: +;; +;; `col-highlight-highlight', `col-highlight-unhighlight'. +;; +;; Internal variables defined here: +;; +;; `col-highlight-face', `col-highlight-idle-interval', +;; `col-highlight-idle-timer', `col-highlight-when-idle-p'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2011/01/03 dadams +;; Added autoload cookies for defgroup, defcustom, defface, and commands. +;; 2008/09/03 dadams +;; col-highlight-highlight: Bind vline-current-window-only to t. +;; 2008/08/08 dadams +;; col-highlight-(un)highlight: Added optional arg. +;; 2008/01/21 dadams +;; Use vline.el instead of column-marker.el. +;; Added: group column-highlight, option col-highlight-vline-face-flag. +;; col-highlight-toggle-when-idle: col-highlight-unhighlight when turn off. +;; col-highlight-flash: Use col-highlight-highlight, not mode. +;; col-highlight-(un)highlight: Respect col-highlight-vline-face-flag. +;; Don't highlight minibuffer. +;; Renamed: face col-highlight-face to col-highlight. +;; Removed semi-support for Emacs 20. +;; 2006/09/08 dadams +;; Created. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(require 'vline) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;###autoload +(defgroup column-highlight nil + "Highlight the current column." + :prefix "col-highlight-" + :group 'editing :group 'cursor :group 'hl-line :group 'frames + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +col-highlight.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/cgi-bin/wiki/col-highlight.el")) + +;;;###autoload +(defcustom col-highlight-vline-face-flag t + "*Non-nil means `column-highlight-mode' uses `col-highlight-face'. +nil means that it uses `vline-face'." + :type 'boolean :group 'column-highlight) + +;;;###autoload +(defcustom col-highlight-period 1 + "*Number of seconds to highlight the current column." + :type 'integer :group 'column-highlight) + +;;;###autoload +(defface col-highlight '((t (:background "SlateGray3"))) + "*Face for current-column highlighting by `column-highlight-mode'. +Not used if `col-highlight-vline-face-flag' is nil." + :group 'column-highlight :group 'faces) + +(defvar col-highlight-face 'col-highlight + "Face used for highlighting current column. +Do NOT change this.") + +(defvar col-highlight-idle-interval 5 + "Number of seconds to wait before highlighting current column. +Do NOT change this yourself to change the wait period; instead, use +`\\[col-highlight-set-interval]'.") + +(defvar col-highlight-when-idle-p nil + "Non-nil means highlight the current column whenever Emacs is idle. +Do NOT change this yourself; instead, use +`\\[toggle-highlight-column-when-idle]'.") + +(defvar col-highlight-idle-timer + (progn ; Cancel to prevent duplication. + (when (boundp 'col-highlight-idle-timer) + (cancel-timer col-highlight-idle-timer)) + (run-with-idle-timer col-highlight-idle-interval t 'col-highlight-highlight)) + "Timer used to highlight current column whenever Emacs is idle.") + +;; Turn it off, by default. +;; You must use `toggle-highlight-column-when-idle' to turn it on. +(cancel-timer col-highlight-idle-timer) + +;;;###autoload +(define-minor-mode column-highlight-mode + "Toggle highlighting the current column. +With ARG, turn column highlighting on if and only if ARG is positive. + +Column-Highlight mode uses the functions +`col-highlight-unhighlight' and `col-highlight-highlight' +on `pre-command-hook' and `post-command-hook'." + :init-value nil :global t :group 'column-highlight + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +col-highlight.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag + "Download" "http://www.emacswiki.org/cgi-bin/wiki/col-highlight.el") + :link '(url-link :tag "Description" + "http://www.emacswiki.org/cgi-bin/wiki/ChangingCursorDynamically") + :link '(emacs-commentary-link :tag "Commentary" "col-highlight") + (cond (column-highlight-mode + (add-hook 'pre-command-hook #'col-highlight-unhighlight) + (add-hook 'post-command-hook #'col-highlight-highlight)) + (t + (col-highlight-unhighlight) + (remove-hook 'pre-command-hook #'col-highlight-unhighlight) + (remove-hook 'post-command-hook #'col-highlight-highlight)))) + +;;;###autoload +(defalias 'toggle-highlight-column-when-idle 'col-highlight-toggle-when-idle) +;;;###autoload +(defun col-highlight-toggle-when-idle (&optional arg) + "Turn on or off highlighting the current column when Emacs is idle. +With prefix argument, turn on if ARG > 0; else turn off." + (interactive "P") + (setq col-highlight-when-idle-p + (if arg (> (prefix-numeric-value arg) 0) (not col-highlight-when-idle-p))) + (cond (col-highlight-when-idle-p + (timer-activate-when-idle col-highlight-idle-timer) + (add-hook 'pre-command-hook #'col-highlight-unhighlight) + (message "Turned ON highlighting current column when Emacs is idle.")) + (t + (cancel-timer col-highlight-idle-timer) + (col-highlight-unhighlight) + (remove-hook 'pre-command-hook #'col-highlight-unhighlight) + (message "Turned OFF highlighting current column when Emacs is idle.")))) + +;;;###autoload +(defun col-highlight-set-interval (secs) + "Set wait until highlight current column when Emacs is idle. +Whenever Emacs is idle for this many seconds, the current column +will be highlighted in the face that is the value of variable +`col-highlight-face'. + +To turn on or off automatically highlighting the current column +when Emacs is idle, use `\\[toggle-highlight-column-when-idle]." + (interactive + "nSeconds to idle, before highlighting current column: ") + (timer-set-idle-time col-highlight-idle-timer + (setq col-highlight-idle-interval secs) t)) + + +;;;###autoload +(defalias 'flash-column-highlight 'col-highlight-flash) +;;;###autoload +(defun col-highlight-flash (&optional arg) + "Highlight the current column for `col-highlight-period' seconds. +With a prefix argument, highlight for that many seconds." + (interactive) + (col-highlight-highlight) + (let ((column-period col-highlight-period)) + (when current-prefix-arg + (setq column-period (prefix-numeric-value current-prefix-arg))) + (run-at-time column-period nil #'col-highlight-unhighlight))) + +(defun col-highlight-highlight (&optional minibuffer-also-p) + "Highlight current column." + (unless (and (minibufferp) (not minibuffer-also-p)) + (let ((vline-current-window-only t)) + (if col-highlight-vline-face-flag + (let ((vline-style 'face) + (vline-face col-highlight-face)) + (vline-show)) + (vline-show))))) + +(defun col-highlight-unhighlight (&optional minibuffer-also-p) + "Turn off highlighting of current column. +If optional arg MINIBUFFER-ALSO-P is nil, then do nothing if the +current buffer is the minibuffer. " + (unless (and (minibufferp) (not minibuffer-also-p)) + (if col-highlight-vline-face-flag + (let ((vline-style 'face) + (vline-face col-highlight-face)) + (vline-clear)) + (vline-clear)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'col-highlight) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; col-highlight.el ends here diff --git a/auto-install/crosshairs.el b/auto-install/crosshairs.el new file mode 100644 index 0000000..b0bd523 --- /dev/null +++ b/auto-install/crosshairs.el @@ -0,0 +1,360 @@ +;;; crosshairs.el --- Highlight the current line and column. +;; +;; Filename: crosshairs.el +;; Description: Highlight the current line and column. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2006-2011, Drew Adams, all rights reserved. +;; Created: Fri Sep 08 13:09:19 2006 +;; Version: 22.0 +;; Last-Updated: Mon Jan 3 20:26:52 2011 (-0800) +;; By: dradams +;; Update #: 404 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el +;; Keywords: faces, frames, emulation, highlight, cursor, accessibility +;; Compatibility: GNU Emacs: 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `col-highlight', `hl-line', `hl-line+', `vline'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library highlights the current line and the current column. +;; It combines the features of libraries `hl-line.el', `hl-line+.el', +;; and `col-highlight.el', which let you highlight the line or column +;; individually. See those libraries for more information. +;; +;; Command `crosshairs-mode' toggles this highlighting on and off. +;; You can do this twice in succession to flash the crosshairs to +;; show you where the cursor is. An alternative way to +;; flash-highlight is to use command `flash-crosshairs' (once). +;; +;; Command `crosshairs-highlight' shows crosshairs highlighting until +;; your next action (next command, technically). Command +;; `crosshairs-unhighlight' turns off crosshairs highlighting due to +;; `crosshairs-highlight'. +;; +;; With no prefix arg, command `crosshairs' is +;; `crosshairs-highlight'. With a prefix arg, it is +;; `crosshairs-mode'. +;; +;; You can also have crosshairs highlighting come on automatically, +;; when Emacs is idle. Command `toggle-crosshairs-when-idle' toggles +;; this mode. +;; +;; +;; See also: +;; +;; * Library `hl-line+.el', which highlights the current line. +;; +;; * Library `col-highlight.el', which highlights the current column. +;; +;; * Library `cursor-chg.el' or library `oneonone.el', to change the +;; cursor type when Emacs is idle. +;; +;; +;; User options defined here: +;; +;; `crosshairs-mode', `crosshairs-overlay-priority', +;; `crosshairs-vline-same-face-flag'. +;; +;; Commands defined here: +;; +;; `crosshairs', `crosshairs-flash', `crosshairs-highlight', +;; `crosshairs-mode', `crosshairs-toggle-when-idle', +;; `crosshairs-unhighlight', `flash-crosshairs', +;; `toggle-crosshairs-when-idle'. +;; +;; Internal variables defined here: +;; +;; `crosshairs-flash-col-timer', `crosshairs-flash-line-timer', +;; `crosshairs-highlight-when-idle-p'. +;; +;; Suggested alternative key bindings: +;; +;; (global-set-key [(control ?+)] 'crosshairs) +;; or (global-set-key [(control ?+)] 'crosshairs-mode) +;; or (global-set-key [(control ?+)] 'crosshairs-flash) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2011/01/03 dadams +;; Added autoload cookies for defgroup, defcustoms, commands. +;; 2010/06/29 dadams +;; Added: crosshairs-overlay-priority. +;; crosshairs-(un)highlight: Set/remove priority if crosshairs-overlay-priority. +;; 2008/09/03 dadams +;; crosshairs-mode: Don't set previous state if explicit ARG. +;; Added message indicating position. +;; Added: crosshairs, crosshairs-(un)highlight. +;; 2008/08/31 dadams +;; crosshairs-flash: Cancel timers at the outset. +;; Remove hl-line-unhighlight-now from pre-command-hook. +;; 2008/08/08 dadams +;; Added: crosshairs-flash-col-timer, crosshairs-flash-line-timer. +;; crosshairs-flash: +;; Call col-highlight-(un)highlight with arg t. +;; Save unhighlighting timers in crosshairs-flash-(col|line)-timer. +;; First, cancel unhighlighting timers. +;; 2008/01/21 dadams +;; Use vline.el now, instead of column-marker.el. +;; Added group crosshairs, option crosshairs-vline-same-face-flag. +;; crosshairs-mode, crosshairs-toggle-when-idle: +;; If both are already on or off, reflect that as the crosshair state. +;; crosshairs-toggle-when-idle: +;; crosshairs-highlight-when-idle-p, not col-highlight-when-idle-p. +;; crosshairs-flash: +;; Save/restore global-hl-line-mode. +;; Clear and rehighlight column initially. Maybe highlight twice (bug). +;; Don't use highlight modes to unhighlight - just unhighlight. +;; Renamed: line-show-period to hl-line-flash-show-period. +;; Removed semi-support for Emacs 20. +;; 2006/09/08 dadams +;; Created. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(require 'hl-line+) ;; Requires `hl-line.el'. +(require 'col-highlight) ;; Requires `vline.el'. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(defgroup crosshairs nil + "Highlight the current line and column." + :prefix "crosshairs-" + :group 'editing :group 'cursor :group 'hl-line :group 'frames + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +crosshairs.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el")) + +;;;###autoload +(defcustom crosshairs-overlay-priority nil + "*Priority to use for overlay `global-hl-line-overlay'." + :type '(choice + (const :tag "No priority (default priority)" nil) + (integer :tag "Priority" 100)) + :group 'crosshairs) + +;;;###autoload +(defcustom crosshairs-vline-same-face-flag t + "*Non-nil means use face `hl-line' for column highlighting also. +nil means highlight the column according to the value of `vline-style' +and face `vline'." + :type 'boolean :group 'crosshairs) + +(defvar crosshairs-highlight-when-idle-p nil + "Non-nil means highlight current line and column when Emacs is idle. +Do NOT change this yourself; instead, use +`\\[toggle-crosshairs-when-idle]'.") + +(defvar crosshairs-flash-line-timer (timer-create) + "Timer used to unhighlight current line for `crosshairs-flash'.") + +(defvar crosshairs-flash-col-timer (timer-create) + "Timer used to unhighlight current column for `crosshairs-flash'.") + +;;;###autoload +(define-minor-mode crosshairs-mode + "Toggle highlighting the current line and column. +With ARG, turn highlighting on if and only if ARG is positive." + :init-value nil :global t :group 'crosshairs + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +crosshairs.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el") + :link '(url-link :tag "Description" + "http://www.emacswiki.org/cgi-bin/wiki/ChangingCursorDynamically") + :link '(emacs-commentary-link :tag "Commentary" "crosshairs") + ;; If both were already on or off, reflect that as the previous crosshairs state. + (unless arg + (cond ((and global-hl-line-mode column-highlight-mode) + (setq crosshairs-mode nil)) + ((and (not global-hl-line-mode) (not column-highlight-mode)) + (setq crosshairs-mode t)))) + (cond (crosshairs-mode + (unless global-hl-line-mode + (global-hl-line-mode 1) + (global-hl-line-highlight)) + (column-highlight-mode 1) + (message "Point: %d - Crosshairs mode enabled" (point))) + (t + (global-hl-line-mode -1) + (global-hl-line-unhighlight) + (column-highlight-mode -1) + (message "Point: %d - Crosshairs mode disabled" (point))))) + +;;;###autoload +(defalias 'toggle-crosshairs-when-idle 'crosshairs-toggle-when-idle) +;;;###autoload +(defun crosshairs-toggle-when-idle (&optional arg) + "Toggle highlighting the current line and column when Emacs is idle. +With prefix argument, turn on if ARG > 0; else turn off. +You can use commands `col-highlight-set-interval' and +`hl-line-when-idle-interval' to change the idle times." + (interactive "P") + ;; First, if both are already on or off, reflect that as the crosshair state. + (when (or (and hl-line-when-idle-p col-highlight-when-idle-p) + (and (not hl-line-when-idle-p) (not col-highlight-when-idle-p))) + (setq crosshairs-highlight-when-idle-p hl-line-when-idle-p)) + (setq crosshairs-highlight-when-idle-p (if arg + (> (prefix-numeric-value arg) 0) + (not crosshairs-highlight-when-idle-p))) + (setq hl-line-when-idle-p crosshairs-highlight-when-idle-p + col-highlight-when-idle-p crosshairs-highlight-when-idle-p) + (cond (crosshairs-highlight-when-idle-p + (timer-activate-when-idle col-highlight-idle-timer) + (timer-activate-when-idle hl-line-idle-timer) + (add-hook 'pre-command-hook #'col-highlight-unhighlight) + (add-hook 'pre-command-hook #'hl-line-unhighlight-now) + (message "Turned ON highlighting line and column when Emacs is idle.")) + (t + (cancel-timer col-highlight-idle-timer) + (cancel-timer hl-line-idle-timer) + (remove-hook 'pre-command-hook #'col-highlight-unhighlight) + (remove-hook 'pre-command-hook #'hl-line-unhighlight-now) + (message "Turned OFF highlighting line and column when Emacs is idle.")))) + +;;;###autoload +(defalias 'flash-crosshairs 'crosshairs-flash) +;;;###autoload +(defun crosshairs-flash (&optional seconds) + "Highlight the current line and column temporarily. +Highlight the line for `hl-line-flash-show-period' and the column for +`column-show-period' seconds. With prefix argument SECONDS, highlight +both for SECONDS seconds." + (interactive "P") + (cancel-timer crosshairs-flash-line-timer) ; Cancel to prevent duplication. + (cancel-timer crosshairs-flash-col-timer) + (let ((global-hl-line-mode global-hl-line-mode)) + (col-highlight-unhighlight t) + (col-highlight-highlight t) + (when column-highlight-mode (col-highlight-highlight t)) ; Extra - a vline bug. + (hl-line-highlight-now) + (remove-hook 'pre-command-hook 'hl-line-unhighlight-now) + (let ((line-period hl-line-flash-show-period) ; Defined in `hl-line+.el'. + (column-period col-highlight-period)) ; Defined in `col-highlight.el'. + (when seconds + (setq line-period (prefix-numeric-value seconds) + column-period line-period)) + (setq crosshairs-flash-line-timer (run-at-time + line-period nil + #'global-hl-line-unhighlight) + crosshairs-flash-col-timer (run-at-time + column-period nil + #'col-highlight-unhighlight t))))) + +;;;###autoload +(defun crosshairs (&optional modalp) + "Highlight current position with crosshairs. +With no prefix arg, highlighting turns off at the next command. +With a prefix arg, highlighting stays on until you toggle it off using +`crosshairs-mode'." + (interactive "P") + (if modalp (crosshairs-mode 1) (crosshairs-highlight))) + +;;;###autoload +(defun crosshairs-highlight (&optional mode nomsg) + "Echo current position and highlight it with crosshairs. +If optional arg MODE is `line-only', then highlight only the line. +If optional arg MODE is `col-only', then highlight only the column. + Interactively: + A non-negative prefix argument uses MODE `line-only'. + A negative prefix argument uses MODE `col-only'. + +Optional arg NOMSG non-nil means show no message. + +If the current buffer is not the same as the value of `orig-buff', +then indicate the buffer, as well as the position. Variable +`orig-buff' is not bound here; if you want to take advantage of this +feature in your code, then bind it. + +Return current position as a marker." + (interactive (list (and current-prefix-arg + (if (wholenump (prefix-numeric-value current-prefix-arg)) + 'line-only + 'col-only)))) + (when crosshairs-mode (crosshairs-mode -1)) + (prog1 (point-marker) + (unless (eq mode 'line-only) (require 'col-highlight nil t)) + (unless (eq mode 'col-only) (require 'hl-line nil t)) + (setq mark-active nil) + (crosshairs-unhighlight 'even-if-frame-switch) + (when (and (boundp 'global-hl-line-overlay) (not (eq mode 'col-only))) + (unless global-hl-line-overlay + (setq global-hl-line-overlay (make-overlay 1 1)) ; to be moved + (overlay-put global-hl-line-overlay 'face hl-line-face)) + (overlay-put global-hl-line-overlay 'window (selected-window)) + (when crosshairs-overlay-priority + (overlay-put global-hl-line-overlay 'priority crosshairs-overlay-priority) + (when (boundp 'vline-overlay-table) + (mapcar (lambda (ov) (when (overlayp ov) + (overlay-put ov 'priority crosshairs-overlay-priority))) + vline-overlay-table))) + (hl-line-move global-hl-line-overlay)) + (when (and (fboundp 'col-highlight-highlight) (not (eq mode 'line-only))) + (redisplay t) ; Force a redisplay, or else it doesn't always show up. + (col-highlight-highlight)) + (when (or (boundp 'global-hl-line-overlay) (fboundp 'col-highlight-highlight)) + (add-hook 'pre-command-hook 'crosshairs-unhighlight)) + (unless nomsg + (if (and (boundp 'orig-buff) (eq (current-buffer) orig-buff)) + (message "Point: %d" (point)) + (message "Buffer: `%s', Point: %d" (current-buffer) (point)))))) + +;;;###autoload +(defun crosshairs-unhighlight (&optional arg) + "Turn off crosshairs highlighting of current position. +Optional arg nil means do nothing if this event is a frame switch." + (interactive) + (when (or arg (not (and (consp last-input-event) + (eq (car last-input-event) 'switch-frame)))) + (when (fboundp 'col-highlight-unhighlight) (col-highlight-unhighlight t)) + (when (and (boundp 'global-hl-line-overlay) global-hl-line-overlay) + (when crosshairs-overlay-priority + (overlay-put global-hl-line-overlay 'priority nil)) + (delete-overlay global-hl-line-overlay)) + (remove-hook 'pre-command-hook 'crosshairs-unhighlight))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'crosshairs) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; crosshairs.el ends here diff --git a/auto-install/csv-mode.el b/auto-install/csv-mode.el new file mode 100644 index 0000000..f6cf3f4 --- /dev/null +++ b/auto-install/csv-mode.el @@ -0,0 +1,1286 @@ +;;; csv-mode.el --- major mode for editing comma-separated value files + +;; Copyright (C) 2003, 2004 Francis J. Wright + +;; Author: Francis J. Wright +;; Time-stamp: <23 August 2004> +;; URL: http://centaur.maths.qmul.ac.uk/Emacs/ +;; Version: $Id: csv-mode.el,v 1.50 2004/08/23 17:51:26 fjw Exp $ +;; Keywords: convenience + +;; This file is not part of GNU Emacs. + +;; This package is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This package is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This package is intended for use with GNU Emacs 21 (only) and +;; implements the following commands to process records of CSV +;; (comma-separated value) type: `csv-sort-fields' and +;; `csv-sort-numeric-fields' sort respectively lexicographically and +;; numerically on a specified field or column; `csv-reverse-region' +;; reverses the order. They are based closely on, and use, code in +;; `sort.el'. `csv-kill-fields' and `csv-yank-fields' respectively +;; kill and yank fields or columns, although they do not use the +;; normal kill ring. `csv-kill-fields' can kill more than one field +;; at once, but multiple killed fields can be yanked only as a fixed +;; group equivalent to a single field. `csv-align-fields' aligns +;; fields into columns; `csv-unalign-fields' undoes such alignment; +;; separators can be hidden within aligned records. `csv-transpose' +;; interchanges rows and columns. For details, see the documentation +;; for the individual commands. + +;; CSV mode supports a generalised comma-separated values format +;; (character-separated values) in which the fields can be separated +;; by any of several single characters, specified by the value of the +;; customizable user option `csv-separators'. CSV data fields can be +;; delimited by quote characters (and must if they contain separator +;; characters). This implementation supports quoted fields, where the +;; quote characters allowed are specified by the value of the +;; customizable user option `csv-field-quotes'. By default, the only +;; separator is a comma and the only field quote is a double quote. +;; These user options can be changed ONLY by CUSTOMIZING them, +;; e.g. via the command `customize-variable'. + +;; CSV mode commands ignore blank lines and comment lines beginning +;; with the value of the buffer local variable `csv-comment-start', +;; which by default is #. The user interface is similar to that of +;; the standard commands `sort-fields' and `sort-numeric-fields', but +;; see the major mode documentation below. + +;; The global minor mode `csv-field-index-mode' provides display of +;; the current field index in the mode line, cf. `line-number-mode' +;; and `column-number-mode'. It is on by default. + +;;; Installation: + +;; Put this file somewhere that Emacs can find it (i.e. in one of the +;; directories in your `load-path' such as `site-lisp'), optionally +;; byte-compile it (recommended), and put this in your .emacs file: +;; +;; (add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) +;; (autoload 'csv-mode "csv-mode" +;; "Major mode for editing comma-separated value files." t) + +;;; History: + +;; Begun on 15 November 2003 to provide lexicographic sorting of +;; simple CSV data by field and released as csv.el. Facilities to +;; kill multiple fields and customize separator added on 9 April 2004. +;; Converted to a major mode and renamed csv-mode.el on 10 April 2004, +;; partly at the suggestion of Stefan Monnier to avoid conflict with csv.el by Ulf Jasper. +;; Field alignment, comment support and CSV mode customization group +;; added on 1 May 2004. Support for index ranges added on 6 June +;; 2004. Multiple field separators added on 12 June 2004. +;; Transposition added on 22 June 2004. Separator invisibility added +;; on 23 June 2004. + +;;; See also: + +;; the standard GNU Emacs 21 packages align.el, which will align +;; columns within a region, and delim-col.el, which helps to prettify +;; columns in a text region or rectangle; + +;; csv.el by Ulf Jasper , which provides +;; functions for reading/parsing comma-separated value files and is +;; available at http://de.geocities.com/ulf_jasper/emacs.html (and in +;; the gnu.emacs.sources archives). + +;;; To do (maybe): + +;; Make separators and quotes buffer-local and locally settable. +;; Support (La)TeX tables: set separator and comment; support record +;; end string. +;; Convert comma-separated to space- or tab-separated. + +;;; Code: + +(defgroup CSV nil + "Major mode for editing files of comma-separated value type." + :group 'convenience) + +(defvar csv-separator-chars nil + "Field separators as a list of character. +Set by customizing `csv-separators' -- do not set directly!") + +(defvar csv-separator-regexp nil + "Regexp to match a field separator. +Set by customizing `csv-separators' -- do not set directly!") + +(defvar csv-skip-regexp nil + "Regexp used by `skip-chars-forward' etc. to skip fields. +Set by customizing `csv-separators' -- do not set directly!") + +(defvar csv-font-lock-keywords nil + "Font lock keywords to highlight the field separators in CSV mode. +Set by customizing `csv-separators' -- do not set directly!") + +(defcustom csv-separators '(",") + "Field separators: a list of *single-character* strings. +For example: (\",\"), the default, or (\",\" \";\" \":\"). +Neighbouring fields may be separated by any one of these characters. +The first is used when inserting a field separator into the buffer. +All must be different from the field quote characters, `csv-field-quotes'." + ;; Suggested by Eckhard Neber + :group 'CSV + :type '(repeat string) + ;; Character would be better, but in Emacs 21.3 does not display + ;; correctly in a customization buffer. + :set (lambda (variable value) + (mapc (lambda (x) + (if (or (/= (length x) 1) + (and (boundp 'csv-field-quotes) + (member x csv-field-quotes))) + (error))) + value) + (custom-set-default variable value) + (setq csv-separator-chars (mapcar 'string-to-char value) + csv-skip-regexp (apply 'concat "^\n" csv-separators) + csv-separator-regexp (apply 'concat `("[" ,@value "]")) + csv-font-lock-keywords + ;; NB: csv-separator-face variable evaluates to itself. + `((,csv-separator-regexp . csv-separator-face))))) + +(defcustom csv-field-quotes '("\"") + "Field quotes: a list of *single-character* strings. +For example: (\"\\\"\"), the default, or (\"\\\"\" \"'\" \"`\"). +A field can be delimited by a pair of any of these characters. +All must be different from the field separators, `csv-separators'." + :group 'CSV + :type '(repeat string) + ;; Character would be better, but in Emacs 21 does not display + ;; correctly in a customization buffer. + :set (lambda (variable value) + (mapc (lambda (x) + (if (or (/= (length x) 1) + (member x csv-separators)) + (error))) + value) + (when (boundp 'csv-mode-syntax-table) + ;; FIRST remove old quote syntax: + (with-syntax-table text-mode-syntax-table + (mapc (lambda (x) + (modify-syntax-entry + (string-to-char x) + (string (char-syntax (string-to-char x))) + ;; symbol-value to avoid compiler warning: + (symbol-value 'csv-mode-syntax-table))) + csv-field-quotes)) + ;; THEN set new quote syntax: + (csv-set-quote-syntax value)) + ;; BEFORE setting new value of `csv-field-quotes': + (custom-set-default variable value))) + +(defun csv-set-quote-syntax (field-quotes) + "Set syntax for field quote characters FIELD-QUOTES to be \"string\". +FIELD-QUOTES should be a list of single-character strings." + (mapc (lambda (x) + (modify-syntax-entry + (string-to-char x) "\"" + ;; symbol-value to avoid compiler warning: + (symbol-value 'csv-mode-syntax-table))) + field-quotes)) + +(defvar csv-comment-start nil + "String that starts a comment line, or nil if no comment syntax. +Such comment lines are ignored by CSV mode commands. +This variable is buffer local\; its default value is that of +`csv-comment-start-default'. It is set by the function +`csv-set-comment-start' -- do not set it directly!") + +(make-variable-buffer-local 'csv-comment-start) + +(defcustom csv-comment-start-default "#" + "String that starts a comment line, or nil if no comment syntax. +Such comment lines are ignored by CSV mode commands. +Default value of buffer-local variable `csv-comment-start'. +Changing this variable does not affect any existing CSV mode buffer." + :group 'CSV + :type '(choice (const :tag "None" nil) string) + :set (lambda (variable value) + (custom-set-default variable value) + (set-default 'csv-comment-start value))) + +(defcustom csv-align-style 'left + "Aligned field style: one of 'left, 'centre, 'right or 'auto. +Alignment style used by `csv-align-fields'. +Auto-alignment means left align text and right align numbers." + :group 'CSV + :type '(choice (const left) (const centre) + (const right) (const auto))) + +(defcustom csv-align-padding 1 + "Aligned field spacing: must be a positive integer. +Number of spaces used by `csv-align-fields' after separators." + :group 'CSV + :type 'integer) + +(defcustom csv-header-lines 0 + "Header lines to skip when setting region automatically." + :group 'CSV + :type 'integer) + +(defcustom csv-invisibility-default nil + "If non-nil, make separators in aligned records invisible." + :group 'CSV + :type 'boolean) + +(defface csv-separator-face + '((((class color)) (:foreground "red")) + (t (:weight bold))) + "CSV mode face used to highlight separators." + :group 'CSV) + +;; This mechanism seems to keep XEmacs happy: +(defvar csv-separator-face 'csv-separator-face + "Face name to use to highlight separators.") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Mode definition, key bindings and menu +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defconst csv-mode-line-help-echo + ;; See bindings.el for details of `mode-line-format' construction. + (get-text-property 0 'help-echo (car default-mode-line-format)) + "Primary default mode line help echo text.") + +(defconst csv-mode-line-format + ;; See bindings.el for details of `mode-line-format' construction. + (append (butlast default-mode-line-format 2) + (cons `(csv-field-index-string + ("" csv-field-index-string + ,(propertize "--" 'help-echo csv-mode-line-help-echo))) + (last default-mode-line-format 2))) + "Mode line format string for CSV mode.") + +(define-derived-mode csv-mode text-mode "CSV" + "Major mode for editing files of comma-separated value type. + +CSV mode is derived from `text-mode', and runs `text-mode-hook' before +running `csv-mode-hook'. It turns `auto-fill-mode' off by default. +CSV mode can be customized by user options in the CSV customization +group. The separators are specified by the value of `csv-separators'. + +CSV mode commands ignore blank lines and comment lines beginning with +the value of `csv-comment-start', which delimit \"paragraphs\". +\"Sexp\" is re-interpreted to mean \"field\", so that `forward-sexp' +\(\\[forward-sexp]), `kill-sexp' (\\[kill-sexp]), etc. all apply to fields. +Standard comment commands apply, such as `comment-dwim' (\\[comment-dwim]). + +If `font-lock-mode' is enabled then separators, quoted values and +comment lines are highlighted using respectively `csv-separator-face', +`font-lock-string-face' and `font-lock-comment-face'. + +The user interface (UI) for CSV mode commands is similar to that of +the standard commands `sort-fields' and `sort-numeric-fields', except +that if there is no prefix argument then the UI prompts for the field +index or indices. In `transient-mark-mode' only: if the region is not +set then the UI attempts to set it to include all consecutive CSV +records around point, and prompts for confirmation; if there is no +prefix argument then the UI prompts for it, offering as a default the +index of the field containing point if the region was not set +explicitly. The region set automatically is delimited by blank lines +and comment lines, and the number of header lines at the beginning of +the region given by the value of `csv-header-lines' are skipped. + +Sort order is controlled by `csv-descending'. + +CSV mode provides the following specific keyboard key bindings: + +\\{csv-mode-map}" + (turn-off-auto-fill) + ;; Set syntax for field quotes: + (csv-set-quote-syntax csv-field-quotes) + ;; Make sexp functions apply to fields: + (set (make-local-variable 'forward-sexp-function) 'csv-forward-field) + ;; Paragraph means a group of contiguous records: + (make-local-variable 'paragraph-separate) + (make-local-variable 'paragraph-start) + ;; Comment support: + (make-local-variable 'comment-start) + (csv-set-comment-start csv-comment-start) + (setq + ;; Font locking -- separator plus syntactic: + font-lock-defaults '(csv-font-lock-keywords) + buffer-invisibility-spec csv-invisibility-default + ;; Mode line to support `csv-field-index-mode': + mode-line-format csv-mode-line-format) + ;; Enable or disable `csv-field-index-mode' (could probably do this + ;; a bit more efficiently): + (csv-field-index-mode (symbol-value 'csv-field-index-mode))) + +(defun csv-set-comment-start (string) + "Set comment start for this CSV mode buffer to STRING. +It must be either a string or nil." + (interactive + (list (edit-and-eval-command + "Comment start (string or nil): " csv-comment-start))) + (setq csv-comment-start string + paragraph-separate "[:space:]*$" ; white space + paragraph-start "\n") ; must include \n explicitly! + (if string + (progn + (setq paragraph-separate (concat paragraph-separate "\\|" string) + paragraph-start (concat paragraph-start "\\|" string) + comment-start string) + (modify-syntax-entry + (string-to-char string) "<" csv-mode-syntax-table) + (modify-syntax-entry ?\n ">" csv-mode-syntax-table)) + (with-syntax-table text-mode-syntax-table + (modify-syntax-entry (string-to-char string) + (string (char-syntax (string-to-char string))) + csv-mode-syntax-table) + (modify-syntax-entry ?\n + (string (char-syntax ?\n)) + csv-mode-syntax-table)))) + +(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) + +(define-key csv-mode-map [(control ?c) (control ?v)] 'csv-toggle-invisibility) +(define-key csv-mode-map [(control ?c) (control ?t)] 'csv-transpose) +(define-key csv-mode-map [(control ?c) (control ?c)] 'csv-set-comment-start) +(define-key csv-mode-map [(control ?c) (control ?u)] 'csv-unalign-fields) +(define-key csv-mode-map [(control ?c) (control ?a)] 'csv-align-fields) +(define-key csv-mode-map [(control ?c) (control ?z)] 'csv-yank-as-new-table) +(define-key csv-mode-map [(control ?c) (control ?y)] 'csv-yank-fields) +(define-key csv-mode-map [(control ?c) (control ?k)] 'csv-kill-fields) +(define-key csv-mode-map [(control ?c) (control ?d)] 'csv-toggle-descending) +(define-key csv-mode-map [(control ?c) (control ?r)] 'csv-reverse-region) +(define-key csv-mode-map [(control ?c) (control ?n)] 'csv-sort-numeric-fields) +(define-key csv-mode-map [(control ?c) (control ?s)] 'csv-sort-fields) + +(defvar csv-descending nil + "If non-nil, CSV mode sort functions sort in order of descending sort key. +Usually they sort in order of ascending sort key.") + +(defun csv-toggle-descending () + "Toggle `csv-descending'." + (interactive) + (setq csv-descending (not csv-descending)) + (message "Sort order is %sscending" (if csv-descending "de" "a"))) + +(defun csv-toggle-invisibility () + "Toggle `buffer-invisibility-spec'." + (interactive) + (setq buffer-invisibility-spec (not buffer-invisibility-spec)) + (message "Separators in aligned records will be %svisible \ +\(after re-aligning if soft\)" + (if buffer-invisibility-spec "in" "")) + (redraw-frame (selected-frame))) + +(easy-menu-define + csv-menu + csv-mode-map + "CSV major mode menu keymap" + '("CSV" + ["Sort By Field Lexicographically" csv-sort-fields :active t + :help "Sort lines in region lexicographically by the specified field"] + ["Sort By Field Numerically" csv-sort-numeric-fields :active t + :help "Sort lines in region numerically by the specified field"] + ["Reverse Order of Lines" csv-reverse-region :active t + :help "Reverse the order of the lines in the region"] + ["Use Descending Sort Order" csv-toggle-descending :active t + :style toggle :selected csv-descending + :help "If selected, use descending order when sorting"] + "--" + ["Kill Fields (Columns)" csv-kill-fields :active t + :help "Kill specified fields of each line in the region"] + ["Yank Fields (Columns)" csv-yank-fields :active t + :help "Yank killed fields as specified field of each line in region"] + ["Yank As New Table" csv-yank-as-new-table :active t + :help "Yank killed fields as a new table at point"] + ["Align Fields into Columns" csv-align-fields :active t + :help "Align the start of every field of each line in the region"] + ["Unalign Columns into Fields" csv-unalign-fields :active t + :help "Undo soft alignment and optionally remove redundant white space"] + ["Transpose Rows and Columns" csv-transpose :active t + :help "Rewrite rows (which may have different lengths) as columns"] + "--" + ["Forward Field" forward-sexp :active t + :help "Move forward across one field\; with ARG, do it that many times"] + ["Backward Field" backward-sexp :active t + :help "Move backward across one field\; with ARG, do it that many times"] + ["Kill Field Forward" kill-sexp :active t + :help "Kill field following cursor\; with ARG, do it that many times"] + ["Kill Field Backward" backward-kill-sexp :active t + :help "Kill field preceding cursor\; with ARG, do it that many times"] + "--" + ("Alignment Style" + ["Left" (setq csv-align-style 'left) :active t + :style radio :selected (eq csv-align-style 'left) + :help "If selected, `csv-align-fields' left aligns fields"] + ["Centre" (setq csv-align-style 'centre) :active t + :style radio :selected (eq csv-align-style 'centre) + :help "If selected, `csv-align-fields' centres fields"] + ["Right" (setq csv-align-style 'right) :active t + :style radio :selected (eq csv-align-style 'right) + :help "If selected, `csv-align-fields' right aligns fields"] + ["Auto" (setq csv-align-style 'auto) :active t + :style radio :selected (eq csv-align-style 'auto) + :help "\ +If selected, `csv-align-fields' left aligns text and right aligns numbers"] + ) + ["Show Current Field Index" csv-field-index-mode :active t + :style toggle :selected csv-field-index-mode + :help "If selected, display current field index in mode line"] + ["Make Separators Invisible" csv-toggle-invisibility :active t + :style toggle :selected buffer-invisibility-spec + :help "If selected, separators in aligned records are invisible"] + ["Set Buffer's Comment Start" csv-set-comment-start :active t + :help "Set comment start string for this buffer"] + ["Customize CSV Mode" (customize-group 'CSV) :active t + :help "Open a customization buffer to change CSV mode options"] + )) + +(require 'sort) + +(defsubst csv-not-looking-at-record () + "Return t if looking at blank or comment line, nil otherwise. +Assumes point is at beginning of line." + (looking-at paragraph-separate)) + +(defun csv-interactive-args (&optional type) + "Get arg or field(s) and region interactively, offering sensible defaults. +Signal an error if the buffer is read-only. +If TYPE is noarg then return a list `(beg end)'. +Otherwise, return a list `(arg beg end)', where arg is: + the raw prefix argument by default\; + a single field index if TYPE is single\; + a list of field indices or index ranges if TYPE is multiple. +Field defaults to the current prefix arg\; if not set, prompt user. + +A field index list consists of positive or negative integers or ranges, +separated by any non-integer characters. A range has the form m-n, +where m and n are positive or negative integers, m < n, and n defaults +to the last field index if omitted. + +In transient mark mode, if the mark is not active then automatically +select and highlight CSV records around point, and query user. +The default field when read interactively is the current field." + ;; Must be run interactively to activate mark! + (let* ((arg current-prefix-arg) (default-field 1) + (region + (if (and transient-mark-mode (not mark-active)) + ;; Set region automatically: + (save-excursion + (let (startline lbp) + (if arg + (beginning-of-line) + (setq lbp (line-beginning-position)) + (while (re-search-backward csv-separator-regexp lbp 1) + ;; Move as far as possible, i.e. to beginning of line. + (setq default-field (1+ default-field)))) + (if (csv-not-looking-at-record) + (error "Point may not be within CSV records")) + (setq startline (point)) + ;; Set mark at beginning of region: + (while (not (or (bobp) (csv-not-looking-at-record))) + (forward-line -1)) + (if (csv-not-looking-at-record) (forward-line 1)) + ;; Skip header lines: + (forward-line csv-header-lines) + (set-mark (point)) ; OK since in save-excursion + ;; Move point to end of region: + (goto-char startline) + (beginning-of-line) + (while (not (or (eobp) (csv-not-looking-at-record))) + (forward-line 1)) + ;; Show mark briefly if necessary: + (unless (and (pos-visible-in-window-p) + (pos-visible-in-window-p (mark))) + (exchange-point-and-mark) + (sit-for 1) + (exchange-point-and-mark)) + (or (y-or-n-p "Region OK? ") + (error "Action aborted by user")) + (message nil) ; clear y-or-n-p message + (list (region-beginning) (region-end)))) + ;; Use region set by user: + (list (region-beginning) (region-end))))) + (setq default-field (number-to-string default-field)) + (cond + ((eq type 'multiple) + (if arg + ;; Ensure that field is a list: + (or (consp arg) + (setq arg (list (prefix-numeric-value arg)))) + ;; Read field interactively, ignoring non-integers: + (setq arg + (mapcar + (lambda (x) + (if (string-match "-" x 1) ; not first character + ;; Return a range as a pair - the cdr may be nil: + (let ((m (substring x 0 (match-beginning 0))) + (n (substring x (match-end 0)))) + (cons (car (read-from-string m)) + (and (not (string= n "")) + (car (read-from-string n))))) + ;; Return a number as a number: + (car (read-from-string x)))) + (split-string + (read-string + "Fields (sequence of integers or ranges): " default-field) + "[^-+0-9]+"))))) + ((eq type 'single) + (if arg + (setq arg (prefix-numeric-value arg)) + (while (not (integerp arg)) + (setq arg (eval-minibuffer "Field (integer): " default-field)))))) + (if (eq type 'noarg) region (cons arg region)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Sorting by field +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun csv-nextrecfun () + "Called by `csv-sort-fields-1' with point at end of previous record. +It moves point to the start of the next record. +It should move point to the end of the buffer if there are no more records." + (forward-line) + (while (and (not (eobp)) (csv-not-looking-at-record)) + (forward-line))) + +(defun csv-sort-fields-1 (field beg end startkeyfun endkeyfun) + "Modified version of `sort-fields-1' that skips blank or comment lines. + +FIELD is a single field index, and BEG and END specify the region to +sort. + +STARTKEYFUN moves from the start of the record to the start of the key. +It may return either a non-nil value to be used as the key, or +else the key is the substring between the values of point after +STARTKEYFUN and ENDKEYFUN are called. If STARTKEYFUN is nil, the key +starts at the beginning of the record. + +ENDKEYFUN moves from the start of the sort key to the end of the sort key. +ENDKEYFUN may be nil if STARTKEYFUN returns a value or if it would be the +same as ENDRECFUN." + (let ((tbl (syntax-table))) + (if (zerop field) (setq field 1)) + (unwind-protect + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (set-syntax-table sort-fields-syntax-table) + (sort-subr csv-descending + 'csv-nextrecfun 'end-of-line + startkeyfun endkeyfun))) + (set-syntax-table tbl)))) + +(defun csv-sort-fields (field beg end) + "Sort lines in region lexicographically by the ARGth field of each line. +If not set, the region defaults to the CSV records around point. +Fields are separated by `csv-separators' and null fields are allowed anywhere. +Field indices increase from 1 on the left or decrease from -1 on the right. +A prefix argument specifies a single field, otherwise prompt for field index. +Ignore blank and comment lines. The variable `sort-fold-case' +determines whether alphabetic case affects the sort order. +When called non-interactively, FIELD is a single field index\; +BEG and END specify the region to sort." + ;; (interactive "*P\nr") + (interactive (csv-interactive-args 'single)) + (barf-if-buffer-read-only) + (csv-sort-fields-1 field beg end + (lambda () (csv-sort-skip-fields field) nil) + (lambda () (skip-chars-forward csv-skip-regexp)))) + +(defun csv-sort-numeric-fields (field beg end) + "Sort lines in region numerically by the ARGth field of each line. +If not set, the region defaults to the CSV records around point. +Fields are separated by `csv-separators'. +Null fields are allowed anywhere and sort as zeros. +Field indices increase from 1 on the left or decrease from -1 on the right. +A prefix argument specifies a single field, otherwise prompt for field index. +Specified non-null field must contain a number in each line of the region, +which may begin with \"0x\" or \"0\" for hexadecimal and octal values. +Otherwise, the number is interpreted according to sort-numeric-base. +Ignore blank and comment lines. +When called non-interactively, FIELD is a single field index\; +BEG and END specify the region to sort." + ;; (interactive "*P\nr") + (interactive (csv-interactive-args 'single)) + (barf-if-buffer-read-only) + (csv-sort-fields-1 field beg end + (lambda () + (csv-sort-skip-fields field) + (let* ((case-fold-search t) + (base + (if (looking-at "\\(0x\\)[0-9a-f]\\|\\(0\\)[0-7]") + (cond ((match-beginning 1) + (goto-char (match-end 1)) + 16) + ((match-beginning 2) + (goto-char (match-end 2)) + 8) + (t nil))))) + (string-to-number (buffer-substring (point) + (save-excursion + (forward-sexp 1) + (point))) + (or base sort-numeric-base)))) + nil)) + +(defun csv-reverse-region (beg end) + "Reverse the order of the lines in the region. +This is just a CSV-mode style interface to `reverse-region', which is +the function that should be used non-interactively. It takes two +point or marker arguments, BEG and END, delimiting the region." + ;; (interactive "*P\nr") + (interactive (csv-interactive-args 'noarg)) + (barf-if-buffer-read-only) + (reverse-region beg end)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Moving by field +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defsubst csv-end-of-field () + "Skip forward over one field." + (skip-syntax-forward " ") + (if (eq (char-syntax (following-char)) ?\") + (goto-char (scan-sexps (point) 1))) + (skip-chars-forward csv-skip-regexp)) + +(defsubst csv-beginning-of-field () + "Skip backward over one field." + (skip-syntax-backward " ") + (if (eq (char-syntax (preceding-char)) ?\") + (goto-char (scan-sexps (point) -1))) + (skip-chars-backward csv-skip-regexp)) + +(defun csv-forward-field (arg) + "Move forward across one field, cf. `forward-sexp'. +With ARG, do it that many times. Negative arg -N means +move backward across N fields." + (interactive "p") + (if (< arg 0) + (csv-backward-field (- arg)) + (while (>= (setq arg (1- arg)) 0) + (if (or (bolp) + (when (and (not (eobp)) (eolp)) (forward-char) t)) + (while (and (not (eobp)) (csv-not-looking-at-record)) + (forward-line 1))) + (if (memq (following-char) csv-separator-chars) (forward-char)) + (csv-end-of-field)))) + +(defun csv-backward-field (arg) + "Move backward across one field, cf. `backward-sexp'. +With ARG, do it that many times. Negative arg -N means +move forward across N fields." + (interactive "p") + (if (< arg 0) + (csv-forward-field (- arg)) + (while (>= (setq arg (1- arg)) 0) + (when (or (eolp) + (when (and (not (bobp)) (bolp)) (backward-char) t)) + (while (progn + (beginning-of-line) + (csv-not-looking-at-record)) + (backward-char)) + (end-of-line)) + (if (memq (preceding-char) csv-separator-chars) (backward-char)) + (csv-beginning-of-field)))) + +(defun csv-sort-skip-fields (n &optional yank) + "Position point at the beginning of field N on the current line. +Fields are separated by `csv-separators'\; null terminal field allowed. +Assumes point is initially at the beginning of the line. +YANK non-nil allows N to be greater than the number of fields, in +which case extend the record as necessary." + (if (> n 0) + ;; Skip across N - 1 fields. + (let ((i (1- n))) + (while (> i 0) + (csv-end-of-field) + (if (eolp) + (if yank + (if (> i 1) (insert (car csv-separators))) + (error "Line has too few fields: %s" + (buffer-substring + (save-excursion (beginning-of-line) (point)) + (save-excursion (end-of-line) (point))))) + (forward-char)) ; skip separator + (setq i (1- i)))) + (end-of-line) + ;; Skip back across -N - 1 fields. + (let ((i (1- (- n)))) + (while (> i 0) + (csv-beginning-of-field) + (if (bolp) + (error "Line has too few fields: %s" + (buffer-substring + (save-excursion (beginning-of-line) (point)) + (save-excursion (end-of-line) (point))))) + (backward-char) ; skip separator + (setq i (1- i))) + ;; Position at the front of the field + ;; even if moving backwards. + (csv-beginning-of-field)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Field index mode +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Based partly on paren.el + +(defcustom csv-field-index-delay 0.125 + "Time in seconds to delay before updating field index display." + :group 'CSV + :type '(number :tag "seconds")) + +(defvar csv-field-index-idle-timer nil) + +(defvar csv-field-index-string nil) +(make-variable-buffer-local 'csv-field-index-string) + +(defvar csv-field-index-old nil) +(make-variable-buffer-local 'csv-field-index-old) + +(define-minor-mode csv-field-index-mode + "Toggle CSV-Field-Index mode. +With prefix ARG, turn CSV-Field-Index mode on if and only if ARG is positive. +Returns the new status of CSV-Field-Index mode (non-nil means on). +When CSV-Field-Index mode is enabled, the current field index appears in +the mode line after `csv-field-index-delay' seconds of Emacs idle time." + :group 'CSV + :global t + :init-value t ; for documentation, since default is t + ;; This macro generates a function that first sets the mode + ;; variable, then runs the following code, runs the mode hooks, + ;; displays a message if interactive, updates the mode line and + ;; finally returns the variable value. + + ;; First, always disable the mechanism (to avoid having two timers): + (when csv-field-index-idle-timer + (cancel-timer csv-field-index-idle-timer) + (setq csv-field-index-idle-timer nil)) + ;; Now, if the mode is on and any buffer is in CSV mode then + ;; re-initialize and enable the mechanism by setting up a new timer: + (if csv-field-index-mode + (if (memq t (mapcar (lambda (buffer) + (with-current-buffer buffer + (when (eq major-mode 'csv-mode) + (setq csv-field-index-string nil + csv-field-index-old nil) + t))) + (buffer-list))) + (setq csv-field-index-idle-timer + (run-with-idle-timer csv-field-index-delay t + 'csv-field-index))) + ;; but if the mode is off then remove the display from the mode + ;; lines of all CSV buffers: + (mapc (lambda (buffer) + (with-current-buffer buffer + (when (eq major-mode 'csv-mode) + (setq csv-field-index-string nil + csv-field-index-old nil) + (force-mode-line-update)))) + (buffer-list)))) + +(defun csv-field-index () + "Construct `csv-field-index-string' to display in mode line. +Called by `csv-field-index-idle-timer'." + (if (eq major-mode 'csv-mode) + (save-excursion + (let ((lbp (line-beginning-position)) (field 1)) + (while (re-search-backward csv-separator-regexp lbp 1) + ;; Move as far as possible, i.e. to beginning of line. + (setq field (1+ field))) + (if (csv-not-looking-at-record) (setq field nil)) + (when (not (eq field csv-field-index-old)) + (setq csv-field-index-old field + csv-field-index-string + (and field (propertize (format "F%d" field) + 'help-echo csv-mode-line-help-echo))) + (force-mode-line-update)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Killing and yanking fields +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar csv-killed-fields nil + "A list of the fields or sub-records last killed by `csv-kill-fields'.") + +(defun csv-kill-fields (fields beg end) + "Kill specified fields of each line in the region. +If not set, the region defaults to the CSV records around point. +Fields are separated by `csv-separators' and null fields are allowed anywhere. +Field indices increase from 1 on the left or decrease from -1 on the right. +The fields are stored for use by `csv-yank-fields'. Fields can be +specified in any order but are saved in increasing index order. +Ignore blank and comment lines. + +When called interactively, a prefix argument specifies a single field, +otherwise prompt for a field list, which may include ranges in the form +m-n, where m < n and n defaults to the last field index if omitted. + +When called non-interactively, FIELDS is a single field index or a +list of field indices, with ranges specified as (m.n) or (m), and BEG +and END specify the region to process." + ;; (interactive "*P\nr") + (interactive (csv-interactive-args 'multiple)) + (barf-if-buffer-read-only) + ;; Kill the field(s): + (setq csv-killed-fields nil) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (if (or (cdr fields) (consp (car fields))) + (csv-kill-many-columns fields) + (csv-kill-one-column (car fields))))) + (setq csv-killed-fields (nreverse csv-killed-fields))) + +(defmacro csv-kill-one-field (field killed-fields) + "Kill field with index FIELD in current line. +Save killed field by `push'ing onto KILLED-FIELDS. +Assumes point is at beginning of line. +Called by `csv-kill-one-column' and `csv-kill-many-columns'." + `(progn + ;; Move to start of field to kill: + (csv-sort-skip-fields ,field) + ;; Kill to end of field (cf. `kill-region'): + (push (delete-and-extract-region + (point) + (progn (csv-end-of-field) (point))) + ,killed-fields) + (if (eolp) (delete-char -1) ; delete trailing separator at eol + (delete-char 1)))) ; or following separator otherwise + +(defun csv-kill-one-column (field) + "Kill field with index FIELD in all lines in (narrowed) buffer. +Save killed fields in `csv-killed-fields'. +Assumes point is at `point-min'. Called by `csv-kill-fields'. +Ignore blank and comment lines." + (while (not (eobp)) + (or (csv-not-looking-at-record) + (csv-kill-one-field field csv-killed-fields)) + (forward-line))) + +(defun csv-kill-many-columns (fields) + "Kill several fields in all lines in (narrowed) buffer. +FIELDS is an unordered list of field indices. +Save killed fields in increasing index order in `csv-killed-fields'. +Assumes point is at `point-min'. Called by `csv-kill-fields'. +Ignore blank and comment lines." + (if (eolp) (error "First record is empty")) + ;; Convert non-positive to positive field numbers: + (let ((last 1) (f fields)) + (csv-end-of-field) + (while (not (eolp)) + (forward-char) ; skip separator + (csv-end-of-field) + (setq last (1+ last))) ; last = # fields in first record + (while f + (cond ((consp (car f)) + ;; Expand a field range: (m.n) -> m m+1 ... n-1 n. + ;; If n is nil then it defaults to the number of fields. + (let* ((range (car f)) (cdrf (cdr f)) + (m (car range)) (n (cdr range))) + (if (< m 0) (setq m (+ m last 1))) + (if n + (if (< n 0) (setq n (+ n last 1))) + (setq n last)) + (setq range (list n)) + (while (> n m) (push (setq n (1- n)) range)) + (setcar f (car range)) + (setcdr f (cdr range)) + (setcdr (setq f (last range)) cdrf))) + ((zerop (car f)) (setcar f 1)) + ((< (car f) 0) (setcar f (+ f last 1)))) + (setq f (cdr f)))) + (goto-char (point-min)) + ;; Kill from right to avoid miscounting: + (setq fields (sort fields '>)) + (while (not (eobp)) + (or (csv-not-looking-at-record) + (let ((fields fields) killed-fields field) + (while fields + (setq field (car fields) + fields (cdr fields)) + (beginning-of-line) + (csv-kill-one-field field killed-fields)) + (push (mapconcat 'identity killed-fields (car csv-separators)) + csv-killed-fields))) + (forward-line))) + +(defun csv-yank-fields (field beg end) + "Yank fields as the ARGth field of each line in the region. +ARG may be arbitrarily large and records are extended as necessary. +If not set, the region defaults to the CSV records around point\; +if point is not in a CSV record then offer to yank as a new table. +The fields yanked are those last killed by `csv-kill-fields'. +Fields are separated by `csv-separators' and null fields are allowed anywhere. +Field indices increase from 1 on the left or decrease from -1 on the right. +A prefix argument specifies a single field, otherwise prompt for field index. +Ignore blank and comment lines. When called non-interactively, FIELD +is a single field index\; BEG and END specify the region to process." + ;; (interactive "*P\nr") + (interactive (condition-case err + (csv-interactive-args 'single) + (error (list nil nil err)))) + (barf-if-buffer-read-only) + (if (null beg) + (if (y-or-n-p (concat (error-message-string end) + ". Yank as a new table? ")) + (csv-yank-as-new-table) + (error (error-message-string end))) + (if (<= field 0) (setq field (1+ field))) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let ((fields csv-killed-fields)) + (while (not (eobp)) + (unless (csv-not-looking-at-record) + ;; Yank at start of specified field if possible, + ;; otherwise yank at end of record: + (if (zerop field) + (end-of-line) + (csv-sort-skip-fields field 'yank)) + (and (eolp) (insert (car csv-separators))) + (when fields + (insert (car fields)) + (setq fields (cdr fields))) + (or (eolp) (insert (car csv-separators)))) + (forward-line))))))) + +(defun csv-yank-as-new-table () + "Yank fields as a new table starting at point. +The fields yanked are those last killed by `csv-kill-fields'." + (interactive "*") + (let ((fields csv-killed-fields)) + (while fields + (insert (car fields) ?\n) + (setq fields (cdr fields))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Aligning fields +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun csv-align-fields (hard beg end) + "Align all the fields in the region to form columns. +The alignment style is specified by `csv-align-style'. The number of +spaces specified by `csv-align-fields' appears after each separator. +Use soft alignment done by displaying virtual white space after the +separators unless invoked with an argument, in which case insert real +space characters into the buffer after the separators. +Unalign first (see `csv-unalign-fields'). Ignore blank and comment lines. + +In hard-aligned records, separators become invisible whenever +`buffer-invisibility-spec' is non-nil. In soft-aligned records, make +separators invisible if and only if `buffer-invisibility-spec' is +non-nil when the records are aligned\; this can be changed only by +re-aligning. \(Unaligning always makes separators visible.) + +When called non-interactively, use hard alignment if HARD is non-nil\; +BEG and END specify the region to align." + (interactive (csv-interactive-args)) + (setq end (set-marker (make-marker) end)) + (csv-unalign-fields hard beg end) ; if hard then barfs if buffer read only + (save-excursion + (save-restriction + (narrow-to-region beg end) + (set-marker end nil) + (goto-char (point-min)) + (let (widths) + ;; Construct list of column widths: + (while (not (eobp)) ; for each record... + (or (csv-not-looking-at-record) + (let ((w widths) x) + (setq beg (point)) ; beginning of current field + (while (not (eolp)) + (csv-end-of-field) + (setq x (- (point) beg)) ; field width + (if w + (if (> x (car w)) (setcar w x)) + (setq w (list x) + widths (nconc widths w))) + (or (eolp) (forward-char)) ; skip separator + (setq w (cdr w) + beg (point))))) + (forward-line)) + + ;; Align fields: + (goto-char (point-min)) + (while (not (eobp)) ; for each record... + (or (csv-not-looking-at-record) + (let ((w widths) (padding 0) x) + (setq beg (point)) ; beginning of current field + (while (and w (not (eolp))) + (let ((left-padding 0) (right-padding 0) overlay) + (csv-end-of-field) + (set-marker end (point)) ; end of current field + (setq x (- (point) beg) ; field width + x (- (car w) x)) ; required padding + + ;; beg = beginning of current field + ;; end = (point) = end of current field + + ;; Compute required padding: + (cond + ((eq csv-align-style 'left) + ;; Left align -- pad on the right: + (setq left-padding csv-align-padding + right-padding x)) + ((eq csv-align-style 'right) + ;; Right align -- pad on the left: + (setq left-padding (+ csv-align-padding x))) + ((eq csv-align-style 'auto) + ;; Auto align -- left align text, right align numbers: + (if (string-match "\\`[-+.[:digit:]]+\\'" + (buffer-substring beg (point))) + ;; Right align -- pad on the left: + (setq left-padding (+ csv-align-padding x)) + ;; Left align -- pad on the right: + (setq left-padding csv-align-padding + right-padding x))) + ((eq csv-align-style 'centre) + ;; Centre -- pad on both left and right: + (let ((y (/ x 2))) ; truncated integer quotient + (setq left-padding (+ csv-align-padding y) + right-padding (- x y))))) + + (if hard + ;; Hard alignment... + (progn + (when (> left-padding 0) ; pad on the left + ;; Insert spaces before field: + (if (= beg end) ; null field + (insert (make-string left-padding ?\ )) + (goto-char beg) ; beginning of current field + (insert (make-string left-padding ?\ )) + (goto-char end))) ; end of current field + (unless (eolp) + (if (> right-padding 0) ; pad on the right + ;; Insert spaces after field: + (insert (make-string right-padding ?\ ))) + ;; Make separator (potentially) invisible; + ;; in Emacs 21.3, neighbouring overlays + ;; conflict, so use the following only + ;; with hard alignment: + (overlay-put (make-overlay (point) (1+ (point))) + ;; 'face 'secondary-selection) ; test + 'invisible t) + (forward-char))) ; skip separator + + ;; Soft alignment... + + (if buffer-invisibility-spec ; csv-hide-separators + + ;; Hide separators... + (progn + ;; Merge right-padding from previous field + ;; with left-padding from this field: + (setq padding (+ padding left-padding)) + (when (> padding 0) + (goto-char beg) ; beginning of current field + (if (bolp) + ;; Display spaces before first field + ;; by overlaying first character: + (overlay-put + (make-overlay (point) (1+ (point))) + 'before-string + (make-string padding ?\ )) + ;; Display separator as spaces: + (overlay-put + (make-overlay (1- (point)) (point)) + ;; 'face 'secondary-selection)) ; test + ;; 'display (make-string padding ?\ ))) + ;; Above 'display mangles buffer + ;; horribly if any string is empty! + 'display `(space :width ,padding))) + (goto-char end)) ; end of current field + (unless (eolp) + (setq padding right-padding) + (forward-char))) ; skip separator + + ;; Do not hide separators... + (when (> left-padding 0) ; pad on the left + ;; Display spaces before field: + (setq overlay (make-overlay beg (point))) + (overlay-put overlay 'before-string + (make-string left-padding ?\ ))) + (unless (eolp) + (if (> right-padding 0) ; pad on the right + ;; Display spaces after field: + (overlay-put + (or overlay + (make-overlay beg (point))) + 'after-string (make-string right-padding ?\ ))) + (forward-char))) ; skip separator + + )) + + (setq w (cdr w) + beg (point))))) + (forward-line))))) + (set-marker end nil)) + +(defun csv-unalign-fields (hard beg end) + "Undo soft alignment and optionally remove redundant white space. +Undo soft alignment introduced by `csv-align-fields'. If invoked with +an argument then also remove all spaces and tabs around separators. +Also make all invisible separators visible again. +Ignore blank and comment lines. When called non-interactively, remove +spaces and tabs if HARD non-nil\; BEG and END specify region to unalign." + (interactive (csv-interactive-args)) + ;; Remove any soft alignment: + (mapc 'delete-overlay (overlays-in beg end)) + (when hard + (barf-if-buffer-read-only) + ;; Remove any white-space padding around separators: + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (while (not (eobp)) + (or (csv-not-looking-at-record) + (while (not (eolp)) + ;; Delete horizontal white space forward: + ;; (delete-horizontal-space) + ;; This relies on left-to-right argument evaluation; + ;; see info node (elisp) Function Forms. + (delete-region (point) + (+ (point) (skip-chars-forward " \t"))) + (csv-end-of-field) + ;; Delete horizontal white space backward: + ;; (delete-horizontal-space t) + (delete-region (point) + (+ (point) (skip-chars-backward " \t"))) + (or (eolp) (forward-char)))) + (forward-line)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Transposing rows and columns +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun csv-transpose (beg end) + "Rewrite rows (which may have different lengths) as columns. +Null fields are introduced as necessary within records but are +stripped from the ends of records. Preserve soft alignment. +This function is its own inverse. Ignore blank and comment lines. +When called non-interactively, BEG and END specify region to process." + ;; (interactive "*P\nr") + (interactive (csv-interactive-args 'noarg)) + (barf-if-buffer-read-only) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + ;; Delete rows and collect them as a reversed list of lists of + ;; fields, skipping comment and blank lines: + (let ((sep (car csv-separators)) + (align (overlays-in beg end)) + rows columns) + ;; Remove soft alignment if necessary: + (when align + (mapc 'delete-overlay align) + (setq align t)) + (while (not (eobp)) + (if (csv-not-looking-at-record) + ;; Skip blank and comment lines: + (forward-line) + (let ((lep (line-end-position))) + (push + (csv-split-string + (buffer-substring-no-properties (point) lep) + csv-separator-regexp nil t) + rows) + (delete-region (point) lep) + (or (eobp) (delete-char 1))))) + ;; Rows must have monotonic decreasing lengths to be + ;; transposable, so ensure this by padding with null fields. + ;; rows is currently a reversed list of field lists, which + ;; must therefore have monotonic increasing lengths. + (let ((oldlen (length (car rows))) newlen + (r (cdr rows))) + (while r + (setq newlen (length (car r))) + (if (< newlen oldlen) + (nconc (car r) (make-list (- oldlen newlen) nil)) + (setq oldlen newlen)) + (setq r (cdr r)))) + ;; Collect columns as a reversed list of lists of fields: + (while rows + (let (column (r rows) row) + (while r + (setq row (car r)) + ;; Provided it would not be a trailing null field, push + ;; field onto column: + (if (or column (string< "" (car row))) + (push (car row) column)) + ;; Pop field off row: + (setcar r (cdr row)) + ;; If row is now empty then remove it: + (or (car r) (setq rows (cdr rows))) + (setq r (cdr r))) + (push column columns))) + ;; Insert columns into buffer as rows: + (setq columns (nreverse columns)) + (while columns + (insert (mapconcat 'identity (car columns) sep) ?\n) + (setq columns (cdr columns))) + ;; Re-do soft alignment if necessary: + (if align (csv-align-fields nil (point-min) (point-max))))))) + +;; The following generalised version of `split-string' is taken from +;; the development version of WoMan and should probably replace the +;; standard version in subr.el. However, CSV mode (currently) needs +;; only the `allowbeg' option. + +(defun csv-split-string + (string &optional separators subexp allowbeg allowend) + "Splits STRING into substrings where there are matches for SEPARATORS. +Each match for SEPARATORS is a splitting point. +The substrings between the splitting points are made into a list +which is returned. +If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\". +SUBEXP specifies a subexpression of SEPARATORS to be the splitting +point\; it defaults to 0. + +If there is a match for SEPARATORS at the beginning of STRING, we do +not include a null substring for that, unless ALLOWBEG is non-nil. +Likewise, if there is a match at the end of STRING, we do not include +a null substring for that, unless ALLOWEND is non-nil. + +Modifies the match data; use `save-match-data' if necessary." + (or subexp (setq subexp 0)) + (let ((rexp (or separators "[ \f\t\n\r\v]+")) + (start 0) + notfirst + (list nil)) + (while (and (string-match rexp string + (if (and notfirst + (= start (match-beginning subexp)) + (< start (length string))) + (1+ start) start)) + (< (match-beginning subexp) (length string))) + (setq notfirst t) + (or (and (not allowbeg) (eq (match-beginning subexp) 0)) + (and (eq (match-beginning subexp) (match-end subexp)) + (eq (match-beginning subexp) start)) + (push (substring string start (match-beginning subexp)) list)) + (setq start (match-end subexp))) + (or (and (not allowend) (eq start (length string))) + (push (substring string start) list)) + (nreverse list))) + +(provide 'csv-mode) + +;;; csv-mode.el ends here diff --git a/auto-install/doremi.el b/auto-install/doremi.el new file mode 100644 index 0000000..394f8be --- /dev/null +++ b/auto-install/doremi.el @@ -0,0 +1,581 @@ +;;; doremi.el --- Do Re Mi: Incremental change using arrow keys or mouse wheel. +;; +;; Filename: doremi.el +;; Description: Incremental change using arrow keys or mouse wheel. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2004-2011, Drew Adams, all rights reserved. +;; Created: Thu Sep 02 08:21:37 2004 +;; Version: 21.1 +;; Last-Updated: Wed Sep 7 15:53:07 2011 (-0700) +;; By: dradams +;; Update #: 1600 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/doremi.el +;; Keywords: keys, cycle, repeat, higher-order +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `mwheel', `ring', `ring+'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Do Re Mi: Incremental change using arrow keys or mouse wheel. +;; +;; When you invoke Do Re Mi commands, you can then press and hold an +;; up/down arrow key, or turn the mouse wheel, to run up and down the +;; scale: do, re, mi,... +;; +;; Use the up/down arrow keys or the mouse wheel to: +;; +;; - Change nearly any parameter incrementally (dynamically). +;; +;; - Repeat an action. +;; +;; - Cycle through a set of values, without changing anything (for +;; example, to choose an item). In this use, think of choosing +;; from a menu. This is similar to using a minibuffer history. +;; The input choices can take the form of any Emacs-Lisp sequence +;; (list, array, string, vector) - this sequence is converted to a +;; circular structure (ring). +;; +;; - Do just about anything: call a different function for each +;; arrow. +;; +;; This works with numerical parameters that can be incremented and +;; decremented, and it works with parameters that can take on one of a +;; number of values. In fact, it is even more general than that: you +;; can use it to associate nearly any function or pair of functions +;; with the arrow keys and the mouse wheel. +;; +;; By default, the up and down arrow keys are used, but any other keys +;; may be used instead. Mouse wheel movements are recognized for +;; Emacs 20 and Emacs 21 (using library `mwheel.el'). `mouse-2' +;; presses are ignored, so that they won't interfere with rotating the +;; wheel. +;; +;; See the doc string for function `doremi' for more information. +;; +;; Code defining a few example commands is included here (but +;; commented out), so you can see how to use this. For more examples +;; of using function `doremi', see files `doremi-frm.el' and +;; `doremi-cmd.el'. +;; +;; This library uses library `ring+.el', which provides extensions to +;; the standard library `ring.el' to let you manipulate circular +;; structures. +;; +;; +;; Non-interactive functions defined here: +;; +;; `doremi', `doremi-intersection', `doremi-limit', +;; `doremi-set-new-value', `doremi-wrap'. +;; +;; User options (variables) defined here: +;; +;; `doremi-boost-down-keys', `doremi-boost-scale-factor', +;; `doremi-boost-up-keys', `doremi-down-keys', `doremi-up-keys'. +;; +;; Add this to your initialization file (~/.emacs or ~/_emacs): +;; +;; (require 'doremi) +;; +;; See also these related libraries that make use of `doremi': +;; +;; `doremi-frm.el' - Incrementally adjust frame properties. +;; `doremi-cmd.el' - Other Do Re Mi commands. +;; `doremi-mac.el' - Macro to define Do Re Mi commands and +;; automatically add them to Do Re Mi menu. +;; +;; This has been tested on GNU Emacs 20, 21, and 22 on MS Windows. +;; +;; +;; TO DO?: +;; +;; - Replace `boost-*' keys by test for modifiers (as for wheel). +;; - Combine with customize. That is, have customize buffers use +;; Do Re Mi commands to defined numeric or enumeration values. +;; - Provide buttons (menu items) in menus that act like up & down +;; arrows. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2011/09/07 dadams +;; doremi: Use mouse-wheel-(up|down)-event everywhere. Thx to Michael Heerdegen. +;; 2011/01/04 dadams +;; Removed autoload cookies from non-interactive functions. +;; Added autoload cookies for defgroup, defcustom. +;; 2009/11/14 dadams +;; doremi-wrap: Wrap value around, instead of just moving to the other limit. +;; 2009/11/07 dadams +;; doremi: Increment can now be a list of numbers. +;; Use >= 0, not natnump, since not necessarily an integer. +;; 2009/06/26 dadams +;; Added: doremi-intersection. +;; Renamed options doremi-...-key to doremi-...-keys, and made them lists. +;; Added top-level warning when load the library if obsolete vars are boundp. +;; doremi, doremi-set-new-value: Use these new list vars. +;; doremi: Handle Emacs 23 mouse-wheel modifiers using doremi-intersection (ugly hack). +;; 2009/06/19 dadams +;; doremi-*-key: fixed :type, clarified doc string about value. +;; 2009/06/18 dadams +;; doremi: Use single-key-description in messages. +;; 2007/12/31 dadams +;; doremi: Use doremi-set-new-value instead of wrapping input functions. +;; Commented out setting redisplay-dont-pause to t. +;; Added: doremi-set-new-value. +;; oremi-boost-scale-factor: Clarified doc string. +;; property -> parameter in all doc strings (RMS). +;; 2007/10/21 dadams +;; doremi: Don't let switch-frame events quit the loop. +;; Added: doremi-limit, doremi-wrap. +;; 2006/01/07 dadams +;; Added :link. +;; 2005/07/25 dadams +;; Added :prefix to defgroup. +;; 2005/01/16 dadams +;; doremi: Bind redisplay-dont-pause to `t' for Emacs 21. +;; Use error-message-string to format error string. +;; 2005/01/01 dadams +;; defvar -> defcustom. Added (defgroup doremi). +;; 2004/11/28 dadams +;; doremi: Allowed for GROWTH-FN to be a function, not just a flag. +;; Added initial value to initial prompt. +;; Corrected addition of last event to unread-command-events. +;; Improved error messages. +;; 2004/09/26 dadams +;; Renamed do-re-mi* to doremi*. +;; Prefixed everything here with doremi-. +;; Changed convert-sequence-to-ring to ring-convert-sequence-to-ring. +;; 2004/09/24 dadams +;; Added use of mouse wheel. Changed key sequences to events. +;; Change prompt to add Meta info only for non-enumeration. +;; Suppress keystroke echoing. +;; 2004/09/19 dadams +;; Moved doremi-buffers to doremi-cmd.el. +;; Commented-out commands test-*. +;; 2004/09/11 dadams +;; Moved to doremi-frm.el: adjust-*, cycle-frame-configs, +;; grow-font, move-frame-*, and apply of push-frame-config. +;; 2004/09/07 dadams +;; Added: cycle-frame-configs. +;; Apply push-frame-config to frame commands here. +;; 2004/09/06 dadams +;; Added boost-*. Added error treatment to move-frame-*. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(require 'ring+) ;; ring-convert-sequence-to-ring, ring-insert+extend, + ;; ring-member, ring-next, ring-previous +(require 'mwheel nil t) ; (no error if not found): mwheel-event-button + +(and (< emacs-major-version 20) (eval-when-compile (require 'cl))) ;; when, unless + +;; In Emacs 20, because `mwheel.el' is not loaded, byte-compiling +;; would give the following error messages, which can be ignored: +;; +;; While compiling doremi: +;; ** reference to free variable mouse-wheel-down-event +;; ** reference to free variable mouse-wheel-up-event +;; While compiling the end of the data: +;; ** the function mwheel-event-button is not known to be defined. +;; +;; This eliminates (only) the first of these two byte-compiler messages: +(defvar mouse-wheel-down-event) +(defvar mouse-wheel-up-event) + +;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; User Options (Variables) + +;;;###autoload +(defgroup doremi nil + "Do Re Mi: Incremental change using arrow keys or mouse wheel. +Define commands to perform repetitive or incremental operations." + :prefix "doremi-" :group 'convenience + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +doremi.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/cgi-bin/wiki/doremi.el") + :link '(url-link :tag "Description" + "http://www.emacswiki.org/cgi-bin/wiki/Doremi") + :link '(emacs-commentary-link :tag "Commentary" "doremi")) + +;;;###autoload +(defcustom doremi-up-keys '(up) + "*Keys (events) associated with one direction of adjusting by `doremi'. +The other direction is associated with `doremi-down-keys'. + +The value must be a list of keyboard events: characters or symbols. +For example, a list element might be `?\C-p' or `prior'." + :type '(repeat (restricted-sexp :match-alternatives (integerp symbolp))) :group 'doremi) + +;;;###autoload +(defcustom doremi-down-keys '(down) + "*Keys (events) associated with one direction of adjusting by `doremi'. +The other direction is associated with `doremi-up-keys'. + +The value must be a list of keyboard events: characters or symbols. +For example, a list element might be `?\C-n' or `next'." + :type '(repeat (restricted-sexp :match-alternatives (integerp symbolp))) :group 'doremi) + +;;;###autoload +(defcustom doremi-boost-up-keys '(M-up) + "*Like `doremi-up-keys', but increments by `doremi-boost-scale-factor'. + +The value must be a list of keyboard events: characters or symbols. +For example, a list element might be `?\M-p' or `S-prior'." + :type '(repeat (restricted-sexp :match-alternatives (integerp symbolp))) :group 'doremi) + +;;;###autoload +(defcustom doremi-boost-down-keys '(M-down) + "*Like `doremi-down-keys', but increments by `doremi-boost-scale-factor'. + +The value must be a list of keyboard events: characters or symbols. +For example, a list element might be `?\M-n' or `S-next'." + :type '(repeat (restricted-sexp :match-alternatives (integerp symbolp))) :group 'doremi) + +;;;###autoload +(defcustom doremi-boost-scale-factor 10 + "*Factor to boost incremental change of numerical properties. +Using `doremi-boost-up-keys' or `doremi-boost-down-keys', instead of +`doremi-up-keys' or `doremi-down-keys' means that the increment is +this many times larger. Using a modifier key with the mouse wheel has +the same effect as using `doremi-boost-up-keys' or +`doremi-boost-down-keys'." + :type 'integer :group 'doremi) + +;; Originally, the key-variable options were for a single key, not a list of keys. +;; Top-level warning when load the library. +(when (or (boundp 'doremi-up-key) (boundp 'doremi-boost-up-key) + (boundp 'doremi-down-key) (boundp 'doremi-boost-down-key)) + (message "WARNING: Single-key options `doremi-...-key' are OBSOLETE. Use `doremi-...-keys'.")) + +;;; Non-Interactive Functions + +(defun doremi (setter-fn init-val incr &optional growth-fn enum allow-new-p) + "Use arrow keys and/or mouse wheel to adjust some parameter. + +Variables `doremi-up-keys' and `doremi-down-keys' are variables that +you can assign to any key sequences. You can use these keys or the +mouse wheel to dynamically adjust any parameter. The keys can be held +down for continual adjustment. + +Example parameters include background color and font size, but a +parameter can be anything that is adjustable in any of these ways: + * A numerical parameter that can be incremented or decremented, such + as frame height. + * A parameter that can take on one of several values (an enumerated + choice), such as a frame background color. + * A parameter that has an associated function to change its value + incrementally. + +SETTER-FN is a function that adjusts the parameter. Two forms: + 1) It takes a value as argument and sets the parameter to this value. + 2) It is a \"growth\" function, which takes an increment as argument + and incrementally adjusts the value of the parameter. + + Note that \"growth\" function really means, here, that the function + takes an increment as argument and does the incrementation (or + whatever) itself. It is contrasted with an absolute SETTER-FN that + just uses a value that is incremented by `doremi'. The difference is + which function does the incrementing, SETTER-FN or `doremi'. + + In case #1, the new parameter value _must_ be returned by SETTER-FN. + In case #2, the new parameter value should be returned by SETTER-FN, + so that it can be echoed to the user. + +INIT-VAL is the initial value for adjustment. In the case of an + incremental growth function (case #2), this is ignored. + +INCR is an adjustment increment. + For an absolute SETTER-FN (#1), this is applied to INIT-VAL before + calling the function. If ENUM is non-nil, then INCR is ignored. + For an incremental growth function, this is passed to the function. + +INCR can be a number or a list of numbers. When it is a list of +numbers, each is incremented or decremented (and possibly boosted by +`doremi-boost-scale-factor' - see below). + +If GROWTH-FN is non-nil, then SETTER-FN is an incremental growth + function (case #2), and it is called with INCR as its only argument. +If GROWTH-FN is a function, then it is used as an alternative growth + function. In this case, SETTER-FN is called for `doremi-up-keys' + and GROWTH-FN is called for `doremi-down-keys' (mouse wheel is + similar). + +ENUM is a choice-enumeration sequence (list, array, string...). + If ENUM is non-nil, then it is converted to a ring (circular + structure), and `doremi-up-keys' and `doremi-down-keys' set the + parameter to `ring-next' and `ring-previous' values, respectively. + +If ENUM is non-nil, then ALLOW-NEW-P defines what happens if INIT-VAL +is not a member of ENUM. If ALLOW-NEW-P is nil, then an error is +raised. If non-nil, then INIT-VAL is added (to the ring created from +ENUM). If the symbol `extend', then if the ring is full it is +extended to include INIT-VAL; other non-nil values cause the oldest +item in a full ring to be dropped. + +For numerical parameters (not enumerated choices), there are actually +two levels of incrementation. For faster incrementation, you can use +`doremi-boost-up-keys' and `doremi-boost-down-keys', or you can use +any keyboard modifier(s) (Shift, Meta, Control...) with the mouse +wheel. Incrementation is then `doremi-boost-scale-factor' times +faster. + +For examples of using `doremi', see the source code of libraries +`doremi.el', `doremi-frm.el', and `doremi-cmd.el'." + (setq incr (or incr 1)) + (let ((new-incr incr)) + ;; $$$$ (redisplay-dont-pause t)) ; To give continual feedback. + ;; Convert sequence of values (list, array, vector, string) to a ring. + (when (and enum (sequencep enum)) (setq enum (ring-convert-sequence-to-ring enum))) + + ;; Loop. Prompt, read event, and act on arrow-key or mouse-wheel event. + (let ((prompt (format "Use %s, %s, or mouse wheel to adjust value" + (single-key-description (car doremi-up-keys)) + (single-key-description (car doremi-down-keys)))) + (keys (append doremi-up-keys doremi-down-keys + doremi-boost-up-keys doremi-boost-down-keys)) + (echo-keystrokes 0) ; Suppress keystroke echoing. + (wheel-down (if (boundp 'mouse-wheel-up-event) + mouse-wheel-up-event + 'wheel-down)) ; Emacs 20. + (wheel-up (if (boundp 'mouse-wheel-down-event) + mouse-wheel-down-event + 'wheel-up)) ; Emacs 20. + evnt save-prompt) + (unless enum (setq prompt (concat prompt " (modifier key: faster)"))) + (setq prompt (format (concat prompt ". Value now: %s") init-val) + save-prompt prompt) + (while (progn (setq evnt (read-event prompt) + prompt nil) + (or (member evnt keys) + (and (consp evnt) + (member (event-basic-type (car evnt)) + `(switch-frame mouse-wheel mouse-2 + ,wheel-up ,wheel-down))))) + ;; Set up the proper increment value. + (cond ((member evnt doremi-up-keys) (setq new-incr incr)) ; + + ((member evnt doremi-down-keys) ; - + (setq new-incr (if (atom incr) (- incr) (mapcar #'- incr)))) + ((member evnt doremi-boost-up-keys) ; ++ + (setq new-incr + (if (atom incr) + (* doremi-boost-scale-factor incr) + (mapcar #'(lambda (in) (* doremi-boost-scale-factor in)) incr)))) + ((member evnt doremi-boost-down-keys) ; -- + (setq new-incr + (if (atom incr) + (* doremi-boost-scale-factor (- incr)) + (mapcar #'(lambda (in) (* doremi-boost-scale-factor (- in))) incr)))) + + ;; Emacs 20 mouse wheel. + ((and (consp evnt) (equal 'mouse-wheel (event-basic-type (car evnt)))) + (setq new-incr (if (< 0 (nth 2 evnt)) + incr + (if (atom incr) (- incr) (mapcar #'- incr)))) + (when (event-modifiers evnt) ; Boost it + (setq new-incr + (if (atom new-incr) + (* doremi-boost-scale-factor new-incr) + (mapcar #'(lambda (in) (* doremi-boost-scale-factor in)) new-incr))))) + + ;; Emacs 21+ mouse wheel: `mwheel.el' + ;; Free vars here: `mouse-wheel-down-event', `mouse-wheel-up-event'. + ;; Those vars and function `mwheel-event-button' are defined in `mwheel.el'. + ((and (consp evnt) (member (event-basic-type (car evnt)) + `(,wheel-up ,wheel-down))) + (let ((button (mwheel-event-button evnt))) + (cond ((eq button mouse-wheel-down-event) (setq new-incr incr)) + ((eq button mouse-wheel-up-event) + (setq new-incr (if (atom incr) (- incr) (mapcar #'- incr)))) + (t (error "`doremi', bad mwheel-scroll binding - report bug to %s%s%s%s" + "drew.adams" "@" "oracle" ".com")))) + (when (if (> emacs-major-version 22) ; Boost it + (doremi-intersection (event-modifiers evnt) + '(shift control meta alt hyper super)) + (event-modifiers evnt)) + (setq new-incr + (if (atom new-incr) + (* doremi-boost-scale-factor new-incr) + (mapcar #'(lambda (in) (* doremi-boost-scale-factor in)) new-incr))))) + (t (error "`doremi', unexpected event: `%S' - report bug to %s%s%s%s" + evnt "drew.adams" "@" "oracle" ".com"))) + (if (and (consp evnt) (memq (event-basic-type (car evnt)) '(mouse-2 switch-frame))) + (message save-prompt) ; Just skip mouse-2 event (ignore while using wheel). + + ;; Adjust setting and update INIT-VAL. Four cases are treated separately: + ;; 1) ENUM non-nil: use `ring-next' and `ring-previous'. + ;; 2) SETTER-FN and GROWTH-FN are both "growth" functions: call one of them. + ;; 3) SETTER-FN is a "growth" function: call it on the INCR arg. + ;; 4) otherwise (absolute fn): increment INIT-VAL, then call SETTER-FN on it. + (condition-case failure + (setq init-val + (cond (;; 1) Ring of values (enumeration list). Use `ring-next''... + (ring-p enum) + ;; If INIT-VAL is not already in the ring, add it. + ;; Extend the ring size if ALLOW-NEW-P is `extend'. + (when (and allow-new-p (not (ring-member enum init-val))) + (ring-insert+extend enum init-val + (eq 'extend allow-new-p))) + (when (< (ring-length enum) 2) + (error "`doremi' - Need at least two alternatives: %s" enum)) + (let* ((vec (cdr (cdr enum))) + (veclen (length vec))) + (if (and (numberp new-incr) (>= new-incr 0)) + (doremi-set-new-value setter-fn (ring-next enum init-val)) + (doremi-set-new-value setter-fn (ring-previous enum init-val))))) + + ;; 2) Two incremental growth functions. Call one on (new) INCR only. + ((functionp growth-fn) + (if (atom new-incr) + (if (and (numberp new-incr) (>= new-incr 0)) + (doremi-set-new-value setter-fn new-incr) + (doremi-set-new-value growth-fn (- new-incr))) + (if (and (numberp (car new-incr)) (>= (car new-incr) 0)) + (doremi-set-new-value setter-fn new-incr) + (doremi-set-new-value growth-fn (mapcar #'- new-incr))))) + + ;; 3) Single incremental growth function. Call it on (new) INCR only. + (growth-fn (doremi-set-new-value setter-fn new-incr)) + + ;; 4) Otherwise. Increment value. Call setter function on new value. + ((and (numberp new-incr) (numberp init-val)) + (doremi-set-new-value setter-fn (+ init-val new-incr))) + (t (error "`doremi' - Bad argument. INIT-VAL: %s, INCR: %s" + init-val new-incr)))) + (error (error "%s" (error-message-string failure)))))) + (message nil) + (setq unread-command-events (cons evnt unread-command-events))))) + +(defun doremi-intersection (list1 list2) + "Set intersection of lists LIST1 and LIST2. +This is a non-destructive operation: it copies the data if necessary." + (and list1 list2 (if (equal list1 list2) + list1 + (let ((result ())) + (unless (>= (length list1) (length list2)) + (setq list1 (prog1 list2 (setq list2 list1)))) ; Swap them. + (while list2 + (when (member (car list2) list1) + (setq result (cons (car list2) result))) + (setq list2 (cdr list2))) + result)))) + +(defun doremi-set-new-value (setter-fn newval) + "Apply SETTER-FN to NEWVAL, and return NEWVAL. Display progress message." + (prog1 (setq newval (funcall setter-fn newval)) + (message "Use %s, %s, or mouse wheel again. New value: %s" + (single-key-description (car doremi-up-keys)) + (single-key-description (car doremi-down-keys)) + newval))) + +(defun doremi-limit (value min max) + "Limit VALUE to MIN or MAX limit if either is overshot. +MIN or MAX = nil means no such limit. +Return the new, possibly limited value." + (cond ((and max (> value max)) max) + ((and min (< value min)) min) + (t value))) + +;; $$$$$ +;; (defun doremi-wrap (value min max) +;; "Wrap VALUE around if it overshoots MIN or MAX." +;; (cond ((> value max) min) +;; ((< value min) max) +;; (t value))) + +(defun doremi-wrap (value min max) + "Wrap VALUE around if it overshoots MIN or MAX. +Return the new, wrapped value. +MAX must be greater than min." + (let ((new value) + (del (- max min))) + (while (> new max) (setq new (- new del))) + (while (< new min) (setq new (+ new del))) + new)) + + +;;; Example Commands. Uncomment these and try them to get the idea. +;; +;; See also the commands in `doremi-cmd.el' and `doremi-frm.el' for +;; more examples. + + +;; Uses an enumeration list, (buffer-list). +;; (defun doremi-buffers+ () +;; "Successively cycle among existing buffers." +;; (interactive) +;; (doremi (lambda (newval) (switch-to-buffer newval 'norecord) newval) +;; (current-buffer) +;; nil ; ignored +;; nil ; ignored +;; (buffer-list))) + +;; Test command that uses an enumeration list. +;; This command changes nothing. It just echoes successive values. +;; (defun test-list+ () +;; (interactive) +;; (doremi (lambda (newval) newval) 'c 1 nil '(a b c d e f g))) + +;; Test command that uses an enumeration list. +;; In this test, the init-val is not a member of the enumeration list. +;; An error is raised. +;; This command changes nothing. It just echoes successive values. +;; (defun test-list-prohibit-nonmember+ () +;; (interactive) +;; (doremi (lambda (newval) newval) 'c 1 nil '(a b))) + +;; Test command that uses an enumeration list. +;; In this test, the init-val is not a member of the enumeration list. +;; Because of non-nil 6th arg ALLOW-NEW-P, the initial value 'c is added +;; to the enumeration. +;; This command changes nothing. It just echoes successive values. +;; (defun test-list-allow-nonmember+ () +;; (interactive) +;; (doremi (lambda (newval) newval) 'c 1 nil '(a b) t)) + +;; Test command that uses an enumeration list. +;; In this test, the init-val is not a member of the enumeration list. +;; Because 6th arg ALLOW-NEW-P is 'extend, the enumeration is enlarged +;; to include the initial value 'c. +;; This command changes nothing. It just echoes successive values. +;; (defun test-list-allow-nonmember+extend+ () +;; (interactive) +;; (doremi (lambda (newval) newval) 'c 1 nil '(a b) 'extend)) + +;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'doremi) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; doremi.el ends here diff --git a/auto-install/hexrgb.el b/auto-install/hexrgb.el new file mode 100644 index 0000000..ca05428 --- /dev/null +++ b/auto-install/hexrgb.el @@ -0,0 +1,729 @@ +;;; hexrgb.el --- Functions to manipulate colors, including RGB hex strings. +;; +;; Filename: hexrgb.el +;; Description: Functions to manipulate colors, including RGB hex strings. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2004-2011, Drew Adams, all rights reserved. +;; Created: Mon Sep 20 22:58:45 2004 +;; Version: 21.0 +;; Last-Updated: Wed Feb 16 16:49:51 2011 (-0800) +;; By: dradams +;; Update #: 782 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/hexrgb.el +;; Keywords: number, hex, rgb, color, background, frames, display +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Functions to manipulate colors, including RGB hex strings. +;; +;; This library provides functions for converting between RGB (red, +;; green, blue) color components and HSV (hue, saturation, value) +;; color components. It helps you convert among Emacs color +;; components (whole numbers from 0 through 65535), RGB and HSV +;; floating-point components (0.0 through 1.0), Emacs color-name +;; strings (such as "blue"), and hex RGB color strings (such as +;; "#FC43A7912"). +;; +;; An RGB hex string, such as used as a frame `background-color' +;; property, is a string of 1 + (3 * n) characters, the first of +;; which is "#". The other characters are hexadecimal digits, in +;; three groups representing (from the left): red, green, and blue +;; hex codes. +;; +;; Constants defined here: +;; +;; `hexrgb-defined-colors', `hexrgb-defined-colors-alist', +;; `hexrgb-defined-colors-no-dups', +;; `hexrgb-defined-colors-no-dups-alist'. +;; +;; Options defined here: +;; +;; `hexrgb-canonicalize-defined-colors-flag'. +;; +;; Commands defined here: +;; +;; `hexrgb-blue', `hexrgb-complement', `hexrgb-green', +;; `hexrgb-hue', `hexrgb-read-color', `hexrgb-red', +;; `hexrgb-saturation', `hexrgb-value'. +;; +;; Non-interactive functions defined here: +;; +;; `hexrgb-approx-equal', `hexrgb-canonicalize-defined-colors', +;; `hexrgb-color-name-to-hex', `hexrgb-color-values-to-hex', +;; `hexrgb-color-value-to-float', `hexrgb-defined-colors', +;; `hexrgb-defined-colors-alist', +;; `hexrgb-delete-whitespace-from-string', +;; `hexrgb-float-to-color-value', `hexrgb-hex-char-to-integer', +;; `hexrgb-hex-to-color-values', `hexrgb-hex-to-hsv', +;; `hexrgb-hex-to-rgb', `hexrgb-hsv-to-hex', `hexrgb-hex-to-int', +;; `hexrgb-hsv-to-rgb', `hexrgb-increment-blue', +;; `hexrgb-increment-equal-rgb', `hexrgb-increment-green', +;; `hexrgb-increment-hex', `hexrgb-increment-red', +;; `hexrgb-int-to-hex', `hexrgb-rgb-hex-string-p', +;; `hexrgb-rgb-to-hex', `hexrgb-rgb-to-hsv'. +;; +;; +;; Add this to your initialization file (~/.emacs or ~/_emacs): +;; +;; (require 'hexrgb) +;; +;; Do not try to use this library without a window manager. +;; That is, do not use this with `emacs -nw'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2011/02/16 dadams +;; hexrgb-increment-hex: INCOMPATIBLE CHANGE: +;; Swapped order of args NB-DIGITS, INCREMENT, to fit other functions. +;; hexrgb-increment-*: Took the change to hexrgb-increment-hex into account. +;; Improved various doc strings. +;; 2011/01/08 dadams +;; Restored autoload cookie for eval-and-compile hexrgb-canonicalize-defined-colors. +;; 2011/01/03 dadams +;; Removed autoload cookies from non-interactive functions. +;; 2010/12/18 dadams +;; hexrgb-canonicalize-defined-colors: Added autoload cookie. Thx to Richard Kim. +;; 2010/12/06 dadams +;; hexrgb-hex-to-color-values: Correct start offset for blue. Thx to "Linda" on Emacs Wiki. +;; 2009/11/14 dadams +;; hexrgb-rgb-to-hsv: Corrected hue when > 1.0. Use strict inequality for hue limit tests. +;; hexrgb-approx-equal: Convert RFUZZ and AFUZZ to their absolute values. +;; 2009/11/03 dadams +;; Added: hexrgb-delete-whitespace-from-string, hexrgb-canonicalize-defined-colors, +;; hexrgb-defined-colors(-no-dups)(-alist), hexrgb-canonicalize-defined-colors-flag. +;; hexrgb-read-color: Use function hexrgb-defined-colors-alist, not the constant. +;; 2008/12/25 dadams +;; hexrgb-rgb-to-hsv: +;; Replace (not (equal 0.0e+NaN saturation)) by standard test (= saturation saturation). +;; Thx to Michael Heerdegen for the bug report. +;; 2008-10-17 dadams +;; hexrgb-defined-colors(-alist): Prevent load-time error if user tries to use emacs -nw. +;; 2007/12/30 dadams +;; Added: hexrgb-hex-to-color-values. +;; 2007/10/20 dadams +;; hexrgb-read-color: Treat pseudo colors too (e.g. *point foreground*). +;; 2007/01/21 dadams +;; hexrgb-read-color: Error if empty string (and not allow-empty-name-p). +;; 2006/06/06 dadams +;; Added: hexrgb-defined-colors(-alist). Use instead of (x-defined-colors). +;; hexrgb-(red|green|blue): Added interactive specs. +;; 2006/06/04 dadams +;; hexrgb-read-color: Added optional arg allow-empty-name-p. +;; 2006/06/02 dadams +;; Added: hexrgb-rgb-hex-string-p. Used it. +;; 2006/05/30 dadams +;; Added: hexrgb-hex-to-(hsv|rgb), hexrgb-hsv-to-hex, hexrgb-color-name-to-hex, +;; hexrgb-complement, hexrgb-read-color, hexrgb-hue, hexrgb-saturation, +;; hexrgb-value, hexrgb-red, hexrgb-blue, hexrgb-green. +;; approx-equal: Add optional fuzz factor arguments. Changed the algorithm. +;; Renamed: approx-equal to hexrgb-approx-equal. +;; hexrgb-rgb-to-hsv: Changed test from < to <=: (when (<= hue 0.0)...). +;; hexrgb-hsv-to-rgb: Treat hue = 0.0 (int 0) the same as hue = 1.0 (int 6). +;; hexrgb-rgb-to-hex, hexrgb-increment-hex: Corrected doc strings. +;; 2006/05/22 dadams +;; Added: hexrgb-hsv-to-hex, hexrgb-rgb-to-hex. Require cl.el when byte-compile. +;; 2005/08/09 dadams +;; hexrgb-rgb-to-hsv: Side-stepped Emacs-20 bug in comparing NaN. +;; hexrgb-increment-*: Added optional arg wrap-p. +;; hexrgb-increment-hex: Prevent wrap if not wrap-p. +;; 2005/08/02 dadams +;; hexrgb-rgb-to-hes: Bug fix: If delta is zero, then so are hue and saturation. +;; 2005/06/24 dadams +;; hexrgb-rgb-to-hsv: Bug fix: test for NaN (e.g. on divide by zero). +;; 2005/02/08 dadams +;; hexrgb-hsv-to-rgb: Bug fix (typo: p, q -> pp, qq; added ww). +;; 2005/01/09 dadams +;; hexrgb-int-to-hex: Fixed bug in hexrgb-int-to-hex: nb-digits not respected. +;; Added: hexrgb-hsv-to-rgb, hexrgb-rgb-to-hsv, approx-equal. +;; Renamed old hexrgb-increment-value to hexrgb-increment-equal-rgb. +;; 2005/01/05 dadams +;; hexrgb-int-to-hex: Used a suggestion from Juri Linkov. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'cl)) ;; case + +;; Unless you first load `hexrgb.el', then either `palette.el' or `eyedropper.el', you will get +;; warnings about variables and functions with prefix `eyedrop-' when you byte-compile +;; `hexrgb.el'. You can ignore these warnings. + +(defvar eyedrop-picked-foreground) +(defvar eyedrop-picked-background) + +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(eval-and-compile + (defun hexrgb-canonicalize-defined-colors (list) + "Copy of LIST with color names canonicalized. +LIST is a list of color names (strings). +Canonical names are lowercase, with no whitespace. +There are no duplicate names." + (let ((tail list) + this new) + (while tail + (setq this (car tail) + this (hexrgb-delete-whitespace-from-string (downcase this) 0 (length this))) + (unless (member this new) (push this new)) + (pop tail)) + (nreverse new))) + + (defun hexrgb-delete-whitespace-from-string (string &optional from to) + "Remove whitespace from substring of STRING from FROM to TO. +If FROM is nil, then start at the beginning of STRING (FROM = 0). +If TO is nil, then end at the end of STRING (TO = length of STRING). +FROM and TO are zero-based indexes into STRING. +Character FROM is affected (possibly deleted). Character TO is not." + (setq from (or from 0) + to (or to (length string))) + (with-temp-buffer + (insert string) + (goto-char (+ from (point-min))) + (let ((count from) + char) + (while (and (not (eobp)) (< count to)) + (setq char (char-after)) + (if (memq char '(?\ ?\t ?\n)) (delete-char 1) (forward-char 1)) + (setq count (1+ count))) + (buffer-string))))) + +;;;###autoload +(defconst hexrgb-defined-colors (eval-when-compile (and window-system (x-defined-colors))) + "List of all supported colors.") + +;;;###autoload +(defconst hexrgb-defined-colors-no-dups + (eval-when-compile + (and window-system (hexrgb-canonicalize-defined-colors (x-defined-colors)))) + "List of all supported color names, with no duplicates. +Names are all lowercase, without any spaces.") + +;;;###autoload +(defconst hexrgb-defined-colors-alist + (eval-when-compile (and window-system (mapcar #'list (x-defined-colors)))) + "Alist of all supported color names, for use in completion. +See also `hexrgb-defined-colors-no-dups-alist', which is the same +thing, but without any duplicates, such as \"light blue\" and +\"LightBlue\".") + +;;;###autoload +(defconst hexrgb-defined-colors-no-dups-alist + (eval-when-compile + (and window-system + (mapcar #'list (hexrgb-canonicalize-defined-colors (x-defined-colors))))) + "Alist of all supported color names, with no duplicates, for completion. +Names are all lowercase, without any spaces.") + +;;;###autoload +(defcustom hexrgb-canonicalize-defined-colors-flag t + "*Non-nil means remove duplicate color names. +Names are considered duplicates if they are the same when abstracting +from whitespace and letter case." + :type 'boolean + :group 'Icicles :group 'doremi-frame-commands :group 'faces :group 'convenience) + +;; You should use these two functions, not the constants, so users can change +;; the behavior by customizing `hexrgb-canonicalize-defined-colors-flag'. + +(defun hexrgb-defined-colors () + "List of supported color names. +If `hexrgb-canonicalize-defined-colors-flag' is non-nil, then names +are lowercased, whitespace is removed, and there are no duplicates." + (if hexrgb-canonicalize-defined-colors-flag + hexrgb-defined-colors-no-dups + hexrgb-defined-colors)) + +(defun hexrgb-defined-colors-alist () + "Alist of supported color names. Usable for completion. +If `hexrgb-canonicalize-defined-colors-flag' is non-nil, then names +are lowercased, whitespace is removed, and there are no duplicates." + (if hexrgb-canonicalize-defined-colors-flag + hexrgb-defined-colors-no-dups-alist + hexrgb-defined-colors-alist)) + +;; RMS added this function to Emacs (23) as `read-color', with some feature loss. +;;;###autoload +(defun hexrgb-read-color (&optional convert-to-RGB-p allow-empty-name-p prompt) + "Read a color name or RGB hex value: #RRRRGGGGBBBB. +Completion is available for color names, but not for RGB hex strings. +If you input an RGB hex string, it must have the form #XXXXXXXXXXXX or +XXXXXXXXXXXX, where each X is a hex digit. The number of Xs must be a +multiple of 3, with the same number of Xs for each of red, green, and +blue. The order is red, green, blue. + +Color names that are normally considered equivalent are canonicalized: +They are lowercased, whitespace is removed, and duplicates are +eliminated. E.g. \"LightBlue\" and \"light blue\" are both replaced +by \"lightblue\". If you do not want this behavior, but want to +choose names that might contain whitespace or uppercase letters, then +customize option `hexrgb-canonicalize-defined-colors-flag' to nil. + +In addition to standard color names and RGB hex values, the following +are available as color candidates. In each case, the corresponding +color is used. + +* `*copied foreground*' - last copied foreground, if available +* `*copied background*' - last copied background, if available +* `*mouse-2 foreground*' - foreground where you click `mouse-2' +* `*mouse-2 background*' - background where you click `mouse-2' +* `*point foreground*' - foreground under the cursor +* `*point background*' - background under the cursor + +\(You can copy a color using eyedropper commands such as +`eyedrop-pick-foreground-at-mouse'.) + +Checks input to be sure it represents a valid color. If not, raises +an error (but see exception for empty input with non-nil +ALLOW-EMPTY-NAME-P). + +Interactively, or with optional arg CONVERT-TO-RGB-P non-nil, converts +an input color name to an RGB hex string. Returns the RGB hex string. + +Optional arg ALLOW-EMPTY-NAME-P controls what happens if you enter an +empty color name (that is, you just hit `RET'). If non-nil, then +`hexrgb-read-color' returns an empty color name, \"\". If nil, then +it raises an error. Programs must test for \"\" if ALLOW-EMPTY-NAME-P +is non-nil. They can then perform an appropriate action in case of +empty input. + +Optional arg PROMPT is the prompt. Nil means use a default prompt." + (interactive "p") ; Always convert to RGB interactively. + (let* ((completion-ignore-case t) + ;; Free variables here: `eyedrop-picked-foreground', `eyedrop-picked-background'. + ;; They are defined in library `palette.el' or library `eyedropper.el'. + (colors (if (fboundp 'eyedrop-foreground-at-point) + (append (and eyedrop-picked-foreground + '(("*copied foreground*"))) + (and eyedrop-picked-background + '(("*copied background*"))) + '(("*mouse-2 foreground*") + ("*mouse-2 background*") + ("*point foreground*") ("*point background*")) + (hexrgb-defined-colors-alist)) + (hexrgb-defined-colors-alist))) + (color (completing-read (or prompt "Color (name or #R+G+B+): ") + colors)) + hex-string) + (when (fboundp 'eyedrop-foreground-at-point) + (cond ((string= "*copied foreground*" color) (setq color eyedrop-picked-foreground)) + ((string= "*copied background*" color) (setq color eyedrop-picked-background)) + ((string= "*point foreground*" color) (setq color (eyedrop-foreground-at-point))) + ((string= "*point background*" color) (setq color (eyedrop-background-at-point))) + ((string= "*mouse-2 foreground*" color) + (setq color (prog1 (eyedrop-foreground-at-mouse + (read-event "Click `mouse-2' to choose foreground color - ")) + (read-event)))) ; Discard mouse up event. + ((string= "*mouse-2 background*" color) + (setq color (prog1 (eyedrop-background-at-mouse + (read-event "Click `mouse-2' to choose background color - ")) + (read-event)))))) ; Discard mouse up event. + (setq hex-string (or (string-match "^#\\([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+$" color) + (and (string-match "^\\([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+$" color) + t))) + (if (and allow-empty-name-p (string= "" color)) + "" + (when (and hex-string (not (eq 0 hex-string))) + (setq color (concat "#" color))) ; No #; add it. + (unless hex-string + (when (or (string= "" color) + (not (if (fboundp 'test-completion) ; Not defined in Emacs 20. + (test-completion color colors) + (try-completion color colors)))) + (error "No such color: %S" color)) + (when convert-to-RGB-p (setq color (hexrgb-color-name-to-hex color)))) + (when (interactive-p) (message "Color: `%s'" color)) + color))) + +(defun hexrgb-rgb-hex-string-p (color &optional laxp) + "Non-nil if COLOR is an RGB string #XXXXXXXXXXXX. +Each X is a hex digit. The number of Xs must be a multiple of 3, with +the same number of Xs for each of red, green, and blue. + +Non-nil optional arg LAXP means that the initial `#' is optional. In +that case, for a valid string of hex digits: when # is present 0 is +returned; otherwise, t is returned." + (or (string-match "^#\\([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+$" color) + (and laxp (string-match "^\\([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+$" color) t))) + +;;;###autoload +(defun hexrgb-complement (color) + "Return the color that is the complement of COLOR." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (let ((red (hexrgb-red color)) + (green (hexrgb-green color)) + (blue (hexrgb-blue color))) + (setq color (hexrgb-rgb-to-hex (- 1.0 red) (- 1.0 green) (- 1.0 blue)))) + (when (interactive-p) (message "Complement: `%s'" color)) + color) + +;;;###autoload +(defun hexrgb-hue (color) + "Return the hue component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (car (hexrgb-rgb-to-hsv (hexrgb-red color) (hexrgb-green color) (hexrgb-blue color)))) + +;;;###autoload +(defun hexrgb-saturation (color) + "Return the saturation component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (cadr (hexrgb-rgb-to-hsv (hexrgb-red color) (hexrgb-green color) (hexrgb-blue color)))) + +;;;###autoload +(defun hexrgb-value (color) + "Return the value component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (caddr (hexrgb-rgb-to-hsv (hexrgb-red color) (hexrgb-green color) (hexrgb-blue color)))) + +;;;###autoload +(defun hexrgb-red (color) + "Return the red component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (/ (hexrgb-hex-to-int (substring color 1 (1+ (/ (1- (length color)) 3)))) + (expt 16.0 (/ (1- (length color)) 3.0)))) + +;;;###autoload +(defun hexrgb-green (color) + "Return the green component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (let* ((len (/ (1- (length color)) 3)) + (start (1+ len))) + (/ (hexrgb-hex-to-int (substring color start (+ start len))) + (expt 16.0 (/ (1- (length color)) 3.0))))) + +;;;###autoload +(defun hexrgb-blue (color) + "Return the blue component of COLOR, in range 0 to 1 inclusive. +COLOR is a color name or hex RGB string that starts with \"#\"." + (interactive (list (hexrgb-read-color))) + (setq color (hexrgb-color-name-to-hex color)) + (let* ((len (/ (1- (length color)) 3)) + (start (+ 1 len len))) + (/ (hexrgb-hex-to-int (substring color start (+ start len))) + (expt 16.0 (/ (1- (length color)) 3.0))))) + +(defun hexrgb-rgb-to-hsv (red green blue) + "Convert RED, GREEN, BLUE components to HSV (hue, saturation, value). +Each input component is 0.0 to 1.0, inclusive. +Returns a list of HSV components of value 0.0 to 1.0, inclusive." + (let* ((min (min red green blue)) + (max (max red green blue)) + (value max) + (delta (- max min)) + hue saturation) + (if (hexrgb-approx-equal 0.0 delta) + (setq hue 0.0 + saturation 0.0) ; Gray scale - no color; only value. + (if (and (condition-case nil + (setq saturation (/ delta max)) + (arith-error nil)) + ;; Must be a number, not a NaN. The standard test for a NaN is (not (= N N)), + ;; but an Emacs 20 bug makes (= N N) return t for a NaN also. + (or (< emacs-major-version 21) (= saturation saturation))) + (if (hexrgb-approx-equal 0.0 saturation) + (setq hue 0.0 + saturation 0.0) ; Again, no color; only value. + ;; Color + (setq hue (if (hexrgb-approx-equal red max) + (/ (- green blue) delta) ; Between yellow & magenta. + (if (hexrgb-approx-equal green max) + (+ 2.0 (/ (- blue red) delta)) ; Between cyan & yellow. + (+ 4.0 (/ (- red green) delta)))) ; Between magenta & cyan. + hue (/ hue 6.0)) + ;; (when (<= hue 0.0) (setq hue (+ hue 1.0))) ; $$$$$$ + ;; (when (>= hue 1.0) (setq hue (- hue 1.0)))) ; $$$$$$ + (when (< hue 0.0) (setq hue (+ hue 1.0))) + (when (> hue 1.0) (setq hue (- hue 1.0)))) + (setq hue 0.0 ; Div by zero (max=0): H:=0, S:=0. (Hue undefined.) + saturation 0.0))) + (list hue saturation value))) + +(defun hexrgb-hsv-to-rgb (hue saturation value) + "Convert HUE, SATURATION, VALUE components to RGB (red, green, blue). +Each input component is 0.0 to 1.0, inclusive. +Returns a list of RGB components of value 0.0 to 1.0, inclusive." + (let (red green blue int-hue fract pp qq tt ww) + (if (hexrgb-approx-equal 0.0 saturation) + (setq red value + green value + blue value) ; Gray + (setq hue (* hue 6.0) ; Sectors: 0 to 5 + int-hue (floor hue) + fract (- hue int-hue) + pp (* value (- 1 saturation)) + qq (* value (- 1 (* saturation fract))) + ww (* value (- 1 (* saturation (- 1 (- hue int-hue)))))) + (case int-hue + ((0 6) (setq red value + green ww + blue pp)) + (1 (setq red qq + green value + blue pp)) + (2 (setq red pp + green value + blue ww)) + (3 (setq red pp + green qq + blue value)) + (4 (setq red ww + green pp + blue value)) + (otherwise (setq red value + green pp + blue qq)))) + (list red green blue))) + +(defun hexrgb-hsv-to-hex (hue saturation value) + "Return the hex RBG color string for inputs HUE, SATURATION, VALUE. +The inputs are each in the range 0 to 1. +The output string is of the form \"#RRRRGGGGBBBB\"." + (hexrgb-color-values-to-hex + (mapcar (lambda (x) (floor (* x 65535.0))) (hexrgb-hsv-to-rgb hue saturation value)))) + +(defun hexrgb-rgb-to-hex (red green blue) + "Return the hex RBG color string for inputs RED, GREEN, BLUE. +The inputs are each in the range 0 to 1. +The output string is of the form \"#RRRRGGGGBBBB\"." + (hexrgb-color-values-to-hex + (mapcar (lambda (x) (floor (* x 65535.0))) (list red green blue)))) + +(defun hexrgb-hex-to-hsv (color) + "Return a list of HSV (hue, saturation, value) color components. +Each component is a value from 0.0 to 1.0, inclusive. +COLOR is a color name or a hex RGB string that starts with \"#\" and +is followed by an equal number of hex digits for red, green, and blue +components." + (let ((rgb-components (hexrgb-hex-to-rgb color))) + (apply #'hexrgb-rgb-to-hsv rgb-components))) + +(defun hexrgb-hex-to-rgb (color) + "Return a list of RGB (red, green, blue) color components. +Each component is a value from 0.0 to 1.0, inclusive. +COLOR is a color name or a hex RGB string that starts with \"#\" and +is followed by an equal number of hex digits for red, green, and blue +components." + (unless (hexrgb-rgb-hex-string-p color) (setq color (hexrgb-color-name-to-hex color))) + (let ((len (/ (1- (length color)) 3))) + (list (/ (hexrgb-hex-to-int (substring color 1 (1+ len))) 65535.0) + (/ (hexrgb-hex-to-int (substring color (1+ len) (+ 1 len len))) 65535.0) + (/ (hexrgb-hex-to-int (substring color (+ 1 len len))) 65535.0)))) + +(defun hexrgb-color-name-to-hex (color) + "Return the RGB hex string for the COLOR name, starting with \"#\". +If COLOR is already a string starting with \"#\", then just return it." + (let ((components (x-color-values color))) + (unless components (error "No such color: %S" color)) + (unless (hexrgb-rgb-hex-string-p color) + (setq color (hexrgb-color-values-to-hex components)))) + color) + +;; Color "components" would be better in the name than color "value" +;; but this name follows the Emacs tradition (e.g. `x-color-values', +;; 'ps-color-values', `ps-e-x-color-values'). +(defun hexrgb-color-values-to-hex (components) + "Convert list of rgb color COMPONENTS to a hex string, #XXXXXXXXXXXX. +Each X in the string is a hexadecimal digit. +Input COMPONENTS is as for the output of `x-color-values'." +;; Just hard-code 4 as the number of hex digits, since `x-color-values' +;; seems to produce appropriate integer values for `4'. + (concat "#" (hexrgb-int-to-hex (nth 0 components) 4) ; red + (hexrgb-int-to-hex (nth 1 components) 4) ; green + (hexrgb-int-to-hex (nth 2 components) 4))) ; blue + +(defun hexrgb-hex-to-color-values (color) + "Convert hex COLOR to a list of RGB color components. +COLOR is a hex rgb color string, #XXXXXXXXXXXX +Each X in the string is a hexadecimal digit. There are 3N X's, N > 0. +The output list is as for `x-color-values'." + (let* ((hex-strgp (string-match + "^\\(#\\)?\\(\\([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+\\)$" + color)) + (ndigits (/ (if (eq (match-beginning 1) (match-end 1)) + (length color) + (1- (length color))) + 3)) + red green blue) + (unless hex-strgp (error "Invalid RGB color string: %s" color)) + (setq color (substring color (match-beginning 2) (match-end 2)) + red (hexrgb-hex-to-int (substring color 0 ndigits)) + green (hexrgb-hex-to-int (substring color ndigits (* 2 ndigits))) + blue (hexrgb-hex-to-int (substring color (* 2 ndigits) (* 3 ndigits)))) + (list red green blue))) + +(defun hexrgb-increment-red (hex nb-digits increment &optional wrap-p) + "Increment red component of rgb string HEX by INCREMENT. +String HEX starts with \"#\". Each color is NB-DIGITS hex digits long. +If optional arg WRAP-P is non-nil then the result wraps around zero. + For example, with NB-DIGITS 3, incrementing \"#fffffffff\" by 1 + causes it to wrap around to \"#000ffffff\"." + (concat "#" + (hexrgb-increment-hex (substring hex 1 (1+ nb-digits)) nb-digits increment wrap-p) + (substring hex (1+ nb-digits) (1+ (* nb-digits 2))) + (substring hex (1+ (* nb-digits 2))))) + +(defun hexrgb-increment-green (hex nb-digits increment &optional wrap-p) + "Increment green component of rgb string HEX by INCREMENT. +String HEX starts with \"#\". Each color is NB-DIGITS hex digits long. +If optional arg WRAP-P is non-nil then the result wraps around zero. + For example, with NB-DIGITS 3, incrementing \"#fffffffff\" by 1 + causes it to wrap around to \"#fff000fff\"." + (concat + "#" (substring hex 1 (1+ nb-digits)) + (hexrgb-increment-hex (substring hex (1+ nb-digits) (1+ (* nb-digits 2))) + nb-digits + increment + wrap-p) + (substring hex (1+ (* nb-digits 2))))) + +(defun hexrgb-increment-blue (hex nb-digits increment &optional wrap-p) + "Increment blue component of rgb string HEX by INCREMENT. +String HEX starts with \"#\". Each color is NB-DIGITS hex digits long. +If optional arg WRAP-P is non-nil then the result wraps around zero. + For example, with NB-DIGITS 3, incrementing \"#fffffffff\" by 1 + causes it to wrap around to \"#ffffff000\"." + (concat "#" (substring hex 1 (1+ (* nb-digits 2))) + (hexrgb-increment-hex (substring hex (1+ (* nb-digits 2))) + nb-digits + increment + wrap-p))) + +(defun hexrgb-increment-equal-rgb (hex nb-digits increment &optional wrap-p) + "Increment each color component (r,g,b) of rgb string HEX by INCREMENT. +String HEX starts with \"#\". Each color is NB-DIGITS hex digits long. +If optional arg WRAP-P is non-nil then the result wraps around zero. + For example, with NB-DIGITS 3, incrementing \"#fffffffff\" by 1 + causes it to wrap around to \"#000000000\"." + (concat + "#" + (hexrgb-increment-hex (substring hex 1 (1+ nb-digits)) nb-digits increment wrap-p) + (hexrgb-increment-hex (substring hex (1+ nb-digits) (1+ (* nb-digits 2))) + nb-digits + increment + wrap-p) + (hexrgb-increment-hex (substring hex (1+ (* nb-digits 2))) nb-digits increment wrap-p))) + +(defun hexrgb-increment-hex (hex nb-digits increment &optional wrap-p) + "Increment hexadecimal-digits string HEX by INCREMENT. +Only the first NB-DIGITS of HEX are used. +If optional arg WRAP-P is non-nil then the result wraps around zero. + For example, with NB-DIGITS 3, incrementing \"fff\" by 1 causes it + to wrap around to \"000\"." + (let* ((int (hexrgb-hex-to-int hex)) + (new-int (+ increment int))) + (if (or wrap-p + (and (>= int 0) ; Not too large for the machine. + (>= new-int 0) ; For the case where increment < 0. + (<= (length (format (concat "%X") new-int)) nb-digits))) ; Not too long. + (hexrgb-int-to-hex new-int nb-digits) ; Use incremented number. + hex))) ; Don't increment. + +(defun hexrgb-hex-to-int (hex) + "Convert HEX string argument to an integer. +The characters of HEX must be hex characters." + (let* ((factor 1) + (len (length hex)) + (indx (1- len)) + (int 0)) + (while (>= indx 0) + (setq int (+ int (* factor (hexrgb-hex-char-to-integer (aref hex indx)))) + indx (1- indx) + factor (* 16 factor))) + int)) + +;; From `hexl.el'. This is the same as `hexl-hex-char-to-integer' defined there. +(defun hexrgb-hex-char-to-integer (character) + "Take a CHARACTER and return its value as if it were a hex digit." + (if (and (>= character ?0) (<= character ?9)) + (- character ?0) + (let ((ch (logior character 32))) + (if (and (>= ch ?a) (<= ch ?f)) + (- ch (- ?a 10)) + (error "Invalid hex digit `%c'" ch))))) + +;; Originally, I used the code from `int-to-hex-string' in `float.el'. +;; This version is thanks to Juri Linkov . +;; +(defun hexrgb-int-to-hex (int &optional nb-digits) + "Convert integer argument INT to a #XXXXXXXXXXXX format hex string. +Each X in the output string is a hexadecimal digit. +NB-DIGITS is the number of hex digits. If INT is too large to be +represented with NB-DIGITS, then the result is truncated from the +left. So, for example, INT=256 and NB-DIGITS=2 returns \"00\", since +the hex equivalent of 256 decimal is 100, which is more than 2 digits." + (setq nb-digits (or nb-digits 4)) + (substring (format (concat "%0" (int-to-string nb-digits) "X") int) (- nb-digits))) + +;; Inspired by Elisp Info manual, node "Comparison of Numbers". +(defun hexrgb-approx-equal (x y &optional rfuzz afuzz) + "Return non-nil if numbers X and Y are approximately equal. +RFUZZ is a relative fuzz factor. AFUZZ is an absolute fuzz factor. +RFUZZ defaults to 1.0e-8. AFUZZ defaults to (/ RFUZZ 10). +RFUZZ and AFUZZ are converted to their absolute values. +The algorithm is: + (< (abs (- X Y)) (+ AFUZZ (* RFUZZ (+ (abs X) (abs Y)))))." + (setq rfuzz (or rfuzz 1.0e-8) + rfuzz (abs rfuzz) + afuzz (or afuzz (/ rfuzz 10)) + afuzz (abs afuzz)) + (< (abs (- x y)) (+ afuzz (* rfuzz (+ (abs x) (abs y)))))) + +(defun hexrgb-color-value-to-float (n) + "Return the floating-point equivalent of color-component value N. +N must be an integer between 0 and 65535, or else an error is raised." + (unless (and (wholenump n) (<= n 65535)) + (error "Not a whole number less than 65536")) + (/ (float n) 65535.0)) + +(defun hexrgb-float-to-color-value (x) + "Return the color-component value equivalent of floating-point number X. +X must be between 0.0 and 1.0, or else an error is raised." + (unless (and (numberp x) (<= 0.0 x) (<= x 1.0)) + (error "Not a floating-point number between 0.0 and 1.0")) + (floor (* x 65535.0))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'hexrgb) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; hexrgb.el ends here diff --git a/auto-install/hl-line+.el b/auto-install/hl-line+.el new file mode 100644 index 0000000..5f025dd --- /dev/null +++ b/auto-install/hl-line+.el @@ -0,0 +1,257 @@ +;;; hl-line+.el --- Extensions to hl-line.el. +;; +;; Filename: hl-line+.el +;; Description: Extensions to hl-line.el. +;; Author: Drew Adams +;; Maintainer: Drew Adams +;; Copyright (C) 2006-2011, Drew Adams, all rights reserved. +;; Created: Sat Aug 26 18:17:18 2006 +;; Version: 22.0 +;; Last-Updated: Thu Feb 24 15:22:18 2011 (-0800) +;; By: dradams +;; Update #: 434 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/hl-line+.el +;; Keywords: highlight, cursor, accessibility +;; Compatibility: GNU Emacs: 22.x, 23.x +;; +;; Features that might be required by this library: +;; +;; `hl-line'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This library extends standard library `hl-line.el' in these ways: +;; +;; 1. As an alternative to turning on `hl-line' highlighting at all +;; times, you can turn it on only when Emacs is idle. To do that, +;; use command `toggle-hl-line-when-idle' and customize +;; `global-hl-line-mode' to nil. +;; +;; 2. As another alternative, you can turn it on for only a few +;; seconds. To do that, use command `flash-line-highlight' and +;; customize `global-hl-line-mode' to nil. +;; +;; 3. It provides a face, `hl-line', that you can customize, instead +;; of using option `hl-line-face'. +;; +;; I suggested #3 to the Emacs developers, and it has been added +;; to Emacs 22, but with a different default value. If you use +;; library `crosshairs.el', you might want to customize this to a +;; value similar to what is used there, so that the horizontal and +;; vertical highlights will be the same. +;; +;; To use this library, put this in your Emacs init file (~/.emacs): +;; +;; (require 'hl-line+) ; Load this file (it will load `hl-line.el') +;; +;; To turn on `global-hl-line-mode' only when Emacs is idle, by +;; default, add this line also to your init file: +;; +;; (toggle-hl-line-when-idle 1) ; Highlight only when idle +;; +;; You can use command `toggle-hl-line-when-idle' to turn idle +;; highlighting on and off at any time. You can use command +;; `hl-line-when-idle-interval' to change the number of idle seconds +;; to wait before highlighting. +;; +;; +;; See also these libraries: +;; +;; * `col-highlight.el', which highlights the current column. +;; +;; * `crosshairs.el', which highlights the current line and the +;; current column, at the same time. It requires libraries +;; `col-highlight.el' and `hl-line+.el'. +;; +;; * `hl-spotlight.el', which extends `hl-line.el' by spotlighting +;; the lines around the cursor. +;; +;; * `cursor-chg.el' or library `oneonone.el', to change the cursor +;; type when Emacs is idle. +;; +;; +;; Faces defined here: +;; +;; `hl-line'. +;; +;; User options defined here: +;; +;; `hl-line-flash-show-period', +;; `hl-line-inhibit-highlighting-for-modes'. +;; +;; Commands defined here: +;; +;; `flash-line-highlight', `hl-line-flash', +;; `hl-line-toggle-when-idle', `hl-line-when-idle-interval', +;; `toggle-hl-line-when-idle'. +;; +;; Non-interactive functions defined here: +;; +;; `hl-line-highlight-now', `hl-line-unhighlight-now'. +;; +;; Internal variables defined here: +;; +;; `hl-line-idle-interval', `hl-line-idle-timer', +;; `hl-line-when-idle-p'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2011/01/04 dadams +;; Added autoload cookies for defcustom, defface and commands. +;; 2010/10/03 dadams +;; hl-line-flash: +;; Set ARG in interactive spec and use it. Thx to Philip Weaver. +;; 2009/12/18 dadams +;; Added: hl-line-inhibit-highlighting-for-modes. +;; hl-line-highlight-now: Respect hl-line-inhibit-for-modes. Thx to Sylecn. +;; 2009/02/16 dadams +;; Removed spotlight stuff - moved to new library hl-spotlight.el. +;; 2009/02/15 dadams +;; Added: hl-spotlight(-height|-old-state|widen|limits|mode), +;; global-hl-spotlight-mode. +;; 2008/01/28 dadams +;; Fix from Yann Yodique: Moved adding/removing hl-line-unhighlight-now as +;; pre-command-hook from hl-line-toggle-when-idle to hl-line-(un)highlight-now. +;; 2008/01/20 dadams +;; Renamed: line-show-period to hl-line-flash-show-period. +;; 2007/10/11 dadams +;; Commentary typo: toggle-cursor-type-when-idle -> toggle-hl-line-when-idle. +;; 2007/01/10 dadams +;; Update commentary to indicate that the face is now provided by default. +;; 2006/09/08 dadams +;; Added: flash-line-highlight, hl-line-flash. +;; Renamed: hl-line-when-idle(-off) to hl-line-(un)highlight-now. +;; 2006/09/04 dadams +;; Added: hl-line-when-idle-p, hl-line-idle-interval, hl-line-idle-timer, +;; hl-line-toggle-when-idle, hl-line-when-idle-interval, +;; hl-line-when-idle(-off). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(require 'hl-line) + +(defvar hl-line-face) ; Quiet the byte-compiler. +(defvar global-hl-line-mode) ; Quiet the byte-compiler. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; This will be ignored, since this is now defined by default in Emacs 22. +;; I include it here as a different face definition that you might want to try. +;;;###autoload +(defface hl-line '((t (:background "SlateGray3"))) ; Try also (:underline "Yellow") + "*Face to use for `hl-line-face'." :group 'hl-line) +(setq hl-line-face 'hl-line) + +;;;###autoload +(defcustom hl-line-flash-show-period 1 + "*Number of seconds for `hl-line-flash' to highlight the line." + :type 'integer :group 'cursor :group 'hl-line) + +;; Possible value: `(Info-mode help-mode view-mode Man-mode)' +;;;###autoload +(defcustom hl-line-inhibit-highlighting-for-modes () + "*Modes where highlighting is inhibited for `hl-line-highlight-now'. +A list of `major-mode' values (symbols)." + :type 'list :group 'hl-line) + +(defvar hl-line-idle-interval 5 + "Number of seconds to wait before turning on `global-hl-line-mode'. +Do NOT change this yourself to change the wait period; instead, use +`\\[hl-line-when-idle-interval]'.") + +(defvar hl-line-idle-timer + (progn ; Cancel to prevent duplication. + (when (boundp 'hl-line-idle-timer) (cancel-timer hl-line-idle-timer)) + (run-with-idle-timer hl-line-idle-interval t 'hl-line-highlight-now)) + "Timer used to turn on `global-hl-line-mode' whenever Emacs is idle.") + +;; Turn it off, by default. You must use `toggle-hl-line-when-idle' to turn it on. +(cancel-timer hl-line-idle-timer) + +(defvar hl-line-when-idle-p nil + "Non-nil means to turn on `global-hl-line-mode' whenever Emacs is idle. +Do NOT change this yourself; instead, use `\\[toggle-hl-line-when-idle]'.") + +;;;###autoload +(defalias 'toggle-hl-line-when-idle 'hl-line-toggle-when-idle) +;;;###autoload +(defun hl-line-toggle-when-idle (&optional arg) + "Turn on or off using `global-hl-line-mode' when Emacs is idle. +When on, use `global-hl-line-mode' whenever Emacs is idle. +With prefix argument, turn on if ARG > 0; else turn off." + (interactive "P") + (setq hl-line-when-idle-p + (if arg (> (prefix-numeric-value arg) 0) (not hl-line-when-idle-p))) + (cond (hl-line-when-idle-p + (timer-activate-when-idle hl-line-idle-timer) + (message "Turned ON using `global-hl-line-mode' when Emacs is idle.")) + (t + (cancel-timer hl-line-idle-timer) + (message "Turned OFF using `global-hl-line-mode' when Emacs is idle.")))) + +;;;###autoload +(defun hl-line-when-idle-interval (secs) + "Set wait until using `global-hl-line-mode' when Emacs is idle. +Whenever Emacs is idle for this many seconds, `global-hl-line-mode' +will be turned on. + +To turn on or off using `global-hl-line-mode' when idle, +use `\\[toggle-hl-line-when-idle]." + (interactive "nSeconds to idle, before using `global-hl-line-mode': ") + (timer-set-idle-time hl-line-idle-timer (setq hl-line-idle-interval secs) t)) + +(defun hl-line-highlight-now () + "Turn on `global-hl-line-mode' and highlight current line now." + (unless (or global-hl-line-mode + (member major-mode hl-line-inhibit-highlighting-for-modes)) + (global-hl-line-mode 1) + (global-hl-line-highlight) + (add-hook 'pre-command-hook 'hl-line-unhighlight-now))) + +(defun hl-line-unhighlight-now () + "Turn off `global-hl-line-mode' and unhighlight current line now." + (global-hl-line-mode -1) + (global-hl-line-unhighlight) + (remove-hook 'pre-command-hook 'hl-line-unhighlight-now)) + +;;;###autoload +(defalias 'flash-line-highlight 'hl-line-flash) +;;;###autoload +(defun hl-line-flash (&optional arg) + "Highlight the current line for `hl-line-flash-show-period' seconds. +With a prefix argument, highlight for that many seconds." + (interactive "P") + (hl-line-highlight-now) + (let ((line-period hl-line-flash-show-period)) + (when arg (setq line-period (prefix-numeric-value arg))) + (run-at-time line-period nil #'hl-line-unhighlight-now))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'hl-line+) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; hl-line+.el ends here diff --git a/auto-install/htmlize.el b/auto-install/htmlize.el new file mode 100644 index 0000000..f15d5fe --- /dev/null +++ b/auto-install/htmlize.el @@ -0,0 +1,1770 @@ +;;; htmlize.el -- Convert buffer text and decorations to HTML. + +;; Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006 Hrvoje Niksic + +;; Author: Hrvoje Niksic +;; Modified by: Carsten Dominik +;; Keywords: hypermedia, extensions + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This package converts the buffer text and the associated +;; decorations to HTML. Mail to to discuss +;; features and additions. All suggestions are more than welcome. + +;; To use this, just switch to the buffer you want HTML-ized and type +;; `M-x htmlize-buffer'. You will be switched to a new buffer that +;; contains the resulting HTML code. You can edit and inspect this +;; buffer, or you can just save it with C-x C-w. `M-x htmlize-file' +;; will find a file, fontify it, and save the HTML version in +;; FILE.html, without any additional intervention. `M-x +;; htmlize-many-files' allows you to htmlize any number of files in +;; the same manner. `M-x htmlize-many-files-dired' does the same for +;; files marked in a dired buffer. + +;; htmlize supports three types of HTML output, selected by setting +;; `htmlize-output-type': `css', `inline-css', and `font'. In `css' +;; mode, htmlize uses cascading style sheets to specify colors; it +;; generates classes that correspond to Emacs faces and uses ... to color parts of text. In this mode, the +;; produced HTML is valid under the 4.01 strict DTD, as confirmed by +;; the W3C validator. `inline-css' is like `css', except the CSS is +;; put directly in the STYLE attribute of the SPAN element, making it +;; possible to paste the generated HTML to other documents. In `font' +;; mode, htmlize uses ... to colorize HTML, +;; which is not standard-compliant, but works better in older +;; browsers. `css' mode is the default. + +;; You can also use htmlize from your Emacs Lisp code. When called +;; non-interactively, `htmlize-buffer' and `htmlize-region' will +;; return the resulting HTML buffer, but will not change current +;; buffer or move the point. + +;; I tried to make the package elisp-compatible with multiple Emacsen, +;; specifically aiming for XEmacs 19.14+ and GNU Emacs 19.34+. Please +;; let me know if it doesn't work on some of those, and I'll try to +;; fix it. I relied heavily on the presence of CL extensions, +;; especially for cross-emacs compatibility; please don't try to +;; remove that particular dependency. When byte-compiling under GNU +;; Emacs, you're likely to get some warnings; just ignore them. + +;; The latest version should be available at: +;; +;; +;; +;; You can find a sample of htmlize's output (possibly generated with +;; an older version) at: +;; +;; + +;; Thanks go to the multitudes of people who have sent reports and +;; contributed comments, suggestions, and fixes. They include Ron +;; Gut, Bob Weiner, Toni Drabik, Peter Breton, Thomas Vogels, Juri +;; Linkov, Maciek Pasternacki, and many others. + +;; User quotes: "You sir, are a sick, sick, _sick_ person. :)" +;; -- Bill Perry, author of Emacs/W3 + + +;;; Code: + +(require 'cl) +(eval-when-compile + (if (string-match "XEmacs" emacs-version) + (byte-compiler-options + (warnings (- unresolved)))) + (defvar font-lock-auto-fontify) + (defvar font-lock-support-mode) + (defvar global-font-lock-mode) + (when (and (eq emacs-major-version 19) + (not (string-match "XEmacs" emacs-version))) + ;; Older versions of GNU Emacs fail to autoload cl-extra even when + ;; `cl' is loaded. + (load "cl-extra"))) + +(defconst htmlize-version "1.34") + +;; Incantations to make custom stuff work without customize, e.g. on +;; XEmacs 19.14 or GNU Emacs 19.34. +(eval-and-compile + (condition-case () + (require 'custom) + (error nil)) + (if (and (featurep 'custom) (fboundp 'custom-declare-variable)) + nil ; we've got what we needed + ;; No custom or obsolete custom, define surrogates. Define all + ;; three macros, so we don't hose another library that expects + ;; e.g. `defface' to work after (fboundp 'defcustom) succeeds. + (defmacro defgroup (&rest ignored) nil) + (defmacro defcustom (var value doc &rest ignored) + `(defvar ,var ,value ,doc)) + (defmacro defface (face value doc &rest stuff) + `(make-face ,face)))) + +(defgroup htmlize nil + "Convert buffer text and faces to HTML." + :group 'hypermedia) + +(defcustom htmlize-head-tags "" + "*Additional tags to insert within HEAD of the generated document." + :type 'string + :group 'htmlize) + +(defcustom htmlize-output-type 'css + "*Output type of generated HTML, one of `css', `inline-css', or `font'. +When set to `css' (the default), htmlize will generate a style sheet +with description of faces, and use it in the HTML document, specifying +the faces in the actual text with . + +When set to `inline-css', the style will be generated as above, but +placed directly in the STYLE attribute of the span ELEMENT: . This makes it easier to paste the resulting HTML to +other documents. + +When set to `font', the properties will be set using layout tags +, , , , and . + +`css' output is normally preferred, but `font' is still useful for +supporting old, pre-CSS browsers, and both `inline-css' and `font' for +easier embedding of colorized text in foreign HTML documents (no style +sheet to carry around)." + :type '(choice (const css) (const inline-css) (const font)) + :group 'htmlize) + +(defcustom htmlize-generate-hyperlinks t + "*Non-nil means generate the hyperlinks for URLs and mail addresses. +This is on by default; set it to nil if you don't want htmlize to +insert hyperlinks in the resulting HTML. (In which case you can still +do your own hyperlinkification from htmlize-after-hook.)" + :type 'boolean + :group 'htmlize) + +(defcustom htmlize-hyperlink-style " + a { + color: inherit; + background-color: inherit; + font: inherit; + text-decoration: inherit; + } + a:hover { + text-decoration: underline; + } +" + "*The CSS style used for hyperlinks when in CSS mode." + :type 'string + :group 'htmlize) + +(defcustom htmlize-replace-form-feeds t + "*Non-nil means replace form feeds in source code with HTML separators. +Form feeds are the ^L characters at line beginnings that are sometimes +used to separate sections of source code. If this variable is set to +`t', form feed characters are replaced with the
separator. If this +is a string, it specifies the replacement to use. Note that
 is
+temporarily closed before the separator is inserted, so the default
+replacement is effectively \"

\".  If you specify
+another replacement, don't forget to close and reopen the 
 if you
+want the output to remain valid HTML.
+
+If you need more elaborate processing, set this to nil and use
+htmlize-after-hook."
+  :type 'boolean
+  :group 'htmlize)
+
+(defcustom htmlize-html-charset nil
+  "*The charset declared by the resulting HTML documents.
+When non-nil, causes htmlize to insert the following in the HEAD section
+of the generated HTML:
+
+  
+
+where CHARSET is the value you've set for htmlize-html-charset.  Valid
+charsets are defined by MIME and include strings like \"iso-8859-1\",
+\"iso-8859-15\", \"utf-8\", etc.
+
+If you are using non-Latin-1 charsets, you might need to set this for
+your documents to render correctly.  Also, the W3C validator requires
+submitted HTML documents to declare a charset.  So if you care about
+validation, you can use this to prevent the validator from bitching.
+
+Needless to say, if you set this, you should actually make sure that
+the buffer is in the encoding you're claiming it is in.  (Under Mule
+that is done by ensuring the correct \"file coding system\" for the
+buffer.)  If you don't understand what that means, this option is
+probably not for you."
+  :type '(choice (const :tag "Unset" nil)
+		 string)
+  :group 'htmlize)
+
+(defcustom htmlize-convert-nonascii-to-entities (featurep 'mule)
+  "*Whether non-ASCII characters should be converted to HTML entities.
+
+When this is non-nil, characters with codes in the 128-255 range will be
+considered Latin 1 and rewritten as \"&#CODE;\".  Characters with codes
+above 255 will be converted to \"&#UCS;\", where UCS denotes the Unicode
+code point of the character.  If the code point cannot be determined,
+the character will be copied unchanged, as would be the case if the
+option were nil.
+
+When the option is nil, the non-ASCII characters are copied to HTML
+without modification.  In that case, the web server and/or the browser
+must be set to understand the encoding that was used when saving the
+buffer.  (You might also want to specify it by setting
+`htmlize-html-charset'.)
+
+Note that in an HTML entity \"&#CODE;\", CODE is always a UCS code point,
+which has nothing to do with the charset the page is in.  For example,
+\"©\" *always* refers to the copyright symbol, regardless of charset
+specified by the META tag or the charset sent by the HTTP server.  In
+other words, \"©\" is exactly equivalent to \"©\".
+
+By default, entity conversion is turned on for Mule-enabled Emacsen and
+turned off otherwise.  This is because Mule knows the charset of
+non-ASCII characters in the buffer.  A non-Mule Emacs cannot tell
+whether a character with code 0xA9 represents Latin 1 copyright symbol,
+Latin 2 \"S with caron\", or something else altogether.  Setting this to
+t without Mule means asserting that 128-255 characters always mean Latin
+1.
+
+For most people htmlize will work fine with this option left at the
+default setting; don't change it unless you know what you're doing."
+  :type 'sexp
+  :group 'htmlize)
+
+(defcustom htmlize-ignore-face-size 'absolute
+  "*Whether face size should be ignored when generating HTML.
+If this is nil, face sizes are used.  If set to t, sizes are ignored
+If set to `absolute', only absolute size specifications are ignored.
+Please note that font sizes only work with CSS-based output types."
+  :type '(choice (const :tag "Don't ignore" nil)
+		 (const :tag "Ignore all" t)
+		 (const :tag "Ignore absolute" absolute))
+  :group 'htmlize)
+
+(defcustom htmlize-css-name-prefix ""
+  "*The prefix used for CSS names.
+The CSS names that htmlize generates from face names are often too
+generic for CSS files; for example, `font-lock-type-face' is transformed
+to `type'.  Use this variable to add a prefix to the generated names.
+The string \"htmlize-\" is an example of a reasonable prefix."
+  :type 'string
+  :group 'htmlize)
+
+(defcustom htmlize-use-rgb-txt t
+  "*Whether `rgb.txt' should be used to convert color names to RGB.
+
+This conversion means determining, for instance, that the color
+\"IndianRed\" corresponds to the (205, 92, 92) RGB triple.  `rgb.txt'
+is the X color database that maps hundreds of color names to such RGB
+triples.  When this variable is non-nil, `htmlize' uses `rgb.txt' to
+look up color names.
+
+If this variable is nil, htmlize queries Emacs for RGB components of
+colors using `color-instance-rgb-components' and `x-color-values'.
+This can yield incorrect results on non-true-color displays.
+
+If the `rgb.txt' file is not found (which will be the case if you're
+running Emacs on non-X11 systems), this option is ignored."
+  :type 'boolean
+  :group 'htmlize)
+
+(defcustom htmlize-html-major-mode nil
+  "The mode the newly created HTML buffer will be put in.
+Set this to nil if you prefer the default (fundamental) mode."
+  :type '(radio (const :tag "No mode (fundamental)" nil)
+		 (function-item html-mode)
+		 (function :tag "User-defined major mode"))
+  :group 'htmlize)
+
+(defvar htmlize-before-hook nil
+  "Hook run before htmlizing a buffer.
+The hook functions are run in the source buffer (not the resulting HTML
+buffer).")
+
+(defvar htmlize-after-hook nil
+  "Hook run after htmlizing a buffer.
+Unlike `htmlize-before-hook', these functions are run in the generated
+HTML buffer.  You may use them to modify the outlook of the final HTML
+output.")
+
+(defvar htmlize-file-hook nil
+  "Hook run by `htmlize-file' after htmlizing a file, but before saving it.")
+
+(defvar htmlize-buffer-places)
+ 
+;;; Some cross-Emacs compatibility.
+
+;; I try to conditionalize on features rather than Emacs version, but
+;; in some cases checking against the version *is* necessary.
+(defconst htmlize-running-xemacs (string-match "XEmacs" emacs-version))
+
+(eval-and-compile
+  ;; save-current-buffer, with-current-buffer, and with-temp-buffer
+  ;; are not available in 19.34 and in older XEmacsen.  Strictly
+  ;; speaking, we should stick to our own namespace and define and use
+  ;; htmlize-save-current-buffer, etc.  But non-standard special forms
+  ;; are a pain because they're not properly fontified or indented and
+  ;; because they look weird and ugly.  So I'll just go ahead and
+  ;; define the real ones if they're not available.  If someone
+  ;; convinces me that this breaks something, I'll switch to the
+  ;; "htmlize-" namespace.
+  (unless (fboundp 'save-current-buffer)
+    (defmacro save-current-buffer (&rest forms)
+      `(let ((__scb_current (current-buffer)))
+	 (unwind-protect
+	     (progn ,@forms)
+	   (set-buffer __scb_current)))))
+  (unless (fboundp 'with-current-buffer)
+    (defmacro with-current-buffer (buffer &rest forms)
+      `(save-current-buffer (set-buffer ,buffer) ,@forms)))
+  (unless (fboundp 'with-temp-buffer)
+    (defmacro with-temp-buffer (&rest forms)
+      (let ((temp-buffer (gensym "tb-")))
+	`(let ((,temp-buffer
+		(get-buffer-create (generate-new-buffer-name " *temp*"))))
+	   (unwind-protect
+	       (with-current-buffer ,temp-buffer
+		 ,@forms)
+	     (and (buffer-live-p ,temp-buffer)
+		  (kill-buffer ,temp-buffer))))))))
+
+;; We need a function that efficiently finds the next change of a
+;; property (usually `face'), preferably regardless of whether the
+;; change occurred because of a text property or an extent/overlay.
+;; As it turns out, it is not easy to do that compatibly.
+;;
+;; Under XEmacs, `next-single-property-change' does that.  Under GNU
+;; Emacs beginning with version 21, `next-single-char-property-change'
+;; is available and does the same.  GNU Emacs 20 had
+;; `next-char-property-change', which we can use.  GNU Emacs 19 didn't
+;; provide any means for simultaneously examining overlays and text
+;; properties, so when using Emacs 19.34, we punt and fall back to
+;; `next-single-property-change', thus ignoring overlays altogether.
+
+(cond
+ (htmlize-running-xemacs
+  ;; XEmacs: good.
+  (defun htmlize-next-change (pos prop &optional limit)
+    (next-single-property-change pos prop nil (or limit (point-max)))))
+ ((fboundp 'next-single-char-property-change)
+  ;; GNU Emacs 21: good.
+  (defun htmlize-next-change (pos prop &optional limit)
+    (next-single-char-property-change pos prop nil limit)))
+ ((fboundp 'next-char-property-change)
+  ;; GNU Emacs 20: bad, but fixable.
+  (defun htmlize-next-change (pos prop &optional limit)
+    (let ((done nil)
+	  (current-value (get-char-property pos prop))
+	  newpos next-value)
+      ;; Loop over positions returned by next-char-property-change
+      ;; until the value of PROP changes or we've hit EOB.
+      (while (not done)
+	(setq newpos (next-char-property-change pos limit)
+	      next-value (get-char-property newpos prop))
+	(cond ((eq newpos pos)
+	       ;; Possibly at EOB?  Whatever, just don't infloop.
+	       (setq done t))
+	      ((eq next-value current-value)
+	       ;; PROP hasn't changed -- keep looping.
+	       )
+	      (t
+	       (setq done t)))
+	(setq pos newpos))
+      pos)))
+ (t
+  ;; GNU Emacs 19.34: hopeless, cannot properly support overlays.
+  (defun htmlize-next-change (pos prop &optional limit)
+    (unless limit
+      (setq limit (point-max)))
+    (let ((res (next-single-property-change pos prop)))
+      (if (or (null res)
+	      (> res limit))
+	  limit
+	res)))))
+ 
+;;; Transformation of buffer text: HTML escapes, untabification, etc.
+
+(defvar htmlize-basic-character-table
+  ;; Map characters in the 0-127 range to either one-character strings
+  ;; or to numeric entities.
+  (let ((table (make-vector 128 ?\0)))
+    ;; Map characters in the 32-126 range to themselves, others to
+    ;; &#CODE entities;
+    (dotimes (i 128)
+      (setf (aref table i) (if (and (>= i 32) (<= i 126))
+			       (char-to-string i)
+			     (format "&#%d;" i))))
+    ;; Set exceptions manually.
+    (setf
+     ;; Don't escape newline, carriage return, and TAB.
+     (aref table ?\n) "\n"
+     (aref table ?\r) "\r"
+     (aref table ?\t) "\t"
+     ;; Escape &, <, and >.
+     (aref table ?&) "&"
+     (aref table ?<) "<"
+     (aref table ?>) ">"
+     ;; Not escaping '"' buys us a measurable speedup.  It's only
+     ;; necessary to quote it for strings used in attribute values,
+     ;; which htmlize doesn't do.
+     ;(aref table ?\") """
+     )
+    table))
+
+;; A cache of HTML representation of non-ASCII characters.  Depending
+;; on availability of `encode-char' and the setting of
+;; `htmlize-convert-nonascii-to-entities', this maps non-ASCII
+;; characters to either "&#;" or "" (mapconcat's mapper
+;; must always return strings).  It's only filled as characters are
+;; encountered, so that in a buffer with e.g. French text, it will
+;; only ever contain French accented characters as keys.  It's cleared
+;; on each entry to htmlize-buffer-1 to allow modifications of
+;; `htmlize-convert-nonascii-to-entities' to take effect.
+(defvar htmlize-extended-character-cache (make-hash-table :test 'eq))
+
+(defun htmlize-protect-string (string)
+  "HTML-protect string, escaping HTML metacharacters and I18N chars."
+  ;; Only protecting strings that actually contain unsafe or non-ASCII
+  ;; chars removes a lot of unnecessary funcalls and consing.
+  (if (not (string-match "[^\r\n\t -%'-;=?-~]" string))
+      string
+    (mapconcat (lambda (char)
+		 (cond
+		  ((< char 128)
+		   ;; ASCII: use htmlize-basic-character-table.
+		   (aref htmlize-basic-character-table char))
+		  ((gethash char htmlize-extended-character-cache)
+		   ;; We've already seen this char; return the cached
+		   ;; string.
+		   )
+		  ((not htmlize-convert-nonascii-to-entities)
+		   ;; If conversion to entities is not desired, always
+		   ;; copy the char literally.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (char-to-string char)))
+		  ((< char 256)
+		   ;; Latin 1: no need to call encode-char.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (format "&#%d;" char)))
+		  ((and (fboundp 'encode-char)
+			;; Must check if encode-char works for CHAR;
+			;; it fails for Arabic and possibly elsewhere.
+			(encode-char char 'ucs))
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (format "&#%d;" (encode-char char 'ucs))))
+		  (t
+		   ;; encode-char doesn't work for this char.  Copy it
+		   ;; unchanged and hope for the best.
+		   (setf (gethash char htmlize-extended-character-cache)
+			 (char-to-string char)))))
+	       string "")))
+
+(defconst htmlize-ellipsis "...")
+(put-text-property 0 (length htmlize-ellipsis) 'htmlize-ellipsis t htmlize-ellipsis)
+
+(defun htmlize-buffer-substring-no-invisible (beg end)
+  ;; Like buffer-substring-no-properties, but don't copy invisible
+  ;; parts of the region.  Where buffer-substring-no-properties
+  ;; mandates an ellipsis to be shown, htmlize-ellipsis is inserted.
+  (let ((pos beg)
+	visible-list invisible show next-change)
+    ;; Iterate over the changes in the `invisible' property and filter
+    ;; out the portions where it's non-nil, i.e. where the text is
+    ;; invisible.
+    (while (< pos end)
+      (setq invisible (get-char-property pos 'invisible)
+	    next-change (htmlize-next-change pos 'invisible end))
+      (if (not (listp buffer-invisibility-spec))
+	  ;; If buffer-invisibility-spec is not a list, then all
+	  ;; characters with non-nil `invisible' property are visible.
+	  (setq show (not invisible))
+	;; Otherwise, the value of a non-nil `invisible' property can be:
+	;; 1. a symbol -- make the text invisible if it matches
+	;;    buffer-invisibility-spec.
+	;; 2. a list of symbols -- make the text invisible if
+	;;    any symbol in the list matches
+	;;    buffer-invisibility-spec.
+	;; If the match of buffer-invisibility-spec has a non-nil
+	;; CDR, replace the invisible text with an ellipsis.
+	(let (match)
+	  (if (symbolp invisible)
+	      (setq match (member* invisible buffer-invisibility-spec
+				   :key (lambda (i)
+					  (if (symbolp i) i (car i)))))
+	    (setq match (block nil
+			  (dolist (elem invisible)
+			    (let ((m (member*
+				      elem buffer-invisibility-spec
+				      :key (lambda (i)
+					     (if (symbolp i) i (car i))))))
+			      (when m (return m))))
+			  nil)))
+	  (setq show (cond ((null match) t)
+			   ((and (cdr-safe (car match))
+				 ;; Conflate successive ellipses.
+				 (not (eq show htmlize-ellipsis)))
+			    htmlize-ellipsis)
+			   (t nil)))))
+      (cond ((eq show t)
+	     (push (buffer-substring-no-properties pos next-change) visible-list))
+	    ((stringp show)
+	     (push show visible-list)))
+      (setq pos next-change))
+    (if (= (length visible-list) 1)
+	;; If VISIBLE-LIST consists of only one element, return it
+	;; without concatenation.  This avoids additional consing in
+	;; regions without any invisible text.
+	(car visible-list)
+      (apply #'concat (nreverse visible-list)))))
+
+(defun htmlize-trim-ellipsis (text)
+  ;; Remove htmlize-ellipses ("...") from the beginning of TEXT if it
+  ;; starts with it.  It checks for the special property of the
+  ;; ellipsis so it doesn't work on ordinary text that begins with
+  ;; "...".
+  (if (get-text-property 0 'htmlize-ellipsis text)
+      (substring text (length htmlize-ellipsis))
+    text))
+
+(defconst htmlize-tab-spaces
+  ;; A table of strings with spaces.  (aref htmlize-tab-spaces 5) is
+  ;; like (make-string 5 ?\ ), except it doesn't cons.
+  (let ((v (make-vector 32 nil)))
+    (dotimes (i (length v))
+      (setf (aref v i) (make-string i ?\ )))
+    v))
+
+(defun htmlize-untabify (text start-column)
+  "Untabify TEXT, assuming it starts at START-COLUMN."
+  (let ((column start-column)
+	(last-match 0)
+	(chunk-start 0)
+	chunks match-pos tab-size)
+    (while (string-match "[\t\n]" text last-match)
+      (setq match-pos (match-beginning 0))
+      (cond ((eq (aref text match-pos) ?\t)
+	     ;; Encountered a tab: create a chunk of text followed by
+	     ;; the expanded tab.
+	     (push (substring text chunk-start match-pos) chunks)
+	     ;; Increase COLUMN by the length of the text we've
+	     ;; skipped since last tab or newline.  (Encountering
+	     ;; newline resets it.)
+	     (incf column (- match-pos last-match))
+	     ;; Calculate tab size based on tab-width and COLUMN.
+	     (setq tab-size (- tab-width (% column tab-width)))
+	     ;; Expand the tab.
+	     (push (aref htmlize-tab-spaces tab-size) chunks)
+	     (incf column tab-size)
+	     (setq chunk-start (1+ match-pos)))
+	    (t
+	     ;; Reset COLUMN at beginning of line.
+	     (setq column 0)))
+      (setq last-match (1+ match-pos)))
+    ;; If no chunks have been allocated, it means there have been no
+    ;; tabs to expand.  Return TEXT unmodified.
+    (if (null chunks)
+	text
+      (when (< chunk-start (length text))
+	;; Push the remaining chunk.
+	(push (substring text chunk-start) chunks))
+      ;; Generate the output from the available chunks.
+      (apply #'concat (nreverse chunks)))))
+
+(defun htmlize-despam-address (string)
+  "Replace every occurrence of '@' in STRING with @.
+`htmlize-make-hyperlinks' uses this to spam-protect mailto links
+without modifying their meaning."
+  ;; Suggested by Ville Skytta.
+  (while (string-match "@" string)
+    (setq string (replace-match "@" nil t string)))
+  string)
+
+(defun htmlize-make-hyperlinks ()
+  "Make hyperlinks in HTML."
+  ;; Function originally submitted by Ville Skytta.  Rewritten by
+  ;; Hrvoje Niksic, then modified by Ville Skytta and Hrvoje Niksic.
+  (goto-char (point-min))
+  (while (re-search-forward
+	  "<\\(\\(mailto:\\)?\\([-=+_.a-zA-Z0-9]+@[-_.a-zA-Z0-9]+\\)\\)>"
+	  nil t)
+    (let ((address (match-string 3))
+	  (link-text (match-string 1)))
+      (delete-region (match-beginning 0) (match-end 0))
+      (insert "<"
+	      (htmlize-despam-address link-text)
+	      ">")))
+  (goto-char (point-min))
+  (while (re-search-forward "<\\(\\(URL:\\)?\\([a-zA-Z]+://[^;]+\\)\\)>"
+			    nil t)
+    (let ((url (match-string 3))
+	  (link-text (match-string 1)))
+      (delete-region (match-beginning 0) (match-end 0))
+      (insert "<" link-text ">"))))
+
+;; Tests for htmlize-make-hyperlinks:
+
+;; 
+;; 
+;; 
+;; 
+;; 
+;; 
+
+(defun htmlize-defang-local-variables ()
+  ;; Juri Linkov reports that an HTML-ized "Local variables" can lead
+  ;; visiting the HTML to fail with "Local variables list is not
+  ;; properly terminated".  He suggested changing the phrase to
+  ;; syntactically equivalent HTML that Emacs doesn't recognize.
+  (goto-char (point-min))
+  (while (search-forward "Local Variables:" nil t)
+    (replace-match "Local Variables:" nil t)))
+  
+ 
+;;; Color handling.
+
+(if (fboundp 'locate-file)
+    (defalias 'htmlize-locate-file 'locate-file)
+  (defun htmlize-locate-file (file path)
+    (dolist (dir path nil)
+      (when (file-exists-p (expand-file-name file dir))
+	(return (expand-file-name file dir))))))
+
+(defvar htmlize-x-library-search-path
+  '("/usr/X11R6/lib/X11/"
+    "/usr/X11R5/lib/X11/"
+    "/usr/lib/X11R6/X11/"
+    "/usr/lib/X11R5/X11/"
+    "/usr/local/X11R6/lib/X11/"
+    "/usr/local/X11R5/lib/X11/"
+    "/usr/local/lib/X11R6/X11/"
+    "/usr/local/lib/X11R5/X11/"
+    "/usr/X11/lib/X11/"
+    "/usr/lib/X11/"
+    "/usr/local/lib/X11/"
+    "/usr/X386/lib/X11/"
+    "/usr/x386/lib/X11/"
+    "/usr/XFree86/lib/X11/"
+    "/usr/unsupported/lib/X11/"
+    "/usr/athena/lib/X11/"
+    "/usr/local/x11r5/lib/X11/"
+    "/usr/lpp/Xamples/lib/X11/"
+    "/usr/openwin/lib/X11/"
+    "/usr/openwin/share/lib/X11/"))
+
+(defun htmlize-get-color-rgb-hash (&optional rgb-file)
+  "Return a hash table mapping X color names to RGB values.
+The keys in the hash table are X11 color names, and the values are the
+#rrggbb RGB specifications, extracted from `rgb.txt'.
+
+If RGB-FILE is nil, the function will try hard to find a suitable file
+in the system directories.
+
+If no rgb.txt file is found, return nil."
+  (let ((rgb-file (or rgb-file (htmlize-locate-file
+				"rgb.txt"
+				htmlize-x-library-search-path)))
+	(hash nil))
+    (when rgb-file
+      (with-temp-buffer
+	(insert-file-contents rgb-file)
+	(setq hash (make-hash-table :test 'equal))
+	(while (not (eobp))
+	  (cond ((looking-at "^\\s-*\\([!#]\\|$\\)")
+		 ;; Skip comments and empty lines.
+		 )
+		((looking-at
+		  "[ \t]*\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\)")
+		 (setf (gethash (downcase (match-string 4)) hash)
+		       (format "#%02x%02x%02x"
+			       (string-to-number (match-string 1))
+			       (string-to-number (match-string 2))
+			       (string-to-number (match-string 3)))))
+		(t
+		 (error
+		  "Unrecognized line in %s: %s"
+		  rgb-file
+		  (buffer-substring (point) (progn (end-of-line) (point))))))
+	  (forward-line 1))))
+    hash))
+
+;; Compile the RGB map when loaded.  On systems where rgb.txt is
+;; missing, the value of the variable will be nil, and rgb.txt will
+;; not be used.
+(defvar htmlize-color-rgb-hash (htmlize-get-color-rgb-hash))
+ 
+;;; Face handling.
+
+(defun htmlize-face-specifies-property (face prop)
+  ;; Return t if face specifies PROP, as opposed to it being inherited
+  ;; from the default face.  The problem with e.g.
+  ;; `face-foreground-instance' is that it returns an instance for
+  ;; EVERY face because every face inherits from the default face.
+  ;; However, we'd like htmlize-face-{fore,back}ground to return nil
+  ;; when called with a face that doesn't specify its own foreground
+  ;; or background.
+  (or (eq face 'default)
+      (assq 'global (specifier-spec-list (face-property face prop)))))
+
+(defun htmlize-face-color-internal (face fg)
+  ;; Used only under GNU Emacs.  Return the color of FACE, but don't
+  ;; return "unspecified-fg" or "unspecified-bg".  If the face is
+  ;; `default' and the color is unspecified, look up the color in
+  ;; frame parameters.
+  (let* ((function (if fg #'face-foreground #'face-background))
+	 color)
+    (if (>= emacs-major-version 22)
+	;; For GNU Emacs 22+ set INHERIT to get the inherited values.
+	(setq color (funcall function face nil t))
+      (setq color (funcall function face))
+      ;; For GNU Emacs 21 (which has `face-attribute'): if the color
+      ;; is nil, recursively check for the face's parent.
+      (when (and (null color)
+		 (fboundp 'face-attribute)
+		 (face-attribute face :inherit)
+		 (not (eq (face-attribute face :inherit) 'unspecified)))
+	(setq color (htmlize-face-color-internal
+		     (face-attribute face :inherit) fg))))
+    (when (and (eq face 'default) (null color))
+      (setq color (cdr (assq (if fg 'foreground-color 'background-color)
+			     (frame-parameters)))))
+    (when (or (eq color 'unspecified)
+	      (equal color "unspecified-fg")
+	      (equal color "unspecified-bg"))
+      (setq color nil))
+    (when (and (eq face 'default)
+	       (null color))
+      ;; Assuming black on white doesn't seem right, but I can't think
+      ;; of anything better to do.
+      (setq color (if fg "black" "white")))
+    color))
+
+(defun htmlize-face-foreground (face)
+  ;; Return the name of the foreground color of FACE.  If FACE does
+  ;; not specify a foreground color, return nil.
+  (cond (htmlize-running-xemacs
+	 ;; XEmacs.
+	 (and (htmlize-face-specifies-property face 'foreground)
+	      (color-instance-name (face-foreground-instance face))))
+	(t
+	 ;; GNU Emacs.
+	 (htmlize-face-color-internal face t))))
+
+(defun htmlize-face-background (face)
+  ;; Return the name of the background color of FACE.  If FACE does
+  ;; not specify a background color, return nil.
+  (cond (htmlize-running-xemacs
+	 ;; XEmacs.
+	 (and (htmlize-face-specifies-property face 'background)
+	      (color-instance-name (face-background-instance face))))
+	(t
+	 ;; GNU Emacs.
+	 (htmlize-face-color-internal face nil))))
+
+;; Convert COLOR to the #RRGGBB string.  If COLOR is already in that
+;; format, it's left unchanged.
+
+(defun htmlize-color-to-rgb (color)
+  (let ((rgb-string nil))
+    (cond ((null color)
+	   ;; Ignore nil COLOR because it means that the face is not
+	   ;; specifying any color.  Hence (htmlize-color-to-rgb nil)
+	   ;; returns nil.
+	   )
+	  ((string-match "\\`#" color)
+	   ;; The color is already in #rrggbb format.
+	   (setq rgb-string color))
+	  ((and htmlize-use-rgb-txt
+		htmlize-color-rgb-hash)
+	   ;; Use of rgb.txt is requested, and it's available on the
+	   ;; system.  Use it.
+	   (setq rgb-string (gethash (downcase color) htmlize-color-rgb-hash)))
+	  (t
+	   ;; We're getting the RGB components from Emacs.
+	   (let ((rgb
+		  ;; Here I cannot conditionalize on (fboundp ...) 
+		  ;; because ps-print under some versions of GNU Emacs
+		  ;; defines its own dummy version of
+		  ;; `color-instance-rgb-components'.
+		  (if htmlize-running-xemacs
+		      (mapcar (lambda (arg)
+				(/ arg 256))
+			      (color-instance-rgb-components
+			       (make-color-instance color)))
+		    (mapcar (lambda (arg)
+			      (/ arg 256))
+			    (x-color-values color)))))
+	     (when rgb
+	       (setq rgb-string (apply #'format "#%02x%02x%02x" rgb))))))
+    ;; If RGB-STRING is still nil, it means the color cannot be found,
+    ;; for whatever reason.  In that case just punt and return COLOR.
+    ;; Most browsers support a decent set of color names anyway.
+    (or rgb-string color)))
+
+;; We store the face properties we care about into an
+;; `htmlize-fstruct' type.  That way we only have to analyze face
+;; properties, which can be time consuming, once per each face.  The
+;; mapping between Emacs faces and htmlize-fstructs is established by
+;; htmlize-make-face-map.  The name "fstruct" refers to variables of
+;; type `htmlize-fstruct', while the term "face" is reserved for Emacs
+;; faces.
+
+(defstruct htmlize-fstruct
+  foreground				; foreground color, #rrggbb
+  background				; background color, #rrggbb
+  size					; size
+  boldp					; whether face is bold
+  italicp				; whether face is italic
+  underlinep				; whether face is underlined
+  overlinep				; whether face is overlined
+  strikep				; whether face is struck through
+  css-name				; CSS name of face
+  )
+
+(defun htmlize-face-emacs21-attr (fstruct attr value)
+  ;; For ATTR and VALUE, set the equivalent value in FSTRUCT.
+  (case attr
+    (:foreground
+     (setf (htmlize-fstruct-foreground fstruct) (htmlize-color-to-rgb value)))
+    (:background
+     (setf (htmlize-fstruct-background fstruct) (htmlize-color-to-rgb value)))
+    (:height
+     (setf (htmlize-fstruct-size fstruct) value))
+    (:weight
+     (when (string-match (symbol-name value) "bold")
+       (setf (htmlize-fstruct-boldp fstruct) t)))
+    (:slant
+     (setf (htmlize-fstruct-italicp fstruct) (or (eq value 'italic)
+						 (eq value 'oblique))))
+    (:bold
+     (setf (htmlize-fstruct-boldp fstruct) value))
+    (:italic
+     (setf (htmlize-fstruct-italicp fstruct) value))
+    (:underline
+     (setf (htmlize-fstruct-underlinep fstruct) value))
+    (:overline
+     (setf (htmlize-fstruct-overlinep fstruct) value))
+    (:strike-through
+     (setf (htmlize-fstruct-strikep fstruct) value))))
+
+(defun htmlize-face-size (face)
+  ;; The size (height) of FACE, taking inheritance into account.
+  ;; Only works in Emacs 21 and later.
+  (let ((size-list
+	 (loop
+	  for f = face then (face-attribute f :inherit)
+	  until (or (not f) (eq f 'unspecified))
+	  for h = (face-attribute f :height)
+	  collect (if (eq h 'unspecified) nil h))))
+    (reduce 'htmlize-merge-size (cons nil size-list))))
+
+(defun htmlize-face-to-fstruct (face)
+  "Convert Emacs face FACE to fstruct."
+  (let ((fstruct (make-htmlize-fstruct
+		  :foreground (htmlize-color-to-rgb
+			       (htmlize-face-foreground face))
+		  :background (htmlize-color-to-rgb
+			       (htmlize-face-background face)))))
+    (cond (htmlize-running-xemacs
+	   ;; XEmacs doesn't provide a way to detect whether a face is
+	   ;; bold or italic, so we need to examine the font instance.
+	   ;; #### This probably doesn't work under MS Windows and/or
+	   ;; GTK devices.  I'll need help with those.
+	   (let* ((font-instance (face-font-instance face))
+		  (props (font-instance-properties font-instance)))
+	     (when (equalp (cdr (assq 'WEIGHT_NAME props)) "bold")
+	       (setf (htmlize-fstruct-boldp fstruct) t))
+	     (when (or (equalp (cdr (assq 'SLANT props)) "i")
+		       (equalp (cdr (assq 'SLANT props)) "o"))
+	       (setf (htmlize-fstruct-italicp fstruct) t))
+	     (setf (htmlize-fstruct-strikep fstruct)
+		   (face-strikethru-p face))
+	     (setf (htmlize-fstruct-underlinep fstruct)
+		   (face-underline-p face))))
+	  ((fboundp 'face-attribute)
+	   ;; GNU Emacs 21 and further.
+	   (dolist (attr '(:weight :slant :underline :overline :strike-through))
+	     (let ((value (if (>= emacs-major-version 22)
+			      ;; Use the INHERIT arg in GNU Emacs 22.
+			      (face-attribute face attr nil t)
+			    ;; Otherwise, fake it.
+			    (let ((face face))
+			      (while (and (eq (face-attribute face attr)
+					      'unspecified)
+					  (not (eq (face-attribute face :inherit)
+						   'unspecified)))
+				(setq face (face-attribute face :inherit)))
+			      (face-attribute face attr)))))
+	       (when (and value (not (eq value 'unspecified)))
+		 (htmlize-face-emacs21-attr fstruct attr value))))
+	   (let ((size (htmlize-face-size face)))
+	     (unless (eql size 1.0) 	; ignore non-spec
+	       (setf (htmlize-fstruct-size fstruct) size))))
+	  (t
+	   ;; Older GNU Emacs.  Some of these functions are only
+	   ;; available under Emacs 20+, hence the guards.
+	   (when (fboundp 'face-bold-p)
+	     (setf (htmlize-fstruct-boldp fstruct) (face-bold-p face)))
+	   (when (fboundp 'face-italic-p)
+	     (setf (htmlize-fstruct-italicp fstruct) (face-italic-p face)))
+	   (setf (htmlize-fstruct-underlinep fstruct)
+		 (face-underline-p face))))
+    ;; Generate the css-name property.  Emacs places no restrictions
+    ;; on the names of symbols that represent faces -- any characters
+    ;; may be in the name, even ^@.  We try hard to beat the face name
+    ;; into shape, both esthetically and according to CSS1 specs.
+    (setf (htmlize-fstruct-css-name fstruct)
+	  (let ((name (downcase (symbol-name face))))
+	    (when (string-match "\\`font-lock-" name)
+	      ;; Change font-lock-FOO-face to FOO.
+	      (setq name (replace-match "" t t name)))
+	    (when (string-match "-face\\'" name)
+	      ;; Drop the redundant "-face" suffix.
+	      (setq name (replace-match "" t t name)))
+	    (while (string-match "[^-a-zA-Z0-9]" name)
+	      ;; Drop the non-alphanumerics.
+	      (setq name (replace-match "X" t t name)))
+	    (when (string-match "\\`[-0-9]" name)
+	      ;; CSS identifiers may not start with a digit.
+	      (setq name (concat "X" name)))
+	    ;; After these transformations, the face could come
+	    ;; out empty.
+	    (when (equal name "")
+	      (setq name "face"))
+	    ;; Apply the prefix.
+	    (setq name (concat htmlize-css-name-prefix name))
+	    name))
+    fstruct))
+
+(defmacro htmlize-copy-attr-if-set (attr-list dest source)
+  ;; Expand the code of the type
+  ;; (and (htmlize-fstruct-ATTR source)
+  ;;      (setf (htmlize-fstruct-ATTR dest) (htmlize-fstruct-ATTR source)))
+  ;; for the given list of boolean attributes.
+  (cons 'progn
+	(loop for attr in attr-list
+	      for attr-sym = (intern (format "htmlize-fstruct-%s" attr))
+	      collect `(and (,attr-sym ,source)
+			    (setf (,attr-sym ,dest) (,attr-sym ,source))))))
+
+(defun htmlize-merge-size (merged next)
+  ;; Calculate the size of the merge of MERGED and NEXT.
+  (cond ((null merged)     next)
+	((integerp next)   next)
+	((null next)       merged)
+	((floatp merged)   (* merged next))
+	((integerp merged) (round (* merged next)))))
+
+(defun htmlize-merge-two-faces (merged next)
+  (htmlize-copy-attr-if-set
+   (foreground background boldp italicp underlinep overlinep strikep)
+   merged next)
+  (setf (htmlize-fstruct-size merged)
+	(htmlize-merge-size (htmlize-fstruct-size merged)
+			    (htmlize-fstruct-size next)))
+  merged)
+
+(defun htmlize-merge-faces (fstruct-list)
+  (cond ((null fstruct-list)
+	 ;; Nothing to do, return a dummy face.
+	 (make-htmlize-fstruct))
+	((null (cdr fstruct-list))
+	 ;; Optimize for the common case of a single face, simply
+	 ;; return it.
+	 (car fstruct-list))
+	(t
+	 (reduce #'htmlize-merge-two-faces
+		 (cons (make-htmlize-fstruct) fstruct-list)))))
+
+;; GNU Emacs 20+ supports attribute lists in `face' properties.  For
+;; example, you can use `(:foreground "red" :weight bold)' as an
+;; overlay's "face", or you can even use a list of such lists, etc.
+;; We call those "attrlists".
+;;
+;; htmlize supports attrlist by converting them to fstructs, the same
+;; as with regular faces.
+
+(defun htmlize-attrlist-to-fstruct (attrlist)
+  ;; Like htmlize-face-to-fstruct, but accepts an ATTRLIST as input.
+  (let ((fstruct (make-htmlize-fstruct)))
+    (cond ((eq (car attrlist) 'foreground-color)
+	   ;; ATTRLIST is (foreground-color . COLOR)
+	   (setf (htmlize-fstruct-foreground fstruct)
+		 (htmlize-color-to-rgb (cdr attrlist))))
+	  ((eq (car attrlist) 'background-color)
+	   ;; ATTRLIST is (background-color . COLOR)
+	   (setf (htmlize-fstruct-background fstruct)
+		 (htmlize-color-to-rgb (cdr attrlist))))
+	  (t
+	   ;; ATTRLIST is a plist.
+	   (while attrlist
+	     (let ((attr (pop attrlist))
+		   (value (pop attrlist)))
+	       (when (and value (not (eq value 'unspecified)))
+		 (htmlize-face-emacs21-attr fstruct attr value))))))
+    (setf (htmlize-fstruct-css-name fstruct) "ATTRLIST")
+    fstruct))
+
+(defun htmlize-face-list-p (face-prop)
+  "Return non-nil if FACE-PROP is a list of faces, nil otherwise."
+  ;; If not for attrlists, this would return (listp face-prop).  This
+  ;; way we have to be more careful because attrlist is also a list!
+  (cond
+   ((eq face-prop nil)
+    ;; FACE-PROP being nil means empty list (no face), so return t.
+    t)
+   ((symbolp face-prop)
+    ;; A symbol other than nil means that it's only one face, so return
+    ;; nil.
+    nil)
+   ((not (consp face-prop))
+    ;; Huh?  Not a symbol or cons -- treat it as a single element.
+    nil)
+   (t
+    ;; We know that FACE-PROP is a cons: check whether it looks like an
+    ;; ATTRLIST.
+    (let* ((car (car face-prop))
+	   (attrlist-p (and (symbolp car)
+			    (or (eq car 'foreground-color)
+				(eq car 'background-color)
+				(eq (aref (symbol-name car) 0) ?:)))))
+      ;; If FACE-PROP is not an ATTRLIST, it means it's a list of
+      ;; faces.
+      (not attrlist-p)))))
+
+(defun htmlize-make-face-map (faces)
+  ;; Return a hash table mapping Emacs faces to htmlize's fstructs.
+  ;; The keys are either face symbols or attrlists, so the test
+  ;; function must be `equal'.
+  (let ((face-map (make-hash-table :test 'equal))
+	css-names)
+    (dolist (face faces)
+      (unless (gethash face face-map)
+	;; Haven't seen FACE yet; convert it to an fstruct and cache
+	;; it.
+	(let ((fstruct (if (symbolp face)
+			   (htmlize-face-to-fstruct face)
+			 (htmlize-attrlist-to-fstruct face))))
+	  (setf (gethash face face-map) fstruct)
+	  (let* ((css-name (htmlize-fstruct-css-name fstruct))
+		 (new-name css-name)
+		 (i 0))
+	    ;; Uniquify the face's css-name by using NAME-1, NAME-2,
+	    ;; etc.
+	    (while (member new-name css-names)
+	      (setq new-name (format "%s-%s" css-name (incf i))))
+	    (unless (equal new-name css-name)
+	      (setf (htmlize-fstruct-css-name fstruct) new-name))
+	    (push new-name css-names)))))
+    face-map))
+
+(defun htmlize-unstringify-face (face)
+  "If FACE is a string, return it interned, otherwise return it unchanged."
+  (if (stringp face)
+      (intern face)
+    face))
+
+(defun htmlize-faces-in-buffer ()
+  "Return a list of faces used in the current buffer.
+Under XEmacs, this returns the set of faces specified by the extents
+with the `face' property.  (This covers text properties as well.)  Under
+GNU Emacs, it returns the set of faces specified by the `face' text
+property and by buffer overlays that specify `face'."
+  (let (faces)
+    ;; Testing for (fboundp 'map-extents) doesn't work because W3
+    ;; defines `map-extents' under FSF.
+    (if htmlize-running-xemacs
+	(let (face-prop)
+	  (map-extents (lambda (extent ignored)
+			 (setq face-prop (extent-face extent)
+			       ;; FACE-PROP can be a face or a list of
+			       ;; faces.
+			       faces (if (listp face-prop)
+					 (union face-prop faces)
+				       (adjoin face-prop faces)))
+			 nil)
+		       nil
+		       ;; Specify endpoints explicitly to respect
+		       ;; narrowing.
+		       (point-min) (point-max) nil nil 'face))
+      ;; FSF Emacs code.
+      ;; Faces used by text properties.
+      (let ((pos (point-min)) face-prop next)
+	(while (< pos (point-max))
+	  (setq face-prop (get-text-property pos 'face)
+		next (or (next-single-property-change pos 'face) (point-max)))
+	  ;; FACE-PROP can be a face/attrlist or a list thereof.
+	  (setq faces (if (htmlize-face-list-p face-prop)
+			  (nunion (mapcar #'htmlize-unstringify-face face-prop)
+				  faces :test 'equal)
+			(adjoin (htmlize-unstringify-face face-prop)
+				faces :test 'equal)))
+	  (setq pos next)))
+      ;; Faces used by overlays.
+      (dolist (overlay (overlays-in (point-min) (point-max)))
+	(let ((face-prop (overlay-get overlay 'face)))
+	  ;; FACE-PROP can be a face/attrlist or a list thereof.
+	  (setq faces (if (htmlize-face-list-p face-prop)
+			  (nunion (mapcar #'htmlize-unstringify-face face-prop)
+				  faces :test 'equal)
+			(adjoin (htmlize-unstringify-face face-prop)
+				faces :test 'equal))))))
+    faces))
+
+;; htmlize-faces-at-point returns the faces in use at point.  The
+;; faces are sorted by increasing priority, i.e. the last face takes
+;; precedence.
+;;
+;; Under XEmacs, this returns all the faces in all the extents at
+;; point.  Under GNU Emacs, this returns all the faces in the `face'
+;; property and all the faces in the overlays at point.
+
+(cond (htmlize-running-xemacs
+       (defun htmlize-faces-at-point ()
+	 (let (extent extent-list face-list face-prop)
+	   (while (setq extent (extent-at (point) nil 'face extent))
+	     (push extent extent-list))
+	   ;; extent-list is in reverse display order, meaning that
+	   ;; smallest ones come last.  That is the order we want,
+	   ;; except it can be overridden by the `priority' property.
+	   (setq extent-list (stable-sort extent-list #'<
+					  :key #'extent-priority))
+	   (dolist (extent extent-list)
+	     (setq face-prop (extent-face extent))
+	     ;; extent's face-list is in reverse order from what we
+	     ;; want, but the `nreverse' below will take care of it.
+	     (setq face-list (if (listp face-prop)
+				 (append face-prop face-list)
+			       (cons face-prop face-list))))
+	   (nreverse face-list))))
+      (t
+       (defun htmlize-faces-at-point ()
+	 (let (all-faces)
+	   ;; Faces from text properties.
+	   (let ((face-prop (get-text-property (point) 'face)))
+	     (setq all-faces (if (htmlize-face-list-p face-prop)
+				 (nreverse (mapcar #'htmlize-unstringify-face
+						   face-prop))
+			       (list (htmlize-unstringify-face face-prop)))))
+	   ;; Faces from overlays.
+	   (let ((overlays
+		  ;; Collect overlays at point that specify `face'.
+		  (delete-if-not (lambda (o)
+				   (overlay-get o 'face))
+				 (overlays-at (point))))
+		 list face-prop)
+	     ;; Sort the overlays so the smaller (more specific) ones
+	     ;; come later.  The number of overlays at each one
+	     ;; position should be very small, so the sort shouldn't
+	     ;; slow things down.
+	     (setq overlays (sort* overlays
+				   ;; Sort by ascending...
+				   #'<
+				   ;; ...overlay size.
+				   :key (lambda (o)
+					  (- (overlay-end o)
+					     (overlay-start o)))))
+	     ;; Overlay priorities, if present, override the above
+	     ;; established order.  Larger overlay priority takes
+	     ;; precedence and therefore comes later in the list.
+	     (setq overlays (stable-sort
+			     overlays
+			     ;; Reorder (stably) by acending...
+			     #'<
+			     ;; ...overlay priority.
+			     :key (lambda (o)
+				    (or (overlay-get o 'priority) 0))))
+	     (dolist (overlay overlays)
+	       (setq face-prop (overlay-get overlay 'face))
+	       (setq list (if (htmlize-face-list-p face-prop)
+			      (nconc (nreverse (mapcar
+						#'htmlize-unstringify-face
+						face-prop))
+				     list)
+			    (cons (htmlize-unstringify-face face-prop) list))))
+	     ;; Under "Merging Faces" the manual explicitly states
+	     ;; that faces specified by overlays take precedence over
+	     ;; faces specified by text properties.
+	     (setq all-faces (nconc all-faces list)))
+	   all-faces))))
+ 
+;; htmlize supports generating HTML in two several fundamentally
+;; different ways, one with the use of CSS and nested  tags, and
+;; the other with the use of the old  tags.  Rather than adding
+;; a bunch of ifs to many places, we take a semi-OO approach.
+;; `htmlize-buffer-1' calls a number of "methods", which indirect to
+;; the functions that depend on `htmlize-output-type'.  The currently
+;; used methods are `doctype', `insert-head', `body-tag', and
+;; `insert-text'.  Not all output types define all methods.
+;;
+;; Methods are called either with (htmlize-method METHOD ARGS...) 
+;; special form, or by accessing the function with
+;; (htmlize-method-function 'METHOD) and calling (funcall FUNCTION).
+;; The latter form is useful in tight loops because `htmlize-method'
+;; conses.
+;;
+;; Currently defined output types are `css' and `font'.
+
+(defmacro htmlize-method (method &rest args)
+  ;; Expand to (htmlize-TYPE-METHOD ...ARGS...).  TYPE is the value of
+  ;; `htmlize-output-type' at run time.
+  `(funcall (htmlize-method-function ',method) ,@args))
+
+(defun htmlize-method-function (method)
+  ;; Return METHOD's function definition for the current output type.
+  ;; The returned object can be safely funcalled.
+  (let ((sym (intern (format "htmlize-%s-%s" htmlize-output-type method))))
+    (indirect-function (if (fboundp sym)
+			   sym
+			 (let ((default (intern (concat "htmlize-default-"
+							(symbol-name method)))))
+			   (if (fboundp default)
+			       default
+			     'ignore))))))
+
+(defvar htmlize-memoization-table (make-hash-table :test 'equal))
+
+(defmacro htmlize-memoize (key generator)
+  "Return the value of GENERATOR, memoized as KEY.
+That means that GENERATOR will be evaluated and returned the first time
+it's called with the same value of KEY.  All other times, the cached
+\(memoized) value will be returned."
+  (let ((value (gensym)))
+    `(let ((,value (gethash ,key htmlize-memoization-table)))
+       (unless ,value
+	 (setq ,value ,generator)
+	 (setf (gethash ,key htmlize-memoization-table) ,value))
+       ,value)))
+ 
+;;; Default methods.
+
+(defun htmlize-default-doctype ()
+  nil					; no doc-string
+  ;; According to DTDs published by the W3C, it is illegal to embed
+  ;;  in 
.  This makes sense in general, but is bad for
+  ;; htmlize's intended usage of  to specify the document color.
+
+  ;; To make generated HTML legal, htmlize's `font' mode used to
+  ;; specify the SGML declaration of "HTML Pro" DTD here.  HTML Pro
+  ;; aka Silmaril DTD was a project whose goal was to produce a GPL'ed
+  ;; DTD that would encompass all the incompatible HTML extensions
+  ;; procured by Netscape, MSIE, and other players in the field.
+  ;; Apparently the project got abandoned, the last available version
+  ;; being "Draft 0 Revision 11" from January 1997, as documented at
+  ;; .
+
+  ;; Since by now HTML Pro is remembered by none but the most die-hard
+  ;; early-web-days nostalgics and used by not even them, there is no
+  ;; use in specifying it.  So we return the standard HTML 4.0
+  ;; declaration, which makes generated HTML technically illegal.  If
+  ;; you have a problem with that, use the `css' engine designed to
+  ;; create fully conforming HTML.
+
+  ""
+
+  ;; Now-abandoned HTML Pro declaration.
+  ;""
+  )
+
+(defun htmlize-default-body-tag (face-map)
+  nil					; no doc-string
+  "")
+ 
+;;; CSS based output support.
+
+;; Internal function; not a method.
+(defun htmlize-css-specs (fstruct)
+  (let (result)
+    (when (htmlize-fstruct-foreground fstruct)
+      (push (format "color: %s;" (htmlize-fstruct-foreground fstruct))
+	    result))
+    (when (htmlize-fstruct-background fstruct)
+      (push (format "background-color: %s;"
+		    (htmlize-fstruct-background fstruct))
+	    result))
+    (let ((size (htmlize-fstruct-size fstruct)))
+      (when (and size (not (eq htmlize-ignore-face-size t)))
+	(cond ((floatp size)
+	       (push (format "font-size: %d%%;" (* 100 size)) result))
+	      ((not (eq htmlize-ignore-face-size 'absolute))
+	       (push (format "font-size: %spt;" (/ size 10.0)) result)))))
+    (when (htmlize-fstruct-boldp fstruct)
+      (push "font-weight: bold;" result))
+    (when (htmlize-fstruct-italicp fstruct)
+      (push "font-style: italic;" result))
+    (when (htmlize-fstruct-underlinep fstruct)
+      (push "text-decoration: underline;" result))
+    (when (htmlize-fstruct-overlinep fstruct)
+      (push "text-decoration: overline;" result))
+    (when (htmlize-fstruct-strikep fstruct)
+      (push "text-decoration: line-through;" result))
+    (nreverse result)))
+
+(defun htmlize-css-insert-head (buffer-faces face-map)
+  (insert "    \n"))
+
+(defun htmlize-css-insert-text (text fstruct-list buffer)
+  ;; Insert TEXT colored with FACES into BUFFER.  In CSS mode, this is
+  ;; easy: just nest the text in one  tag for each
+  ;; face in FSTRUCT-LIST.
+  (dolist (fstruct fstruct-list)
+    (princ "" buffer))
+  (princ text buffer)
+  (dolist (fstruct fstruct-list)
+    (ignore fstruct)			; shut up the byte-compiler
+    (princ "" buffer)))
+ 
+;; `inline-css' output support.
+
+(defun htmlize-inline-css-body-tag (face-map)
+  (format ""
+	  (mapconcat #'identity (htmlize-css-specs (gethash 'default face-map))
+		     " ")))
+
+(defun htmlize-inline-css-insert-text (text fstruct-list buffer)
+  (let* ((merged (htmlize-merge-faces fstruct-list))
+	 (style (htmlize-memoize
+		 merged
+		 (let ((specs (htmlize-css-specs merged)))
+		   (and specs
+			(mapconcat #'identity (htmlize-css-specs merged) " "))))))
+    (when style
+      (princ "" buffer))
+    (princ text buffer)
+    (when style
+      (princ "" buffer))))
+ 
+;;; `font' tag based output support.
+
+(defun htmlize-font-body-tag (face-map)
+  (let ((fstruct (gethash 'default face-map)))
+    (format ""
+	    (htmlize-fstruct-foreground fstruct)
+	    (htmlize-fstruct-background fstruct))))
+       
+(defun htmlize-font-insert-text (text fstruct-list buffer)
+  ;; In `font' mode, we use the traditional HTML means of altering
+  ;; presentation:  tag for colors,  for bold,  for
+  ;; underline, and  for strike-through.
+  (let* ((merged (htmlize-merge-faces fstruct-list))
+	 (markup (htmlize-memoize
+		  merged
+		  (cons (concat
+			 (and (htmlize-fstruct-foreground merged)
+			      (format "" (htmlize-fstruct-foreground merged)))
+			 (and (htmlize-fstruct-boldp merged)      "")
+			 (and (htmlize-fstruct-italicp merged)    "")
+			 (and (htmlize-fstruct-underlinep merged) "")
+			 (and (htmlize-fstruct-strikep merged)    ""))
+			(concat
+			 (and (htmlize-fstruct-strikep merged)    "")
+			 (and (htmlize-fstruct-underlinep merged) "")
+			 (and (htmlize-fstruct-italicp merged)    "")
+			 (and (htmlize-fstruct-boldp merged)      "")
+			 (and (htmlize-fstruct-foreground merged) ""))))))
+    (princ (car markup) buffer)
+    (princ text buffer)
+    (princ (cdr markup) buffer)))
+ 
+(defun htmlize-buffer-1 ()
+  ;; Internal function; don't call it from outside this file.  Htmlize
+  ;; current buffer, writing the resulting HTML to a new buffer, and
+  ;; return it.  Unlike htmlize-buffer, this doesn't change current
+  ;; buffer or use switch-to-buffer.
+  (save-excursion
+    ;; Protect against the hook changing the current buffer.
+    (save-excursion
+      (run-hooks 'htmlize-before-hook))
+    ;; Convince font-lock support modes to fontify the entire buffer
+    ;; in advance.
+    (htmlize-ensure-fontified)
+    (clrhash htmlize-extended-character-cache)
+    (clrhash htmlize-memoization-table)
+    (let* ((buffer-faces (htmlize-faces-in-buffer))
+	   (face-map (htmlize-make-face-map (adjoin 'default buffer-faces)))
+	   ;; Generate the new buffer.  It's important that it inherits
+	   ;; default-directory from the current buffer.
+	   (htmlbuf (generate-new-buffer (if (buffer-file-name)
+					     (htmlize-make-file-name
+					      (file-name-nondirectory
+					       (buffer-file-name)))
+					   "*html*")))
+	   ;; Having a dummy value in the plist allows writing simply
+	   ;; (plist-put places foo bar).
+	   (places '(nil nil))
+	   (title (if (buffer-file-name)
+		      (file-name-nondirectory (buffer-file-name))
+		    (buffer-name))))
+      ;; Initialize HTMLBUF and insert the HTML prolog.
+      (with-current-buffer htmlbuf
+	(buffer-disable-undo)
+	(insert (htmlize-method doctype) ?\n
+		(format "\n"
+			htmlize-version htmlize-output-type)
+		"\n  ")
+	(plist-put places 'head-start (point-marker))
+	(insert "\n"
+		"    " (htmlize-protect-string title) "\n"
+		(if htmlize-html-charset
+		    (format (concat "    \n")
+			    htmlize-html-charset)
+		  "")
+		htmlize-head-tags)
+	(htmlize-method insert-head buffer-faces face-map)
+	(insert "  ")
+	(plist-put places 'head-end (point-marker))
+	(insert "\n  ")
+	(plist-put places 'body-start (point-marker))
+	(insert (htmlize-method body-tag face-map)
+		"\n    ")
+	(plist-put places 'content-start (point-marker))
+	(insert "
\n"))
+      (let ((insert-text-method
+	     ;; Get the inserter method, so we can funcall it inside
+	     ;; the loop.  Not calling `htmlize-method' in the loop
+	     ;; body yields a measurable speed increase.
+	     (htmlize-method-function 'insert-text))
+	    ;; Declare variables used in loop body outside the loop
+	    ;; because it's faster to establish `let' bindings only
+	    ;; once.
+	    next-change text face-list fstruct-list trailing-ellipsis)
+	;; This loop traverses and reads the source buffer, appending
+	;; the resulting HTML to HTMLBUF with `princ'.  This method is
+	;; fast because: 1) it doesn't require examining the text
+	;; properties char by char (htmlize-next-change is used to
+	;; move between runs with the same face), and 2) it doesn't
+	;; require buffer switches, which are slow in Emacs.
+	(goto-char (point-min))
+	(while (not (eobp))
+	  (setq next-change (htmlize-next-change (point) 'face))
+	  ;; Get faces in use between (point) and NEXT-CHANGE, and
+	  ;; convert them to fstructs.
+	  (setq face-list (htmlize-faces-at-point)
+		fstruct-list (delq nil (mapcar (lambda (f)
+						 (gethash f face-map))
+					       face-list)))
+	  ;; Extract buffer text, sans the invisible parts.  Then
+	  ;; untabify it and escape the HTML metacharacters.
+	  (setq text (htmlize-buffer-substring-no-invisible
+		      (point) next-change))
+	  (when trailing-ellipsis
+	    (setq text (htmlize-trim-ellipsis text)))
+	  ;; If TEXT ends up empty, don't change trailing-ellipsis.
+	  (when (> (length text) 0)
+	    (setq trailing-ellipsis
+		  (get-text-property (1- (length text))
+				     'htmlize-ellipsis text)))
+	  (setq text (htmlize-untabify text (current-column)))
+	  (setq text (htmlize-protect-string text))
+	  ;; Don't bother writing anything if there's no text (this
+	  ;; happens in invisible regions).
+	  (when (> (length text) 0)
+	    ;; Insert the text, along with the necessary markup to
+	    ;; represent faces in FSTRUCT-LIST.
+	    (funcall insert-text-method text fstruct-list htmlbuf))
+	  (goto-char next-change)))
+
+      ;; Insert the epilog and post-process the buffer.
+      (with-current-buffer htmlbuf
+	(insert "
") + (plist-put places 'content-end (point-marker)) + (insert "\n ") + (plist-put places 'body-end (point-marker)) + (insert "\n\n") + (when htmlize-generate-hyperlinks + (htmlize-make-hyperlinks)) + (htmlize-defang-local-variables) + (when htmlize-replace-form-feeds + ;; Change each "\n^L" to "
". + (goto-char (point-min)) + (let ((source + ;; ^L has already been escaped, so search for that. + (htmlize-protect-string "\n\^L")) + (replacement + (if (stringp htmlize-replace-form-feeds) + htmlize-replace-form-feeds + "

")))
+	    (while (search-forward source nil t)
+	      (replace-match replacement t t))))
+	(goto-char (point-min))
+	(when htmlize-html-major-mode
+	  ;; What sucks about this is that the minor modes, most notably
+	  ;; font-lock-mode, won't be initialized.  Oh well.
+	  (funcall htmlize-html-major-mode))
+	(set (make-local-variable 'htmlize-buffer-places) places)
+	(run-hooks 'htmlize-after-hook)
+	(buffer-enable-undo))
+      htmlbuf)))
+
+;; Utility functions.
+
+(defmacro htmlize-with-fontify-message (&rest body)
+  ;; When forcing fontification of large buffers in
+  ;; htmlize-ensure-fontified, inform the user that he is waiting for
+  ;; font-lock, not for htmlize to finish.
+  `(progn
+     (if (> (buffer-size) 65536)
+	 (message "Forcing fontification of %s..."
+		  (buffer-name (current-buffer))))
+     ,@body
+     (if (> (buffer-size) 65536)
+	 (message "Forcing fontification of %s...done"
+		  (buffer-name (current-buffer))))))
+
+(defun htmlize-ensure-fontified ()
+  ;; If font-lock is being used, ensure that the "support" modes
+  ;; actually fontify the buffer.  If font-lock is not in use, we
+  ;; don't care because, except in htmlize-file, we don't force
+  ;; font-lock on the user.
+  (when (and (boundp 'font-lock-mode)
+	     font-lock-mode)
+    ;; In part taken from ps-print-ensure-fontified in GNU Emacs 21.
+    (cond
+     ((and (boundp 'jit-lock-mode)
+	   (symbol-value 'jit-lock-mode))
+      (htmlize-with-fontify-message
+       (jit-lock-fontify-now (point-min) (point-max))))
+     ((and (boundp 'lazy-lock-mode)
+	   (symbol-value 'lazy-lock-mode))
+      (htmlize-with-fontify-message
+       (lazy-lock-fontify-region (point-min) (point-max))))
+     ((and (boundp 'lazy-shot-mode)
+	   (symbol-value 'lazy-shot-mode))
+      (htmlize-with-fontify-message
+       ;; lazy-shot is amazing in that it must *refontify* the region,
+       ;; even if the whole buffer has already been fontified.  
+       (lazy-shot-fontify-region (point-min) (point-max))))
+     ;; There's also fast-lock, but we don't need to handle specially,
+     ;; I think.  fast-lock doesn't really defer fontification, it
+     ;; just saves it to an external cache so it's not done twice.
+     )))
+
+ 
+;;;###autoload
+(defun htmlize-buffer (&optional buffer)
+  "Convert BUFFER to HTML, preserving colors and decorations.
+
+The generated HTML is available in a new buffer, which is returned.
+When invoked interactively, the new buffer is selected in the current
+window.  The title of the generated document will be set to the buffer's
+file name or, if that's not available, to the buffer's name.
+
+Note that htmlize doesn't fontify your buffers, it only uses the
+decorations that are already present.  If you don't set up font-lock or
+something else to fontify your buffers, the resulting HTML will be
+plain.  Likewise, if you don't like the choice of colors, fix the mode
+that created them, or simply alter the faces it uses."
+  (interactive)
+  (let ((htmlbuf (with-current-buffer (or buffer (current-buffer))
+		   (htmlize-buffer-1))))
+    (when (interactive-p)
+      (switch-to-buffer htmlbuf))
+    htmlbuf))
+
+;;;###autoload
+(defun htmlize-region (beg end)
+  "Convert the region to HTML, preserving colors and decorations.
+See `htmlize-buffer' for details."
+  (interactive "r")
+  ;; Don't let zmacs region highlighting end up in HTML.
+  (when (fboundp 'zmacs-deactivate-region)
+    (zmacs-deactivate-region))
+  (let ((htmlbuf (save-restriction
+		   (narrow-to-region beg end)
+		   (htmlize-buffer-1))))
+    (when (interactive-p)
+      (switch-to-buffer htmlbuf))
+    htmlbuf))
+
+(defun htmlize-region-for-paste (beg end)
+  "Htmlize the region and return just the HTML as a string.
+This forces the `inline-css' style and only returns the HTML body,
+but without the BODY tag.  This should make it useful for inserting
+the text to another HTML buffer."
+  (let* ((htmlize-output-type 'inline-css)
+	 (htmlbuf (htmlize-region beg end)))
+    (unwind-protect
+	(with-current-buffer htmlbuf
+	  (buffer-substring (plist-get htmlize-buffer-places 'content-start)
+			    (plist-get htmlize-buffer-places 'content-end)))
+      (kill-buffer htmlbuf))))
+
+(defun htmlize-make-file-name (file)
+  "Make an HTML file name from FILE.
+
+In its default implementation, this simply appends `.html' to FILE.
+This function is called by htmlize to create the buffer file name, and
+by `htmlize-file' to create the target file name.
+
+More elaborate transformations are conceivable, such as changing FILE's
+extension to `.html' (\"file.c\" -> \"file.html\").  If you want them,
+overload this function to do it and htmlize will comply."
+  (concat file ".html"))
+
+;; Older implementation of htmlize-make-file-name that changes FILE's
+;; extension to ".html".
+;(defun htmlize-make-file-name (file)
+;  (let ((extension (file-name-extension file))
+;	(sans-extension (file-name-sans-extension file)))
+;    (if (or (equal extension "html")
+;	    (equal extension "htm")
+;	    (equal sans-extension ""))
+;	(concat file ".html")
+;      (concat sans-extension ".html"))))
+
+;;;###autoload
+(defun htmlize-file (file &optional target)
+  "Load FILE, fontify it, convert it to HTML, and save the result.
+
+Contents of FILE are inserted into a temporary buffer, whose major mode
+is set with `normal-mode' as appropriate for the file type.  The buffer
+is subsequently fontified with `font-lock' and converted to HTML.  Note
+that, unlike `htmlize-buffer', this function explicitly turns on
+font-lock.  If a form of highlighting other than font-lock is desired,
+please use `htmlize-buffer' directly on buffers so highlighted.
+
+Buffers currently visiting FILE are unaffected by this function.  The
+function does not change current buffer or move the point.
+
+If TARGET is specified and names a directory, the resulting file will be
+saved there instead of to FILE's directory.  If TARGET is specified and
+does not name a directory, it will be used as output file name."
+  (interactive (list (read-file-name
+		      "HTML-ize file: "
+		      nil nil nil (and (buffer-file-name)
+				       (file-name-nondirectory
+					(buffer-file-name))))))
+  (let ((output-file (if (and target (not (file-directory-p target)))
+			 target
+		       (expand-file-name
+			(htmlize-make-file-name (file-name-nondirectory file))
+			(or target (file-name-directory file)))))
+	;; Try to prevent `find-file-noselect' from triggering
+	;; font-lock because we'll fontify explicitly below.
+	(font-lock-mode nil)
+	(font-lock-auto-fontify nil)
+	(global-font-lock-mode nil)
+	;; Ignore the size limit for the purposes of htmlization.
+	(font-lock-maximum-size nil)
+	;; Disable font-lock support modes.  This will only work in
+	;; more recent Emacs versions, so htmlize-buffer-1 still needs
+	;; to call htmlize-ensure-fontified.
+	(font-lock-support-mode nil))
+    (with-temp-buffer
+      ;; Insert FILE into the temporary buffer.
+      (insert-file-contents file)
+      ;; Set the file name so normal-mode and htmlize-buffer-1 pick it
+      ;; up.  Restore it afterwards so with-temp-buffer's kill-buffer
+      ;; doesn't complain about killing a modified buffer.
+      (let ((buffer-file-name file))
+	;; Set the major mode for the sake of font-lock.
+	(normal-mode)
+	(font-lock-mode 1)
+	(unless font-lock-mode
+	  ;; In GNU Emacs (font-lock-mode 1) doesn't force font-lock,
+	  ;; contrary to the documentation.  This seems to work.
+	  (font-lock-fontify-buffer))
+	;; htmlize the buffer and save the HTML.
+	(with-current-buffer (htmlize-buffer-1)
+	  (unwind-protect
+	      (progn
+		(run-hooks 'htmlize-file-hook)
+		(write-region (point-min) (point-max) output-file))
+	    (kill-buffer (current-buffer)))))))
+  ;; I haven't decided on a useful return value yet, so just return
+  ;; nil.
+  nil)
+
+;;;###autoload
+(defun htmlize-many-files (files &optional target-directory)
+  "Convert FILES to HTML and save the corresponding HTML versions.
+
+FILES should be a list of file names to convert.  This function calls
+`htmlize-file' on each file; see that function for details.  When
+invoked interactively, you are prompted for a list of files to convert,
+terminated with RET.
+
+If TARGET-DIRECTORY is specified, the HTML files will be saved to that
+directory.  Normally, each HTML file is saved to the directory of the
+corresponding source file."
+  (interactive
+   (list
+    (let (list file)
+      ;; Use empty string as DEFAULT because setting DEFAULT to nil
+      ;; defaults to the directory name, which is not what we want.
+      (while (not (equal (setq file (read-file-name
+				     "HTML-ize file (RET to finish): "
+				     (and list (file-name-directory
+						(car list)))
+				     "" t))
+			 ""))
+	(push file list))
+      (nreverse list))))
+  ;; Verify that TARGET-DIRECTORY is indeed a directory.  If it's a
+  ;; file, htmlize-file will use it as target, and that doesn't make
+  ;; sense.
+  (and target-directory
+       (not (file-directory-p target-directory))
+       (error "target-directory must name a directory: %s" target-directory))
+  (dolist (file files)
+    (htmlize-file file target-directory)))
+
+;;;###autoload
+(defun htmlize-many-files-dired (arg &optional target-directory)
+  "HTMLize dired-marked files."
+  (interactive "P")
+  (htmlize-many-files (dired-get-marked-files nil arg) target-directory))
+
+(provide 'htmlize)
+
+;;; htmlize.el ends here
diff --git a/auto-install/icicles-chg.el b/auto-install/icicles-chg.el
new file mode 100644
index 0000000..954a7a5
--- /dev/null
+++ b/auto-install/icicles-chg.el
@@ -0,0 +1,8375 @@
+;;; icicles-chg.el --- Change logs for Icicles libraries.
+;;
+;; Filename: icicles-chg.el
+;; Description: Change logs for Icicles libraries.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 2007-2011, Drew Adams, all rights reserved.
+;; Created: Tue Nov 27 07:47:53 2007
+;; Version: 22.0
+;; Last-Updated: Fri Sep  9 14:13:24 2011 (-0700)
+;;           By: dradams
+;;     Update #: 7120
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-chg.el
+;; Keywords: extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Change logs for Icicles libraries.
+;;
+;;  This file consolidates the change logs for all Icicles libraries.
+;;  It contains no code.
+;;
+;;  Libraries `icicles-doc1.el' and `icicles-doc2.el' contain only
+;;  documentation, and they do not have change logs.  Initially,
+;;  everything was in one library, `icicles.el', so its change log is
+;;  the oldest.
+;;
+;; ****************************************************************************************************
+;; NOTE: If you byte-compile Icicles (recommended), then WHENEVER `icicles-mac.el' is updated, you
+;;       must load `icicles-mac.el' (not just `icicles-mac.elc'), then compile it, then RECOMPILE *ALL*
+;;       of the other Icicles source files as well.  This is normal for Lisp: code that depends on
+;;       macros needs to be byte-compiled anew after loading the updated macros.
+;; ****************************************************************************************************
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "CHANGE LOG FOR `icicles-cmd1.el'")
+;;  (@> "CHANGE LOG FOR `icicles-cmd2.el'")
+;;  (@> "CHANGE LOG FOR `icicles-face.el'")
+;;  (@> "CHANGE LOG FOR `icicles-fn.el'")
+;;  (@> "CHANGE LOG FOR `icicles-mac.el'")
+;;  (@> "CHANGE LOG FOR `icicles-mcmd.el'")
+;;  (@> "CHANGE LOG FOR `icicles-mode.el'")
+;;  (@> "CHANGE LOG FOR `icicles-opt.el'")
+;;  (@> "CHANGE LOG FOR `icicles-var.el'")
+;;  (@> "CHANGE LOG FOR `icicles.el'")
+;;  (@> "CHANGE LOG FOR `icicles-cmd.el'" - Deprecated file)
+ 
+;;;(@* "CHANGE LOG FOR `icicles-cmd1.el'")
+;;
+;; 2011/09/02 dadams
+;;     icicle-completing-yank: Put kills in order, respecting kill-ring-yank-pointer.
+;;                             (put 'icicle-completing-yank 'delete-selection 'yank).
+;;     icicle-insert-for-yank: Set this-command to yank.
+;; 2011/08/30 dadams
+;;     icicle-yank-maybe-completing: Put delete-selection prop, so region is deleted.
+;; 2011/08/26 dadams
+;;     icicle-comint-dynamic-complete-as-filename, icicle-comint-dynamic-simple-complete,
+;;       icicle-bbdb-complete-name, icicle-explore, icicle-bookmark(-list|-other-window),
+;;       icicle-define-bookmark-command-1, icicle-find-tag-action,
+;;       icicle-kill-a-buffer-and-update-completions, icicle-color-theme,
+;;       icicle-delete-file-or-directory:
+;;         Use icicle-condition-case-no-debug instead of condition-case.  Thx to Michael Heerdegen.
+;;     Make sure to pass format string as first arg to calls to functions error and message.
+;; 2011/08/12 dadams
+;;     icicle-delete-file, icicle-(file|directory)-list, icicle-(dired|file)*,
+;;       icicle-find-file(-absolute|-read-only|in-tags-table)*, icicle-(recent|locate)-file*:
+;;         Use icicle-(un)bind-file-candidate-keys.  Don't do/undo such bindings individually here.
+;;     icicle-find-file-(absolute|in-tags-table)*, icicle-(recent|locate)-file*:
+;;       Bind icicle-full-cand-fn.
+;;     icicle-dired-(project|buffer)*: Removed fboundp test of icicle-bookmark-* (just test Bookmark+).
+;; 2011/08/11 dadams
+;;     icicle-find-file-absolute(-other-window):
+;;       Bind C-x a [+-] to adding/removing tags.
+;; 2011/08/09 dadams
+;;     icicle-define(-file)-command calls: Removed undo code if same as last code, so do not repeat it.
+;; 2011/08/07 dadams
+;;     icicle-(find-file-absolute|recent-file)(-other-window), icicle-locate-file-1,
+;;       icicle-cd-for-(abs|loc)-files:
+;;         Bind icicle-abs-file-candidates to the COLLECTION alist (no longer just list of strings).
+;; 2011/07/30 dadams
+;;     Moved to icicles-cmd2.el and wrapped in eval-after-load bookmark+.el:
+;;       icicle-find-file-(all|some)-tags(-regexp)(-other-window), icicle-(un)tag-a-file.
+;; 2011/07/26 dadams
+;;     Removed: icicle-list-end-string (no longer needed).  Thx to Michael Heerdegen.
+;; 2011/05/22 dadams
+;;     Added defvars for free vars to quiet byte compiler.
+;; 2011/05/21 dadams
+;;     icicle-customize-apropos(-options): let -> let* for interactive form.
+;; 2011/04/29 dadams
+;;     icicle-execute-extended-command(-1), icicle-command-abbrev(-action|-command),
+;;       icicle-execute-named-keyboard-macro, icicle-increment-(option|variable),
+;;       icicle-doremi-increment-variable+:
+;;         Renamed: orig-must-pass-after-match-predicate to icicle-orig-must-pass-after-match-pred,
+;;                  new-last-cmd to icicle-new-last-cmd.
+;; 2011/04/25 dadams
+;;     Commands defined with icicle-define-file-command and using icicle-file-bindings:
+;;       Remove binding for icicle-candidate-help-fn - done in icicles-mac.el now.
+;; 2011/04/13 dadams
+;;     Fixed autoload cookies for icicle-define-file-command commands added yesterday.
+;; 2011/04/12 dadams
+;;     Added: icicle-bookmark-save-marked-files(-as-project|-more|-persistently|-to-variable),
+;;            icicle-find-file-(all|some)-tags(-regexp)(-other-window), icicle-(un)tag-a-file.
+;;     icicle-bookmark(-list|-set|-other-window|-delete-action), icicle-define-bookmark-command-1:
+;;       Applied Bookmark+ renaming: bmkp-sort-and-remove-dups -> bmkp-sort-omit.
+;;     icicle-bookmark-set: Fixed typo: bmkp-light-bookmarks-this-buffer -> bmkp-light-this-buffer. 
+;;     icicle-define-bookmark-command-1: Doc strings now mention corresponding Bookmark+ command.
+;;     icicle-execute-extended-command-1:
+;;       Apply icicle-transform-multi-completion to arg.  Thx to Michael Heerdegen.
+;; 2011/04/04 dadams
+;;     icicle-bookmark-jump-1, icicle-pop-tag-mark: Use icicle-recenter.
+;; 2011/04/02 dadams
+;;     Added: icicle-bookmark-file-this-dir((-all|some)-tags(-regexp))(-other-window),
+;;            icicle-locate-file-(action-fn|no-symlinks-p).
+;;     icicle-kmacro(-action), icicle-clear(-current)-history(-1):
+;;       Use (new) icicle-pref-arg, not pref-arg.
+;;     icicle(-kill|-insert)-buffer(-other-window), icicle-default-buffer-names,
+;;       icicle-filter-buffer-cands-for-mode, icicle-add-buffer-candidate:
+;;         Use (new) icicle-bufflist, not bufflist.
+;;     icicle-locate-file(-1|-no-symlinks)(-other-window):
+;;       Use (new) icicle-locate-file-no-symlinks-p, not no-symlinks-p.
+;; 2011/03/31 dadams
+;;     icicle-search-action-1: Applied renaming: i*-target-window-recenter-amount to icicle-recenter.
+;;     icicle-customize-apropos-options-of-type: Wrap icicle-var-is-of-type-p with condition-case.
+;; 2011/03/29 dadams
+;;     Use new icicle-* vars for various free vars (orig-buff etc.).
+;; 2011/03/26 dadams
+;;     Added: icicle-bookmark-file-(all|some)-tags(-regexp)(-other-window).
+;; 2011/02/22 dadams
+;;     Added: icicle-lisp-completion-at-point.
+;; 2011/01/06 dadams
+;;     Added: icicle-filter-buffer-cands-for-mode.
+;;     icicle-(kill|insert)-buffer, icicle-buffer(-other-window), icicle-add-buffer-candidate:
+;;       Bind C-x M to icicle-filter-buffer-cands-for-mode.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     Added more autoload cookies for cmds & macros; removed from non-cmd fns.  Thx to Richard Kim.
+;;       Specify cmd and file for cmds defined by Icicles macros.
+;;     Require icicles-opt.el before icicles-var.el (but it makes no difference).
+;; 2010/11/21 dadams
+;;     defalias both old-lisp-complete-symbol and (for Emacs 23+) old-lisp-completion-at-point.
+;; 2010/11/10 dadams
+;;     icicle-lisp-complete-symbol: Remove return value.  Let it do everything (chg is in ici*mode.el).
+;; 2010/11/04 dadams
+;;     icicle-lisp-complete-symbol: Fixed return value for Emacs 23.2+.  Thx to Michael Heerdegen.
+;; 2010/11/03 dadams
+;;     defalias old-lisp-completion-at-point, not old-lisp-complete-symbol, for Emacs 23.2+.
+;;     icicle-lisp-complete-symbol:
+;;       Explicitly return nil, for use in completion-at-point-functions (Emacs 23.2+).
+;; 2010/10/25 dadams
+;;     icicle-buffer-list: Use icicle-must-pass-after-match-predicate, not icicle-must-pass-predicate.
+;;     icicle-directory-list:
+;;       Bind icicle-file-predicate instead of using PREDICATE arg.  No emacs-version limit now. 
+;; 2010/10/24 dadams
+;;     icicle-customize-apropos(-faces|-groups|-options(-of-type)), icicle-execute-extended-command,
+;;       icicle-command-abbrev, icicle-execute-named-keyboard-macro, icicle-(re)set-option-to-(t|nil),
+;;       icicle-toggle-option, icicle-increment-(option|variable), icicle-doremi-increment-variable+:
+;;         Use icicle-must-pass-after-match-predicate, not PREDICATE arg.
+;;     icicle-execute-extended-command-1, icicle-command-abbrev-action,
+;;       icicle-increment-(option|variable), icicle-doremi-increment-variable+:
+;;         Restore orginal icicle-must-pass-after-match-predicate.
+;; 2010/10/09 dadams
+;;     icicle-customize-face, icicle-repeat-complex-command, icicle-delete-window:
+;;       Updated doc string for new prefix and modal cycling keys.
+;; 2010/08/27 dadams
+;;     icicle-pp-display-expression: Set the hooks locally instead of let-binding them, to avoid msg
+;;                                   "Making change-major-mode-hook buffer-local while locally
+;;                                   let-bound!" - suggestion from Stefan M.
+;; 2010/07/20 dadams
+;;     icicle-find-file-in-tags-table(-other-window):
+;;       Pick up default-directory of TAGS table.  Thx to Chris Hecker.
+;;     icicle-bookmark-jump-1: Applied renaming of bmkp-use-region-flag to bmkp-use-region.
+;; 2010/07/17 dadams
+;;     Added: icicle-bookmark-url-narrow, icicle-bookmark-url(-other-window).
+;;     icicle-bookmark(-list|-set|-other-window|-propertize-candidate|-help-string),
+;;       icicle-define-bookmark-command-1: w3m -> url.
+;;     Bound URL commands to C-M-u, C-x j u.
+;; 2010/07/02 dadams
+;;     icicle-bookmark-set: Added INTERACTIVEP arg.  Prompt for tags when bmkp-prompt-for-tags-flag.
+;;                          Highlight bookmark if bmkp-auto-light-when-set.
+;;     icicle-bookmark-cmd: Call icicle-bookmark-set with new INTERACTIVEP arg.
+;; 2010/06/25 dadams
+;;     icicle-find-file(-other-window):
+;;       Use default-directory, not nil, as third arg to read-file-name.  Thx to Thomas Lim.
+;;       Note: This more or less reverts a change I made (why?) on 2008/12/27 (see that, below).
+;; 2010/06/18 dadams
+;;     Renamed: bookmarkp-* to bmkp-*.
+;; 2010/06/11 dadams
+;;     icicle-find-file-absolute*, icicle-recent-file*, icicle-locate-file-1:
+;;       Bind C-c + to icicle-make-directory.
+;;     icicle-find-file-in-tags-table*: Removed bindings: C-x m, C-backspace.
+;; 2010/06/10 dadams
+;;     icicle-cd-for-abs-files: Bound enable-recursive-minibuffers to t.
+;; 2010/06/08 dadams
+;;     Added: icicle-bookmark-delete-action: Make it refresh the cache.
+;;     icicle-bookmark(-list|-other-window), icicle-define-bookmark-command-1:
+;;       Use icicle-bookmark-delete-action.
+;;       Use condition-case to filter out bad bookmarks (so no error).  Thx to M. Heerdegen.
+;; 2010/06/04 dadams
+;;     Applied renamings of doremi commands (added +).
+;;     icicle-(buffer|*file|directory)*: Updated doc string to mention icicle-(buffers|files)-ido-like.
+;; 2010/05/30 dadams
+;;     Added: icicle-locate-file-no-symlinks(-other-window), icicle-locate-file(-other-window)-action,
+;;            icicle-locate-file-1.
+;;     icicle-locate-file*: Moved body to icicle-locate-file-1.  Use named action functions.
+;;                          Respect icicle-ignored-directories (via *-files-within).
+;;     icicle-cd-for-loc-files: Added optional arg NO-SYMLINKS-P.
+;;     icicle-dired-saved-file-candidates(-other-window): Handle multi-completion candidates.
+;;     Thx to M. Heerdegen.
+;; 2010/05/28 dadams
+;;     icicle-(recent|locate)-file(-other-window), 
+;;       Use *-transform-multi-completion in *-all-candidates-list-alt-action-fn.  Thx to M. Heerdegen.
+;; 2010/05/27 dadams
+;;     icicle-cd-for-loc-files: Wrap interactive spec in save-selected-window.  Thx to M. Heerdegen.
+;; 2010/05/26 dadams
+;;     icicle-bookmark-set: Removed pseudo-default.  Thx to Michael Heerdegen.
+;; 2010/05/24 dadams
+;;     icicle-comint-replace-orig-completion-fns: Rewrote to not use case.  Thx to Michael Heerdegen.
+;; 2010/05/21 dadams
+;;     icicle-bookmark-help-string:
+;;       Use BOOKMARK-NAME, not BMK, as arg to vanilla fns, for Emacs < 23.  Thx to Alexander Haeckel.
+;; 2010-05-18 dadams
+;;     Added: icicle-cd-for-abs-files, icicle-cd-for-loc-files.
+;;     icicle-find-file-absolute*, icicle-locate-file*: Bind C-c C-d to icicle-cd-for-(abs|loc)-files.
+;;     icicle-locate-file*: Make icicle-list-use-nth-parts be nil if no non-positive prefix arg.
+;; 2010/05/16 dadams
+;;     icicle-define-bookmark-command-1: Defined command requires bookmark+.el.
+;;     Added: icicle-bookmark-specific-(buffers|files)-narrow, icicle-bookmark-this-buffer-narrow.
+;;     icicle-bookmark(-other-window), icicle-bookmark-set:
+;;       Bound C-M-= (b|f), C-M-. for narrowing to specific-(buffers|files), this-buffer.
+;;     icicle-bookmark-cleanup: Updated for added narrowing keys.
+;; 2010/05/15 dadams
+;;     Added: icicle-define-bookmark-command(-1).  Added ARGS param for use as arg for *-alist-only.
+;;     Added same-window commands for bookmark jumping.
+;;     Added: *-specific-(buffers|files)*, *-this-buffer*, *-(all|some)-tags(-regexp)* jump commands,
+;;            *-bookmarked-(buffer|file)-list.
+;;     icicle-bookmark-set: *-selected-buffers-alist-only -> *-specific-buffers-alist-only.
+;; 2010/05/06 dadams
+;;     icicle-bookmark-set: Removed spurious format call with its arg.
+;; 2010/04/29 dadams
+;;     icicle-explore: Bind icicle-remove-icicles-props-p to nil around call to completing-read.
+;;                     Call icicle-unpropertize at the end (without that binding).
+;; 2010/04/20 dadams
+;;     icicle-dired(-other-window): Use icicle-dirs-first-p, not icicle-dirs-last-p, and don't reverse.
+;; 2010/04/17 dadams
+;;     Added: icicle-bookmark-set.
+;;     icicle-bookmark-cmd: Use icicle-bookmark-set, not bookmark-set.  Simpler PARG code in that case.
+;;     icicle-bookmark(-list|-other-window), icicle-define-bookmark-other-window-command:
+;;       Use icicle-transform-multi-completion in icicle-delete-candidate-object.
+;; 2010/04/10 dadams
+;;     Corrected prefix arg use for icicle-find-file(-read-only)(-other-window).  Thx to M. Heerdegen.
+;; 2010/04/09 dadams
+;;     Added: icicle-find-file-read-only(-other-window).
+;;     icicle-find-file(-other-window):
+;;       Prefix arg on individual candidate means visit read-only.
+;;       Prefix arg for the command means reverse the prefix arg effect: read-only for all by default.
+;; 2010/04/02 dadams
+;;     Added: icicle-bookmark-list.
+;;     icicle-bookmark-cleanup: Clean up both minibuffer maps.
+;; 2010/03/27 dadams
+;;     icicle-define-bookmark-other-window-command: Use optional PROMPT arg.
+;; 2010/03/19 dadams
+;;     icicle-define-bookmark-other-window-command: Rich multi-completions per icicle-bookmark.
+;; 2010/03/16 dadams
+;;     icicle-bookmark(-other-window):
+;;       Use tags, not just file names, in the multi-completions.
+;;       Use the default join string, ^G^J, and end string, ^J^J.
+;;       Use just icicle-candidate-properties-alist to highlight the file name.
+;;       Remove extra quote marks from face names.
+;; 2010/03/14 dadams
+;;     icicle-bookmark(-other-window):
+;;       Copy file/buffer name string for candidate-part face, so we don't touch bookmark-alist.
+;;       Handle icicle-bookmark-refresh-cache-flag and C-u.
+;;       Bind the narrow keys in minibuffer-local-completion also (lax for multi-completion).
+;;       Use face file-name-shadow, not icicle-candidate-part (too distracting).
+;;     icicle-bookmark-*-narrow: Use icicle-get-alist-candidate-function.
+;;     icicle-define-bookmark-other-window-command: Rewrote to handle multi-completion.
+;;     icicle-bookmark-non-file-narrow: Use bookmarkp-non-file-bookmark-p.
+;;     icicle-bookmark-propertize-candidate: Typo in a face name.
+;; 2010/03/13 dadams
+;;     icicle-bookmark(-other-window):
+;;       If Bookmark+ available then, depending on icicle-show-multi-completion-flag, use a
+;;         multi-completion showing file or buffer.  Use icicle-candidates-alist to do that.
+;;       Don't put icicle-fancy-candidates prop on prompt.
+;;       Don't use icicle-sorted-bookmark-alist (removed).  Recompute each time.
+;; 2010/03/10 dadams
+;;     icicle-bookmark-help-string:
+;;       Mention the type in the help: sequence, function, bookmark list, desktop, etc.
+;;       Don't show position for types that don't use one.  Don't show file for buffer & Dired.
+;; 2010/03/09 dadams
+;;     icicle-color-theme: Initialize variable icicle-color-themes here, not in icicles-opt.el.
+;; 2010/03/04 dadams
+;;     icicle-bookmark(-other-window): Use bookmarkp-describe-bookmark(-internals) for C-M-RET.
+;; 2010/03/03 dadams
+;;     icicle-bookmark(-other-window), icicle-define-bookmark-other-window-command:
+;;       Use bookmarkp-sort-and-remove-dups.
+;;       Bind icicle-sort-orders-alist, using bookmarkp predicates.
+;;     icicle-bookmark(-other-window):
+;;       Set icicle-sorted-bookmark-alist and bookmarkp-sorted-alist.
+;;       Use bookmarkp-sorted-alist.
+;;       Don't append original icicle-sort-orders-alist.  Just include a couple of its entries.
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer,
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist.
+;; 2010/02/28 dadams
+;;     icicle-send-bug-report: Formatted body a bit.
+;; 2010/02/14 dadams
+;;     Added: icicle-bookmark-bookmark-list-other-window, icicle-bookmark-bookmark-list-narrow.
+;;     icicle-bookmark(-other-window):
+;;       Bound to C-M- prefix: icicle-bookmark-bookmark-list-narrow.  Updated doc string.
+;; 2010/02/13 dadams
+;;     Added: icicle-bookmark-(desktop|man)-other-window,
+;;            icicle-bookmark-(dired|desktop|man)-narrow.
+;;     icicle-define-bookmark-other-window-command: Raise error if bookmark+.el not found.
+;;     icicle-bookmark(-other-window):
+;;       Bound to C-M- prefix: icicle-bookmark-(dired|desktop|man)-narrow.
+;;     icicle-bookmark-propertize-candidate:
+;;       Handle also: sequence, function, bookmark list, desktop, man, buffer, bad bookmarks.
+;; 2010/02/02 dadams
+;;     icicle-bookmark-jump-1: Don't select minibuffer window and give it focus.
+;; 2010/01/30 dadams
+;;     icicle-dired(-other-window), icicle-(find|recent|locate)-file(-absolute)(-other-window)
+;;       icicle-find-file-in-tags-table(-other-window):
+;;         Bind icicle-all-candidates-list-alt-action-fn to open Dired on matching files.
+;; 2010/01/13 dadams
+;;     icicle-recent-file(-other-window):
+;;       Restore C-S-RET as icicle-remove-from-recentf-candidate-action (accidentally removed).
+;; 2010/01/12 dadams
+;;     Added: icicle-pp-display-expression.
+;;     icicle-pp-eval-expression: Use icicle-pp-display-expression.
+;;     icicle-bbdb-complete-name: save-excursion + set-buffer -> with-current-buffer.
+;; 2009/12/21 dadams
+;;     fset -> defalias.
+;; 2009/12/13 dadams
+;;     Added: icicle-bookmark-dired-other-window, icicle-dired(-other-window).
+;;     *-buffer*, *-dired-project*, *-find-file(-absolute)*, *-(recent|locate)-file*,
+;;       *-find-file-in-tags-table*:
+;;         Bind C-x m to icicle-bookmark-(non-file|dired|file)-other-window.
+;; 2009/11/27 dadams
+;;     Added: icicle(-doremi)-increment-(variable|option).
+;; 2009/11/25 dadams
+;;     icicle-color-theme: Raise error for empty input.  Thx to Ahei.
+;; 2009/11/24 dadams
+;;     icicle-color-theme: Take a snapshot each time invoked, unless prefix arg.
+;; 2009/11/22 dadams
+;;     icicle-color-theme: Use color-theme-initialize instead of load-library, to load themes.
+;; 2009/11/21 dadams
+;;     icicle-color-theme: Use color-theme-snapshot to let C-g undo changes.
+;;                         Try to load color-theme-library.el (available with version 6.6.0).
+;; 2009/11/17 dadams
+;;     icicle-bbdb-complete-name: Bind completion-case-ignore.
+;; 2009/11/14 dadams
+;;     icicle-bbdb-complete-name: Replace macro bbdb-hashtable by its expansion.
+;; 2009/09/21 dadams
+;;     icicle-lisp-complete-symbol:
+;;       Complete symbol in buffer as far as possible first.  Show completions initially.
+;; 2009/09/17 dadams
+;;     icicle-delete-file, icicle-(file|directory)-list,
+;;       icicle-find-file(-absolute)(-other-window),
+;;       icicle-(recent|locate)-file(-other-window),
+;;       icicle-find-file-in-tags-table(-other-window): Use icicle-file-bindings (new macro).
+;; 2009/09/16 dadams
+;;     Added: icicle-insert-buffer.
+;;     icicle-kill-buffer, icicle-buffer(-other-window), icicle-add-buffer-candidate:
+;;       Use icicle-buffer-bindings (new macro).
+;; 2009/08/29 dadams
+;;     Added: icicle-define-bookmark-other-window-command, icicle-select-bookmarked-region,
+;;            icicle-bookmark(-region|-info|-gnus|-w3m|(-non|-local|-remote)-file)-other-window.
+;;     icicle-bookmark-propertize-candidate: Updated to reflect renamed bookmark+.el face names.
+;;     icicle-bookmark-file-narrow: Use bookmarkp-file-bookmark-p.
+;;     (lambda...) -> #'(lambda...).
+;; 2009/08/25 dadams
+;;     Added: icicle-bookmark-cleanup-on-quit.
+;;     icicle-bookmark(-other-window): Use icicle-bookmark-cleanup-on-quit.
+;;     icicle-bookmark-cleanup: Removed code to return to original window a focus minibuffer.
+;; 2009/08/24 dadams
+;;     Added: icicle-bookmark-propertize-candidate.
+;;     icicle-bookmark(-other-window): Put faces on bookmark candidates according to type.
+;; 2009/08/23 dadams
+;;     Added: icicle-bookmark-(region|info|gnus|w3m|(non-|local-|remote-)file)-narrow.
+;;     icicle-bookmark(-other-window): Bind keys to bookmark candidate narrowing commands.
+;;     icicle-bookmark-cleanup: Unbind the same commands.
+;;     icicle-bookmark-cmd:
+;;       Let bookmark+.el (latest version) handle prompting for name, even for region bookmark.
+;;       Remove any newlines in bookmark name, when no prompting (thx to Thierry Volpiatto).
+;; 2009/08/21 dadams
+;;     icicle-bookmark-jump-1: Typo.
+;; 2009/08/20 dadams
+;;     icicle-bookmark-cmd: Use icicle-bookmark-other-window, not icicle-bookmark.
+;;                          Fix trimmed-name: no longer than def-name.
+;;     icicle-bookmark(-other-window): Bind enable-recursive-minibuffers, in case need to read.
+;;     icicle-bookmark-jump-1: No crosshair highlighting for region bookmarks.
+;; 2009/08/19 dadams
+;;     Added: icicle-bookmark-help-string.
+;;     icicle-bookmark-cmd: Handle creation of region bookmarks (new default values).
+;;                          icicle-bookmark-name-length-max now applies to whole bookmark name.
+;;     icicle-bookmark(-other-window):
+;;       Apply icicle-candidate-short-help to candidates.  Use also for the help function.
+;;     icicle-bookmark-jump-1: Use bookmark--jump-via if it is defined.
+;; 2009/06/21 dadams
+;;     icicle-bookmark-jump-1: Removed temporary Emacs 23 workaround for (fixed) bug #1175.
+;; 2009/06/07 dadams
+;;     icicle-get-alist-candidate -> funcall icicle-get-alist-candidate-function.
+;; 2009/05/22 dadams
+;;     Require icicles-mac.el if load-library doesn't find it.
+;;     Created - Split off from icicles-cmd.el.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-cmd2.el'")
+;;
+;; 2011/09/09 dadams
+;;     icicle-search-w-isearch-string: Added prefix-arg treatment.
+;; 2011/09/08 dadams
+;;     Added: icicle-search-w-isearch-string, from a lambda in icicles-mode.el.
+;; 2011/09/05 dadams
+;;     icicle-imenu-*: Others -> Other, as submenu name.
+;;     icicle-search, icicle-imenu*-full: Mention C-x . in doc strings.
+;; 2011/09/04 dadams
+;;     icicle-add-key+cmd: Handle Emacs 23+ consp char-range events, for self-insert.
+;;                         Applied renaming of icicle-complete-keys-self-insert-flag to *-ranges.
+;;     Removed: icicle-insert-char.
+;; 2011/09/02 dadams
+;;     Removed: icicle-Info-index-cmd, icicle-Info-menu-cmd, icicle-Info-goto-node-cmd.
+;;     icicle-Info-index(-20|-action): Use old-Info-index.
+;;     icicle-Info-goto-node-1: Use old-Info-goto-node.
+;; 2011/08/27 dadams
+;;     icicle-search-char-property-scan: Added optional ACTION arg.  Move hit-end after ACTION.
+;;     Added: icicle-imenu-1.  Created from old icicle-imenu*, but: (1) added args FULLP for full,
+;;            SUBMENU-FN to pick submenu, (2) pass PREDICATE and pos after forward-sexp for FULLP.
+;;     icicle-imenu, icicle-imenu-command: Use icicle-imenu-1.
+;;     Added: icicle-imenu(-command|-non-interactive-function)-full, icicle-search-defs-full,
+;;            icicle-imenu-(macro|variable|user-option|face|key-(implicit|explicit)-map)(-full), 
+;;     icicle-apply-action, icicle-apply-list-action, icicle-search-regexp-scan,
+;;       icicle-search-action-1, icicle-search-bookmark, icicle-define-search-bookmark-command,
+;;       icicle-search-thing-scan, icicle-search-char-property-scan:
+;;         Use icicle-condition-case-no-debug instead of condition-case.  Thx to Michael Heerdegen.
+;; 2011/08/26 dadams
+;;     icicle-imenu:
+;;       When multiple Others menus, name them uniquely.
+;;       When only one submenu, just use it (no choosing).
+;;     icicle-complete-keys-action: Removed useless condition-case.
+;;     Make sure to pass format string as first arg to calls to functions error and message.
+;; 2011/08/17 dadams
+;;     icicle-search-thing-scan: Use correct code (not 1+) also if thingatpt+.el is loaded.
+;;     icicle-search-regexp-scan: Quit while loop if no more match, except if complementing.
+;;     icicle-search-read-context-regexp, icicle-search-(thing|property)-args, icicle-tags-search:
+;;       Change prompt when complementing (add: *NOT*).
+;; 2011/08/16 dadams
+;;     icicle-maybe-byte-compile-after-load the eval-after-load definitions.
+;; 2011/08/14 dadams
+;;     icicle-search-thing-scan: Handle icicle-search-complement-domain-p.
+;;     Updated doc strings of search commands to mention complementing.
+;;     icicle-imenu(-command|-non-interactive-function), icicle-complete-keys-1:
+;;       Replaced mapc with dolist so do not require cl.el at runtime (Emacs 20).
+;;     icicle-imenu: Ignore case when completing to the type (function etc.). 
+;; 2011/08/13 dadams
+;;     Added: icicle-bookmark-a-file.
+;;     icicle-search-regexp-scan, icicle-search-char-property-scan:
+;;       Handle icicle-search-complement-domain-p.
+;; 2011/08/12 dadams
+;;     icicle-find-file-tagged(-other-window): 
+;;       Bind icicle-full-cand-fn.  Use icicle-file-bindings.
+;;       Use icicle-(un)bind-file-candidate-keys.  Don't do/undo such bindings individually here.
+;; 2011/08/09 dadams
+;;     icicle-find-file-tagged(-other-window): Bind C-x a [+-] to adding/removing tags.
+;;     icicle-define(-file)-command calls: Removed undo code if same as last code, so do not repeat it.
+;; 2011/08/08 dadams
+;;     icicle-find-file-tagged(-other-window): Prefix arg means use all (not just tagged) autofiles.
+;; 2011/08/07 dadams
+;;     Added: icicle-find-file-tagged(-other-window).
+;; 2011/08/05 dadams
+;;     icicle-(un)tag-a-file: Bind icicle-use-candidates-only-once-flag to t.
+;; 2011/07/31 dadams
+;;     Added: icicle-search-xml-element-text-node.
+;;     icicle-search-thing(-scan): Added TRANSFORM-FN arg.
+;;     icicle-search-define-candidates: Added message when only one candidate.
+;; 2011/07/30 dadams
+;;     Moved here from icicles-cmd1.el and wrapped in eval-after-load bookmark+.el:
+;;       icicle-find-file-(all|some)-tags(-regexp)(-other-window), icicle-(un)tag-a-file.
+;;     Moved here from synonyms.el and wrapped in eval-after-load synonyms.el: (icicle)-synonyms.
+;;     Moved here from icicles-fn.el and wrapped in eval-after-load hexrgb.el:
+;;       icicle-color-*-lessp (except -rgb-), icicle-color-completion-setup, icicle-color-help,
+;;        icicle-make-color-candidate.
+;;     Soft-require hexrgb.el only when byte-compile.
+;;     icicle-frame-(bg|fg), icicle-read-color: Wrap in eval-after-load hexrgb.el.
+;;     icicle-(insert|complete)-thesaurus-entry(-cand-fn): Wrap in eval-after-load synonyms.el.
+;;     icicle-choose(-(in)visible)-faces, icicle-(hide|show)(-only)-faces:
+;;       Use eval-after-load highlight.el, not featurep.
+;;     icicle-pick-color-by-name(-action), palette keys: Use eval-after-load palette.el, not featurep.
+;; 2011/07/27 dadams
+;;     icicle-search-read-word: Changed regexp to what vanilla Emacs uses for word search.
+;;     icicle-search(-word): Updated doc string wrt word search.
+;; 2011/07/26 dadams
+;;     Removed: icicle-list-end-string (no longer needed).  Thx to Michael Heerdegen.
+;; 2011/07/24 dadams
+;;     Moved here from palette.el, and renamed with prefix icicle-:
+;;       icicle-pick-color-by-name, icicle-pick-color-by-name-action
+;;     Moved here from highlight.el, and renamed with prefix icicle- (from hlt-) and suffix -faces:
+;;       icicle-(hide|show)(-only)-faces, icicle-choose(-(in)visible)-faces.
+;;     Added: icicle-invisible-face-p.
+;;     icicle-choose(-(in)visible)-faces: Corrected:
+;;       Lax if icicle-WYSIWYG-Completions-flag.  Put icicle-fancy-candidates on prompt.
+;;       Use icicle-list-*, for multi-completions.  Use icicle-invisible-face-p to test invisibility.
+;;     Added eval-when-compile with soft requires for bookmark+.el and highlight.el.
+;; 2011/07/18 dadams
+;;     icicle-search-thing, icicle-search-thing-scan:
+;;       Moved normalizing BEG, END to *-scan, for multiple buffers case.  Thx to M. Heerdegen.
+;; 2011/07/13 dadams
+;;     icicle-search-replace-cand-in-mct: Changed <= to < for len-rep.  Thx to M. Heerdegen.
+;; 2011/07/04 dadams
+;;     icicle-search-in-context-default-fn:
+;;       Bound icicle-last-completion-candidate, icicle-completion-candidates.  Thx to M. Heerdegen.
+;; 2011/07/02 dadams
+;;     Added: icicle-defined-thing-p.
+;;     icicle-things-alist: Use icicle-defined-thing-p.  Thx to Michael Heerdegen.
+;; 2011/06/03 dadams
+;;     Replace icicle-help-in-mode-line-flag by icicle-help-in-mode-line-delay everywhere.
+;; 2011/05/25 dadams
+;;     icicle-fundoc, icicle-vardoc, icicle-plist:
+;;       Use icicle-doc-action only.  Bind icicle-list-use-nth-parts to (1).  Thx to Michael Heerdegen.
+;; 2011/05/24 dadams
+;;     icicle-invisible-p: Use invisible-p if available (Emacs 22+).
+;; 2011/05/22 dadams
+;;     Added defvars for free vars to quiet byte compiler.
+;; 2011/05/16 dadams
+;;     icicle-search-thing-args: Message about C-M-; when ignoring comments and THING is comment.
+;; 2011/05/15 dadams
+;;     Added: icicle-search-xml-element.
+;;     icicle-search-thing, icicle-search-thing-scan: Added PREDICATE optional arg.
+;; 2011/05/14 dadams
+;;     Added: icicle-things-alist.
+;;     icicle-search-thing-args, icicle-(next|previous)-visible-thing:
+;;       Use icicle-things-alist, not (now removed) option icicle-thing-types.
+;;     icicle-next-visible-thing-1: Change comparison to < from <=
+;;     Removed: icicle-defined-thing-p (not used).
+;; 2011/05/13 dadams
+;;     Renamed: icicle-last-visible-thing-type to icicle-last-thing-type.
+;;     icicle-last-thing-type: Use thgcmd-last-thing-type value as default, if available.
+;;     icicle-search-thing: Ensure BEG is before END (swap if needed).
+;;     icicle-search-thing-args, icicle-(next|previous)-visible-thing:
+;;       Use completing-read, not read-string, to read thing type.
+;;     icicle-(next|previous)-visible-thing: Do not set this-command (no need).
+;;     icicle-search-thing-scan: Removed code defining BEG, END if nil.  Go to BEG, not min BEG, END.
+;;     icicle-next-visible-thing-2: Do not return an empty thing.
+;; 2011/05/11 dadams
+;;     Added: icicle-invisible-p, icicle-previous-single-char-property-change.
+;;     icicle-search-thing-scan:
+;;       Handle also text invisible due to overlay, and invisible prop other than t.
+;;     icicle-next-visible-thing-2: Separate handling overlay and text prop.  Use icicle-invisible-p.
+;; 2011/05/10 dadams
+;;     Added: icicle-last-visible-thing-type, icicle-previous-visible-thing,
+;;            icicle-next-visible-thing-(and-bounds|1|2).
+;;     Alias icicle-next-visible-thing-(1|2) to the same commands from thing-cmds.el.
+;;     icicle-search-thing-scan:
+;;       Use when, not while, to skip over invisible (since use next-single-property-change).
+;;       Use new icicle-next-visible-and-bounds, so save-excursion and goto min.
+;;     Old icicle-next-visible is now ~ *-2, but that handles backward too.  New one is a command.
+;; 2011/05/07 dadams
+;;     Added: icicle-with-comments-hidden, icicle-hide/show-comments, icicle-search-thing,
+;;              icicle-defined-thing-p, icicle-next-visible-thing, icicle-search-thing-args,
+;;              icicle-search-thing-scan.
+;;     icicle-search: Doc string tweak.
+;; 2011/05/04 dadams
+;;     icicle-search-read-context-regexp: Changed prompt to make clear that we search within contexts.
+;;     icicle-search-define-candidates: Remove any region highlighting, so we can see search hits.
+;; 2011/04/29 dadams
+;;     icicle-choose-candidate-of-type: Rewrote buffer bindings based on icicle-buffer-bindings.
+;; 2011/04/26 dadams
+;;     Added: icicle-search-autofile-bookmark.
+;; 2011/04/12 dadams
+;;     Added: icicle-search-bookmark-list-marked, icicle-named-colors.
+;;     icicle-search-bookmark, icicle-define-search-bookmark-command:
+;;       Applied Bookmark+ renaming: bmkp-sort-and-remove-dups -> bmkp-sort-omit.
+;;     icicle-comint-search: Improved doc string (don't use C-next etc.).
+;;     icicle-frame-(bg|fg), icicle-read-color: Rename free var named-colors to icicle-named-colors.
+;;       Bind it in icicle-frame-(bg|fg), icicle-read-color, for use in icicle-color-completion-setup.
+;; 2011/04/04 dadams
+;;     icicle-insert-thesaurus-entry-cand-fn, icicle-goto-marker-1-action, icicle-search-final-act,
+;;       icicle-comint-search:  Use icicle-recenter.
+;; 2011/04/02 dadams
+;;     Added: icicle-info-(buff|window), icicle-key-prefix(-2), icicle-active-map,
+;;     Moved here from icicles-var.el:
+;;       icicle-orig-buff-key-complete, icicle-orig-extra-cands, icicle-orig-font, icicle-orig-frame,
+;;       icicle-orig-menu-bar, icicle-orig-pixelsize, icicle-orig-pointsize, icicle-this-cmd-keys,
+;;       icicle-orig-show-initially-flag, icicle-orig-sort-orders-alist, icicle-orig-win-key-complete.
+;;     icicle-Info-index(-goto-node)(-action):
+;;       Use (new) icicle-info-(buff|window), not info-(buff|window).
+;;     icicle-describe-option-of-type, icicle-describe-opt-of-type-complete:
+;;       Use (new) icicle-pref-arg, not pref-arg.
+;;     icicle-search: Bind (new) icicle-scan-fn-or-regexp.
+;;     Moved any alias inside emacs-major-version test.
+;;     icicle-complete-keys-1: Bind (new) icicle-key-prefix.
+;;     icicle-complete-keys-action: Use (new) icicle-key-prefix, not prefix.
+;;     icicle-keys+cmds-w-prefix: Bind (new) icicle-key-prefix-2.  Use icicle-active-map, not map.
+;;     icicle-add-key+cmd: Use icicle-key-prefix-2 and icicle-active-map, not prefix and map.
+;; 2011/03/31 dadams
+;;     icicle-describe-opt-of-type-complete: Wrap icicle-var-is-of-type-p with condition-case.
+;; 2011/03/29 dadams
+;;     icicle-search-action-1: Set icicle-other-window.  Use icicle-target-window-recenter-amount.
+;;     Use new icicle-* vars for various free vars (orig-buff etc.).
+;;     icicle-frame-(bg|fg), icicle-read-color: prompt -> icicle-prompt.
+;; 2011/03/03 dadams
+;;     icicle-insert-thesaurus-entry: Changed to strict completion from lax.
+;;     icicle-describe-option-of-type, icicle-(fun|var)doc, icicle-plist:
+;;       Removed mention of RET in prompt.
+;; 2011/02/17 dadams
+;;     Added defalias old-read-color for read-color.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     Added more autoload cookies for commands.  Thx to Richard Kim.
+;;       Specify command and file for commands defined by Icicles macros.
+;;     Require icicles-opt.el before icicles-var.el (but it makes no difference).
+;; 2010/12/14 dadams
+;;     icicle-search-regexp-scan: Don't create marker if hit string is "".
+;;     icicle-search-highlight-all-input-matches:
+;;       Don't search within empty search contexts.  Do nothing if input and expanded input are "".
+;;       If search doesn't advance point then forward-char.  Stop searching if eobp.
+;;       Don't add (empty) overlay if search is empty.
+;;     icicle-search-highlight-context-levels: Don't add overlay for empty match.
+;;     icicle-search-highlight-input-matches-here: If search doesn't advance point then forward-char.
+;;     icicle-search-char-property-scan: Don't create empty overlays.
+;; 2010/11/10 dadams
+;;     Added: icicle-read-args-for-set-completion-methods.
+;;     icicle-set-((S-)TAB|completion)-methods-for-command: Added METHODS arg.
+;; 2010/11/09 dadams
+;;     Added: icicle-set-((S-)TAB|completion)-methods-for-command.
+;; 2010/11/07 dadams
+;;     Applied renaming of icicle-all-candidates-action-p to icicle-all-candidates-action.
+;; 2010/10/27 dadams
+;;     icicle-where-is: Use different prompt if prefix arg.  Clarify the pref-arg diff in doc string.
+;; 2010/10/25 dadams
+;;     icicle-search: Remove mention of icicle-search-context-match-predicate (no longer exists).
+;; 2010/10/24 dadams
+;;     icicle-where-is, icicle-apropos-(variable|option|function|command), icicle-apply,
+;;       icicle-save-string-to-variable, icicle-choose-candidate-of-type,
+;;       icicle-read-var-value-satisfying:
+;;         Use icicle-must-pass-after-match-predicate, not PREDICATE arg.
+;; 2010/10/09 dadams
+;;     icicle-Info-goto-node, icicle-apply, icicle-goto-marker, icicle-occur, icicle-complete-keys,
+;;       icicle-(comint|compilation)-search, icicle-search(-sentences|-paragraphs|-pages):
+;;         Updated doc string for new prefix and modal cycling keys.
+;; 2010/07/17 dadams
+;;     Added: icicle-search-url-bookmark.
+;;     icicle-search-bookmark, icicle-define-search-bookmark-command: w3m -> url.  Added C-M-u binding.
+;; 2010/07/14 dadams
+;;     icicle-Info-index: Bind C-x m to icicle-bookmark-info-other-window.
+;;     icicle-Info-read-node-name: Restore original binding of C-x m, if any.
+;; 2010/06/21 dadams
+;;     icicle-comint-search: Wrap search with unwind-protect to remove hook.  Thx to M. Heerdegen.
+;; 2010/06/18 dadams
+;;     icicle-search-replace-match: Specific error message for read-only buffer.  Thx to M. Heerdegen.
+;;     Renamed: bookmarkp-* to bmkp-*.
+;; 2010/06/12 dadams
+;;     icicle-goto-marker-or-set-mark-command:
+;;       Set this-command so C-SPC C-SPC activates when not t-m mode.  Thx to Chris Hecker.
+;; 2010/06/11 dadams
+;;     icicle-search-action-1: (unless (pos-visible-in-window-p) (recenter -2)).  Thx to M. Heerdegen.
+;; 2010/06/08 dadams
+;;     icicle-search-bookmark, icicle-define-search-bookmark-command:
+;;       Use icicle-bookmark-delete-action.
+;;       Use condition-case to filter out bad bookmarks (so no error).
+;; 2010/06/04 dadams
+;;     Added: icicle-ido-like-mode.
+;; 2010/05/16 dadams
+;;     Added: icicle-search-(all|some)-tags(-regexp)-bookmark, icicle-search-desktop-bookmark,
+;;            icicle-search-specific-(buffers|files)-bookmark, icicle-search-this-buffer-bookmark.
+;;     icicle-define-search-bookmark-command: Defined cmd requires bookmark+.el.  Added &rest arg ARGS.
+;; 2010/05/15 dadams
+;;     icicle-search-highlight-and-maybe-replace: If candidate number is nil, set to 0.
+;;     icicle-search: Updated doc string: Can sort.  Don't say not to use C-|.
+;; 2010/05/09 dadams
+;;     Icicles search: Change to allow sorting.  Use mctized candidates, not alist + candidate nb.
+;;       icicle-search-highlight-and-maybe-replace:
+;;         Use *-replace-cand-in-mct, not *-replace-cand-in-alist.  Do not *-input-matches-here.
+;;       icicle-search-replace-cand-in-mct: Rewrote.
+;;         Handle multi-completions also.  Update CAND+MRKER to use replacement string, but keep props.
+;;       icicle-search-in-context-default-fn: Rewrote.
+;;         Update icicle-last-completion-candidate to current candidate.  Insert that.
+;;         Recompute input-match highlighting in current context.  Remove current if no candidates.
+;;       icicle-search-action-1: Do nothing if no candidates.
+;;       icicle-search-help: Bind icicle-whole-candidate-as-text-prop-p to t, not nil.
+;; 2010/05/04 dadams
+;;     icicle-object-action: Pass TYP to icicle-apply-to-saved-candidate. (UNTESTED)
+;;     icicle-choose-anything-candidate: Pass TYPE to icicle-apply-to-saved-candidate. (UNTESTED)
+;;     icicle-apply, icicle-read-var-value-satisfying: Bug fix: Removed #'.
+;; 2010/04/30 dadams
+;;     icicle-search: Delete icicle-search-current-overlay via icicle-no-match-hook (& restore hook). 
+;; 2010/04/29 dadams
+;;     icicle-apply: Added optional args predicate initial-input hist def inherit-input-method.
+;;                   Pass them to icicle-explore.
+;;     icicle-goto-marker-1: Pass a PREDICATE arg that ensures the marker points somewhere.
+;; 2010/04/25 dadams
+;;     icicle-complete-keys-action:
+;;       Bind icicle-*, esp. *-initially-flag, around call of this-command-keys.  Thx to M Heerdegen.
+;;     icicle-complete-keys: Save some icicle-* vars to reuse in icicle-complete-keys-action.
+;; 2010/04/17 dadams
+;;     icicle-search-bookmark, icicle-define-search-bookmark-command:
+;;       Use icicle-transform-multi-completion in icicle-delete-candidate-object.
+;; 2010/04/08 dadams
+;;     icicle-get-anything-candidates: Removed #' - it was preventing the fn from being functionp.
+;; 2010/04/03 dadams
+;;     Removed: icicle-search-desktop-bookmark (no need).
+;; 2010/04/02 dadams
+;;     Removed:
+;;       icicle-add-region, icicle-delete-region-from-alist, icicle-purge-bad-file-regions,
+;;       icicle-region-add-buffers, icicle-region-add-short-help, icicle-region-help,
+;;       icicle-region-open-all-files, icicle-regions, icicle-region-sorted, 
+;;       icicle-remove-all-regions-action, icicle-remove-all-regions-in-buffer, icicle-remove-region,
+;;       icicle-search-all-regions, icicle-search-region(-action), icicle-select-region(-action).
+;;     Added:
+;;       icicle-search-bookmark-list-bookmark, icicle-search-bookmarks-together,
+;;       icicle-search-desktop-bookmark, icicle-search-dired-bookmark, icicle-search-man-bookmark.
+;;     icicle-exchange-point-and-mark, icicle-search(-define-candidates),
+;;       icicle-char-properties-in-buffers:
+;;         Use only region bookmarks, not Icicles saved regions.
+;;     icicle-exchange-point-and-mark: Negative prefix arg prompts for bookmark name.
+;;     icicle-search-define-candidates(-1): Raise the no-candidates error in parent, not in (-1).
+;;     icicle-search-bookmark: Use full multi-completions.  Use bookmark sort orders.
+;;                             Define narrowing keys in both minibuffer maps.
+;;     icicle-search-bookmark-action: Transform multi-completion. Use bookmark posns only for region.
+;;     icicle-define-search-bookmark-command: Added PROMPT arg.  Use multi-completions, bookmark sorts.
+;; 2010/03/28 dadams
+;;     Renamed: icicle-search-all-regions to icicle-search-region.
+;;     Removed: old icicle-search-region (use icicle-search-region-bookmark instead),
+;;              icicle-region-add-buffers, icicle-region-add-short-help, icicle-region-help,
+;;              icicle-region-sorted, icicle-region-open-all-files, icicle-add-region,
+;;              icicle-remove-region, icicle-delete-region-from-alist,
+;;              icicle-purge-bad-file-regions, icicle-remove-all-regions-(in-buffer|action).
+;;     icicle-search-all-regions: Use region bookmarks, not icicle-region-alist.
+;; 2010/03/27 dadams
+;;     Added: icicle-search-(bookmark-list|desktop|dired|man)-bookmark.
+;;     icicle-search-bookmark: Use multi-completions.
+;;     icicle-search-bookmark-action:
+;;       Use icicle-transform-multi-completion.  Use both minibuffer completion maps.
+;;       Search region if region bookmark.
+;;     icicle-define-search-bookmark-command: Added optional PROMPT arg.  Use multi-completions.
+;; 2010/03/13 dadams
+;;     Applied renaming of icicle-add-buffer-name-flag to icicle-show-multi-completion-flag.
+;; 2010/03/09 dadams
+;;     icicle-regions: Use icicle-reversible-sort (with KEY arg), not sort.
+;; 2010/03/03 dadams
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist,
+;;                        icicle-alternative-sort-function to icicle-alternative-sort-comparer,
+;;                        icicle-last-sort-function to icicle-last-sort-comparer.
+;; 2010/02/06 dadams
+;;     icicle-where-is: Make sure orig-buff is current when look up the bindings.
+;; 2010/01/12 dadams
+;;     icicle-insert-thesaurus-entry-cand-fn, icicle-marker+text,
+;;       icicle-search-(bookmark|region)-action, icicle-char-properties-in-buffer,
+;;       icicle-search-char-property-scan:
+;;         save-excursion + set-buffer -> with-current-buffer (+ save-excursion).
+;;     icicle-search-regexp-scan: set-buffer -> with-current-buffer.
+;; 2009/12/13 dadams
+;;     icicle-Info-read-node-name: Bind C-x m to icicle-bookmark-info-other-window.
+;; 2009/11/24 dadams
+;;     icicle-read-color: Copy the prompt string, so *-color-completion-setup can put props.
+;; 2009/11/22 dadams
+;;     icicle-frame-(bg|fg): Don't apply *-make-color-candidate to named-colors (done already).
+;; 2009/11/03 dadams
+;;     icicle-frame-(bg|fg): Use named-colors, not x-defined-colors.
+;;     icicle-read-color: No need to bind icicle-transform-function, since we use hexrgb.el.
+;; 2009/09/05 dadams
+;;     icicle-search-replace-all-search-hits:
+;;       Bind to nil: icicle-minibuffer-message-ok-p, icicle-help-in-mode-line-flag.
+;;     icicle-search-action-1: Add condition-case to ignore disappearance of *Completions* win.
+;;     icicle-search-highlight-and-maybe-replace:
+;;       Apply renaming of icicle-acting-on-next/prev (no -p).
+;;       Use length of *-completion-candidates, not mct.
+;;       Fix assignment of new candidate nb, and for both directions.
+;;       Bind icicle-minibuffer-message-ok-p to inhibit no-candidates msg.
+;;       Wrap around to first only if not icicle-acting-on-next/prev.
+;; 2009/09/02 dadams
+;;     icicle-exchange-point-and-mark: Respect icicle-region-bookmarks-flag.
+;; 2009/08/29 dadams
+;;     Added: icicle-define-search-bookmark-command,
+;;            icicle-search(-region|-info|-gnus|-w3m|(-non|-local|-remote)-file)-bookmark,
+;;            icicle-search-bookmark-action.
+;;     Moved (and redefined) to icicles-cmd1.el: icicle-select-bookmarked-region.
+;;     (lambda...) -> #'(lambda...).
+;; 2009/08/25 dadams
+;;     Added icicle-select-bookmarked-region.
+;;     icicle-exchange-point-and-mark:
+;;       If bookmark+ is loaded, use region bookmarks.
+;;       Raise error if try to save inactive region or try to select with no saved regions.
+;; 2009/08/11 dadams
+;;     Added: icicle-search-replace-all-search-hits.
+;;     Renamed: icicle-search-replace-candidate to icicle-search-replace-cand-in-alist.
+;;     Added: icicle-search-replace-cand-in-mct (not used, for now).
+;;     icicle-search:
+;;       Bind icicle-all-candidates-list-alt-action-fn to icicle-search-replace-all-search-hits.
+;;       Bind replace-count to 0.  Bind icicle-current-input to empty string.
+;;       Updated doc string.
+;;     icicle-search-replace-search-hit:
+;;       Do not bind icicle-completion-candidates, icicle-candidate-nb, icicle-last-input.
+;;       No lack-of-current-candidate error if icicle-all-candidates-action-p.
+;;     Added: icicle-search-action-1 (factored out from icicle-search-action.
+;;     icicle-search-action, icicle-search-help:
+;;       Bind icicle-whole-candidate-as-text-prop-p to nil, to force use of alist.
+;;     icicle-search-action(-1): Do not bind icicle-candidate-nb, so don't save and restore it.
+;;     icicle-search-in-context-default-fn: If replacement tried, then update the dialog state. 
+;;     icicle-search-highlight-and-maybe-replace: REWRITE.
+;;       Msg if string to be replaced is not found in candidate.
+;;       Swap order: Don't search unless first time (or replacing all).
+;;       icicle-search-replace-candidate -> icicle-search-replace-cand-in-alist.
+;;       If replacement done, then: Update alist, minibuffer-completion-table, and
+;;         minibuffer content.  Change candidate nb if navigating next/prev.  Complete again.
+;;         Return indication of whether we tried to replace something.
+;;     icicle-search-replace-cand-in-alist: Added catch, to skip whole list traversal.
+;;     Moved byte-compile quieting defvars to top level.  Added one for tooltip-mode.
+;; 2009/07/20 dadams
+;;     icicle-font: Ensure no nil elements in COLLECTION arg to completing-read, for Emacs 22+.
+;; 2009/06/07 dadams
+;;     icicle-get-alist-candidate -> funcall icicle-get-alist-candidate-function.
+;;     Added: icicle-purge-bad-file-regions.
+;;     icicle-add-region, icicle-(select|search)-region-action:
+;;       Special-case Info buffers.  Thx to Thierry Volpiatto.
+;; 2009/05/28 dadams
+;;     Bind icicle-search-replacement to nil.  (Somehow forgot when moved to icicle-explore.)
+;;     icicle-search-replace-search-hit: Raise an error if icicle-candidate-nb is nil.
+;; 2009/05/26 dadams
+;;     icicle-compilation-search: Use value 'until-move for next-error-highlight.
+;; 2009/05/22 dadams
+;;     Added: icicle-Info-virtual-book. 
+;;     Require icicles-mac.el if load-library doesn't find it.
+;;     icicle-search: Set icicle-search-final-choice to result.
+;;     Created - Split off from icicles-cmd.el.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-face.el'")
+;;
+;; 2011/08/16 dadams
+;;     Require icicles-mac.el.
+;;     icicle-maybe-byte-compile-after-load the eval-after-load definitions.
+;; 2011/07/30 dadams
+;;     eval-after-load hexrgb.el, not runtime error if not feature, for all fns that use hexrgb.el.
+;;     Moved here from icicles-opt.el: icicle-increment-color-value.
+;;     icicle-search-context-level-*: Use fboundp icicle-increment-color-satur*, not featurep hexrgb.
+;;     Soft-require hexrgb.el when byte compile.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/05/05 dadams
+;;     icicle-mustmatch-completion: Changed line-width from 2 to -2.
+;; 2010/04/08 dadams
+;;     Added autoload cookies.
+;; 2010/03/13 dadams
+;;     Made icicle-candidate-part paler (light background): #EF84FFEAF427, not #DB17FFF4E581.
+;; 2010/02/17 dadams
+;;     Moved functions here from icicles-opt.el: icicle-increment-color-(hue|saturation). 
+;;     So no longer require icicles-opt.el.
+;; 2009/04/18 dadams
+;;     Removed load-time warning about using Icicles in a text terminal.
+;; 2009/04/12 dadams
+;;     Added: face icicle-mode-line-help.
+;; 2009/01/13 dadams
+;;     Added: icicle-extra-candidate.
+;; 2008/10/26 dadams
+;;     Added group: Icicles-Files.
+;; 2008/03/29 dadams
+;;     Redefined and renamed faces for completion status indicators.
+;;       Renamed: icicle-completing-mustmatch-prompt-prefix to icicle-mustmatch-completion,
+;;                icicle-mode-lighter-highlight(-plus) to icicle(-multi-command)-completion.
+;;       Removed: icicle-completing-prompt-prefix, icicle-prompt-suffix.
+;; 2008/03/09 dadams
+;;     Added: icicle-mode-lighter-highlight.
+;; 2007/12/10 dadams
+;;     Added: icicle-input-completion-fail-lax.
+;; 2007/11/18 dadams
+;;     Added: icicle-proxy-candidate.
+;;     icicle-special-candidate: No longer use a raised box.
+;; 2007/10/22 dadams
+;;     icicle-special-candidate: Raised box.
+;; 2007/08/19 dadams
+;;     Added: icicle-input-completion-fail.
+;; 2007/06/21 dadams
+;;     Added: icicle-candidate-part.  Changed definition of icicle-special-candidate.
+;; 2007/06/17 dadams
+;;     Added: icicle-saved-candidate.
+;; 2007/06/12 dadams
+;;     icicle-prompt-suffix: No box for dark background.
+;; 2007/06/11 dadams
+;;     Better defaults for dark background frames.
+;; 2007/06/07 dadams
+;;     Changed emacs-commentary-link to point to icicles-doc1.el and icicles-doc2.el.
+;; 2007/05/22 dadams
+;;     Protected icicle-search-context-level-1 to *-8, in case hexrgb is not loaded.
+;; 2007/04/20 dadams
+;;     Added: icicle-search-context-level-1 through *-8.
+;;     Require icicles-opt.el.
+;; 2006/12/22 dadams
+;;     Renamed group icicles to Icicles.
+;;     Added Icicles subgroups, and assigned them instead of group Icicles:
+;;      -Buffers, -Completions-Display, -Key-Bindings, -Key-Completion, -Matching,
+;;      -Minibuffer-Display, -Miscellaneous, -Searching.
+;; 2006/11/06 dadams
+;;     icicle-search-highlight-all-flag -> icicle-search-highlight-threshold (integer)
+;; 2006/10/16 dadams
+;;     icicle-special-candidate: changed background from Pink to #DB17FFF4E581.
+;; 2006/10/04 dadams
+;;     Added: icicle-special-candidate.
+;; 2006/08/13 dadams
+;;     Added: icicle-completing-prompt-prefix.
+;; 2006/07/16 dadams
+;;     Added dark-background face suggestions from Le Wang - thx.
+;; 2006/06/30 dadams
+;;     Added: minibuffer-prompt for Emacs < 22 (e.g. Emacs 21.4 has propertize).
+;; 2006/04/28 dadams
+;;     Added: icicle-whitespace-highlight.
+;; 2006/04/14 dadams
+;;     Renamed icicle-search-refined-regexp to icicle-search-current-input.
+;; 2006/04/07 dadams
+;;     Added: icicle-search-main-regexp-others.
+;;     Renamed: icicle-search-main-regexp to icicle-search-main-regexp-current.
+;; 2006/03/27 dadams
+;;     Added: icicle-search-*-regexp.
+;; 2006/03/22 dadams
+;;     Renamed: icicle-root-highlight-* to icicle-match-highlight-*.
+;; 2006/03/21 dadams
+;;     Added: icicle-common-match-highlight-Completions.
+;;     icicle-root-highlight-Completions: Changed default face.
+;; 2006/03/08 dadams
+;;     Added: icicle-current-candidate-highlight.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-fn.el'")
+;;
+;; 2011/09/05 dadams
+;;     icicle-display-candidates-in-Completions: Act on new option icicle-hide-non-matching-lines-flag.
+;; 2011/09/02 dadams
+;;     Added: icicle-delete-dups.
+;;     icicle-display-candidates-in-Completions: Don't highlight an empty match.
+;;     icicle-insert-candidates:
+;;       If only one column then colwidth should not be more than max-cand-len.
+;;       If whole cand is a single \n then do not treat it as the last \n (do not remove mouse-face).
+;; 2011/08/27 dadams
+;;     icicle-recentf-make-menu-items, icicle-display-candidates-in-Completions,
+;;       icicle-command-abbrev-save, icicle-kill-a-buffer: 
+;;         Use icicle-condition-case-no-debug instead of condition-case.  Thx to Michael Heerdegen.
+;; 2011/08/26 dadams
+;;     icicle-place-cursor: Put cursor at eob if get invalid-regexp error.
+;;     icicle-get-candidates-from-saved-set: Use %s, not %S, in error format string.
+;; 2011/08/15 dadams
+;;     icicle-display-completion-list: Do not call (last ...) if COMPLETIONS is null.
+;;     Added: icicle-all-completions.
+;;     Use icicle-all-completions, not all-completions, wherever a 4th arg is passed.
+;; 2011/08/12 dadams
+;;     icicle-completing-p: Handle cases of filename must-match maps.
+;;     icicle-file-name-input-p: Improved doc string.
+;; 2011/08/09 dadams
+;;     Added: icicle-replace-mct-cand-in-mct.
+;; 2011/08/07 dadams
+;;     icicle-display-candidates-in-Completions,
+;;       icicle-highlight-(initial-whitespace|complete-input|lighter), icicle-case-string-less-p,
+;;       icicle-expanded-common-match-1, icicle-insert-cand-in-minibuffer, icicle-place-cursor,
+;;       icicle-(special|extra)-candidates-first-p: Handle absolute file names too:
+;;           (icicle-file-name-input-p) -> (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+;;     icicle-display-candidates-in-Completions:: icicle-transform-multi-completion for image-file.
+;; 2011/08/03 dadams
+;;     icicle-lisp-vanilla-completing-read:
+;;       Handle recent Emacs 24 changes: make-compose-keymap etc.  Thx to Stefan Monnier.
+;; 2011/07/30 dadams
+;;     Moved to icicles-cmd2.el and wrapped in eval-after-load hexrgb:
+;;       icicle-color-*-lessp (except -rgb-), icicle-color-completion-setup, icicle-color-help,
+;;        icicle-make-color-candidate.
+;; 2011/07/27 dadams
+;;     Use icicle-completions-format everywhere, not icicle-completions-format-internal (removed).
+;;     icicle-nb-of-cand-in-Completions-horiz: Bind icicle-completions-format to horizontal, not nil.
+;; 2011/07/26 dadams
+;;     icicle-insert-candidates: Vertical multiline: add only one newline, not two.  Use \' not $.
+;;     Removed: icicle-list-end-string (no longer needed).
+;;     Thx to Michael Heerdegen.
+;; 2011/07/20 dadams
+;;     icicle-mctized-full-candidate: Don't change icicle-completions-format-internal to horizontal.
+;;     icicle-insert-candidates: If any candidate is multiline then use only one column.
+;;     Thx to Michael Heerdegen.
+;; 2011/07/06 dadams
+;;     icicle-fit-completions-window:
+;;       Emacs 22/23 fix: do not call fit-window-to-buffer.  Thx to Michael Heerdegen.
+;;     icicle-read-face-name: Added version for Emacs 24+.
+;; 2011/06/05 dadams
+;;     icicle-unsorted(-file-name)-prefix-candidates, icicle-prefix-any(-file-name)-candidates-p:
+;;       Add METADATA arg to icicle-completion-(try|all)-completion(s) calls.
+;; 2011/06/03 dadams
+;;     icicle-completion-(all|try)-completion(s):
+;;       Added optional METADATA arg to handle Emacs 24's new METADATA arg.
+;;     Replace icicle-help-in-mode-line-flag by icicle-help-in-mode-line-delay everywhere.
+;;     icicle-show-in-mode-line: Use icicle-help-in-mode-line-delay, not hard-coded 10 sec.
+;; 2011/05/31 dadams
+;;     icicle-read-file-name: Reordered let bindings (cosmetic).
+;; 2011/05/22 dadams
+;;     Added defvars for free vars to quiet byte compiler.
+;; 2011/05/12 dadams
+;;     icicle-candidate-short-help: Do nothing if string is empty ("").
+;; 2011/05/07 dadams
+;;     icicle-insert-cand-in-minibuffer: Go to prompt end before insert.
+;; 2011/05/04 dadams
+;;     icicle-transform-multi-completion: If cand is "" just return it.  (Emacs 20 split-string bug.)
+;; 2011/05/03 dadams
+;;     Added: icicle-position, icicle-merge-saved-order-less-p.
+;;     icicle-display-candidates-in-Completions: Respect icicle-highlight-saved-candidates-flag.
+;; 2011/04/20 dadams
+;;     icicle-completion-setup-function: Last version is for Emacs 23.3 also. Thx to Michael Heerdegen.
+;; 2011/04/18 dadams
+;;     icicle-face-valid-attribute-values: Added Emacs 23+ version.  Thx to Aankhen.
+;; 2011/04/12 dadams
+;;     Added defvars for icicle-dirs-done and icicle-files, for free vars.
+;;       Bind *-files in icicle-dired-read-shell-command.  Bind *-dirs-done in icicle-files-within.
+;;       Use *-files in icicle-*-add-dired-*.  Use *-dirs-done in icicle-files-within-1.
+;;     icicle-color-completion-setup: Renamed (free elsewhere): named-colors -> icicle-named-colors.
+;;                                    Applied renaming: prompt -> icicle-prompt.
+;;     icicle-unsorted-file-name-prefix-candidates, icicle-unsorted-file-name-apropos-candidates,
+;;       icicle-apropos-any-file-name-candidates-p:
+;;         Use minibuffer-completion-predicate, not default-directory, in calls to all-completions.
+;;         Thx to Michael Heerdegen.
+;; 2011/03/31 dadams
+;;     icicle-read-file-name, icicle-read-number, icicle-read-char-exclusive,
+;;       icicle-read-string-completing, icicle-color-completion-setup:
+;;         Wrap calls to icicle-var-is-of-type-p with condition-case.  Thx to Michael Heerdegen.
+;; 2011/03/29 dadams
+;;     icicle-show-help-in-mode-line: Removed boundp condition for icicle-completing-keys-p.
+;;     icicle-scroll-or-update-Completions:
+;;       Applied renaming: icicle-scroll-Completions to icicle-scroll-Completions-forward.
+;;     icicle-color-completion-setup: prompt -> icicle-prompt.
+;;     icicle-alt-act-fn-for-type: orig-window -> icicle-orig-window.
+;; 2011/03/26 dadams
+;;     icicle-read-face-name: Need copy-sequence for prompt in later Emacs versions also (forgot).
+;; 2011/03/17 dadams
+;;     icicle-display-candidates-in-Completions: Added 2-pixel margin around thumbnail image.
+;; 2011/03/04 dadams
+;;     icicle-read-file-name: Bind read-file-name-predicate.  Thx to Michael Heerdegen.
+;;     icicle-alt-act-fn-for-type: Ensure orig-window is live before use it.  Thx to Michael Heerdegen.
+;; 2011/02/22 dadams
+;;     icicle-display-candidates-in-Completions: Show thumbnail for an image file.
+;;                                               Call icicle-fit-completions-window explicitly here.
+;;     icicle-fit-completions-window: Added optional arg (not used yet).  Ensure window is Completions.
+;; 2011/02/20 dadams
+;;     Added: icicle-color-(distance)-(hsv|rgb)-lessp.
+;;     icicle-color-completion-setup: Added sort orders for HSV and RGB: component order and distance.
+;; 2011/02/17 dadams
+;;     icicle-join-nth-parts: If only one part then don't append the join string.
+;; 2011/01/31 dadams
+;;     icicle-insert-candidates: Fixed test for remainder cands: (= n (* r c)), not (= 0 (mod n r)).
+;; 2011/01/11 dadams
+;;     icicle-choose-completion-string:
+;;       Removed code that uses base-size, choose-completion-delete-max-match.  Just replace all input.
+;; 2011/01/05 dadams
+;;     Added: icicle-file-type-less-p.
+;;     icicle-highlight-input-noncompletion: When move overlay, specify buffer (for recursive minibuf).
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/23 dadams
+;;     icicle-expand-file-name-20: Allow for inputs to be nil.
+;; 2010/12/18 dadams
+;;     Moved icicle-assoc-delete-all to icicles-mac.el, since used there.
+;;     Added autoload cookies for cmds & macro; removed them from non-interactive functions.
+;; 2010/12/14 dadams
+;;     Added: icicle-expand-file-name-20.
+;;     Renamed: icicle-expand-file-name to icicle-expand-file-or-dir-name.
+;;     icicle-abbreviate-or-expand-file-name, icicle-expand-file-or-dir-name:
+;;       Use icicle-expand-file-name-20.
+;;     icicle-completion-setup-function for Emacs < 22: Fix typo: last-command -> this-command.
+;;     icicle-expanded-common-match: Removed from doc string: statement that result is regexp-quoted.
+;; 2010/12/11 dadams
+;;     icicle-completion-setup-function: Added a version for Emacs 23.2+.  Thx to Michael Heerdegen.
+;; 2010/11/20 dadams
+;;     icicle-toggle-icicle-mode-twice: Soft-require icicles-mode.el.
+;;     eval-after-load for crm.el:
+;;       Put toggle-twice on eval-after-load of icicles-mode, instead of doing it if i-m.el is loaded.
+;; 2010/11/07 dadams
+;;     Added helper macro icicle-maybe-cached-action.
+;;     icicle-alt-act-fn-for-type: use icicle-maybe-cached-action so use same action for all cands.
+;; 2010/11/06 dadams
+;;     icicle-fuzzy-candidates: Filter using icicle-must-pass-after-match-predicate.
+;;                              Respect also extra cands and proxy cands.
+;;                              Let C-g exit completion.
+;; 2010/10/25 dadams
+;;     icicle-read-shell-command-completing:
+;;       Use icicle-must-pass-after-match-predicate, not icicle-must-pass-predicate.
+;; 2010/10/24 dadams
+;;     icicle-unsorted(-file-name)-(prefix|apropos)-candidates:
+;;       Respect icicle-must-pass-after-match-predicate.
+;;     icicle-alt-act-fn-for-type: Use icicle-must-pass-after-match-predicate, not PREDICATE arg.
+;; 2010/10/07 dadams
+;;     Added: icicle-current-TAB-method (function).  Use it in place of var everywhere.
+;; 2010/10/04 dadams
+;;     directory-sep-char -> ?/ (It was removed from Emacs 24.)
+;; 2010/06/18 dadams
+;;     icicle-completing-read:
+;;       Initialize icicle-completions-format-internal to icicle-completions-format.
+;;     icicle-mctized-full-candidate:
+;;       Set icicle-completions-format-internal to horizontal for multi-line multi-completions.
+;;     icicle-insert-candidates:
+;;       Remove face property from end of candidate to next column.
+;;       Replace icicle-completions-format by icicle-completions-format-internal.
+;;     Renamed: bookmarkp-* to bmkp-*.
+;; 2010/06/14 dadams
+;;     icicle-read-from-minibuffer:
+;;       If add file-name default to prompt, remove dir part first.  Thx to Chris Hecker.
+;;     icicle-next-candidate: Do not icicle-recompute-candidates if this command was repeated.
+;;     icicle-increment-cand-nb+signal-end: 
+;;       Signal wrap from initial, not from 0.  Negative INCR -> start at end.  Thx to M. Heerdegen.
+;;     icicle-call-then-update-Completions:
+;;       Set icicle-last-input to nil so icicle-save-or-restore-input makes next-candidate recompute.
+;; 2010/06/12 dadams
+;;     icicle-fit-completions-window: Let-bind window-min-height to prevent deletion in Emacs 23.
+;; 2010/06/10 dadams
+;;     icicle-maybe-sort-and-strip-candidates:
+;;       Set icicle-completion-candidates to result of *maybe...maybe*.  (It broke C-~.)
+;; 2010/06/09 dadams
+;;     icicle-isearch-complete-past-string: Use the last-used ring.  Thx to Michael Heerdegen.
+;; 2010/06/08 dadams
+;;     icicle-display-candidates-in-Completions: Show also total when truncated: N shown / M.
+;;     icicle-maybe-sort-maybe-truncate: Save icicle-nb-candidates-before-truncation before truncating.
+;; 2010/06/04 dadams
+;;     Added: icicle-clear-lighter, icicle-maybe-sort-maybe-truncate, icicle-take.
+;;     icicle-(prefix|apropos)-candidates, icicle-strip-ignored-files-and-sort,
+;;       icicle-maybe-sort-and-strip-candidates, icicle-display-Completions:
+;;         Use icicle-maybe-sort-maybe-truncate, not icicle-reversible-sort.
+;;     icicle-(un)highlight-lighter: Use icicle-clear-lighter (factored out).
+;; 2010/05/30 dadams
+;;     Added: icicle-files-within-1.
+;;     icicle-files-within:
+;;       Use icicle-files-within-1.  Optionally don't follow symlinks (new arg NO-SYMLINKS-P).
+;;       Don't process same dir twice.  Respect icicle-ignored-directories.  Thx to Michael Heerdegen.
+;; 2010/05/18 dadams
+;;     icicle-save-or-restore-input:
+;;       Use icicle-file-directory-p, not file-directory-p (fails: ~/foo//usr/).  Thx to M. Heerdegen.
+;; 2010/05/04 dadams
+;;     icicle-alt-act-fn-for-type: Pass TYPE to icicle-apply-to-saved-candidate.
+;; 2010/04/30 dadams
+;;     icicle(-file-name)-unsorted-(apropos|prefix)-candidates, icicle-fuzzy-candidates:
+;;       Set icicle-common-match-string to nil when no candidates.
+;; 2010/04/29 dadams
+;;     icicle-unpropertize: Do nothing unless icicle-remove-icicles-props-p.
+;; 2010/04/27 dadams
+;;     icicle-show-help-in-mode-line: Test value, not just boundp, of icicle-completing-keys-p.
+;; 2010/04/21 dadams
+;;     icicle-mode-line-name-less-p: Removed bogus calls to symbol-name.  Thx to Michael Heerdegen.
+;; 2010/04/20 dadams
+;;     Added: icicle-dirs-first-p.
+;; 2010/04/02/dadams
+;;     icicle-completing-p: Cache t, not the keymap portion.
+;; 2010/03/16 dadams
+;;     icicle-display-candidates-in-Completions, treating icicle-candidate-properties-alist:
+;;       For subsequent matches of join string, skip over the last join string (not 1 char).
+;;     icicle-candidate-short-help: Treat each property individually.
+;; 2010/03/13 dadams
+;;     icicle-reversible-sort: Respect icicle-transform-before-sort-p.
+;; 2010/03/10 dadams
+;;     icicle-show-help-in-mode-line:
+;;       Put this test first: If candidate is a string with a help property, use that.
+;;       Use get-file-buffer, not get-buffer, for a visited file.
+;; 2010/03/09 dadams
+;;     icicle-reversible-sort: Added optional KEY arg.  Set LIST to sort result and return it.
+;;     icicle-multi-sort: Set RESULT to funcall result.
+;; 2010/03/03 dadams
+;;     Added: icicle-multi-sort, icicle-make-plain-predicate, icicle-alpha-p.
+;;     icicle-reversible-sort: Use icicle-sort-comparer and icicle-multi-sort.
+;;                             Reset to unsorted if an error is raised.
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer,
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist.
+;;     icicle-read-shell-command-completing: Removed extra binding for icicle-sort-function.
+;; 2010/01/12 dadams
+;;     icicle-display-candidates-in-Completions: set-buffer -> with-current-buffer.
+;; 2009/12/25 dadams
+;;     icicle-strip-ignored-files-and-sort:
+;;       Call completion-ignored-build-apply and icicle-update-ignored-extensions-regexp.
+;; 2009/12/21 dadams
+;;     fset -> defalias.
+;; 2009/12/07 dadams
+;;     Added: icicle-minibuffer-default-add-dired-shell-commands.
+;;     icicle-dired-read-shell-command: Instead of using minibuffer-default-add-shell-commands,
+;;       use icicle-minibuffer-default-add-dired-shell-commands.
+;;     icicle-read-shell-command-completing: Bind insert-default-directory to nil.
+;;     icicle-dir-prefix-wo-wildcards: Don't ever return nil - return "" if need be.
+;;     icicle-read-string:
+;;       Handle a consp default-value when user enters "": use the car.  Thx to Sakuma Ryo.
+;; 2009/12/03 dadams
+;;     icicle-completing-read:
+;;       Make sure we don't use a nil def value for init value.  Thx to Sebastian Luque.
+;; 2009/11/27 dadams
+;;     *-display-candidates-in-Completions, *-prefix-candidates, *-fuzzy-candidates:
+;;       Handle swank completions too.
+;; 2009/11/25 dadams
+;;     icicle-insert-candidates: Handle vertical layout: icicle-completions-format.
+;; 2009/11/03 dadams
+;;     icicle-color-completion-setup: Use hexrgb-defined-colors, not x-defined-colors.
+;;                                    No icicle-transform-function, since we use hexrgb.el.
+;; 2009/10/25 dadams
+;;     Added: icicle-dir-prefix-wo-wildcards.  Use in icicle-insert-cand-in-minibuffer.
+;;     icicle-save-or-restore-input: Remove test comparing last completion with current input.
+;;     icicle-abbreviate-or-expand-file-name: If arg is absolute, do not expand.
+;;     icicle-display-candidates-in-Completions, icicle-prefix-candidates,
+;;       icicle-not-basic-prefix-completion-p:
+;;         Updated for new completion methods.  Use *-current-TAB-method, not old fuzzy flag.
+;; 2009/10/24 dadams
+;;     icicle-unsorted-file-name-*-candidates, icicle-*-any-file-name-candidates-p:
+;;       Got rid of slashed-p.
+;;     icicle-unsorted-file-name-apropos-candidates:
+;;       Set icicle-common-match-string to nil if there are no candidates.
+;;     icicle-apropos-any-file-name-candidates-p:
+;;       When input is a dir, remove final /, so we don't non-match highlight the / (empty dir).
+;;       Bind case-fold-search, for apropos matching.
+;;     icicle-abbreviate-or-expand-file-name: Set DIR to nil if it's relative.
+;; 2009/10/22 dadams
+;;     Added: icicle-file-name-directory.
+;;     icicle-completion-setup-function, icicle-display-candidates-in-Completions,
+;;       icicle-save-or-restore-input, icicle-file-name-directory-w-default,
+;;       icicle-historical-alphabetic-p:
+;;         Use icicle-file-name-directory, not file-name-directory.
+;; 2009/10/17 dadams
+;;     icicle-completion-try-completion: Return RES.
+;; 2009/10/12 dadams
+;;     icicle-unsorted-prefix-candidates, icicle-prefix-any-candidates-p:
+;;       Use length of INPUT, not length from point backward to field-beginning.
+;;     icicle-input-from-minibuffer: Added optional LEAVE-ENVVARS-P arg.
+;;     icicle-next-candidate, icicle-highlight-complete-input:
+;;       Call icicle-input-from-minibuffer with LEAVE-ENVVARS-P arg.
+;;     icicle-completion-all-completions:
+;;       If not basic completion (Emacs 23) and input ends in $, then append $ to cands also.
+;; 2009/09/25 dadams
+;;     icicle-file-name-prefix-candidates: Use whole input, not just nondirectory.
+;;     Added: icicle-not-basic-prefix-completion-p.  Use where appropriate.
+;; 2009/09/19 dadams
+;;     icicle-unpropertize: Remove the internal text properties added by Icicles.
+;;     icicle-completing-read, icicle-read-file-name: Call icicle-unpropertize unconditionally.
+;; 2009/09/12 dadams
+;;     icicle-kill-a-buffer: Bind enable-recursive-minibuffers, to confirm modified buffer.
+;; 2009/09/05 dadams
+;;     icicle-msg-maybe-in-minibuffer: Do nothing if icicle-minibuffer-message-ok-p is nil.
+;; 2009/08/19 dadams
+;;     icicle-candidate-short-help: Return (possibly propertized) STRING.
+;; 2009/08/09 dadams
+;;     Added: icicle-insert-cand-in-minibuffer - factored out code from icicle-next-candidate.
+;;     eval-after-load "crm":
+;;       Test that icy-mode is available using featurep, not fboundp.  Thx to Michael Heerdegen.
+;; 2009/07/26 dadams
+;;     icicle-completing-read, icicle-read-file-name-1:
+;;       Bind minibuffer-history-variable to itself.
+;; 2009/07/13 dadams
+;;     icicle-read-face-name (Emacs 20 version): Use copy-sequence on prompt, before add prop.
+;; 2009/07/12 dadams
+;;     icicle-display-completion-list:
+;;       Use different protection (fboundp) for fix for latest Emacs 23 crap (base size in cdr).
+;; 2009/07/11 dadams
+;;     icicle-next-candidate:
+;;       If icicle-regexp-quote-flag, regexp-quote before string-match for highlighting root.
+;;     icicle-place-cursor: If icicle-regexp-quote-flag, regexp-quote input to search for it.
+;; 2009/07/02 dadams
+;;     icicle-displayable-cand-from-saved-set:
+;;       If icicle-readable-to-markers returns an atom, just use that.
+;; 2009/06/17 dadams
+;;     icicle-fit-completions-window: Scale text size initially.
+;; 2009/06/07 dadams
+;;     icicle-get-alist-candidate -> funcall icicle-get-alist-candidate-function.
+;;     icicle-mctize-all:  If PRED is nil, so is NEWPRED (use and instead of when).
+;; 2009/05/22 dadams
+;;     Require icicles-mac.el if load-library doesn't find it.
+;; 2009/05/18 dadams
+;;     icicle-display-candidates-in-Completions: deactivate-mark in *Completions* after display.
+;; 2009/05/17 dadams
+;;     icicle-next-candidate: Updated to reflect thumb-frm.el name changes.
+;; 2009/05/17 dadams
+;;     Added: icicle-toggle-icicle-mode-twice.
+;;     In eval-after-load crm: Use icicle-toggle-icicle-mode-twice, not icy-mode calls.
+;; 2009/05/15 dadams
+;;     icicle-unhighlight-lighter: Wrap redisplay in condition-case, like elsewhere.
+;; 2009/05/11 dadams
+;;     Added: icicle-upcase.  Use in place of upcase everywhere, to work around Emacs 20 bug.
+;;     Added: icicle-local-keys-first-p.
+;;     icicle-display-candidates-in-Completions:
+;;       Don't highlight historical candidate if in icicle-hist-cands-no-highlight.
+;; 2009/05/09 dadams
+;;     icicle-input-from-minibuffer: Keep text properties when pick up input.
+;;     icicle-highlight-input-noncompletion(-rest): Use an overlay instead of text property.
+;;     icicle-show-help-in-mode-line: Fix special case for pseudo-key/cmd ..: go up to prefix.
+;; 2009/05/07 dadams
+;;     icicle-display-candidates-in-Completions, in the code that hides common match:
+;;       Don't reset display property to nil.
+;;       Use icicle-common-match-string, not current input.
+;;     icicle-expanded-common-match-1:
+;;       If input doesn't match candidate, return nil.  Throw nil, not input, everywhere.
+;;     *-unsorted(-file-name)-apropos-candidates, *-apropos-any(-file-name)-candidates-p:
+;;       Protect calls to icicle-apropos-complete-match-fn with condition-case, for Emacs 20.
+;;     icicle-place-cursor: Added optional arg.
+;; 2009/05/05 dadams
+;;     icicle-alt-act-fn-for-type:
+;;       Bind completion-ignore-case, based on read-buffer-completion-ignore-case.
+;; 2009/05/03 dadams
+;;     Use (fboundp 'minibuffer-default-add-completions), not (> emacs-major version 22).
+;; 2009/05/01 dadams
+;;     Renamed: icicle-choose-action-for-type to icicle-alt-act-fn-for-type.
+;;     icicle-type-actions-alist: Rewrote.  Handle both list of objs and single obj.
+;;     icicle-quote-file-name-part-of-cmd: Rewrote.  Quote file name always, and only file name.
+;; 2009/04/30 dadams
+;;     icicle-show-in-mode-line: Clear any message (e.g. Computing completion candidates...).
+;; 2009/04/29 dadams
+;;     icicle-get-alist-candidate: If NO-ERROR-P is 'no-error-no-msg, just return nil (no msg).
+;;     icicle-choose-action-for-type: Use lax completion.
+;; 2009/04/28 dadams
+;;     icicle-choose-action-for-type: 
+;;       Moved here from icicles-mac.el, changed to a function, and locally bind
+;;       *-alt-action-fn  to icicle-choose-action-for-type function.
+;;       For undefined TYPE, provide all functions as candidates.
+;;     Added eval-when-compile of load-library icicles-mac.
+;; 2009/04/27 dadams
+;;     icicle-recompute-candidates:
+;;       Keep no-display completion mode, if that's current.
+;;       Set icicle-last-completion-command only if completion type, not user input, changed.
+;;     icicle-complete-again-update: Added icicle-prefix-complete-no-display to first case.
+;; 2009/04/19 dadams
+;;     Use unless instead of or for fset's. (cosmetic)
+;;     icicle-completing-read, icicle-read-from-minibuffer, icicle-read-string:
+;;       Renamed history parameter to HIST-m@%=!$+&^*z, so C-h f output looks less strange.
+;; 2009/04/18 dadams
+;;     Soft-require hexrgb.el unconditionally, not just when there is a window-system.
+;; 2009/04/12 dadams
+;;     icicle-display-candidates-in-Completions: Added number of candidates to mode-line.
+;;     icicle-show-help-in-mode-line: Use face icicle-show-help-in-mode-line.  Fix prefix keys.
+;; 2009/04/11 dadams
+;;     icicle-candidate-short-help:
+;;       Do nothing if either icicle-help-in-mode-line-flag or tooltip-mode is nil.
+;;     icicle-show-help-in-mode-line:
+;;       If no symbol help, try string.
+;;       Handle lambdas, menu-function-# from easy-menu, and prefix keys.
+;;     icicle-make-color-candidate: Construct short help only if user will see it.
+;; 2009/04/10 dadams
+;;     Added: icicle-candidate-short-help, icicle-color-completion-setup (from i*-read-color).
+;;     Moved here from icicle-cmds.el:
+;;      icicle-remove-color-duplicates, icicle-color-help, icicle-make-color-candidate.
+;;     icicle-make-color-candidate: Added short help, using icicle-candidate-short-help.
+;;     icicle-show-help-in-mode-line:
+;;       Treat :icicle-candidate-help text property on strings.
+;;       Use candidate, not cand, for stringp clause, and use icicle-transform-multi-completion.
+;;       Renamed: :icicle-candidate-help to icicle-mode-line-help.
+;; 2009/04/08 dadams
+;;     icicle-show-help-in-mode-line: Treat absolute file names too.
+;; 2009/04/07 dadams
+;;     icicle-show-help-in-mode-line: (bufferp (get-buffer...)...) -> (get-buffer...) Duh.
+;; 2009/04/06 dadams
+;;     Added: icicle-show-help-in-mode-line - from code in icicle-next-candidate:
+;;              Added arg.  Handle: faces, buffer names, file names, :icicle-candidate-help.
+;;     Added: icicle-help-line-(buffer|file).
+;;     icicle-next-candidate: Use icicle-show-help-in-mode-line.
+;; 2009/04/05 dadams
+;;     Added: icicle-show-in-mode-line.
+;;     icicle-next-candidate: Use icicle-show-in-mode-line to show help in mode-line.
+;; 2009/04/04 dadams
+;;     Added: icicle-buffer-smaller-p, icicle-major-mode-name-less-p,
+;;            icicle-mode-line-name-less-p, icicle-buffer-file/process-name-less-p.
+;; 2009/04/03 dadams
+;;     icicle-read-from-minibuffer: Save filtered default val as icicle-filtered-default-value.
+;;     icicle-lisp-vanilla-completing-read: Use icicle-filtered-default-value, not DEF, at end.
+;; 2009/03/29 dadams
+;;     icicle-read-shell-command: If non-nil initial-contents, punt to use original (old-*).
+;; 2009/03/27 dadams
+;;     Don't fset minibuffer-default-add-completions unless > Emacs 22.
+;; 2009/03/27 dadams
+;;     icicle-read-from-minibuffer: Use icicle-filter-wo-input on default-value (all values).
+;;     icicle-completing-read, icicle-read-file-name-1:
+;;       Use icicle-filter-wo-input on default value only to get init value.
+;;     Added: icicle-minibuffer-default-add-completions, icicle-first-N.
+;; 2009/03/26 dadams
+;;     icicle-completing-read, icicle-read-file-name-1:
+;;       Filter default values using icicle-filter-wo-input.
+;;     icicle-filter-wo-input: Return the candidate, if it passes filtering.
+;; 2009/03/16 dadams
+;;     Added: icicle-recentf-make-menu-items.
+;; 2009/03/10 dadams
+;;     icicle-read-shell-command-completing: Applied renamings: icicle-guess-commands-in-path,
+;;       icicle-shell-command-candidates-cache, icicle-recompute-shell-command-candidates.
+;;     Moved to icicles-opt.el and renamed: icicle-shell-command-candidates.
+;; 2009/03/08 dadams
+;;     Added: icicle-quote-file-name-part-of-cmd.
+;;     icicle-read-shell-command-completing:
+;;       Call icicle-quote-file-name-part-of-cmd to escape spaces etc. in file names.
+;;       Removed unneeded minibuffer-local-*-map let bindings.
+;;     icicle-dired-smart-shell-command:
+;;       Protected dired-default-directory with fboundp, for Emacs 20.
+;; 2009/03/01 dadams
+;;     icicle-read-from-minibuffer:
+;;       No longer use icicle-complete-on-demand-cmd and on-demand-map.
+;; 2009/02/28 dadams
+;;     Don't fset old-dired-smart-shell-command here - do after load Dired-X (icicles-mode.el).
+;;     Added for Emacs 20: definition of replace-regexp-in-string.
+;;     icicle-read-(number|string-completing):
+;;       No need for fboundp of replace-regexp-in-string, since provide it now for Emacs 20.
+;;     icicle-read-file-name: Treat directory candidates as special candidates.
+;;     icicle-read-shell-command-completing:
+;;       Candidate help depends on candidate type.
+;;       Use existing icicle-extra-candidates as its own default, not icicle-file-extras.
+;; 2009/02/27 dadams
+;;     icicle-shell-command: Fixed typo: shell-command -> old-shell-command.
+;;     icicle-read-shell-command-completing: Append icicle-file-extras to i*-extra-candidates.
+;; 2009/02/23 dadams
+;;     icicle-read-shell-command-completing:
+;;       Bind icicle-extra-candidates-dir-insert-p, not insert-default-directory, to nil.
+;;     icicle-next-candidate: Protect dir insertion with icicle-extra-candidates-dir-insert-p.
+;; 2009/02/22 dadams
+;;     icicle-dired-read-shell-command: Use minibuffer-default-add-shell-commands if available.
+;; 2009/02/20 dadams
+;;     icicle-read-from-minibuffer: Treat icicle-complete-on-demand-cmd - on-demand completion.
+;;     Added: icicle-dired-smart-shell-command, icicle-read-shell-command-completing,
+;;            icicle-dired-read-shell-command, icicle-extra-candidates-first-p,
+;;            icicle-require-match-p, icicle-shell-command(-on-region).
+;;     icicle-read-shell-command:
+;;       Call icicle-read-shell-command-completing.  Define always, not just when mailcap.
+;;     icicle-dired-guess-shell-command: Just call icicle-read-shell-command-completing.
+;;     icicle-shell-command-candidates: Cache completions in icicle-shell-command-candidates.
+;;     icicle-highlight-input-noncompletion(-rest), icicle-highlight-lighter:
+;;       Use function icicle-require-match-p, not var.
+;;     icicle-completing-p: Test also whether parent map is a completion map.  Always cache.
+;; 2009/02/17 dadams
+;;     icicle-read-shell-command: Handle nil default-value.  Thx to Kao Felix.
+;;     icicle-read-file-name: Append new proxy cands to any existing ones.
+;;                            Don't assume that a proxy cand is a variable.
+;; 2009/01/25 dadams
+;;     Added: *-dired-guess-shell-command, *-read-shell-command, *-shell-command-candidates.
+;; 2009/01/17 dadams
+;;     icicle-display-candidates-in-Completions: Highlight Levenshtein (1) match.
+;;     icicle-unsorted-apropos(-file-name)-candidates, icicle-display-Completions,
+;;       icicle-apropos-any(-file-name)-candidates-p: Removed PCM.
+;;     Added: icicle-levenshtein(-strict|-one)-match, icicle-levenshtein-one-regexp,
+;;            icicle-substrings-of-length.
+;; 2009/01/15 dadams
+;;     Lose "icicle-" for fboundp's: completion-all-completions, completion-try-completion.
+;; 2009/01/14 dadams
+;;     Added: icicle-remove-dups-if-extras.
+;; 2009/01/13 dadams
+;;     Added: icicle-completion-all-completions, icicle-completion-try-completion.
+;;     icicle-unsorted(-file-name)-(prefix|apropos)-candidates, icicle-display-Completions,
+;;       icicle-any-(prefix|apropos)(-file-name)-candidates-p:
+;;         Respect icicle-respect-completion-styles-p (Emacs 23).
+;;     icicle-unsorted-file-name-prefix-candidates: Removed matching "^"++(regexp-quote input).
+;;     icicle(-unsorted)(-file-name)-(prefix|apropos)-candidates:
+;;       Call icicle-transform-candidates for extra candidates and proxy candidates too.
+;;     icicle-display-candidates-in-Completions: Highlight extra candidates.
+;;     icicle-face-valid-attribute-values:
+;;       Use font-family-list instead of x-font-family-list, if available.
+;; 2009/01/03 dadams
+;;     icicle-call-then-update-Completions:
+;;       If icicle-last-completion-command is nil, test icicle-current-completion-mode - don't
+;;       just call icicle-prefix-complete.  E.g. icicle-search shouldn't end with a single
+;;       prefix match.
+;; 2008/12/25 dadams
+;;     Added: icicle-save-raw-input (factored out from icicle-save-or-restore-input).
+;;     icicle-save-or-restore-input:
+;;       Change test whether last-command is cycling cmd to add also not being completing cmd.
+;;       Use icicle-completing-p instead of testing this-command for being a cycling cmd.
+;;       Use icicle-save-raw-input.
+;;     icicle-next-candidate: Set icicle-cycling-p (new var) to t.
+;; 2008/12/20 dadams
+;;     icicle-save-or-restore-input: Don't restore last input if this is a completing command.
+;; 2008/12/07 dadams
+;;     icicle-completing-read, icicle-read-file-name-1:
+;;       Removed icicle-prompt.  Don't add completion prompt prefix, except for Emacs 20.
+;; 2008/12/06 dadams
+;;     icicle-call-then-update-Completions:
+;;       To update, call icicle-last-completion-command, not icicle-(apropos|prefix)-complete.
+;; 2008/12/02 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates:
+;;       Call icicle-filter-wo-input before filtering with user input (as the doc string says).
+;; 2008/11/28 dadams
+;;     icicle-recompute-candidates, icicle-save-or-restore-input:
+;;       Test property icicle-(prefix|apropos)-completing-command, not eq cmds.
+;; 2008/11/23 dadams
+;;     icicle-read-file-name:
+;;       Don't initialize icicle-proxy-candidates unless icicle-add-proxy-candidates-flag.
+;;       Don't add + to completion indicator if Emacs 23.
+;; 2008/11/22 dadams
+;;     icicle-completing-read:
+;;       Bind icicle-fancy-cands-internal-p.  Do not call icicle-mctize-all unless fancy cands.
+;;     icicle-mctized-full-candidate:
+;;       No-op unless icicle-fancy-cands-internal-p or icicle-whole-candidate-as-text-prop-p.
+;;     icicle-read-(number|char-exclusive|string-completing|face-name):
+;;       Put icicle-fancy-candidates property on prompt if proxy candidates.
+;;     icicle-display-candidates-in-Completions:
+;;       Don't transform candidates unless icicle-fancy-cands-internal-p.
+;; 2008/11/18 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Add icicle-special-candidate property as text property to candidates in
+;;         icicle-completion-candidates, instead of just to display candidate, so returned also.
+;;       Added support for icicle-display-string property.
+;;       For these properties: look up symbol first in minibuffer-completion-table if obarray.
+;; 2008/11/14 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Respect icicle-hide-common-match-in-Completions-flag.
+;; 2008/11/10 dadams
+;;     icicle(-unsorted)(-file-name)-(apropos|prefix)-candidates:
+;;       Moved special and proxy candidates outside match filtering,
+;;         reversing a change made on 2007/11/18.  Dunno why that change was made.
+;;       But filter special and proxy candidates using the input.
+;; 2008/11/09 dadams
+;;     Added: icicle-join-nth-parts, icicle-display-cand-from-full-cand.
+;;     icicle-transform-multi-completion: Use icicle-join-nth-parts.
+;;     icicle-transform-multi-completion: Don't test icicle-list-join-string (always non-nil).
+;;     icicle-first-matching-candidate:
+;;       Fix: set res properly, not to the tested value.  Thx to Hannes Janetzek.
+;; 2008/11/07 dadams
+;;     icicle-color-name-w-bg: Return input if hexrgb.el is not loaded.  Thx to Fabrice Knevez.
+;; 2008/11/04 dadams
+;;     icicle-read-face-name: Soft-require eyedropper.el or palette.el.
+;; 2008/11/03 dadams
+;;     icicle-expanded-common-match: Bug fix for Emacs 20: If error matching, just return INPUT.
+;;     icicle-highlight-input-noncompletion: Erase any message first before highlighting.
+;; 2008/11/02 dadams
+;;     icicle-display-candidates-in-Completions: For icicle-candidate-properties-alist, use
+;;       narrowed buffer content, not i-current-completion-in-Completions.
+;; 2008/10/24 dadams
+;;     icicle-first-matching-candidate:
+;;       Use regexp-quote on CAND.
+;;       Add icicle-list-end-string to each entry in CANDIDATES.
+;;       Iteration, not recursion.
+;;     icicle-get-alist-candidate: Added optional arg NO-ERROR-P.
+;; 2008/10/18 dadams
+;;     Replaced customize-save-variable by funcall icicle-customize-save-variable-function.
+;; 2008/10/14 dadams
+;;     Applied renaming of icicle-completion-help to icicle-minibuffer-help.
+;; 2008/10/06 dadams
+;;     Don't toggle icy-mode after loading crm.el unless icy-mode is defined (!).
+;;     icicle-ms-windows-NET-USE: If hash tables not available, just run the NET USE process.
+;; 2008/10/04 dadams
+;;     Substitute Icicles version of completing-read-multiple and its maps.  Thx to Per Nordlow.
+;;       Added: (icicle|old)-completing-read-multiple, icicle-define-crm-completion-map,
+;;              (icicle|old)-crm-local-(completion|must-match)-map.
+;;     icicle-display-completion-list: Protect against Emacs 23 nonsense with base-size in cdr.
+;; 2008/09/30 dadams
+;;     Added: icicle-ms-windows-NET-USE.  Thx to Thomas Lim.
+;;     icicle-file-remote-p: Use icicle-ms-windows-NET-USE.
+;;     icicle-highlight-input-noncompletion: Return file-local-p if test shows it's local.
+;;     icicle-call-then-update-Completions:
+;;       Treat also known file-local-p return from icicle-highlight-input-noncompletion.
+;;     Renamed icicle-isearch-complete-1 to icicle-isearch-complete-past-string and moved it
+;;       here from icicles-mcmd.el.
+;;     icicle-isearch-complete-past-string: Always use regexp-search-ring.  Changed prompt.
+;; 2008/09/27 dadams
+;;     icicle-highlight-input-noncompletion: Fixed typo: implicit-remote -> implicit.
+;; 2008/09/20 dadams
+;;     icicle-(apropos|prefix)-candidates, icicle-maybe-sort-and-strip-candidates:
+;;       Strip ignored files if icicle-abs-file-candidates.
+;; 2008/09/19 dadams
+;;     icicle-get-candidates-from-saved-set: Added optional arg DONT-EXPAND-FILESETS-P.
+;;                                           Use icicle-kill-a-buffer, not kill-buffer.
+;;     Moved icicle-kill-a-buffer here from icicles-cmd.el.
+;;     Added: icicle-unpropertize.
+;;     icicle-completing-read, icicle-read-file-name: Use icicle-unpropertize.
+;; 2008/09/16 dadams
+;;     filesets-get-filelist: Fixed :tree so it includes files in subdirs.
+;;     Added: icicle-filesets-files-under.
+;; 2008/09/15 dadams
+;;     Added: icicle-saved-fileset-p, icicle-displayable-cand-from-saved-set.
+;;     icicle-get-candidates-from-saved-set:
+;;       Rewrote code to convert saved candidates to displayable candidates.
+;;         Use icicle-displayable-cand-from-*, icicle-saved-fileset-p.  Require filesets.el.
+;;       Moved filesets-get-fileset-from-name into and of first cond clause.
+;;     Wrapped defun of filesets-get-filelist in eval-after-load.
+;; 2008/09/13 dadams
+;;     Added: icicle-get-candidates-from-saved-set (factored from code in
+;;            icicle-retrieve-candidates-from-set), filesets-get-filelist (redefined),
+;;            icicle-explicit-saved-completion-candidates.
+;;     Moved here from icicles-mcmd.el: icicle-readable-to-markers.
+;; 2008/09/04 dadams
+;;     icicle-read-file-name-1: Removed unused code for non icicle-mode case.
+;; 2008/09/03 dadams
+;;     Removed: icicle-(un)highlight-crosshairs, icicle-unhighlight-crosshairs+cleanup.
+;; 2008/09/01 dadams
+;;     Added: icicle-(un)highlight-crosshairs, icicle-unhighlight-crosshairs+cleanup.
+;; 2008/08/29 dadams
+;;     icicle-mctize-all:
+;;       Do it for all list collections (new icicle-mctized-full-candidate).
+;;       Adjust PRED to use cdr only for conses with string cars.
+;;     icicle-mctized-full-candidate:
+;;       Treat all kinds of list entries: strings, symbols, and conses with symbol args, etc.
+;; 2008/08/25 dadams
+;;     icicle-display-candidates-in-Completions: Do nothing if NO-DISPLAY-P is 'no-msg.
+;; 2008/08/24 dadams
+;;     icicle-filter-wo-input: Filter out empty-string candidates: "".
+;;     Added: icicle-minibuf-input-sans-dir.
+;;     Renamed: icicle-minibuffer-contents-from-minibuffer to icicle-input-from-minibuffer,
+;;              icicle-minibuffer-contents to icicle-minibuf-input.
+;;     icicle-display-candidates-in-Completions, icicle-next-candidate, icicle-place-cursor:
+;;       Use icicle-minibuf-input-sans-dir.
+;; 2008/08/23 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Wrap preliminary display of *Completions* in save-selected-window.
+;; 2008/08/22 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Display *Completions* before calling with-output-to-temp-buffer and filling it.
+;;        This is so we can know the window width, to determine the correct formatting.
+;;     icicle-insert-candidates:
+;;       Don't use lru window or *-Completions-*-default-width (removed).  Failsafe width 40.
+;; 2008/08/21 dadams
+;;     icicle-completing-read:
+;;       Bind minibuffer-completing-file-name to nil if not completing a file name.
+;;       Removed setq of minibuffer-completion-table. Already do it in *-lisp-vanilla-*.
+;; 2008/08/20 dadams
+;;     icicle-insert-candidates:
+;;       Turn off mouse-face after insert candidate.
+;;       Fixup whitespace correctly: Don't remove whitespace that is part of a candidate.
+;;     Added: icicle-ding.
+;;     icicle-read-number: Replaced ding by icicle-ding.
+;; 2008/08/18 dadams
+;;     Moved here from icicles-cmd.el (and renamed from *-less-p): icicle-cdr-lessp.
+;;     Added: icicle-delete-count, icicle-mctize-all, icicle-mctized-(display|full)-candidate,
+;;            icicle-part-1-cdr-lessp.
+;;     Renamed: icicle-delete-if(-not)     to icicle-remove-if(-not),
+;;              icicle-put-alist-candidate to icicle-put-whole-cand-prop,
+;;              icicle-update-completions  to icicle-complete-again-update.
+;;     icicle-completing-read: Factored out transformation to MCT into new fn icicle-mctize-all.
+;; 2008/08/08 dadams
+;;     icicle-completing-read: Updated doc string for Emacs 23.
+;; 2008/08/03 dadams
+;;     icicle-completing-read: Convert the predicate to apply to just the cdr (= original cons).
+;;     icicle-save-or-restore-input: Don't save empty string ("") to C-l history.
+;; 2008/07/27 dadams
+;;     Added: icicle-2nd-part-string-less-p.
+;;     Moved here from icicles-mcmd.el: icicle-transform-multi-completion.
+;; 2008/07/19 dadams
+;;     icicle-choose-completion-string: Don't move to point-max unless in minibuffer.
+;; 2008/06/24 dadams
+;;     Make *-must-match-filename-map an alias for *-filename-completion-map.  Use the latter.
+;; 2008/06/22 dadams
+;;     icicle-completing-read, icicle-read-file-name:
+;;       Remove text properties from result (only) if icicle-unpropertize-*-flag.
+;; 2008/06/21 dadams
+;;     icicle-read-file-name: Remove text properties from result file name.
+;; 2008/06/01 dadams
+;;     icicle-lisp-vanilla-completing-read: Typo: minibuffer-local-must-match-filename-map.
+;;     Put sort predicate properties on some sort predicate symbols, e.g. icicle-dirs-last-p.
+;; 2008/05/22 dadams
+;;     icicle-read-file-name: Bind minibuffer-completing-file-name to t.
+;;     icicle-read-file-name-1: Do not prepend ". " if Emacs 23+, since it uses completing-read.
+;;     icicle-(un)highlight-lighter: Reflect case-sensitivity in lighter.
+;; 2008/05/11 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates:
+;;       Pass input to all-completions only if not icicle-apropos-complete-match-fn.
+;; 2008/05/11 dadams
+;;     Renamed icicle-fit-Completions-window to icicle-fit-completions-window.
+;;     icicle-fit-completions-window: Use current window - not necessarily for *Completions*.
+;; 2008/05/06 dadams
+;;     icicle-highlight-lighter: Wrap redisplay in condition-case to ignore any errors.
+;; 2008/05/05 dadams
+;;     icicle-file-name-input-p: Redefined to just use minibuffer-completing-file-name.
+;; 2008/05/01 dadams
+;;     icicle-lisp-vanilla-completing-read, icicle-lisp-vanilla-completing-read,
+;;       icicle-read-from-minibuffer, icicle-read-number, icicle-read-string-completing:
+;;         Adapted to Emacs 23 change to allow list of strings for default value.
+;; 2008/04/25 dadams
+;;     icicle-call-then-update-Completions:
+;;       nil icicle-test-for-remote-files-flag means don't test for remote file name.
+;;     icicle-highlight-input-noncompletion:
+;;       Correction: implicit, not always, in combination with not incremental completion.
+;;       Added check for icicle-completing-command if value is explicit*.
+;;       Added check for icicle-test-for-remote-files-flag if *-strict with lax completion.
+;;       Protect call to icicle-file-remote-p with check of icicle-test-for-remote-files-flag.
+;; 2008/04/18 dadams
+;;     Renamed icicle-init-value-flag to icicle-default-value.
+;;     icicle-read-from-minibuffer:
+;;       If icicle-default-value is t, add to prompt.  Thx to Dominique Quatrevaux.
+;;     icicle-completing-read, icicle-read-file-name-1, icicle-read-from-minibuffer:
+;;       Change icicle-default-value test to rule out t also.
+;;     icicle-completion-setup-function:
+;;       Don't call file-name-directory unless minibuffer-completing-file-name.
+;; 2008/04/01 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates:
+;;       If icicle-unsorted-apropos-candidates pass input to all-completions.
+;;     icicle-expanded-common-match-1: 
+;;       Use icicle-apropos-complete-match-fn throughout, but return nil if that is nil.
+;;     icicle-display-candidates-in-Completions:
+;;       If icicle-apropos-complete-match-fn is nil, don't try to highlight input match.
+;; 2008/03/31 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Allow for no completion type, for No completions msg.
+;; 2008/03/30 dadams
+;;     icicle-read-file-name-1:
+;;       Bind read-file-name-function to nil.
+;;       Funcall icicle-old-read-file-name-fn instead of old-read-file-name.
+;;     icicle-(un)highlight-lighter: Respect icicle-highlight-lighter-flag.
+;;     Top-level: Moved fset for old-read-file-name to icicles-mode.el and renamed it.
+;; 2008/03/29 dadams
+;;     icicle-completing-read, icicle-read-file-name-1:
+;;       Combine new faces for single-character minibuffer completion status indicator.
+;;       Call icicle-highlight-lighter after establishing require-match, not at beginning.
+;;       No longer use completing-prompt-prefix(-symb).
+;;       No longer use icicle-reminder-prompt-flag (no longer add help to prompt).
+;;     Removed: icicle-control-reminder-prompt.
+;;     icicle-highlight-lighter:
+;;       Combine faces for highlighting.  Indicate multi-command and strict/lax completion.
+;;     icicle-unhighlight-lighter: Add + for multi-command.  Don't bother to propertize strg.
+;;     icicle-file-remote-p: If name matches Windows drive letter, don't try other remote tests.
+;; 2008/03/11 dadams
+;;     icicle-completing-read-history:
+;;       Convert cons list elements to strings.  Lets you use M-o with command-history.
+;; 2008/03/09 dadams
+;;     Added: icicle-(un)highlight-lighter.
+;;     icicle-completing-read, icicle-read-file-name: Call icicle-highlight-lighter.
+;; 2008/03/08 dadams
+;;     icicle-completing-p: Replaced where-is-internal test with completion keymaps test.
+;; 2008/03/05 dadams
+;;     icicle-completing-read:
+;;       Copy TABLE etc. only if candidates are strings.  Thx to Damon Permezel for bug report.
+;;     icicle-files-within: Skip inaccessible directories and unreadable files.  Thx to Damon.
+;; 2008/02/28 dadams
+;;     icicle-completing-read: Fixed test for multicompletion: List of strings, not just list.
+;; 2008/02/24 dadams
+;;     Added: icicle-scatter(-match).
+;;     icicle-display-*-in-Completions: Highlighting of input match can use icicle-scatter.
+;;                                      Use icicle-apropos-complete-match-fn in message.
+;;     icicle-expanded-common-match-1: Use icicle-apropos-complete-match-fn, not string-match.
+;; 2008/02/23 dadams
+;;     icicle-completing-read:
+;;       Change initial-input to a cons with 0 position if icicle-init-value-flag is *-start.
+;;     icicle-lisp-vanilla-completing-read: Set position to end of initial-input, by default.
+;;                                          Convert zero-based position to one-based.
+;; 2008/02/22 dadams
+;;     icicle-completing-read:
+;;       For all alist candidates (not just multi-completion):
+;;         Copy the car and replace the cdr with the whole candidate.
+;;     icicle-get-alist-candidate: Get and return just whole icicle-whole-candidate property.
+;;     icicle-completion-setup-function (for Emacs 20):
+;;       minibuffer-prompt-end -> icicle-minibuffer-prompt-end.
+;; 2008/02/16 dadams
+;;     icicle-get-alist-candidate:
+;;       Reconstitute whole candidate, by consing string onto data, which is only the cdr now.
+;;     icicle-completing-read: Use icicle-put-alist-candidate to put candidate data onto string.
+;;     Added: icicle-put-alist-candidate.  Put only the cdr (data), not whole, onto the string.
+;; 2008/02/14 dadams
+;;     Added: icicle-substring-no-properties.
+;; 2008/02/11 dadams
+;;     icicle-read-string-completing: Moved save-match-data so replace-match can use match data.
+;; 2008/02/06 dadams
+;;     icicle-highlight-input-noncompletion:
+;;       Wait icicle-highlight-input-completion-failure-delay before highlighting.
+;;       Don't highlight if past icicle-highlight-input-completion-failure-threshold.
+;;       Combined input-pending test with highlighting test, and moved it before file-name test.
+;;       Conditionalized face removal.
+;;       Return nil when input within delay preempts highlighting.
+;;     icicle-highlight-initial-whitespace: Removed only vestigial whitespace highlighting.
+;;     icicle-read-number: Moved save-match-data outside cond.
+;; 2008/02/03 dadams
+;;     icicle-choose-completion-string:
+;;       Go to point-max before insert choice.  Respect icicle-dir-candidate-can-exit-p.
+;;     icicle-completion-setup-function:
+;;       Set default dir only if this is a completion cmd or not *-comp-base-is-default-dir-p.
+;;       If icicle-comp-base-is-default-dir-p, set completion-base-size to default-dir length.
+;;     icicle-read-file-name: Bind ffap vars to prevent slowing down ffap-guesser.
+;; 2008/01/29 dadams
+;;     Added: icicle-(apropos|prefix)-any(-file-name)-candidates-p,
+;;            icicle-subst-envvar-in-file-name, icicle-highlight-input-noncompletion-rest,
+;;            icicle-any-candidates-p, icicle-file-remote-p.
+;;     icicle-minibuffer-contents-from-minibuffer: Use icicle-subst-envvar-in-file-name.
+;;     icicle-call-then-update-Completions:
+;;       Reinitialize icicle-input-fail-pos to nil.
+;;       If we know input is a remote file name from failure highlighting, skip remote test.
+;;       Use icicle-file-remote-p, not file-remote-p.
+;;     icicle-highlight-input-noncompletion: Rewrote.
+;;       Takes no args now.
+;;       Do nothing if input pending or input is empty.
+;;       Use icicle-file-remote-p, not file-remote-p.  Return value indicating remote file name.
+;;       Use new values of icicle-highlight-input-completion-failure, including always.
+;;       First check through last two chars, then icicle-highlight-input-noncompletion-rest.
+;;     icicle-highlight-input-noncompletion-rest (was in icicle-highlight-input-noncompletion):
+;;       No longer use icicle-max-chars-noncompletion-highlight.
+;;       Use icicle-any-candidates-p, so don't compute candidate lists.
+;; 2008/01/15 dadams
+;;     icicle-command-abbrev-save: Added condition-case with message in case of error.
+;;     icicle-control-reminder-prompt: Added message.
+;; 2008/01/13 dadams
+;;     icicle-read-face-name: Use icicle-transform-multi-completion.
+;;     icicle-next-candidate: Do not use icicle-transform-multi-completion.
+;;     icicle-next-candidate, icicle-save-or-restore-input: Do not treat handle-switch-frame.
+;; 2008/01/08 dadams
+;;     Renamed icicle-expanded-common-match to icicle-expanded-common-match-1.
+;;     New icicle-expanded-common-match uses longest of two tries.
+;;     icicle-expanded-common-match-1, first loop: Match ecm only up to orig-match-end.
+;;     icicle-read-file-name: Use icicle-var-is-of-type-p for proxy candidates.
+;;     icicle-choose-completion-string, icicle-strip-ignored-files-and-sort,
+;;       icicle-filter-wo-input, icicle-first-matching-candidate,
+;;       icicle-(proxy-candidate|prefix-keys)-first-p,  icicle-var-(matches|inherits)-type-p,
+;;       icicle-read-(number|face-name|file-name|string-completing),
+;;       icicle-unsorted(-file-name)-prefix-candidates, icicle-expanded-common-match-1,
+;;       icicle-next-candidate, icicle-remove-dots: Wrap string-match in save-match-data.
+;;     icicle-display-candidates-in-Completions: Moved save-match-data locations.
+;; 2008/01/05 dadams
+;;     icicle-next-candidate: Don't refresh Completions if last-command = handle-switch-frame.
+;; 2008/01/04 dadams
+;;     icicle-insert-candidates: Put property icicle-keep-newline on final \n of candidate.
+;; 2007/12/31 dadams
+;;     icicle-choose-completion-string: In minibuffer, delete all input before inserting.
+;; 2007/12/27 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates:
+;;       Use null *-apropos-*-match-fn, not function-valued TABLE to inhibit input match.
+;; 2007/12/26 dadams
+;;     icicle-next-candidate: Raise *Completions* frame at the end.
+;; 2007/12/24 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates:
+;;       Don't match input regexp if minibuffer-completion-table is a function.
+;;     icicle-var-inherits-type-p:
+;;       Recheck var-type match after set var-type to its car.
+;;       Handle string (regexp) TYPES elements.
+;;     icicle-value-satisfies-type-p: Skip type check for string type (regexp).
+;;     icicle-var-is-of-type-p: Doc string.  Use icicle-var-matches-type-p.
+;;     Added: icicle-var-matches-type-p, icicle-custom-type.
+;; 2007/12/23 dadams
+;;     icicle-var-is-of-type-p:
+;;       Added MODE arg.  Use icicle-var-inherits-type-p, icicle-var-val-satisfies-type-p.
+;;       Redefined as MODE choice, not just a simple or.  Treat more cases.
+;;     Added: icicle-var-inherits-type-p, icicle-var-val-satisfies-type-p,
+;;            icicle-value-satisfies-type-p.
+;;     icicle-read-(number|char-exclusive|string-completing|face-name):
+;;       Don't fill icicle-proxy-candidates unless icicle-add-proxy-candidates-flag.
+;;       Corrected doc string to refer to icicle-add-proxy-candidates-flag.
+;; 2007/12/22 dadams
+;;     icicle-var-is-of-type-p:
+;;       Check supertypes also.  Use both :validate and :match.
+;;       Wrap type check in condition-case. Use widget-put instead of plist-put.
+;;     Added soft require of wid-edit+.el.
+;; 2007/12/21 dadams
+;;     icicle-var-is-of-type-p: Use :validate, not :match, for the test.
+;; 2007/12/19 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Ensure icicle-last-input is non-nil in (file-name-directory icicle-last-input).
+;; 2007/12/14 dadams
+;;     icicle-fit-Completions-window:
+;;       Don't try to get a property if it's not a symbol.  Thx to Mike Mattie.
+;; 2007/12/11 dadams
+;;     Added: icicle-read-char-exclusive.
+;;     icicle-read-face-name: Include face-name vars as proxy candidates.
+;; 2007/12/10 dadams
+;;     icicle-highlight-input-noncompletion: Use face icicle-input-completion-fail-lax also.
+;; 2007/12/09 dadams
+;;     icicle-highlight-input-noncompletion: Respect icicle-max-chars-noncompletion-highlight.
+;; 2007/12/08 dadams
+;;     icicle-read-file-name:
+;;       Include file-name variables as proxy candidates.  Reset icicle-proxy-candidates at end.
+;;     icicle-read-number: float type is not defined before Emacs 22.
+;;     icicle-read-string-completing:
+;;       Set default to "" if nil, but only after completing-read.
+;;       Set car of hist to var value, replacing var name.  Treat consp hist also.
+;; 2007/12/03 dadams
+;;     Renamed icicle-longest-common-match to icicle-expanded-common-match.
+;; 2007/12/02 dadams
+;;     Added: icicle-var-is-of-type-p.
+;;     icicle-read-(number|string-completing):
+;;       Use icicle-var-is-of-type-p, to handle compatible types.
+;; 2007/11/30 dadams
+;;     icicle-read-file-name, icicle-read-(number|string-completing),
+;;       icicle-display-candidates-in-Completions, icicle-proxy-candidate-first-p:
+;;         Use only membership in icicle-proxy-candidates, not icicle-proxy-candidate property.
+;;     icicle-choose-completion-string:
+;;       Condition for exit: could be no minibuffer-completion-table if extra or proxy cands.
+;; 2007/11/29 dadams
+;;     icicle-read-(number|string-completing):
+;;       Treat icicle-add-proxy-candidates-flag and icicle-proxy-candidates.
+;;     icicle-display-candidates-in-Completions: Treat empty icicle-completion-candidates.
+;; 2007/11/27 dadams
+;;     Added: icicle-read-number, icicle-read-string-completing.
+;;     icicle-read-file-name: Remove icicle-proxy-candidate property in unwind-protect.
+;; 2007/11/25 dadams
+;;     Added: icicle-command-abbrev(-save|-used-more-p).
+;; 2007/11/24 dadams
+;;     icicle-longest-common-match,  first loop: string-match -> not string-match.
+;;                                               len-first -> length of lcm.
+;;     Added: icicle-proxy-candidate-first-p.
+;; 2007/11/18 dadams
+;;     icicle(-unsorted)(-file-name)-(apropos|prefix)-candidates:
+;;       Include also icicle-proxy-candidates.
+;;       Move special and proxy candidates inside match filtering.
+;;     icicle-display-candidates-in-Completions:
+;;       Don't expand directory when highlighting special candidate.
+;; 2007/11/02 dadams
+;;     icicle-longest-common-match:
+;;       First loop: (1) match against at most len-first, (2) put the match into the and test.
+;; 2007/10/28 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Always highlight longest common match for prefix completion.
+;;     icicle-unsorted(-file-name)-prefix-candidates, icicle-fuzzy-candidates:
+;;       Set icicle-common-match-string, regardless of icicle-expand-input-*-flag.
+;;     icicle-save-or-restore-input:
+;;       Update to lcm even if no input change, if completion mode changed.
+;;       Update to lcm if prefix completing, even if icicle-expand-input-*-flag is nil.
+;;       Save input for C-l even if this command is an icicle-completing-command (?).
+;;       Don't reset raw input to "" if cycling, so keep highlight in *Completions*.
+;;     icicle-longest-common-match: Test prefix through embedded input each time.
+;; 2007/10/26 dadams
+;;     icicle-read-face-name (Emacs 22): Fix the treatment of default value.
+;; 2007/10/22 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Highlight only regexp matching part of special candidates.
+;;       Highlight special cands regardless of icicle-highlight-historical-candidates-flag.
+;; 2007/10/02 dadams
+;;     icicle-next-candidate:
+;;       Apply abbreviate-file-name to file-name input.  Thx to Joonhwan Lee.
+;; 2007/09/29 dadams
+;;     Added: icicle-fuzzy-candidates.
+;;     icicle-prefix-candidates: Treat fuzzy completion.
+;;     icicle-display-candidates-in-Completions:
+;;       For prefix completion, highlight literal input match in Completions.
+;; 2007/09/26 dadams
+;;     icicle-read-from-minibuffer: Removed keep-all arg - see also 2006/06/01.
+;; 2007/09/22 dadamms
+;;     icicle-completing-read, icicle-read-from-minibuffer:
+;;       Ensure that init arg is string when get it from default arg via icicle-init-*-flag.
+;; 2007/09/18 dadams
+;;     icicle-call-then-update-Completions:
+;;       Test icicle-current-completion-mode, not icicle-last-completion-command.
+;; 2007/09/16 dadams
+;;     icicle-call-then-update-Completions:
+;;       Don't complete if file-remote-p.
+;;       Highlight completion failure only if input > icicle-*-display-min-input-chars.
+;;     icicle-highlight-input-noncompletion:
+;;       Don't highlight unless also icicle-incremental-completion-flag.
+;;       Call icicle-file-name-*-candidates for file-name input.
+;;       Don't highlight if file-remote-p and reading file name.  Instead, remove highlighting.
+;; 2007/09/14 dadams
+;;     icicle-highlight-input-noncompletion, icicle-update-completions,
+;;       icicle-recompute-candidates:
+;;         Wrapped condition-case around candidates computation.
+;; 2007/09/02 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Restore point and window point to start of candidates in *Completions*.
+;; 2007/08/21 dadams
+;;     icicle-highlight-input-noncompletion: Remove any vestigial highlighting on matched part.
+;; 2007/08/19 dadams
+;;     Added: icicle-lisp-vanilla-completing-read, icicle-highlight-input-noncompletion.
+;;     icicle-completing-read:
+;;       Allow reading and returning string candidates with properties:
+;;         bind minibuffer-allow-text-properties.
+;;       Put whole candidate on string as text property.
+;;       Use icicle-lisp-vanilla-completing-read, not old-completing-read.
+;;     icicle-call-then-update-Completions: Call icicle-highlight-input-noncompletion.
+;;     icicle-get-alist-candidate:
+;;       If icicle-whole-candidate-as-text-prop-p, try to get full candidate from text prop.
+;; 2007/08/16 dadams
+;;     icicle-insert-candidates: Don't reset text props if endpos > point.  Thx Chris Hecker.
+;; 2007/08/14 dadams
+;;     icicle-increment-cand-nb+signal-end: Removed audible bell - use visible bell only.
+;; 2007/07/22 dadams
+;;     icicle-read-face-name (Emacs 22 version):
+;;       Revert multiple branch to not use icicle-make-face-candidate.
+;;     Moved here from icicles-mode.el: icicle-completing-p.
+;; 2007/07/06 dadams
+;;     icicle-display-candidates-in-Completions: Leave cursor at start of candidates.
+;; 2007/07/03 dadams
+;;     icicle-save-or-restore-input:
+;;       Add current-raw-input to icicle-previous(-non)-file-*-raw-inputs, respecting max len.
+;;       Don't save input if current command is C-l or C-L.
+;;       If don't save raw input, set it to empty string.
+;;     Added: icicle-put-at-head.
+;;     icicle-highlight-complete-input: Ensure no error treatment in call to search-forward.
+;;     icicle-display-candidates-in-Completions:
+;;       Ensure non-nil current(-raw)-input, for highlight.
+;; 2007/06/23 dadams
+;;     Added: icicle-completing-read-history.
+;;     Moved here from icicles-cmd.el: icicle-read-from-minibuf-nil-default.
+;; 2007/06/20 dadams
+;;     icicle-make-face-candidate, icicle-read-face-name:
+;;       Use new string value of icicle-WYSIWYG-Completions-flag.
+;; 2007/06/19 dadams
+;;     icicle-read-face-name:
+;;       Use a multi-completion, depending on icicle-WYSIWYG-Completions-flag.
+;;       For Emacs 22, isolate the multiple case and do nothing for it.
+;;     icicle-make-face-candidate: Treat also whole-number value for icicle-WYSIWYG-*-flag.
+;; 2007/06/17 dadams
+;;     icicle-make-face-candidate: Respect icicle-WYSIWYG-Completions-flag.
+;;     icicle-display-candidates-in-Completions: highlight saved candidates.
+;;     icicle-place-overlay: Added priority arg.
+;; 2007/06/13 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Upgrade icicle-incremental-completion-p only if redisplaying.  Thx Mark Elston.
+;; 2007/06/10 dadams
+;;     Removed unconditional add-hook for icicle-fit-Completions-window.
+;; 2007/06/09 dadams
+;;     icicle-insert-candidates: Don't mouse-face last char of candidate if it is a newline.
+;;     icicle-display-candidates-in-Completions: Treat icicle-candidate-properties-alist last.
+;; 2007/06/07 dadams
+;;     icicle-read-face-name: Use (icicle-)face-name-history.
+;; 2007/06/05 dadams
+;;     Added soft require of hexrgb.el, but only if window-system.
+;;     icicle-color*: Protected with featurep hexrgb and error message.
+;; 2007/06/01 dadams
+;;     icicle-completing-read, icicle-read-from-minibuffer, icicle-read-string:
+;;       Use M@R%M=X!L$S+P&L^T*Z to avoid name capture by minibuffer-history-variable's value.
+;;     icicle-display-candidates-in-Completions, icicle-historical-alphabetic-p,
+;;       icicle-most-recent-first-p:
+;;         Ensure value of minibuffer-history-variable is bound.
+;; 2007/05/29 dadams
+;;     icicle-call-then-update-Completions: Don't recomplete if only one candidate.
+;; 2007/05/24 dadams
+;;     icicle-completing-read, icicle-read-file-name:
+;;       Fix length test for consp initial-input.  Thx to Anupam Sengupta.
+;; 2007/05/04 dadams
+;;     icicle-unsorted-*: C-g quits to top-level.
+;;     icicle-candidate-set-1, icicle-scroll-or-update-*, icicle-msg-maybe-in-minibuffer:
+;;       Move to minibuffer window for minibuffer-message.
+;;     icicle-display-candidates-in-Completions, icicle-highlight-initial-whitespace,
+;;     icicle-unsorted-file-name-*-candidates, icicle-longest-common-match,
+;;     icicle-next-candidate, icicle-place-cursor, icicle-highlight-complete-input,
+;;       icicle-special-candidates-first-p, icicle-case-string-less-p:
+;;         Use read-file-name-completion-ignore-case, if completing file name.
+;;     Moved mention of read-file-name-completion-ignore-case and
+;;       icicle-cycle-into-subdirs-flag from icicle-completing-read to icicle-read-file-name.
+;;     Added empty defvars for Emacs 22 standard vars, to quiet byte compiler.
+;; 2007/04/29 dadams
+;;     Added: icicle-last-modified-first-p.
+;;     icicle-call-then-update-Completions: Delete icicle-complete-input-overlay.
+;; 2007/04/08 dadams
+;;     Added: icicle-highlight-candidate-in-Completions, from code in icicle-next-candidate.
+;;            But changed to: 1) make Completions dedicated and 2) not bind case-fold-search.
+;;     icicle-next-candidate: Use icicle-highlight-candidate-in-Completions.
+;; 2007/04/02 dadams
+;;     Moved here from icicles-cmd.el: icicle-filter-alist, icicle-first-matching-candidate.
+;; 2007/04/01 dadams
+;;     icicle-insert-candidates: Don't fixup-whitespace if bolp.
+;; 2007/03/30 dadams
+;;     icicle-fit-Completions-window: Don't resize *Completions* window if split horizontally.
+;;     icicle-insert-candidates:
+;;       Calculate nb of columns using max-candidate-len, not number of candidates.
+;;       Indent at least one colwidth, and leave less space between candidates.
+;; 2007/03/26 dadams
+;;     icicle-completion-setup-function:
+;;       Protected minibuffer-completing-symbol with boundp (not define in Emacs 23).
+;; 2007/03/23 dadams
+;;     icicle-completing-read, icicle-read-file-name:
+;;       Record require-match in icicle-require-match-p.
+;; 2007/03/17 dadams
+;;     icicle-read-face-name: Undo Emacs 21+ brain-dead treatment of PROMPT arg.
+;; 2007/03/14 dadams
+;;     icicle-fit-Completions-window:
+;;       Don't let *Completions* take over the frame, so don't lose other window.
+;;       Respect icicle-Completions-window-max-height property of top-level command.
+;; 2007/03/12 dadams
+;;     Added: icicle-fit-Completions-window.  Use in temp-buffer-show-hook.
+;;     icicle-display-completion-list:
+;;       Print help lines here, not in icicle-completion-setup-*, so window fit includes them.
+;;       Put face on string candidates intro string, Possible completions are:.
+;;     icicle-completion-setup-function:
+;;       Don't print the help lines here.
+;;       Updated wrt latest Emacs 22 CVS version.
+;;     icicle-insert-Completions-help-string: Remove second newline at end.
+;;     icicle-start-of-candidates-in-Completions: Advance 1 or 2 lines, not 0 or 3.
+;; 2007/03/10 dadams
+;;     icicle-display-completion-list: Rewrote to adjust columns to window width.
+;;     Added: icicle-insert-candidates.
+;; 2007/03/09 dadams
+;;     Moved icicle-get-alist-candidate here from icicles-cmd.el.
+;; 2007/03/07 dadams
+;;     icicle-choose-completion-string, icicle-next-candidate:
+;;       Use 0, not t, as frame arg to get-buffer-window.
+;; 2007/03/04 dadams
+;;     icicle-highlight-initial-whitespace: Removed unused local var input-start-position.
+;;     icicle-completing-read: Do not initialize icicle-candidates-alist.
+;; 2007/03/03 dadams
+;;     icicle-reversible-sort: Don't display Sorting candidates message - too annoying.
+;; 2007/03/02 dadams
+;;     icicle-completion-setup-function for Emacs 22: Don't use file-name-directory if nil.
+;; 2007/03/01 dadams
+;;     icicle-completing-read: Initialize icicle-candidates-alist.
+;; 2007/02/24 dadams
+;;     icicle-next-candidate:
+;;       Transform multi-completion icicle-last-completion-candidate.
+;;       If last-command is icicle(mouse)-remove-candidate don't reset common match string or
+;;         redisplay *Completions*.
+;;     icicle-recompute-candidates:
+;;       Don't recompute if icicle-last-completion-command is icicle-mouse-remove-candidate.
+;; 2007/02/18 dadams
+;;     icicle-save-or-restore-input: Use "" if file-name-directory is nil.  Thx Shreevatsa R.
+;; 2007/02/17 dadams
+;;     icicle-reversible-sort: No Sorting... message if icicle-edit-update-p.  Thx Shreevatsa.
+;; 2007/02/05 dadams
+;;     icicle-completing-read: Added info about multi-completions to doc string.
+;; 2007/02/04 dadams
+;;     icicle-display-candidates-in-Completions: Fixed composition of multiple faces.
+;; 2007/02/03 dadams
+;;     Renamed icicle-icompleting-p to icicle-edit-update-p.
+;;     Require icicles-var.el.  Removed eval-when-compile for require of icicles-opt.
+;; 2007/02/02 dadams
+;;     icicle-case-string-less-p: Use var, not function, icicle-completing-p (else too slow).
+;;     icicle-reversible-sort: Added sorting progress message.
+;; 2007/01/29 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Allow for consp proplist value of icicle-special-candidate.
+;;     icicle-special-candidates-first-p: Added neither-special case.  Treat letter case.
+;;     Renamed: icicle-case-insensitive-string-lessp to icicle-case-insensitive-string-less-p.
+;;     Added: icicle-case-string-less-p.
+;;     icicle-historical-alphabetic-p, icicle-most-recent-first-p, icicle-dirs-last-p,
+;;       icicle-part-N-lessp, icicle-prefix-keys-first-p:
+;;         Use icicle-case-string-less-p, not string-lessp.
+;;     icicle-prefix-keys-first-p: Ignore case.
+;; 2007/01/28 dadams
+;;     Added: icicle-command-names-alphabetic-p.
+;;     Moved here from icicles-cmd.el:
+;;       icicle-prefix-keys-first-p, icicle-special-candidates-first-p.
+;; 2007/01/23 dadams
+;;     Added: icicle-read-face-name, icicle-make-face-candidate,
+;;            icicle-face-valid-attribute-values, icicle-color-name-w-bg.
+;;     icicle-choose-completion-string: Added Emacs 21 version.
+;;     icicle-display-candidates-in-Completions:
+;;       Only highlight past inputs if icicle-highlight-historical-candidates-flag.
+;; 2007/01/22 dadams
+;;     icicle-part-N-lessp, icicle-color-*-lessp: Do nothing if strings are not multipart.
+;;     icicle-display-candidates-in-Completions:
+;;       Highlight past inputs after treat *-prop*-alist.
+;;     icicle-delete-whitespace-from-string: Added optional args.
+;; 2007/01/21 dadams
+;;     Added: icicle-part-*-lessp, icicle-color-*-lessp.
+;; 2007/01/20 dadams
+;;     Added: icicle-display-completion-list.
+;; 2007/01/19 dadams
+;;     icicle-display-candidates-in-Completions: Treat icicle-candidate-properties-alist.
+;; 2007/01/15 dadams
+;;     Added: icicle-reversible-sort.  Use it where standard sort function was used.
+;;     Renamed: icicle-sort-and-strip-ignored to icicle-strip-ignored-files-and-sort,
+;;              icicle-sort-dirs-last to icicle-dirs-last-p,
+;;              icicle-sort-case-insensitively to icicle-case-insensitive-string-lessp.
+;;     Grouped sort functions together.
+;; 2007/01/14 dadams
+;;     icicle-next-candidate: Use icicle-transform-multi-completion.  Thx to Rubikitch.
+;;     icicle-transform-candidates: Updated doc string.
+;; 2007/01/12 dadams
+;;     icicle-next-candidate: Use icicle-list-use-nth-parts.  Thx to Rubikitch.
+;;     icicle-display-candidates-in-Completions: Added message when no-display-p.
+;; 2007/01/07 dadams
+;;     icicle-completing-read: Updated doc string for Emacs 22.
+;; 2007/01/06 dadams
+;;     Added: icicle-abbreviate-or-expand-file-name.
+;;     icicle-fix-default-directory: Use icicle-abbreviate-or-expand-file-name.
+;;     icicle-save-or-restore-input: expand-file-name -> icicle-abbreviate-or-expand-file-name.
+;;     icicle-completion-setup-function: Don't set default-directory to nil if minibuf empty.
+;;     icicle-read-file-name: Bug fix: Don't set initial-input to icicle-initial-value if "".
+;; 2007/01/05 dadams
+;;     icicle-completing-read, icicle-read-file-name:
+;;       Use existing string value of icicle-initial-value.  Thx to rubikitch for suggestion.
+;; 2007/01/01 dadams
+;;     Added assq-delete-all for Emacs 20 (moved here from icicles-mode.el).
+;;     Added: icicle-assoc-delete-all.
+;; 2006/12/25 dadams
+;;     Added: icicle-most-recent-first-p.
+;;     icicle-update-completions: Added optional no-display arg.
+;;     Moved here from icicles-opt.el: icicle-historical-alphabetic-p.
+;; 2006/11/10 dadams
+;;     icicle-completing-read, icicle-read-file-name: Prefix prompt by + if a multi-command.
+;; 2006/10/15 dadams
+;;     icicle-save-or-restore-input:
+;;       Change test from cmd is same as last to input is same as last.
+;;     icicle-rebind-completion-maps:
+;;       When turn off, bind C-M-mouse-2 and C-down-mouse-2 to nil.
+;;     icicle-display-candidates-in-Completions: Accumulate (merge) highlight faces.
+;;     Moved to icicles-mode.el:
+;;       icicle-bind-isearch-keys, icicle-rebind-completion-maps,
+;;       icicle-(redefine|restore)-standard-(commands|options),
+;;       icicle-(redefine|restore)-std-completion-fns), icicle-(re|un)map,
+;;       icicle-(bind|restore)-completion-keys, icicle-minibuffer-setup,
+;;       icicle-cancel-*Help*-redirection, icicle-activate-mark,
+;;       icicle-run-icicle-(pre|post)-command-hook, icicle-set-calling-cmd,
+;;       icicle-undo-std-completion-faces, icicle-update-ignored-extensions-regexp,
+;;       icicle-completing-p, icicle-restore-region-face.
+;;     Removed eval-when-compile of *-face, *-var, *-mac, *-cmd.
+;;     Removed some defvars for quieting byte compiler.
+;; 2006/10/05 dadams
+;;     icicle-display-candidates-in-Completions: Highlight candidates that are special.
+;; 2006/10/03 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Removed predicate filtering, as the pred doesn't necessarily apply to the candidate.
+;;       This has been in the code forever, so commented it out, in case it is needed ;-).
+;; 2006/10/01 dadams
+;;     icicle-alternative-sort -> icicle-toggle-alternative-sorting.
+;;     icicle-update-completions: Treat icicle-prefix-word-complete case too.
+;; 2006/09/30 dadams
+;;     Added: icicle-key-description.
+;;     icicle-(bind|restore)-completion-keys:
+;;       Bind icicle-candidate-set-(save|retrieve) to C-M-(<|>), not C-(<|>).
+;;       Bind icicle-toggle-angle-brackets to C-<.
+;;       No longer remap help-command to icicle-completion-help.
+;;       Bind icicle-completion-help to C-?.
+;;       Rename [menu-bar minibuf C-h] to [menu-bar minibuf completion-help].
+;;     icicle-completing-p: Bug fix: Use where-is-internal, not minibuffer-completion-table.
+;; 2006/09/22 dadams
+;;     icicle-minibuffer-setup:
+;;       Apropos-complete, don't prefix-complete, when icicle-show-Completions-initially-flag.
+;; 2006/09/17 dadams
+;;     icicle-completing-p: Ensure minibuffer is active too.
+;; 2006/09/16 dadams
+;;     Bound icicle-insert-key-description to M-q.
+;;     icicle-completing-read:
+;;       Use icicle-list-join-string only to join parts of candidate (alist key).
+;;       Append icicle-list-end-string instead.
+;;     icicle-msg-maybe-in-minibuffer: Fixed doc string (active -> inactive).
+;; 2006/09/12 dadams
+;;     icicle-minibuffer-setup: Set icicle-pre-minibuffer-buffer.
+;;     Renamed icicle-switch-to-minibuffer to icicle-insert-completion.
+;; 2006/09/03 dadams
+;;     Renamed icicle-show-Completions-help to icicle-show-Completions-help-flag.
+;; 2006/08/27 dadams
+;;     Bind Quit in Minibuf menu to icicle-abort-minibuffer-input.
+;; 2006/08/22 dadams
+;;     icicle-save-or-restore-input: If icicle-last-completion-candidate is nil, don't try to restore.
+;; 2006/08/18 dadams
+;;     icicle-minibuffer-setup: Reset icicle-last-completion-candidate to nil.
+;;     icicle-rebind-completion-maps:
+;;       Added icicle-Info-goto-node to icicle-completion-help-string.
+;; 2006/08/15 dadams
+;;     icicle-(bind|restore)-completion-keys:
+;;       Bind icicle-help-on-(previous|next)-(apropos|prefix)-candidate.
+;;       Reorder bindings.  Bind C-mouse-2 to 'ignore, not nil.
+;;     icicle-rebind-completion-maps: Bind icicle-help-on-* in completion-list-mode-map.
+;;     Added: icicle-barf-if-outside-Completions-and-minibuffer.
+;; 2006/08/13 dadams
+;;     icicle-completing-read, icicle-read-file-name: Use icicle-completing*-prompt-prefix.
+;; 2006/08/04 dadams
+;;     icicle-call-then-update-Completions:
+;;       Call icicle-last-completion-command, not just prefix or apropos (so prefix-word too).
+;;     icicle-completing-read, icicle-read-file-name, icicle-next-candidate,
+;;       icicle-recompute-candidates, icicle-call-then-update-Completions:
+;;         Use icicle-remove-Completions-window.
+;;     icicle-(bind|restore)-completion-keys: Bound icicle-pp-eval-expression to M-:.
+;; 2006/08/03 dadams
+;;     icicle-completion-setup-function: Removed useless highlighting code at end (Emacs 20).
+;;     icicle-rebind-completion-maps: Updated icicle-completion-help-string.
+;; 2006/07/30 dadams
+;;     icicle-call-then-update-Completions: save match-data.
+;; 2006/07/29 dadams
+;;     icicle-activate-mark: Do it only if icicle-completing-p.  Thx to Le Wang.
+;;     icicle-rebind-completion-maps:
+;;       Updated to use icicle-dispatch-C-..
+;;       Added icicle-toggle-search-cleanup to icicle-completion-help-string.
+;;     icicle-bind-completion-keys:
+;;       Use icicle-dispatch-C-. instead of icicle-toggle-ignored-extensions.
+;; 2006/07/28 dadams
+;;     icicle-longest-common-match: Treat special case of input such as "$" or "\\>$".
+;; 2006/07/24 dadams
+;;     icicle-call-then-update-Completions: Deactivate mark at the end.  Thx to Le Wang.
+;; 2006/07/23 dadams
+;;     Added: icicle-transform-candidates.
+;;     icicle-rebind-completion-maps, icicle-(bind|restore)-completion-keys:
+;;       Added icicle-toggle-transforming.
+;;     icicle-unsorted(-file-name)-*-candidates: Use icicle-transform-candidates.
+;; 2006/07/20 dadams
+;;     Renamed icicle-arrows-respect-* to icicle-cycling-respects-completion-mode-flag.
+;; 2006/07/19 dadams
+;;     Applied patch from Damien Elmes :
+;;       Added icicle-insert-help-string, icicle-start-of-completions (factored from existing).
+;;       icicle-completion-setup-function: Use icicle-insert-help-string.
+;;       icicle-display-candidates-in-Completions:
+;;         Use icicle-start-of-completions, and adjust loop accordingly.
+;;       icicle-minibuffer-setup:
+;;         Reset icicle-current-completion-type.
+;;         Bind (up|down) to icicle-*-context-candidate, not (previous|next)-history-element.
+;;       icicle-next-candidate: Use icicle-start-of-completions.
+;;       icicle-scroll-or-update-Completions: Use icicle-scroll-completions.
+;;     Renamed: icicle-start-of-completions to icicle-start-of-candidates-in-Completions,
+;;              icicle-insert-help-string to icicle-insert-Completions-help-string,
+;;              icicle-current-completion-type to icicle-current-completion-mode,
+;;              icicle-*-context-candidate to icicle-(next|previous)-candidate-per-mode,
+;;              icicle-scroll-completions to icicle-scroll-Completions.
+;;     icicle-minibuffer-setup:
+;;       Replaced icicle-display-Completions with icicle-prefix-complete, to get initial
+;;         highlight.
+;; 2006/07/18 dadams
+;;     icicle-call-then-update-Completions:
+;;       Delete *Completions* window, depending on icicle-Completions-display-min-input-chars.
+;;         Thx to Damien Elmes.
+;;     icicle-rebind-completion-maps: Add icicle-toggle-case-sensitivity to help list.
+;;     icicle-bind-completion-keys: Bind icicle-toggle-case-sensitivity to S-C-a (i.e. C-A).
+;; 2006/07/17 dadams
+;;     icicle-call-then-update-Completions: sit-for delay if no candidates.  Thx Damien Elmes.
+;; 2006/07/09 dadams
+;;     icicle-save-or-restore-input:
+;;       Put back test: current input differs from last cycling candidate (user has edited it).
+;;     icicle-next-candidate: Removed filtering with predicate (vestigial cruft).
+;; 2006/07/08 dadams
+;;     icicle-save-or-restore-input: Restore if currently cycling, not if not completing.
+;; 2006/07/07 dadams
+;;     icicle-display-candidates-in-Completions: Fixed test for historical candidate.
+;;     Bound icicle-alternative-sort to M-,.  Updated icicle-completion-help-string.
+;; 2006/07/05 dadams
+;;     icicle-save-or-restore-input:
+;;       For restoring: 1) No longer test if current input = *-last-completion-candidate.
+;;                      2) No longer test if current input = icicle-initial-value.
+;;       No longer save icicle-current-input as icicle-last-completion-candidate.
+;;       Simplified the code.
+;;     icicle-call-then-update-Completions: Do not set this-command or last-command.
+;;     Renamed: icicle-current-regexp-input to icicle-current-raw-input.
+;; 2006/07/04 dadams
+;;     icicle-unsorted(-file-name)-prefix-candidates: Update icicle-common-match-string.
+;;     icicle-unsorted-file-name-prefix-candidates:
+;;       If prefix matches an empty directory, then use that directory as the sole completion.
+;;     icicle-next-candidate: Use icicle-*-cycling-command properties.
+;;                            Removed regexp-p arg in calls to icicle-save-or-restore-input.
+;;     icicle-save-or-restore-input:
+;;       Update icicle-common-*-string and icicle-current-regexp-input even if not regexp-p.
+;;       Removed optional regexp-p argument.
+;;       Do not update icicle-last-completion-candidate.
+;;       Use icicle-*-*ing-command properties.
+;;     icicle-recompute-candidates: Use icicle-*-cycling-command properties.
+;; 2006/07/03 dadams
+;;     Bug fixes -
+;;       icicle-next-candidate:
+;;         Don't reset icicle-common-match-string if this is an apropos cycling command
+;;           and last command was an apropos command (cycling or completing).
+;;         Do icicle-save-or-restore-input a second time, after recompute candidates,
+;;           to pick up the common match.
+;;         Always pass icicle-current-input to icicle-place-cursor.
+;;       icicle-save-or-restore-input:
+;;         Don't do anything if last command was a cycling command.
+;;         Don't save input as regexp for C-l if this command is a cycling command,
+;;           unless it is the first or it follows a completion command.
+;; 2006/07/02 dadams
+;;     icicle-place-cursor: position point & mark at least past prompt.  Thx to Peter Povinec.
+;; 2006/06/09 dadams
+;;     icicle(-file-name)-(apropos|prefix)-candidates: Reset icicle-candidate-nb to nil.
+;;     icicle-recompute-candidates: Don't reset icicle-candidate-nb to nil.
+;;     icicle-place-cursor: Prevent error on search-forward.
+;; 2006/06/08 dadams
+;;     icicle-save-or-restore-input: Do not restore if current command is completion.
+;;     Added: icicle-expand-file-name.
+;;     icicle-next-candidate: Don't pass NTH arg to icicle-display-candidates-in-Completions.
+;; 2006/06/06 dadams
+;;     icicle-control-reminder-prompt: condition-case, since it's on kill-emacs-hook.
+;; 2006/06/01 dadams
+;;     icicle-read-from-minibuffer: Emacs 22 removed the keep-all arg it had added.
+;; 2006/05/31 dadams
+;;     icicle-barf-if-outside*: Simplified.
+;; 2006/05/30 dadams
+;;     Bind icicle-erase-minibuffer-or-history to M-k also in non-completion minibuffer maps.
+;; 2006/05/26 dadams
+;;     Bind icicle-erase-minibuffer-or-history to M-k.
+;;     Do not remap (or unmap) kill-sentence (it is on M-k in global map).
+;; 2006/05/19 dadams
+;;     Added: icicle-control-reminder-prompt.
+;;     icicle-reminder-*-flag, icicle-read-file-name: Treat new values of icicle-reminder*.
+;;     Renamed icicle-inhibit-reminder* to icicle-reminder*.
+;; 2006/05/16 dadams
+;;     icicle-recompute-candidates: Add new saved-last-input arg (replaces icicle-last-input).
+;;     icicle-next-candidate: Pass saved old last input to icicle-recompute-candidates.
+;; 2006/05/15 dadams
+;;     Reverted change to icicle-unsorted(-file-name)-apropos-candidates,
+;;       icicle-display-Completions: Use icicle-completion-nospace-flag, not nil.
+;;     Renamed: icicle-completion-nospace-flag to icicle-ignore-space-prefix-flag.
+;;     icicle-toggle-incremental-completion: C-#, icicle-toggle-ignored-space-prefix: C-^.
+;; 2006/05/13 dadams
+;;     icicle-unsorted(-file-name)-apropos-candidates, icicle-display-Completions:
+;;       Use nil, not icicle-completion-nospace-flag.
+;; 2006/05/12 dadams
+;;     icicle-completion-help-string: Added faces and commands. Cleanup.
+;;     Moved from icicles-cmd.el: icicle-barf-if-outside-*.
+;; 2006/05/09 dadams
+;;     icicle-display-*: Only issue Displaying... message when more candidates than threshold.
+;; 2006/05/01 dadams
+;;     icicle-save-or-restore-input: No-restore test is non-nil, not non-"", icicle-last-input.
+;;     icicle-minibuffer-setup: Reset icicle-last-input to nil, not "".
+;;     icicle-next-candidate: Highlight initial whitespace before underline root.
+;; 2006/04/28 dadams
+;;     icicle-save-or-restore-input:
+;;       Restore empty input if it is not a file name.
+;;       Don't expand empty common-match-string file-name input (it would lose trailing /).
+;;     Added: icicle-highlight-initial-whitespace.
+;;     icicle-next-candidate, icicle-call-then-update-Completions:
+;;       Use icicle-highlight-initial-whitespace.
+;; 2006/04/14 dadams
+;;     icicle-call-then-update-Completions: Call icicle-update-input-hook.
+;;     Bound icicle-insert-string-from-variable to C-=.  Update icicle-completion-help-string.
+;; 2006/04/09 dadams
+;;     icicle-bind-completion-keys, icicle-minibuffer-setup:
+;;       Deal with icicle-arrows-respect-completion-type-flag.
+;;     icicle-display-candidates-in-Completions:
+;;       Bug fix: regexp-quote common match when highlighting it.
+;;     icicle-clear-minibuffer: Remove interactive spec.
+;;     Moved to icicles-cmd.el: icicle-customize-apropos*, icicle-repeat-complex-command.
+;; 2006/04/02 dadams
+;;     Bound icicle-toggle-regexp-quote.
+;; 2006/03/31 dadams
+;;     icicle-next-candidate:
+;;       Apply icicle-place-cursor to icicle-current-regexp-input if regexp-p.
+;;     icicle-save-or-restore-input:
+;;       Don't set icicle-current-regexp-input if this is a next-candidate action.
+;; 2006/03/27 dadams
+;;     icicle-place-overlay: Made generic: added args overlay, face, buffer, properties.
+;; 2006/03/25 dadams
+;;     icicle-call-then-update-Completions: Corrected use of icicle-incremental-completion*.
+;; 2006/03/24 dadams
+;;     Renamed icicle-expand-input-to-common-match to icicle-longest-common-match.  Rewrote it.
+;;     icicle-call-then-update-Completions:
+;;       Use icicle-incremental-completion-delay and -threshold.
+;;     Mapped icicle-delete-char.
+;; 2006/03/23 dadams
+;;     icicle-expand-input-to-common-match:
+;;       Return the longest common match.  Don't set icicle-common-match-string here.
+;;     icicle-unsorted-*apropos-candidates: Set icicle-common-match-string here explicitly.
+;;     Added: icicle-maybe-sort-and-strip-candidates.  Use in icicle-candidate-set-1.
+;; 2006/03/22 dadams
+;;     icicle-display-candidates-in-Completions:
+;;       Removed root arg (always use icicle-current-input).
+;;       Always highlight normal match part.
+;;       Highlight common-match part if icicle-expand-input-to-common-match-flag.
+;;     icicle-save-or-restore-input:
+;;       Update regexp even if not icicle-expand-input-to-common-match-flag.
+;;     icicle-recompute-candidates: If no candidates, then delete *Completions* window.
+;;     icicle-next-candidate: Set default-directory only if icicle-file-name-input-p.
+;;     Applied renamings of icicle-match-* faces.
+;; 2006/03/21 dadams
+;;     icicle-expand-input-to-common-match:
+;;       Bug fixes:
+;;         If no overlap between first and second candidates, then no common match.
+;;         If no match with another candidate, then no common match.
+;;         Input must match computed common match.
+;;         When checking others, check only the added (pre|suf)fix, and reduce those as needed.
+;;     icicle-save-or-restore-input:
+;;       Bug fixes:
+;;         When icicle-expand-input-to-common-match-flag, expand using directory from the
+;;           input, not the default-directory.  Thx to cacher3.ericsson.net for report.
+;;         Do test for case-only difference only when case-fold-search.
+;;         If input is a directory (with slash), then use it as is.
+;;         Save icicle-current-regexp-input if no icicle-common-match-string too.
+;;     icicle-display-candidates-in-Completions: Use icicle-common-match-highlight-Completions.
+;; 2006/03/20 dadams
+;;     icicle-save-or-restore-input: Set icicle-current-regexp-input too.
+;;                                   Corrected letter-case test.
+;; 2006/03/19 dadams
+;;     Added: icicle-expand-input-to-common-match.
+;;     icicle-unsorted*-apropos-candidates:
+;;       Set icicle-common-match-string if icicle-expand-input-to-common-match-flag.
+;;     icicle-save-or-restore-input:
+;;       Added regexp-p arg.  Update input to icicle-common-match-string if appropriate.
+;;     icicle-next-candidate: Reset icicle-common-match-string.
+;; 2006/03/17 dadams
+;;     icicle-file-(read|writ)able-p: Put non-empty string condition first.
+;;     Added: icicle-delete-whitespace-from-string.
+;;     icicle-files-within: Moved here from icicle-cmd.el.
+;; 2006/03/14 dadams
+;;     Removed: icicle-reset-icicle-completing-p.
+;;     icicle-completing-read, icicle-read-file-name: Removed icicle-icicle-completing-p.
+;;     icicle-display-*: Added Displaying... message.
+;; 2006/03/13 dadams
+;;     Added: icicle-file-(read|writ)able-p.  Bound them to C-{ and C-} in minibuffer.
+;;     icicle-rebind-completion-maps, icicle-bind-completion-keys: Added the new commands.
+;;     icicle-recompute-candidates: Forgot icicle-keep-only-past-inputs in other branch.
+;; 2006/03/10 dadams
+;;     icicle-save-or-restore-input: Bug fix (thx Toby Cubitt) - Not relative to default dir.
+;;       Use directory-file-name, so don't include /.
+;;       Use file-name-nondirectory, not file-relative-name if not cycling into subdirs.
+;;     Renamed icicle-minibuffer-contents to icicle-minibuffer-contents-from-minibuffer.
+;;     Added new icicle-minibuffer-contents, which can be called outside minibuffer.
+;; 2006/03/08 dadams
+;;     icicle-place-overlay: Use new face, icicle-current-candidate-highlight.
+;; 2006/03/05 dadams
+;;     Bound icicle-toggle-incremental-completion to C-^ in minibuffer.
+;;     Updated icicle-completion-help-string with C-^ binding.
+;;     icicle-display-candidates-in-Completions:
+;;       Allow for on-the-fly changes to icicle-incremental-completion-flag.
+;; 2006/03/01 dadams
+;;     Added: icicle-clear-minibuffer.  Use in icicle-next-candidate.
+;; 2006/02/27 dadams
+;;     icicle-call-then-update-Completions: Set last-command to fn arg.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-mac.el'")
+;;
+;; ****************************************************************************************************
+;; NOTE: If you byte-compile Icicles (recommended), then WHENEVER `icicles-mac.el' is updated, you
+;;       must load `icicles-mac.el' (not just `icicles-mac.elc'), then compile it, then RECOMPILE *ALL*
+;;       of the other Icicles source files as well.  This is normal for Lisp: code that depends on
+;;       macros needs to be byte-compiled anew after loading the updated macros.
+;; ****************************************************************************************************
+;;
+;; 2011/09/08 dadams
+;;     font-lock-add-keywords - Use font-lock-keyword-face for icicle-condition-case-no-debug.
+;; 2011/08/27 dadams
+;;     icicle-condition-case-no-debug: Redefined so it respects debug-on-quit and keeps other handlers.
+;; 2011/08/24 dadams
+;;     Added top-level puts for common-lisp-indent-function.
+;;     icicle-condition-case-no-debug, icicle-with-selected-window: Removed declare declaration.
+;; 2011/08/22 dadams
+;;     icicle-maybe-byte-compile-after-load: Require bytecomp.el.
+;;     font-lock-add-keywords: Quote font-lock-function-name-face, for Emacs 20.
+;; 2011/08/21 dadams
+;;     Added: icicle-condition-case-no-debug.  Thx to Michael Heerdegen.
+;;     icicle-define(-file)-command: Use icicle-condition-case-no-debug.
+;; 2011/08/16 dadams
+;;     Added: icicle-maybe-byte-compile-after-load, icicle-byte-compile-eval-after-load-flag.
+;;     icicle-(buffer|file)-bindings: Use append, not backquote syntax.
+;; 2011/08/12 dadams
+;;     icicle-file-bindings: Removed binding of icicle-ignore-space-prefix-flag (to *-buffer-ignore-*).
+;; 2011/05/22 dadams
+;;     icicle-define(-file)-command: Use #',FUNCTION instead of ',FUNCTION.
+;;     icicle-with-selected-window, icicle-(buffer|file)-bindings:
+;;       Use #' with lambdas (not really needed).
+;; 2011/05/03 dadams
+;;     icicle-buffer-bindings, icicle-file-bindings:
+;;       Had to revert definition for Emacs > 20, but keep it for Emacs 20.  Thx to Michael Heerdegen.
+;; 2011/04/29 dadams
+;;     icicle-buffer-bindings, icicle-file-bindings:
+;;       Do not bind icicle-sort-comparer.  Instead, set it the first time
+;;         (per icicle-(buffer|file)-sort-first-time-p).
+;;       No side effects to icicle-sort-orders-alist.
+;;       If icicle-(buffer|file)-sort is non-nil then put it at the beginning.
+;;       Use old backquote syntax for post-bindings - needed because of vanilla Emacs 20 bug.
+;; 2011/04/25 dadams
+;;     icicle-file-bindings: Bind icicle-candidate-help-fn to icicle-describe-file w/ curr pref arg.
+;; 2011/04/12 dadams
+;;     icicle-buffer-bindings, icicle-file-bindings: Added optional POST-BINDINGS arg.
+;; 2011/04/02 dadams
+;;     icicle-buffer-bindings: Bind (new) icicle-bufflist, not bufflist.
+;; 2011/03/29 dadams
+;;     Renamed: orig-(buff|window) to icicle-orig-(buff|window).
+;; 2011/01/17 dadams
+;;     Require cl.el at compile time for Emacs 20.
+;; 2011/01/06 dadams
+;;     icicle-buffer-bindings: Zero prefix arg limits candidates to buffers with same mode as current.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     icicle-assoc-delete-all: Moved here from icicles-fn.el, since used here.
+;;     Added autoload cookies.
+;; 2010/10/25 dadams
+;;     icicle-(buffer|file)-bindings:
+;;       Use icicle-must-pass-after-match-predicate, not icicle-must-pass-predicate
+;; 2010/10/09 dadams
+;;     icicle-define(-file)-command: Update generated doc: down/up for modal, end/home for prefix.
+;; 2010/06/05 dadams
+;;     icicle-file-bindings: Put back non-insertion for non-ido-like case.
+;; 2010/06/04 dadams
+;;     icicle-(buffer|file)-bindings: Bind vars that depend on icicle-(buffers|files)-ido-like-flag.
+;; 2010/03/03 dadams
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer,
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist.
+;; 2009/12/21 dadams
+;;     fset -> defalias.
+;; 2009/12/13 dadams
+;;     icicle-define-sort-command: Add REVERSED to msg if reversed.
+;; 2009/10/22 dadams
+;;     icicle-define-file-command: Use icicle-file-name-directory, not file-name-directory.
+;; 2009/09/17 dadams
+;;     Added: icicle-file-bindings.
+;; 2009/09/16 dadams
+;;     Added: icicle-buffer-bindings.
+;;     icicle-define(-file)-command: Macroexpand bindings, (e.g. to use icicle-buffer-bindings).
+;; 2009/04/28 dadams
+;;     Moved icicle-choose-action-for-type to icicles-fn.el and changed to a function.
+;; 2009/04/26 dadams
+;;     Added: icicle-choose-action-for-type, icicle-with-selected-window.
+;; 2008/08/31 dadams
+;;     icicle-define(-file)-command: Select window before call select-frame-set-input-focus.
+;; 2008/08/18 dadams
+;;     icicle-try-switch-buffer: Do nothing if icicle-inhibit-try-switch-buffer is non-nil.
+;;     Use renaming from icicles-fn.el: icicle-complete-again-update.
+;; 2008/03/29 dadams
+;;     icicle-define(-file)-command: Do not call icicle-highlight-lighter.
+;; 2008/03/09 dadams
+;;     icicle-define(-file)-command: Call icicle-highlight-lighter.
+;; 2007/11/25 dadams
+;;     icicle-define(-file)-command:
+;;       Bound minibuffer variables, so they are restored after action function
+;;         (in case it uses minibuffer for completion).
+;;       Return nil after, not before select-frame-set-input-focus.
+;;       Added optional arg not-interactive-p.
+;;     Quiet the byte compiler for Emacs versions before 22.
+;; 2007/10/14 dadams
+;;     icicle-define(-file)-command:
+;;       Updated generated doc to reflect icicle-act-before-cycle-flag.
+;; 2007/05/01 dadams
+;;     icicle-define(-file)-command: Reset icicle-candidate-action-fn after reading input.
+;; 2007/04/15 dadams
+;;     icicle-define(-file)-command:
+;;       Simplified action fn: Removed unwind-protect and outer condition-case,
+;;       so don't return error msg now, and only set minibuf focus if succeed.
+;;     icicle-define(-file)-command, icicle-try-switch-buffer: Removed "%s" from handlers.
+;; 2007/02/06 dadams
+;;     icicle-define(-file)-command: Mention mouse bindings in command doc strings.
+;; 2007/01/15 dadams
+;;     Added: icicle-define-sort-command.
+;;     Updated font-lock-add-keywords.  Added lisp-indentation-hack (commented out).
+;; 2007/01/06 dadams
+;;     font-lock-add-keywords: 2 or 3, not 1 or 2, is index after add icicle-define-add-to-*.
+;;                             Use lax matching, so no error if no match.
+;; 2007/01/01 dadams
+;;     Added: icicle-define-add-to-alist-command.
+;;     Removed compile-time require of icicles-var.el.
+;;     font-lock-add-keywords:
+;;       "\\>[ \t'\(]*\\(\\sw+\\)?", not "\\s-+\\(\\sw\\(\\sw\\|\\s_\\)+\\)".
+;;       Added icicle-define-add-to-alist-command.
+;; 2006/10/14 dadams
+;;     Require icicles-var.el.
+;;     Moved conditional eval-when-compile to top level.
+;; 2006/09/24 dadams
+;;     icicle-define(-file)-command: Corrected bindings mentioned in doc strings.
+;; 2006/08/27 dadams
+;;     icicle-define(-file)-command: Ensure orig-window is live before using it.
+;; 2006/08/23 dadams
+;;     Added: icicle-try-switch-buffer.  Use it in icicle-define(-file)-command.
+;; 2006/08/03 dadams
+;;     icicle-define(-file)-command:
+;;       (error (error-message-string...)) -> (error "%s" (error-message-string...)).
+;; 2006/05/16 dadams
+;;     icicle-define(-file)-command: Treat cases where user wiped out orig-buff or orig-window.
+;; 2006/03/31 dadams
+;;     icicle-define(-file)-command: Wrap action fn in unwind-protect to select minibuf frame.
+;; 2006/03/11 dadams
+;;     icicle-define-file-command: Expand file in directory of icicle-last-input.
+;; 2006/03/08 dadams
+;;     icicle-define(-file)-command: Bug fix (thx to TobyCubitt):
+;;       Make sure icicle-candidate-action-fn runs FUNCTION in original buffer and window.
+;; 2006/03/07 dadams
+;;     icicle-define(-file)-command: Mention in doc string that BINDINGS are not in effect
+;;       within icicle-candidate-action-fn.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-mcmd.el'")
+;;
+;; 2011/09/09 dadams
+;;     icicle-switch-to-Completions-buf:
+;;       Do not set icicle-current-input to minibuffer content.  Use that content sans dir, locally.
+;;       If icicle-candidate-nb is defined, use it: just call icicle-move-to-next-completion.
+;;     icicle-insert-completion:
+;;       Set icicle-last-completion-candidate to COMPLETION.
+;;       Set icicle-candidate-nb to icicle-nb-of-cand-at-Completions-pos (point).
+;;       Use icicle-insert-cand-in-minibuffer COMPLETION, not just insert of directory + COMPLETION.
+;;       Set icicle-last-input to icicle-current-input.  Set icicle-cycling-p to t.
+;;       Call icicle-show-help-in-mode-line.
+;; 2011/09/07 dadams
+;;     icicle-erase-minibuffer-or-history-element, icicle-prefix-complete-1,
+;;       icicle-apropos-complete(-1|-no-display), icicle-all-candidates-action-1, icicle-describe-file,
+;;       icicle-apply-to-saved-candidate, icicle-narrow-candidates(-with-predicate): 
+;;         Use icicle-condition-case-no-debug instead of condition-case.  Thx to Michael Heerdegen.
+;; 2011/09/06 dadams
+;;     Added: icicle-resolve-file-name.
+;;     icicle-minibuffer-help: Call help-setup-xref, for back/forward buttons.
+;; 2011/09/05 dadams
+;;     Added: icicle-dispatch-C-x., icicle-toggle-hiding-non-matching-lines.
+;;     icicle-help-string-completion: Added hiding no-match lines.  Use icicle-dispatch-C-x..
+;; 2011/08/30 dadams
+;;     icicle-backward-delete-char-untabify, icicle-delete(-backward)-char:
+;;       Put delete-selection prop, so region is deleted.
+;; 2011/08/26 dadams
+;;     Make sure to pass format string as first arg to calls to functions error and message.
+;;     icicle-candidate-set-save-1: Use %s, not %S, in error format string.
+;; 2011/08/19 dadams
+;;     Fix C-u in minibuffer for Emacs 24:
+;;       Don't bother to define icicle-ensure-overriding-map-is-bound for Emacs 24+.
+;;       icicle-(universal|digit|negative)-argument:
+;;         Use save&set-overriding-map, not icicle-ensure-*, for Emacs 24.
+;; 2011/08/15 dadams
+;;     icicle-candidate-set-complement:
+;;       Apply icicle-must-pass-after-match-predicate to correct the initial domain subtracting from.
+;;       Use icicle-all-completions instead of its definition inline.
+;; 2011/08/13 dadams
+;;     Added: icicle-toggle-search-complementing-domain, toggle-icicle-search-complementing-domain.
+;;     icicle-insert-string-from-variable: Completion candidates now include all string-valued vars.
+;; 2011/08/12 dadams
+;;     Added: icicle-add/remove-tags-and-refresh, icicle-(un)bind-file-candidate-keys.
+;; 2011/08/07 dadams
+;;     icicle-help-on-candidate: For icicle-candidate-help-fn case: icicle-transform-multi-completion.
+;; 2011/07/27 dadams
+;;     Use icicle-completions-format everywhere, not icicle-completions-format-internal (removed).
+;; 2011/07/21 dadams
+;;     Renamed: icicle-nb-of-candidate-in-Completions to icicle-nb-of-cand-at-Completions-pos.
+;; 2011/07/06 dadams
+;;     Applied renaming of icicle-Completions-frame-at-right-flag to icicle-move-Completions-frame.
+;;     icicle-raise-Completions-frame: Handle left value of icicle-move-Completions-frame also.
+;; 2011/06/26 dadams
+;;     icicle-minibuffer-help: Use insert, not princ, with icicle-help-string-completion.
+;;     icicle-minibuffer-help, icicle-help-string-completion:
+;;       Use help-commands-to-key-buttons, not substitute-command-keys, if available.
+;;     Soft-require help-fns+.el for help-commands-to-key-buttons.
+;; 2011/06/03 dadams
+;;     icicle-next-candidate-per-mode:
+;;       Set this-command according to direction, per NTH.  If NTH is nil set it to 1.  For Icomplete+.
+;;     Replace icicle-help-in-mode-line-flag by icicle-help-in-mode-line-delay everywhere.
+;; 2011/05/22 dadams
+;;     Added defvars for free vars to quiet byte compiler.
+;; 2011/05/10 dadams
+;;     icicle-toggle-ignoring-comments: Toggle also ignore-comments-flag from thing-cmds.el.
+;; 2011/05/07 dadams
+;;     Added: icicle-toggle-ignoring-comments.  Bound to C-M-;.
+;;     Changed key for icicle-regexp-quote-input from C-M-; to M-% everywhere.
+;; 2011/05/04 dadams
+;;     icicle-transform-sole-candidate: Do nothing if for some reason icicle-current-input is nil.
+;; 2011/05/03 dadams
+;;     Added: icicle-plus-saved-sort, icicle-toggle-highlight-saved-candidates.
+;;     icicle-help-string-completion: Mention icicle-toggle-highlight-saved-candidates.
+;; 2011/04/29 dadams
+;;     icicle-help-string-completion: Corrected current values shown for sort comparers.
+;; 2011/04/25 dadams
+;;     icicle-describe-file: Sync'd with help-fns+.el - include autofile bookmark info.
+;;     icicle-help-on-candidate(-symbol): Add current-prefix-arg to call to icicle-describe-file.
+;; 2011/04/02 dadams
+;;     icicle-search-define-replacement: Use (new) icicle-scan-fn-or-regexp, not scan-fn-or-regexp.
+;; 2011/03/29 dadams
+;;     Added: icicle-scroll-(back|for)ward.
+;;     Renamed:  icicle-scroll-Completions(-up) to icicle-scroll-Completions-(back|for)ward.
+;;     orig-buf(f) -> icicle-orig-buff.
+;;     icicle-help-on-candidate: Removed boundp condition for icicle-completing-keys-p.
+;;     Applied renaming: icicle-scroll-Completions-backward-p to icicle-scroll-Completions-reverse-p.
+;; 2011/03/20 dadams
+;;     icicle-help-on-candidate-symbol: Don't bind help-xref-following.  Thx to Michael Heerdegen.
+;; 2011/03/17 dadams
+;;     icicle-candidate-set-complement:
+;;       Added condition-case: Emacs 23.2+ all-completions has no 4th arg.
+;;     icicle-delete-backward-char-dots, icicle-replace-input-w-parent-dir:
+;;       Use delete-char, not delete-backward-char (Emacs 23.2+ changed it to interactive only).
+;;     Added soft require of filesets.el when byte-compile.
+;; 2011/03/15 dadams
+;;     icicle-describe-file: Added thumbnails for image files.
+;; 2011/03/04 dadams
+;;     icicle-remove-cand-from-lists, icicle-narrow-candidates-with-predicate:
+;;       Corrected code for updating the predicate.
+;;       Test using emacs version, not boundp of read-file-name-predicate (since Icicles binds it now).
+;; 2011/03/02 dadams
+;;     Added: icicle-all-exif-data.
+;;     icicle-describe-file: Show all EXIF data, using icicle-all-exif-data.
+;; 2011/02/26 dadams
+;;     Added: icicle-Completions-popup-choice(-1), icicle-substitute-keymap-vars.
+;;     icicle-Completions-mouse-3-menu:
+;;       Rewrote to use option icicle-Completions-mouse-3-menu-entries instead of hard-coding menus.
+;;     icicle-candidate-set-define (cosmetic): Use when, not if, to raise error.
+;;     icicle-candidate-set-(difference|union|intersection|complement), : Added start-progress message.
+;; 2011/02/23 dadams
+;;     icicle-help-string-completion, icicle-Completions-mouse-3-menu:
+;;       Add icicle-cycle-image-file-thumbnail.
+;;     icicle-Completions-mouse-3-menu: Handle prefix args (change menu items to reflect).
+;; 2011/02/22 dadams
+;;     Added: icicle-cycle-image-file-thumbnail.
+;;     icicle-describe-file: Show also EXIF data for an image file.
+;;     icicle-remove-Completions-window:
+;;       No-op if Completions is selected or minibuf is selected and Completions was last selected.
+;; 2011/02/20 dadams
+;;     icicle-history: If history is command-history, convert its entries to strings for completion.
+;;     icicle-history, icicle-keep-only-past-inputs: Clarify doc: current completion mode is kept.
+;; 2011/01/20 dadams
+;;     icicle-read+insert-file-name: Bind icicle-must-pass-after-match-predicate to nil.
+;;     icicle-insert-string-at-point:
+;;       A numeric prefix arg when use ALTERNATIVES means evaluate grabbed sexp and insert the value.
+;; 2011/01/17 dadams
+;;     icicle-remove-Completions-window: Bury buffer.
+;;     icicle-toggle-highlight-all-current: barf if not in minibuf or Completions.
+;;     icicle-dispatch-C-^: Use icicle-searching-p.
+;; 2011/01/05 dadams
+;;     Added: icicle-sort-by-file-type.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     Added more autoload cookies for commands.  Thx to Richard Kim.
+;;       Specify command and file for commands defined by Icicles macros.
+;; 2010/12/17 dadams
+;;     icicle-remove-Completions-window: Added FORCE arg.  Remove if FORCE or interactive.
+;;     icicle-abort-recursive-edit: Call icicle-remove-Completions-window with FORCE arg.
+;; 2010/12/14 dadams
+;;     icicle-retrieve-previous-input:
+;;       Added optional arg ALLOW-EMPTY-P (not used yet in calls).
+;;       Remove "" systematically, unless ALLOW-EMPTY-P.
+;;       Non-interactively, use last-recorded if current try is "" (unless ALLOW-EMPTY-P).
+;;     icicle-toggle-highlight-all-current: Turn off incremental completion while erase minibuffer.
+;;     icicle-insert-input: Apply renaming: icicle-expand-file-name to icicle-expand-file-or-dir-name.
+;; 2010/12/02 dadams
+;;     icicle-retrieve-previous-input: Exclude "" from past-input cycling.
+;; 2010/11/30 dadams
+;;     icicle-mouse-save-then-kill: If soft-require of mouse3.el, then use a simpler definition. 
+;; 2010/11/27 dadams
+;;     icicle-insert-list-join-string, icicle-pp-eval-expression-in-minibuffer:
+;;       Protect with 1on1-fit-minibuffer-frame-flag and soft-require of fit-frame.el.
+;;     icicle-(apropos|prefix)-complete-1: Soft-require of fit-frame.el for 1on1-fit-minibuffer-frame.
+;; 2010/11/23 dadams
+;;     icicle-minibuffer-help:
+;;       Don't switch to minibuf window unless start in minibuf or *Completions*.  Thx to M. Heerdegen.
+;; 2010/11/08 dadams
+;;     icicle-next-TAB-completion-method, icicle-next-S-TAB-completion-method:
+;;       Set the icicle-last-top-level-command property only when set the first temporary method.
+;; 2010/11/07 dadams
+;;     icicle-apply-to-saved-candidate: Do not sit-for if icicle-all-candidates-action.
+;;     Applied renaming of icicle-all-candidates-action-p to icicle-all-candidates-action.
+;; 2010/11/06 dadams
+;;     icicle-apropos-complete-and-narrow: Do not regexp-quote if non-basic prefix completion.
+;;     icicle-next-TAB-completion-method, icicle-next-S-TAB-completion-method:
+;;       Prefix arg now means the new method is only for the current top-level command.
+;;       Put properties on icicle-last-top-level-command to implement this.
+;;     icicle-candidate-set-retrieve-1: Do icicle-apropos-complete-no-display if that was the last one.
+;; 2010/11/05 dadams
+;;     icicle-mouse-save-then-kill: Redefined for Emacs 24 (they changed mouse-save-then-kill).
+;;     icicle-candidate-set-retrieve-1: Call icicle-apropos-complete upon minibuffer setup.
+;; 2010/11/04 dadams
+;;     icicle-nb-of-candidate-in-Completions: Treat nil value the same as horizontal value.
+;; 2010/10/24 dadams
+;;     icicle-insert-string-from-variable, icicle(-mouse)-candidate-read-fn-invoke,
+;;       icicle-narrow-candidates, icicle-save-predicate-to-variable:
+;;         Use icicle-must-pass-after-match-predicate, not PREDICATE arg.
+;; 2010/10/09 dadams
+;;     icicle-minibuffer-help, icicle-help-string-completion, icicle-help-on-candidate (doc string):
+;;       Updated for change toward modal cycling.  Fix for swank bindings and M-_ toggle.
+;;     Applied renaming of icicle-cycling-respects-completion-mode to icicle-default-cycling-mode.
+;;     icicle-toggle-search-replace-whole: Corrected toggle binding in doc string.
+;; 2010/10/08 dadams
+;;     icicle-narrow-candidates: Set icicle-current-completion-mode to apropos.
+;;     icicle-apropos-complete-and-narrow:
+;;       Protect regexp-quote by ensuring non-nil icicle-last-input.  Removed yesterday's change.
+;; 2010/10/07 dadams
+;;     icicle-next-TAB-completion-method:
+;;       If icicle-current-TAB-method is nil, set to first one.  member -> memq.
+;;     Use icicle-current-TAB-method function, not variable, everywhere else.
+;;     icicle-apropos-complete-and-narrow:
+;;       If completion mode is prefix, then prefix-complete first.  Thx to Michael Heerdegen.
+;; 2010/10/06 dadams
+;;     icicle-next-TAB-completion-method:
+;;       Use car of icicle-TAB-completion-methods, not basic, as default.  Thx to Michael Heerdegen.
+;; 2010/10/04 dadams
+;;     directory-sep-char -> ?/ (It was removed from Emacs 24.)
+;; 2010/09/26 dadams
+;;     icicle-regexp-quote-input:
+;;       Handle no mark in minibuffer.  Use end of prompt, not point-min.  Thx to Michael Heerdegen.
+;;     icicle-column-wise-cand-nb: Bound NB (missing let binding).
+;; 2010/06/18 dadams
+;;     icicle-nb-of-candidate-in-Completions(-horiz), icicle-move-to-next-completion:
+;;       Replace icicle-completions-format by icicle-completions-format-internal.
+;;     icicle-scroll-Completions: Do nothing if *Completions* is not displayed.
+;; 2010/06/16 dadams
+;;     Added: icicle-col-wise-cand-nb.
+;;     Renamed icicle-nb-of-candidate-in-Completions to icicle-nb-of-cand-in-Completions-horiz.
+;;     Rewrote icicle-nb-of-candidate-in-Completions to handle vertical format also.
+;;     icicle-candidate-set-save-selected-1:
+;;       After setting BEG to next face chg, if BEG > END then raise error.
+;;       After setting END to previous fact chg, BEG > END then swap.
+;;       After extending, if BEG > END then swap.
+;; 2010/06/14 dadams
+;;     icicle-narrow-candidates: Handle Emacs 23.2+: Use completing-read with read-file-name-internal.
+;;     icicle-search-define-replacement:
+;;       Wrap *-remove-Completions-window in save-selected-window.  Thx to M. Heerdegen.
+;;     icicle-help-on-candidate-symbol: Show combined help for fns, vars, and faces (Emacs 22+).
+;; 2010/06/11 dadams
+;;     Added: icicle-make-directory.
+;;     icicle-read+insert-file-name: Bind icicle-make-directory to C-c +.
+;; 2010/06/08 dadams
+;;     icicle-doremi-increment-max-candidates+: Plain C-u resets icicle-max-candidates to nil.
+;; 2010/06/07 dadams
+;;     icicle-exit-minibuffer: Do not fiddle with faces if not in minibuffer.  Thx to M. Heerdegen.
+;;     icicle-prefix-complete-1:
+;;       Sole completion case: Move removal of *Completions* before the top-level throw.
+;; 2010/06/04 dadams
+;;     Added: icicle-doremi-increment-max-candidates+.
+;;     Renamed by adding +: icicle-doremi-increment-swank-(timeout|prefix-length).
+;;     icicle-help-string-completion: Mention missing doremi toggle keys.
+;;     icicle-doremi-zoom-Completions+: Show *Completions* if not shown.
+;; 2010/05/15 dadams
+;;     icicle-all-candidates-action-1: Bind *-minibuffer-message-ok-p, *-help-in-mode-line-flag to nil.
+;; 2010/05/09 dadams
+;;     Added: icicle-dispatch-M-_.
+;;     Removed: icicle-dispatch-C-comma.
+;;     icicle-help-string-completion:
+;;       Removed extra arg to format (icicle-key-descriptions-use-<>-flag).  Corrected arg order.
+;;       Updated to reflect binding changes.
+;;     icicle-toggle-highlight-all-current: Focus to minibuffer before show msg.
+;; 2010/05/04 dadams
+;;     icicle-change-sort-order: Use save-selected-window.  Thx to Michael Heerdegen.
+;;     icicle-apply-to-saved-candidate:
+;;       Only call sit-for if current-message.  Added TYPE arg.  Thx to Michael H.
+;; 2010/05/03 dadams
+;;     icicle-toggle-remote-file-testing: Updated for Emacs 23.2+  Thx to Michael Albinus.
+;; 2010/04/30 dadams
+;;     icicle-(apropos|prefix)-complete-1: Run icicle-no-match-hook when no candidates.
+;; 2010/04/28 dadams
+;;     icicle-remove-cand-from-lists: Fix pred a la icicle-mctize-all.  Thx to M. Heerdegen.
+;; 2010/04/27 dadams
+;;     icicle-apply-to-saved-candidate: Added sit-for for non-C-u case, to see any msg displayed.
+;;     icicle-help-on-candidate: Test value, not just boundp, of icicle-completing-keys-p.
+;; 2010/04/26 dadams
+;;     icicle-toggle-highlight-all-current:
+;;       Save/restore cand nb.  Re-complete, rehighlight.  Go to current cand only if it is defined.
+;; 2010/04/21 dadams
+;;     Added: icicle-sit-for (Emacs 23+), so user input interrupts sit-for after C-u in minibuffer.
+;; 2010/04/20 dadams
+;;     Added: icicle-sort-by-directories-first.
+;;     icicle-nb-of-candidate-in-Completions:
+;;       Bind icicle-completions-format to nil (for calls to *-move-to-next-*).  Thx to M. Heerdegen.
+;; 2010/04/13 dadams
+;;     icicle-(apropos|prefix)-complete-1: Fixed recent file-name completion bugs.
+;;       When icicle-whole-candidate-as-text-prop-p is t and icicle-expand-input-to-common-match-flag
+;;         is nil, expand the input, unless it is a directory.
+;;       Expand file-name input to the common match for the current candidate.
+;; 2010/04/11 dadams
+;;     icicle-(apropos|prefix)-complete-1: Fix last fix:
+;;       Put whole-cand prop on sole candidate only if not a dir, and use icicle-expanded-common-match.
+;; 2010/04/09 dadams
+;;     icicle-(apropos|prefix)-complete-1: When sole candidate, set icicle-current-input to it.
+;;       Needed, in order to get icicle-whole-candidate property when
+;;       icicle-expand-input-to-common-match-flag is nil.  Thx to Michael Heerdegen.
+;; 2010/03/13 dadams
+;;     Added: icicle-toggle-show-multi-completion.
+;; 2010/03/03 dadams
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist,
+;;                        icicle-alternative-sort-function to icicle-alternative-sort-comparer,
+;;                        icicle-last-sort-function to icicle-last-sort-comparer.
+;; 2010/03/02 dadams
+;;     icicle-remove-Completions-window: Do nothing unless *Completions* is shown.
+;;     icicle-delete-windows-on: Do nothing unless buffer is visible.
+;;                               Do not delete frame if it is the only one.
+;; 2010/01/12 dadams
+;;     icicle-mouse-choose-completion, icicle-insert-string-at-point,
+;;       icicle-mouse-candidate-action-1, icicle-mouse-remove-candidate,
+;;       icicle-mouse-candidate-read-fn-invoke, icicle-Completions-mouse-3-menu,
+;;       icicle-mouse-save/unsave-candidate:
+;;         set-buffer -> with-current-buffer.
+;;     icicle-mouse-candidate-read-fn-invoke, icicle-Completions-mouse-3-menu,
+;;       icicle-mouse-save/unsave-candidate:
+;;         Removed unused local var BUFFER.
+;;     icicle-mouse-choose-completion: Removed unused local var ORIG-BUFFER.
+;; 2009/12/21 dadams
+;;     icicle-narrow-candidates:
+;;       Add fn to minibuffer-setup-hook to make the reference buffer be the new minibuffer.
+;;     fset -> defalias.
+;; 2009/12/13 dadams
+;;     icicle-change-sort-order: Add REVERSED to msg when reversed.
+;; 2009/11/27 dadams
+;;     Added: icicle-doremi-increment-swank-(prefix-length|timeout).
+;;     *-next-TAB-completion-method, *-prefix-complete-1: Handle swank completions too.
+;;     *-next-TAB-completion-method: Bind icicle-doremi-increment-swank-(prefix-length|timeout).
+;; 2009/11/26 dadams
+;;     icicle-next-TAB-completion-method: Do not set icicle-inhibit-sort-p to t for fuzzy.
+;; 2009/11/25 dadams
+;;     Added: icicle-completions-format, icicle-row-wise-cand-nb.
+;;     icicle-move-to-next-completion: Handle completions laid out vertically.
+;; 2009/11/07 dadams
+;;     Renamed Icicles doremi cmds (added +).  Applied other doremi cmd renamings (added +).
+;; 2009/10/25 dadams
+;;     icicle-prefix-complete-1: When sole cand, use the candidate, but without any dir.
+;;     Renamed: icicle-next-apropos-match-function to icicle-next-S-TAB-completion-method,
+;;              icicle-toggle-fuzzy-completion to icicle-next-TAB-completion-method (rewrote).
+;;     icicle-(prefix|apropos)-complete-1: Updated no/sole msgs per new completion methods.
+;;     icicle-Completions-mouse-3-menu: Updated with the new command names.
+;;     Updated icicle-help-string-completion.
+;; 2009/10/24 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Removed code treating empty dir via *-any-*-p and ("").
+;;       When only one candidate, set *-last-completion-candidate to:
+;;         If file-name completion:
+;;           If empty input, the input; if dir candidate, input + /; else the sole candidate.
+;;         Else the sole candidate.
+;; 2009/10/22 dadams
+;;     icicle-insert-input, icicle-candidate-action-1, icicle-keep-only-past-inputs,
+;;       icicle-apropos-complete-and-(narrow|widen):
+;;         Use icicle-file-name-directory, not file-name-directory.
+;; 2009/10/21 dadams
+;;     icicle-prefix-complete-1:
+;;       For empty dir we use "" as pseudo-cand.  Ensure not "" when later test for / last char.
+;; 2009/10/12 dadams
+;;     Added: icicle-input-is-a-completion-p.
+;;     icicle-minibuffer-complete-and-exit, icicle-input-is-a-completion-p:
+;;       Use icicle-input-is-a-completion-p.
+;;     icicle-prefix-complete-1:
+;;       For file-name input: Set, and use, current input without substituting env vars.
+;;                            When sole candidate ends in /, add a / to current input also.
+;; 2009/09/26 dadams
+;;     icicle-narrow-candidates(-with-predicate): Bind icicle-progressive-completing-p to t.
+;; 2009/09/25 dadams
+;;     icicle-prefix-complete-1, icicle-transform-sole-candidate:
+;;       Use icicle-current-input, not (car icicle-completion-candidates).
+;;       Don't set icicle-current-input to (car icicle-completion-candidates) if no-catch.
+;; 2009/09/12 dadams
+;;     icicle-delete-candidate-object: Message if no candidates, in non-ALLP case also.
+;;     icicle-delete-candidate-object-1: Bind icicle-completion-candidates to save & restore it.
+;;     icicle-candidate-action-1, icicle-remove-candidate-display-others,
+;;       icicle-delete-candidate-object, icicle-help-on-candidate,
+;;       icicle-candidate-read-fn-invoke:
+;;         Bind icicle-help-in-mode-line-flag to nil, to avoid help-display delay.
+;;     icicle-update-and-next: Do nothing if user hit another key and there are more candidates.
+;; 2009/09/05 dadams
+;;     icicle-narrow-candidates: Don't raise an error if no candidates.  E.g. C-~.
+;;     Use backward and forward as the values of icicle-cycling-command prop for nav commands.
+;;     Apply renaming of icicle-acting-on-next/prev (removed -p).
+;;     icicle-successive-action: Bind it to value of icicle-cycling-command (nav direction).
+;;     icicle-all-candidates-list-alt-action: Raise error if null icicle-completion-candidates.
+;;     icicle-search-define-replacement: Prevent immediate incremental completion kicking in.
+;;     icicle-(widen|narrow)-candidates(-with-predicate):
+;;       Use literal text for (S-)TAB in error message, to avoid S-iso-*.
+;; 2009/09/02 dadams
+;;     icicle-(prefix|apropos)-complete-1, icicle-narrow-candidates(-with-predicate):
+;;       Impose icicle-top-level-when-sole-completion-delay when *-flag is non-nil.
+;; 2009/08/27 dadams
+;;     icicle-goto/kill-failed-input: Do nothing if the overlay is nowhere.
+;;     icicle-mouse-yank-secondary: If yank-secondary is defined, then pass prefix arg also.
+;; 2009/08/23 dadams
+;;     icicle-narrow-candidates-with-predicate: Added optional arg PREDICATE.
+;; 2009/08/20 dadams
+;;     icicle-successive-action: Don't call icicle-show-help-in-mode-line unless string arg.
+;; 2009/08/11 dadams
+;;     icicle-all-candidates-action-1: Added ALTP arg.  Use in call to *-candidate-action-1.
+;;     icicle-all-candidates(-list)-alt-action: Use new ALTP arg in call with *-alt-action-fn.
+;;     icicle-successive-action: Bind icicle-acting-on-next/prev-p around call to action fn.
+;;     icicle(-mouse)-candidate-action-1:
+;;       No longer bind icicle-* to selves.  You must do it in the action fn if you need it.
+;;     icicle-help-string-completion: C-| -> M-| for Replace all.
+;;     icicle-change-history-variable: Protect with boundp: *-populate-interactive-history-flag.
+;;     Wrap require of icicles-var.el in eval-and-compile.
+;; 2009/08/01 dadams
+;;     icicle-change-history-variable:
+;;       Add icicle-interactive-history to choices only if *-populate-interactive-history-flag.
+;; 2009/07/29 dadams
+;;     icicle-other-history:
+;;       Call icicle-use-interactive-command-history only if Emacs 23+ and non-nil history.
+;; 2009/07/27 dadams
+;;     icicle-help-string-completion: Mention icicle-other-history.
+;; 2009/07/26 dadams
+;;     Added: icicle-change-history-variable, icicle-other-history,
+;;            icicle-use-interactive-command-history.
+;;     icicle-history:
+;;       Use icicle-cycling-p instead of get icicle-cycling-command, to avoid completion cmds.
+;; 2009/07/02 dadams
+;;     icicle-candidate-set-save-1: If icicle-get-alist-candidate-function returns nil, use CAND
+;; 2009/06/26 dadams
+;;     icicle-doremi-zoom-Completions, icicle-doremi-candidate-width-factor:
+;;       Use new key-list options, doremi-...-keys (not -key).  You will need the latest DoReMi.
+;; 2009/06/18 dadams
+;;     doremi-buffer-font-size: Changed increment (doremi-*-key) bindings to =, -, M-=, M-i.
+;;     icicle-help-string-completion: Added icicle-doremi-zoom-Completions.
+;; 2009/06/17 dadams
+;;     Added: icicle-doremi-zoom-Completions.
+;;     icicle-doremi-candidate-width-factor: If no candidates, show message; don't use colors.
+;; 2009/06/07 dadams
+;;     icicle-get-alist-candidate -> funcall icicle-get-alist-candidate-function.
+;; 2009/05/27 dadams
+;;     icicle-minibuffer-complete-and-exit:
+;;       Don't exit if any completion is done, unless icicle-require-match-p is t.
+;; 2009/05/22 dadams
+;;     Require icicles-mac.el if load-library doesn't find it.
+;; 2009/05/18 dadams
+;;     icicle-candidate-set-save-selected-1: If empty inactive region and MOREP, raise error.
+;; 2009/05/17 dadams
+;;     icicle-toggle-C-for-actions: Use icicle-toggle-icicle-mode-twice, not icy-mode calls.
+;; 2009/05/15 dadams
+;;     icicle-(prefix|apropos)-complete-1: Fit minibuffer frame after inserting current input.
+;; 2009/05/11 dadams
+;;     icicle-upcase-if-ignore-case, icicle-next-apropos-match-function: Use icicle-upcase.
+;; 2009/05/09 dadams
+;;     Added: icicle-looking(-back)-at-anychar-regexp-p, icicle-(forward|backward)-char-dots,
+;;            icicle-backward-delete-char-untabify-dots, icicle-delete-backward-char-dots,
+;;            icicle-delete-char-dots, icicle-transpose-chars-dots. icicle-insert-dot(-command),
+;;            icicle-anychar-regexp, icicle-toggle-dot, icicle-convert-dots.
+;;     icicle-backward-delete-char-untabify, icicle-delete-backward-char, icicle-delete-char,
+;;       icicle-transpose-chars: Handle dots.
+;;     icicle-prefix-complete: Convert dots and set icicle-dot-string-internal.
+;;     icicle-goto/kill-failed-input: Use overlay.
+;;     icicle-help-string-completion, icicle-Completions-mouse-3-menu:
+;;       Added dot toggling.  Changed binding for icicle-toggle-hiding-common-match.
+;; 2009/05/08 dadams
+;;     icicle-(prefix|apropos)-complete-1: Fixed typo introduced 2009-05-05.
+;; 2009/05/07 dadams
+;;     icicle-retrieve-(previous|last)-input: Call icicle-place-cursor with optional second arg.
+;; 2009/05/05 dadams
+;;     toggle-icicle-case-sensitivity: Treat read-buffer-completion-ignore-case also (Emacs 23).
+;; 2009/05/03 dadams
+;;     icicle-(prefix|apropos)-complete-1:
+;;       Don't stop cycling if last command was an action (treat as if it was a cycling cmd).
+;;     icicle-all-candidates(-list)(-alt)-action, icicle(-mouse)-candidate(-alt)-action,
+;;       icicle-delete-candidate-object, icicle(-mouse)-help-on-candidate:
+;;         Put property icicle-action-command.
+;; 2009/05/02 dadams
+;;     icicle-candidate-alt-action: Respect icicle-alternative-actions-alist.
+;;     icicle-minibuffer-help: Corrected wrt alt action-for-all keys.
+;; 2009/04/30 dadams
+;;     icicle-next-(prefix|apropos)-candidate, icicle-(prefix|apropos)-complete-1,
+;;       icicle-successive-action:
+;;         Reset icicle-next-(apropos|prefix)-complete-cycles-p to nil, as appropriate.
+;;     icicle-prefix-complete-1: Show mode-line help only at very end, and even after cycling.
+;; 2009/04/29 dadams
+;;     icicle-apply-to-saved-candidate:
+;;       Pass no-error-no-msg to icicle-get-alist-candidate function.
+;;       If icicle-get-alist-candidate finds no function, get function from car of entry.
+;;     icicle-apropos-complete-and-(narrow|widen): Handle icicle-apropos-complete-no-display.
+;; 2009/04/27 dadams
+;;     icicle-(prefix|apropos)-complete-1:
+;;       Set icicle-last-completion-command to icicle-*-complete-no-display if arg NO-DISPLAY.
+;;     icicle-history: If icicle-last-completion-command is nil, call icicle-apropos-complete.
+;; 2009/04/26 dadams
+;;     Wrap load of icicles-mac in eval-when-compile, and use load-library, not require.
+;;     Require icicles-opt before icicles-var (not important).
+;; 2009/04/20 dadams
+;;     Added: icicle-(previous|next)-candidate-per-mode-alt-action.
+;; 2009/03/19 dadams
+;;     mouse-choose-completion: Don't fset unless standard function is defined.
+;;     Use when/unless instead of or for fset's. (cosmetic)
+;; 2009/04/15 dadams
+;;     Added: icicle-(next|previous)-candidate-per-mode-help.
+;;     icicle-successive-action: Set mode only if known.  Leave it alone for per-mode functions.
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Don't show help in mode-line when icicle-top-level-when-sole-completion-flag = t.
+;; 2009/04/12 dadams
+;;     icicle-successive-action: Inhibit help in mode line until after action is finished.
+;; 2009/04/06 dadams
+;;     icicle-(prefix|apropos)-complete-1, icicle-candidate-set-retrieve-1,
+;;       icicle-keep-only-past-inputs:
+;;         Call icicle-show-help-in-mode-line for completed input.
+;;     icicle-(prefix|apropos)-complete-1:
+;;       Don't highlight complete input or show help if icicle-*-complete-and-exit-p is bound.
+;; 2009/04/04 dadams
+;;     Renamed: icicle-sort-by-last-use to icicle-sort-by-last-use-as-input.
+;;     icicle-change-sort-order: Purge any nil entries from icicle-sort-functions-alist.
+;;     icicle-current-sort-functions: Respect icicle-buffer-name-sort-predicate.
+;;     icicle-reverse-sort-order: Echo icicle-current-sort-order.
+;; 2009/03/16 dadams
+;;     icicle-candidate-action-1: Respect icicle-use-candidates-only-once-alt-p.
+;; 2009/03/10 dadams
+;;     icicle-remove-Completions-window: Wrap with condition-case, to ignore "Attempt..." error.
+;; 2009/03/01 dadams
+;;     Added: icicle-completing-read+insert, icicle-read+insert-file-name.
+;; 2009/02/28 dadams
+;;     No soft require of subr-21.el now, since provide replace-regexp-in-string for Emacs 20.
+;; 2009/02/23 dadams
+;;     icicle-mouse-choose-completion, icicle-(prefix|apropos)-complete-1,
+;;       icicle-insert-completion, icicle-mouse-candidate-action-1, icicle-update-and-next,
+;;       icicle-narrow-candidates(-with-predicate), icicle-keep-only-past-inputs,
+;;       icicle-insert-input:
+;;         Protect dir insertion with icicle-extra-candidates-dir-insert-p.
+;;     icicle-choose-completion: Use icicle-extra-candidates-dir-insert-p to reset base-size=0.
+;; 2009/02/20 dadams
+;;     Added: icicle-sort-extra-candidates-first.
+;;     icicle-candidate-action-1: Use function icicle-require-match-p, not variable.
+;; 2009/02/17 dadams
+;;     icicle-exit-minibuffer: Don't put nil face property on input.  Thx to Daniel Clemente.
+;; 2009/02/04 dadams
+;;     icicle-(prefix|apropos)-complete-1:
+;;       Do not set icicle-current-input to icicle-last-input unless also icicle-cycling-p.
+;;       Do not cycle unless also was already cycling or icicle-next-*-complete-cycles-p.
+;;       Set icicle-next-*-complete-cycles-p, at end, to save whether input was completed some.
+;; 2009/02/01 dadams
+;;     Added: icicle-up-directory, icicle-replace-input-w-parent-dir.
+;; 2009/01/24 dadams
+;;     icicle-narrow-candidates(-with-predicate):
+;;       Bind icicle-apropos-complete-match-fn to icicle-last-apropos-complete-match-fn.
+;;     icicle-next-apropos-match-function: Save new value as *-last-apropos-complete-match-fn.
+;; 2009/01/18 dadams
+;;     icicle-(prefix|apropos)-complete-1:
+;;       Don't set icicle-current-input to icicle-last-input if icicle-edit-update-p.
+;; 2009/01/17 dadams
+;;     icicle-next-apropos-match-function:
+;;       Add Levenshtein distance in message: (1).
+;;       Don't do icicle-complete-again-update - too slow.
+;; 2009/01/14 dadams
+;;     icicle-remove-cand-from-lists: Treat icicle-remove-dups-if-extras also.
+;; 2009/01/13 dadams
+;;     icicle-delete-windows-on: Delete frame even if it has a minibuffer, if it's not active.
+;; 2008/12/26 dadams
+;;     Added: icicle-widen-candidates, icicle-apropos-complete-and-widen.
+;;       Added icicle-widen-candidates to icicle-Completions-mouse-3-menu.
+;; 2008/12/25 dadams
+;;     icicle-retrieve-previous-input: Corrected logic following cycling.
+;;       Remember whether repeated C-l calls follow cycling: local var was-cycling-p.
+;;       If so, then use current raw input for second C-l.  Otherwise use previous raw input.
+;;       Use icicle-cycling-p instead of testing if this command is a cycling command.
+;;       Handle case of "" raw input, which is never in list of saved raw inputs.
+;;       Restore current raw input after re-completing.
+;;     icicle-(prefix|apropos)-complete-1: Reset icicle-cycling-p (new var) to nil.
+;;     icicle-regexp-quote-input: Reset icicle-expand-input-to-common-match-flag to nil.
+;; 2008/12/22 dadams
+;;     Added: icicle-regexp-quote-input.
+;;       Added it to icicle-help-string-completion, icicle-Completions-mouse-3-menu.
+;; 2008/12/21 dadams
+;;     icicle-minibuffer-complete-and-exit:
+;;       Rewrote to fit new Emacs 23 behavior.  Thx to Daniel Clemente.
+;;         Test minibuffer-completion-confirm first, before we auto-complete.
+;;         icicle-last-input -> icicle-current-input (bug fix bc of call to *-no-display).
+;;     icicle-prefix-complete-1: Bind free var word-complete-input.
+;;     icicle-(apropos|prefix)-complete-1: No messages if NO-DISPLAY-P is 'no-msg.
+;; 2008/12/20 dadams
+;;     icicle-(apropos|prefix)-complete-1, icicle-narrow-candidates(-with-predicate):
+;;       Expand file-name choice if thrown to icicle-read-top.
+;; 2008/12/10 dadams
+;;     icicle-(apropos|prefix)-complete-1: Don't pick up icicle-last-input unless also:
+;;         (1) same completion mode, (2) icicle-completion-candidates is not nil.
+;;     icicle-prefix-complete-1: If WORD-P, don't pick up icicle-last-input unless same command.
+;;       Bind minibuffer-message-timeout to 0 during minibuffer-complete-word.
+;;     icicle-apropos-complete-1:
+;;       Typo in last cond clause: prefix -> apropos, in i-apropos-completing-command.
+;; 2008/12/06 dadams
+;;     icicle-prefix-complete-1: Fixes for word completion.
+;;       Don't initialize *-current-input to *-last-input if word-p and icicle-edit-update-p.
+;;       Recompute candidates after word complete also if editing or didn't repeat last command.
+;;       Cycle if last command was not a prefix completion and input doesn't end in `-'.
+;; 2008/12/05 dadams
+;;     Let repeated completion commands cycle.  Thx to Andrey Zhdanov for the suggestion.
+;;       icicle-(apropos| prefix)-complete-1:
+;;         Call icicle-next-candidate, not scroll, when repeated.  Special treatment for word.
+;;       icicle-(apropos|prefix)-complete*:
+;;         Put icicle(-apropos|-prefix)-cycling-command property on command symbols.
+;; 2008/12/02 dadams
+;;     icicle-minibuffer-complete-and-exit:
+;;       Updated for Emacs 23's minibuffer-confirm-exit-commands.
+;; 2008/11/29 dadams
+;;     icicle-prefix-word-complete:
+;;       Redefined to use (new) icicle-prefix-complete-1.
+;;       Put property icicle-completing-command.
+;;     icicle-prefix-complete-1:
+;;       Useful now also for icicle-prefix-word-complete.  Added arg word-p.
+;;     icicle-(prefix|apropos)-complete-1, icicle-switch-to-Completions-buf:
+;;       Test property icicle-prefix-completing-command, not eq cmds.
+;;     icicle-(prefix|apropos)(-word)-complete(-no-display):
+;;       Put property icicle-(prefix|apropos)-completing-command.
+;;     icicle-next-candidate-per-mode: Use case, not cond.
+;;     icicle-end-of-line+: Bind inhibit-field-text-motion, call end-of-line to get past prompt.
+;; 2008/11/18 dadams
+;;     icicle-minibuffer-complete-and-exit: Allow exit if input matches a current candidate.
+;;     icicle-exit-minibuffer: Remove all Icicles minibuffer faces, but only those.
+;; 2008/11/14 dadams
+;;     Added: icicle-toggle-hiding-common-match.  
+;;     icicle-help-string-completion, icicle-Completions-mouse-3-menu: Mention it.
+;; 2008/11/10 dadams
+;;     icicle-minibuffer-complete-and-exit:
+;;       Use icicle-exit-minibuffer, not old-exit-minibuffer, so remove *Completions*.
+;; 2008/11/09 dadams
+;;     icicle-maybe-multi-completion-completing-p, icicle-transform-sole-candidate:
+;;       Don't test icicle-list-join-string (always non-nil).
+;; 2008/11/03 dadams
+;;     icicle-(apropos|prefix)-complete-1: Added message Computing completion candidates...
+;; 2008/11/02 dadams
+;;     icicle-upcase-if-ignore-case: condition-case, to prevent error on bad chars (Emacs 20).
+;; 2008/10/27 dadams
+;;     Added: icicle-upcase-if-ignore-case.
+;;     icicle-minibuffer-complete-and-exit, icicle-(prefix|apropos)-complete-1:
+;;       Use icicle-upcase-if-ignore-case.
+;; 2008/10/24 dadams
+;;     icicle-minibuffer-complete-and-exit: If icicle-candidates-alist, then just filter it.
+;; 2008/10/18 dadams
+;;     Replaced customize-save-variable by funcall icicle-customize-save-variable-function.
+;; 2008/10/14 dadams
+;;     Added: icicle-help-string(-non)-completion.
+;;     icicle-help-string-completion:
+;;       Renamed from icicle-update-help-string in icicles-mode.el.
+;;       Moved common part to icicles-var.el as icicle-general-help-string.
+;;     Renamed: icicle-completion-help to icicle-minibuffer-help.
+;;     icicle-minibuffer-help: If not completing, use icicle-help-string-non-completion.
+;;                             Move Send an Icicles bug report to the bottom.
+;; 2008/10/11 dadams
+;;     icicle-(next|previous)-line: Fixed so it highlights also candidates in first column.
+;;     icicle-kill-failed-input: Made it two-stage.  Renamed to icicle-goto/kill-failed-input.
+;; 2008/10/10 dadams
+;;     Added: icicle-(next|previous)-candidate-per-mode-action.
+;; 2008/10/09 dadams
+;;     Updated icicle-Completions-mouse-3-menu for C-<.
+;; 2008/10/08 dadams
+;;     Added: icicle-candidate-set-retrieve-more, icicle-candidate-set-retrieve-1.
+;;     icicle-candidate-set-retrieve: Use icicle-candidate-set-retrieve-1.
+;;     icicle-insert-string-at-point:
+;;       Use icicle-pre-minibuffer-buffer, not (cadr (buffer-list)).  Thx to Andrey Zhdanov.
+;;     icicle-beginning-of-line+: Don't move into prompt.  Thx to Andrey Zhdanov.
+;; 2008/10/06 dadams
+;;     icicle-self-insert: Do self-insert-command if executing-kbd-macro.  Thx to Tomer Levin.
+;; 2008/10/01 dadams
+;;     icicle-completion-help: Use icicle-update-help-string, not icicle-completion-help-string.
+;; 2008/09/30 dadams
+;;     Renamed icicle-isearch-complete-1 to icicle-isearch-complete-past-string and moved it
+;;       to icicles-fn.el.
+;; 2008/09/20 dadams
+;;     icicle-toggle-ignored-extensions: Append $ to each extension.
+;;     icicle-dispatch-C-.: Use icicle-searching-p as the condition, not *-file-name-input-p.
+;; 2008/09/14 dadams
+;;     icicle-(minibuffer|apropos)-complete-and-exit: Set icicle-last-input to current input.
+;;     icicle-minibuffer-complete-and-exit: Use apropos completion if that's the current mode.
+;; 2008/09/13 dadams
+;;     icicle-candidate-set-save-1: Save to fileset if zero prefix arg.
+;;     icicle-candidate-set-retrieve: Retrieve also from a fileset.
+;;                                    No default value for completing-read.
+;;     Added: icicle-add-file-to-fileset.
+;;     Renamed:
+;;       icicle-candidate-set-save-to-cache-file to icicle-candidate-set-save-persistently,
+;;       icicle-candidate-set-retrieve-from-cache-file to *-candidate-set-retrieve-persistent.
+;;     icicle-candidate-set-save-persistently: Added arg FILESETP.
+;;     icicle-add/update-saved-completion-set: No default value for completing-read.
+;;     icicle-retrieve-candidates-from-set:
+;;       Factored out code as icicle-get-candidates-from-saved-set - use it.  Don't return name.
+;;     Moved to icicles-fn.el: icicle-readable-to-markers.
+;; 2008/09/09 dadams
+;;     icicle-candidate-set-save(-selected-1): Added NO-ERROR-P arg.
+;;     icicle-candidate-set-save-selected: Call *-save-selected-1 with NO-ERROR-P arg.
+;;     icicle-candidate-set-save-1: Raise error if set to save is empty and not NO-ERROR-P.
+;; 2008/09/08 dadams
+;;     icicle-apropos-complete-and-narrow:
+;;       If currently prefix completing, escape current input before apropos completing.
+;; 2008/09/07 dadams
+;;     icicle-minibuffer-complete-and-exit:
+;;       Use *-prefix-complete-no-display and *-display-candidates-in-Completions when needed.
+;; 2008/09/06 dadams
+;;     icicle-minibuffer-complete-and-exit: Rewrote, based on icicle-apropos-complete-and-exit.
+;;     icicle-prefix-complete-1:
+;;       Wrap most of single-candidate case in (boundp 'icicle-prefix-complete-and-exit-p).
+;; 2008/09/04 dadams
+;;     icicle-minibuffer-complete-and-exit: Temporary bug workaround.
+;; 2008/08/31 dadams
+;;     icicle-completion-help, icicle-pp-eval-expression-in-minibuffer,
+;;       icicle-delete-candidate-object-1, icicle-apply-to-saved-candidate,
+;;       icicle-toggle-highlight-all-current:
+;;         Select window before call select-frame-set-input-focus.
+;; 2008/08/29 dadams
+;;     icicle-minibuffer-complete-and-exit: Update icicle-last-input to minibuffer contents.
+;; 2008/08/28 dadams
+;;     icicle-(apropos|prefix)-complete-1, icicle-narrow-candidates(-with-predicate):
+;;       Update minibuffer-history-variable before throw result.
+;;     icicle-help-on-candidate: Renamed alacarte-menu-items-alist to lacarte-menu-items-alist.
+;; 2008/08/27 dadams
+;;     icicle-kill-failed-input: Reverted mistaken change to use start of *Completions* (duh).
+;; 2008/08/25 dadams
+;;     icicle-minibuffer-complete-and-exit: Call icicle-prefix-complete-no-display with no-msg
+;;       arg, instead of binding minibuffer-message-timeout to 0.
+;;     icicle-(apropos|prefix)-complete-no-display: Added optional NO-MSG-P arg.
+;; 2008/08/24 dadams
+;;     icicle-minibuffer-complete-and-exit: Rewrote to not call original Emacs version.
+;;     Use today's renamings from icicles-fn.el.
+;;     icicle-raise-Completions-frame: Don't do anything unless one-window-p and option = t.
+;;     icicle-choose-completion, *-kill-failed-input, *-current-completion-in-Completions:
+;;       Check point wrt candidates start position, not bobp.
+;;     icicle-current-completion-in-Completions:
+;;       "No completion here" error after, not before, we set beg wrt mouse-face change.
+;;     icicle-mouse-candidate-action-1: Call icicle-update-and-next if there are still cands.
+;; 2008/08/21 dadams
+;;     icicle-candidate-set-retrieve: If completing files, remove directory from candidates.
+;; 2008/08/20 dadams
+;;     icicle-mouse-candidate-action-1: Remove mouse-face property from choice.
+;; 2008/08/19 dadams
+;;     icicle-mouse-remove-candidate:
+;;       Set icicle-last-completion-candidate.  Needed for *-remove-candidate-display-others.
+;;     icicle-mouse-candidate-action-1: Removed unused vars: buffer, base-size.
+;;     Added: icicle-delete-candidate-object-1, with explicit CAND arg and NO-DISPLAY-P option.
+;;     icicle-delete-candidate-object: Added optional ALLP arg.
+;;     icicle-delete-current-candidate-object: Added optional CAND arg.
+;;     icicle-update-and-next: Don't try to move to cand in *Completions* if number not known.
+;; 2008/08/18 dadams
+;;     Added: icicle-remove-cand-from-lists, icicle-update-and-next.
+;;     icicle-narrow-candidates-with-predicate: Update predicate correctly, with lexical-let.
+;;     icicle-remove-candidate, icicle-delete(-current)-candidate-object:
+;;       Removed stuff from doc string about removing all that match.
+;;     icicle-delete-candidate-object, icicle-remove-candidate-display-others:
+;;       Use icicle-remove-cand-from-lists (with mctized candidate) and icicle-update-and-next.
+;;     icicle-delete-current-candidate-object: Changed first condition:
+;;       (and icicle-candidates-alist (consp (car val))) to
+;;       (or icicle-whole-candidate-as-text-prop-p icicle-candidates-alist)
+;;     icicle-remove-candidate-display-others:
+;;       Added optional ALLP arg.
+;;       Reinitialize icicle-last-completion-candidate properly (as elsewhere).
+;;     icicle(-mouse)-candidate-action-1: Use ALLP arg for *-remove-candidate-display-others.
+;;     icicle-history: Don't set minibuffer-completion-predicate if it is nil.
+;;     Use renamings from icicles-fn.el:
+;;       icicle-complete-again-update, icicle-remove-if, icicle-put-whole-cand-prop.
+;;     icicle-narrow-candidates: Do not bind icicle-whole-candidate-as-text-prop-p to nil.
+;;     icicle-Completions-mouse-3-menu: Removed icicle-scroll-Completions from menu.
+;; 2008/08/17 dadams
+;;     icicle-narrow-candidates-with-predicate:
+;;       (read-file-name|minibuffer-completion)-predicate: Removed `, in front.
+;;     icicle-scroll-Completions: Added optional arg (for mouse wheel reversal).
+;;     Added: icicle-scroll-Completions-up.
+;; 2008/08/03 dadams
+;;     Added: icicle-all-candidates-list(-alt)-action.
+;;     icicle-all-candidates(-alt)-action:
+;;       Act on saved candidates, if any.  Use list function, if normal is nil.
+;;     icicle-all-candidates-action-1:
+;;       Use icicle-candidate-action-1 (with cand arg (new)), not funcall, to apply fn-var.
+;;       Act on saved candidates, if any.
+;;       Do not call icicle-abort-recursive-edit at the end.
+;;     icicle-candidate-action-1:
+;;       Added optional CAND arg.
+;;       Save stuff before funcall, in case FN-VAR does its own completion.
+;;     icicle-mouse-candidate-action-1: Save stuff before funcall, in case FN-VAR completes.
+;;     icicle-remove-candidate-display-others:
+;;       When no candidates left, just call icicle-abort-recursive-edit.
+;;     icicle-help-on-candidate: Added optional CAND arg.
+;;     Renamed: icicle-candidate-alternative-action-fn to icicle-candidate-alt-action-fn.
+;; 2008/07/27 dadams
+;;     Added: icicle-sort-by-2nd-parts-alphabetically, icicle-maybe-multi-completion-*.
+;;     icicle-current-sort-functions: Treat icicle-multi-completion-sort-predicate property.
+;;     icicle-dispatch-C-comma: Call icicle-change-sort-order interactively (bug fix).
+;;     icicle-reverse-sort-order: Display candidates, possibly in reverse order (bug fix).
+;;     Moved from here to icicles-fn.el: icicle-transform-multi-completion.
+;; 2008/07/16 dadams
+;;     icicle-mouse-choose-completion: No error if minibuffer is not active.
+;;     icicle-completion-help and top-level: Don't require help-mode.el unless Emacs 22+.
+;;     eval-when-compile require's of fit-frame.el, linkd.el.
+;; 2008/06/24 dadams
+;;     icicle-narrow-candidates: Emacs < 22: Set minibuffer-completing-file-name to nil.
+;; 2008/06/21 dadams
+;;     icicle(-mouse)-choose-completion, icicle-current-completion-in-Completions,
+;;       icicle-mouse-candidate-action-1:
+;;         buffer-substring-no-properties -> buffer-substring.
+;;         *NOTE*: THIS REVERSES A FIX made on 2008/02/03.  Dunno why that fix was made.
+;; 2008/06/03 dadams
+;;     Added: icicle-toggle-C-for-actions.
+;;     icicle-Completions-mouse-3-menu: Added icicle-toggle-C-for-actions.
+;; 2008/06/01 dadams
+;;     Added: icicle-current-sort-functions.  Predicate tests various contexts using properties.
+;;     icicle-change-sort-order: Use icicle-current-sort-functions.
+;;     Added new sort order, defining function icicle-sort-special-candidates-first.
+;; 2008/05/27 dadams
+;;     icicle-isearch-complete-1: Use ring symbols, not their values.
+;; 2008/05/25 dadams
+;;     icicle-isearch-complete: Rewrote.  Handle minibuffer search.
+;;     Added: icicle-isearch-complete-1, from stuff in icicle-isearch-complete.
+;;            Treat string case. Allow recursive minibuffers.  Don't use icicle-isearch-resume.
+;;     Removed: icicle-isearch-resume.
+;; 2008/05/22 dadams
+;;     icicle-toggle-case-sensitivity: Added prefix arg and update lighter.
+;; 2008/05/03 dadams
+;;     icicle-history: Bind minibuffer-completing-file-name to nil.
+;; 2008/05/02 dadams
+;;     (put 'icicle(-mouse)-yank-secondary 'delete-selection 'yank)
+;; 2008/04/25 dadams
+;;     Added: icicle-toggle-remote-file-testing.
+;;     icicle-Completions-mouse-3-menu:
+;;       Added icicle-toggle-remote-file-testing (C-^).
+;;       icicle-toggle-ignored-space-prefix is now bound to M-_, not C-^.
+;;     icicle-dispatch-C-^:
+;;       icicle-toggle-remote-file-testing, not icicle-toggle-ignored-space-prefix.
+;; 2008/04/18 dadams
+;;     Renamed icicle-init-value-flag to icicle-default-value.
+;; 2008/04/13 dadams
+;;     icicle-pp-eval-expression-in-minibuffer: Treat prefix arg (added optional arg).
+;;     icicle-apply-to-saved-candidate: Use icicle-pp-eval-expression, not pp-eval-expression.
+;; 2008/04/02 dadams
+;;     icicle-apropos-complete-and-narrow: No longer bind icicle-top-level-when-*-flag to t.
+;; 2008/03/31 dadams
+;;     icicle-apropos-complete-1: Allow for no completion type, for No completion msg.
+;; 2008/03/29 dadams
+;;     icicle-pp-eval-expression-in-minibuffer, icicle-narrow-candidates(-with-predicate):
+;;       Removed binding of icicle-reminder-prompt-flag.
+;; 2008/03/25 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       When not regexp-matching, use substitute-in-file-name on input, to convert \ to /.
+;; 2008/03/23 dadams
+;;     icicle-scroll-Completions: Respect and update icicle-scroll-Completions-backward-p.
+;; 2008/03/19 dadams
+;;     Added: icicle-insert-newline-in-minibuffer.
+;;     Renamed i*-pp-eval-expression to *-in-minibuffer.  Calls new icicle-pp-eval-expression.
+;; 2008/03/12 dadams
+;;     icicle-completion-help: Add buttons for Commentary (icicles-doc*.el).
+;; 2008/03/11 dadams
+;;     icicle-add/update-saved-completion-set: Clarify error msg for unwritable file.
+;; 2008/03/07 dadams
+;;     Renamed icicle-abort-minibuffer-input to icicle-abort-recursive-edit.
+;; 2008/03/02 dadams
+;;     icicle-describe-file:
+;;       Use default dir if arg is nil.  Error if no readable file. Removed save-excursion.
+;; 2008/02/24 dadams
+;;     icicle-apropos-complete-1: Use icicle-apropos-match-fns-alist lookup for message.
+;;     icicle-Completions-mouse-3-menu: Added item for icicle-next-apropos-match-function.
+;;     Added: icicle-next-apropos-match-function.
+;; 2008/02/22 dadams
+;;     icicle-retrieve-candidates-from-set:
+;;       Like logic for alist in icicle-completing-read:
+;;         Do icicle-readable-to-markers, then copy car and replace cdr with whole candidate.
+;;       Removed RAW arg from call to find-file-noselect.
+;;       Wrap Lisp read in condition-case.
+;;     Renamed, added un: icicle(-mouse)-save-candidate to icicle(-mouse)-save/unsave-candidate.
+;;     icicle-add/update-saved-completion-set: Changed default name to just add .icy.
+;;     icicle-candidate-set-save-1, icicle-retrieve-candidates-from-set:
+;;       Wrap write/read to/from cache file in condition-case.
+;; 2008/02/16 dadams
+;;     icicle-retrieve-candidates-from-set:
+;;       Convert alist cands to propertized strings, using i*-put-alist-* and i*-readable-to-*.
+;;       Set icicle-candidates-alist to reconstituted retrieved candidates.
+;;     icicle-candidate-set-save-1:
+;;       Convert to readable alist from propertized text, using i*-markers-to-*, i*-get-alist-*.
+;;     Added: icicle-readable-to-markers, icicle-markers-to-readable.
+;; 2008/02/15 dadams
+;;     icicle-delete-windows-on:
+;;       Enable recursive minibuffers for interactive use.  Thx to Simon Marshall.
+;; 2008/02/14 dadams
+;;     icicle-add/update-saved-completion-set: Remove properties from completion-set string.
+;;     icicle-change-sort-order, icicle-retrieve-previous-input,
+;;       icicle-insert-string-from-variable, icicle(-mouse)-candidate-read-fn-invoke,
+;;       icicle-narrow-candidates, icicle-save-predicate-to-variable,
+;;       icicle-candidate-set-retrieve, icicle-candidate-set-save-1,
+;;       icicle-add/update-saved-completion-set, icicle-isearch-complete: 
+;;         Bind icicle-whole-candidate-as-text-prop-p to nil.
+;; 2008/02/07 dadams
+;;     icicle-delete-windows-on:
+;;       Delete frame if one-window-p and not a standalone minibuffer.  Thx to Simon Marshall.
+;; 2008/02/03 dadams
+;;     icicle-mouse-choose-completion:
+;;       Use absolute file name for choice and prepend dir in minibuffer.  Set base-size to 0.
+;;       Don't remove *Completions* window.
+;;     icicle-mouse-candidate-action-1: Use absolute file name for choice.
+;;     icicle-mouse-choose-completion, icicle-mouse-candidate-action-1,
+;;       icicle-current-completion-in-Completions: buffer-substring -> *-no-properties.
+;;     icicle-nb-of-candidate-in-Completions: Update last-nb before the test, in loop.
+;;     icicle-prefix-complete-1: If input matches empty dir, use that dir as sole completion.
+;;                               Don't remove *Completions* window until after minibuffer msg.
+;;     icicle-move-to-next-completion: Use icicle-show-Completions-help-flag, not hard-coded 3.
+;;     icicle-candidate-action-1: For require-match case also, remove cand and display others.
+;;     Added: icicle-choose-completion.
+;; 2008/01/30 dadams
+;;     Added: icicle-yank-secondary, icicle-mouse-yank-secondary.
+;; 2008/01/29 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       If icicle-incremental-completion-flag is explicit*, treat like incremental completion.
+;;     icicle-apropos-complete-1:
+;;       Distinguish non-existent dir from empty dir: icicle-apropos-any-file-name-candidates-p.
+;;     icicle-highlight-input-noncompletion takes no args now.
+;; 2008/01/13 dadams
+;;     icicle-mouse-choose-completion, icicle-insert-completion,
+;;       icicle-mouse-candidate-action-1, icicle-mouse-save-candidate:
+;;         Do not use icicle-transform-multi-completion.
+;;     icicle-retrieve-last-input, icicle-(apropos|prefix)-complete-1:
+;;       Do not treat handle-switch-frame.
+;;     icicle-mouse-candidate-action-1: Add back \n only if it has property icicle-keep-newline.
+;;     icicle-mouse-remove-candidate: Removed cruft.
+;;     icicle-remove-candidate-display-others: save-selected-window around Completions display.
+;;     icicle-help-on-candidate: Rewrote.
+;;       Do not use icicle-transform-multi-completion except where appropriate.
+;;       Always use icicle-candidate-help-fn as first priority, if defined.
+;;       Give help for prefix keys too during key completion.
+;;     icicle-help-on-candidate-symbol: No call to icicle-candidate-help-fn here.
+;; 2008/01/04 dadams
+;;     icicle-mouse-choose-completion, icicle-current-completion-in-Completions:
+;;       Add candidate's final \n only if it has property icicle-keep-newline.
+;; 2007/01/01 dadams
+;;     icicle-narrow-candidates: For Emacs < 22, don't tack dir onto file name if absolute.
+;;     icicle-candidate-set-save-1: Only redisplay candidates if *Completions* was displayed.
+;; 2007/12/31 dadams
+;;     icicle-mouse-choose-completion, icicle-mouse-candidate-action-1:
+;;       Add back candidate's final \n that is missing mouse-face.
+;;       Return icicle-candidate-nb, as doc string says.
+;;     icicle-mouse-candidate-action-1: Delete current input from minibuffer before acting.
+;;     Added: icicle-insert-list-join-string.
+;;     Don't mention that C-o is bound to icicle-candidate-action.
+;; 2007/12/26 dadams
+;;     icicle-transform-multi-completion: Empty input after join string means empty part.
+;;     icicle-help-on-candidate: Don't call icicle-raise-Completions-frame.
+;; 2007/12/11 dadams
+;;     icicle-change-sort-order:
+;;       Don't include icicle-proxy-candidate-first-p unless icicle-add-proxy-candidates-flag.
+;; 2007/12/10 dadams
+;;     icicle-exit-minibuffer, icicle-kill-failed-input:
+;;       Face icicle-input-completion-fail-lax also.
+;; 2007/12/09 dadams
+;;     icicle-exit-minibuffer: Remove icicle-input-completion-fail face from input.
+;;     icicle-kill-failed-input: Rehighlight after deleting highlighted part.
+;; 2007/12/08 dadams
+;;     icicle-(next|previous)-line: Rewrote for variable number of columns.
+;;     Added: , icicle-(beginning|end)-of-line+.
+;; 2007/12/03 dadams
+;;     Renamed longest common match (lcm) to expanded common match (ecm).
+;; 2007/11/30 dadams
+;;     icicle-help-on-candidate-symbol:
+;;       Use fboundp, not functionp, to get describe-function for macros too.
+;; 2007/11/28 dadams
+;;     Renamed describe-bindings-in-map to describe-keymap.
+;;     icicle-toggle-proxy-candidates: Swap values for saved and unsaved.
+;; 2007/11/25 dadams
+;;     Added: icicle-sort-by-abbrev-frequency.
+;;     icicle-help-on-candidate-symbol: Treat command abbrevs via apropos for their commands.
+;; 2007/11/24 dadams
+;;     Added: icicle-sort-proxy-candidates-first.
+;; 2007/11/22 dadams
+;;     icicle-help-on-candidate-symbol: Use describe-bindings-in-map for a keymap.
+;; 2007/11/17 dadams
+;;     Added: icicle-toggle-proxy-candidates.  Added to icicle-Completions-mouse-3-menu also.
+;; 2007/11/04 dadams
+;;     Require subr-21 if replace-regexp-in-string is not defined.
+;;     Require icicles-mac (don't wrap in eval-when-compile).
+;;     icicle-Completions-mouse-3-menu: Added the latest toggle commands.
+;; 2007/10/28 dadams
+;;     Added: icicle-toggle-expand-to-common-match, icicle-toggle-search-replace-common-match.
+;;     icicle-retrieve-last-input:
+;;       Treat prefix completion like non-nil expand-input-to-common-match-flag.
+;;     icicle-search-define-replacement: Bind icicle-update-input-hook to nil.
+;;     icicle-toggle-highlight-all-current:
+;;       Save icicle-candidate-nb around rehighlighting.
+;;       Call icicle-search-action to get back to current candidate and highlight it.
+;; 2007/10/27 dadams
+;;     icicle-search-define-replacement:
+;;       Bind candidates, input, and cand #, to restore after read replacement string.
+;; 2007/10/26 dadams
+;;     icicle-toggle-highlight-all-current: select-frame-set-input-focus to minibuffer.
+;; 2007/10/22 dadams
+;;     icicle-doremi-*: Use 4 arrows - one command hands off to the other.
+;; 2007/10/21 dadams
+;;     Added: icicle-doremi-inter-candidates-min-spaces, icicle-doremi-candidate-width-factor.
+;; 2007/10/14 dadams
+;;     Updated doc strings to reflect icicle-act-before-cycle-flag.
+;; 2007/10/13 dadams
+;;     icicle-candidate-action-1:
+;;       Don't set icicle-last-completion-candidate if string.  Used for repeated C-next.
+;;     icicle-remove-candidate-display-others, icicle-history:
+;;       Treat also the case where cand is a string, not a consp.
+;; 2007/10/07 dadams
+;;     icicle-delete-candidate-object: Respect icicle-deletion-action-flag.
+;; 2007/10/02 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Apply abbreviate-file-name to file-name input.  Thx to Joonhwan Lee.
+;;     icicle-toggle-fuzzy-completion: Removed soft require of fuzzy-match+.el.
+;; 2007/09/29 dadams
+;;     Added: icicle-toggle-fuzzy-completion.
+;;     icicle-Completions-mouse-3-menu: Added icicle-toggle-fuzzy-completion.
+;;     icicle-prefix-complete-1: Adjust feedback messages for fuzzy completion.
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Only set icicle-default-directory if (icicle-file-name-input-p).
+;; 2007/09/25 dadams
+;;     icicle-narrow-candidates: Treat icicle-whole-candidate-as-text-prop-p case.
+;;     icicle-kill-failed-input: Rewrote.
+;; 2007/09/21 dadams
+;;     icicle-narrow-candidates:
+;;       Emacs<22, file-name completion: Append directory to each candidate.  Thx Ian Perryman.
+;; 2007/09/14 dadams
+;;     icicle-(apropos|prefix)-complete-1, icicle-prefix-word-complete:
+;;       Wrapped condition-case around candidates computation.
+;; 2007/08/25 dadams
+;;     icicle-mouse-candidate-action-1: Use buffer-substring, not buffer-*-no-properties.
+;; 2007/08/21 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Reset icicle-input-fail-pos.  Call icicle-highlight-input-noncompletion when no match.
+;; 2007/08/19 dadams
+;;     Added: icicle-kill-failed-input.
+;; 2007/08/18 dadams
+;;     icicle-previous-apropos-candidate-alt-action: Fixed typo.  Thx to Hadron Quark.
+;; 2007/07/29 dadams
+;;     icicle-apply-to-saved-candidate:
+;;       Added use-icicle-candidates-alist-p arg.  Use icicle-get-alist-candidate.
+;;       Report original error message also.
+;;     icicle-candidate-action-1: Do nothing if icicle-last-completion-candidate not a string.
+;; 2007/07/27 dadams
+;;     icicle-successive-action:
+;;       icicle-act-first-then-navigate-p -> icicle-act-before-cycle-flag.
+;; 2007/07/08 dadams
+;;     icicle-all-candidates(-alt)-action:
+;;       Use icicle-all-candidates(-alternative)-action-fn if defined.
+;;     icicle-all-candidates-action-1: Added listp arg.
+;;     icicle-mouse-save-candidate:
+;;       Deactivate mark and redisplay completions, to show save highlight.
+;; 2007/07/07 dadams
+;;     Added: icicle-candidate-set-save(-more)-selected(-1),
+;;            icicle-mouse-candidate-set-save(-more), icicle-mouse-save-then-kill.
+;;     icicle-insert-completion: If no current completion, return to minibuffer anyway.
+;;                               Update icicle-current-input with inserted candidate.
+;;     icicle-Completions-mouse-3-menu:
+;;       Added icicle-candidate-set-save-(more(-selected)|-selected).
+;;     icicle-save-candidate: If no defined icicle-candidate-nb, then just display message.
+;;     icicle-candidate-set-save(-more):
+;;       Use icicle-candidate-set-save-1: Intern variable in standard obarray also.  Redisplay
+;;       candidates and reselect minibuffer after reading file/var name.  Put eof error in
+;;       minibuf.  Deactivate mark and redisplay completions.  Separate msg if reset.
+;;     icicle-candidate-set-retrieve: If nothing to restore, don't restore nothing.
+;;                                    If single candidate to restore, no *Completions* display.
+;;                                    Else, update candidate display.
+;; 2007/07/04 dadams
+;;     icicle-Completions-mouse-3-menu: Added icicle-retrieve-(next|\previous)-input.
+;; 2007/07/03 dadams
+;;     Added: icicle-insert-history-element, icicle-retrieve-(next|previous)-input.
+;;     icicle-history, icicle-keep-only-past-inputs:
+;;       Don't retrieve last input unless following a cycling command.
+;;     icicle-history:
+;;       Do an initial icicle-apropos-complete unless icicle-last-completion-command.
+;;       If not following a cycling command, call icicle-last-completion-command (don't set it
+;;         to empty string) and reset icicle-last-input to nil.
+;;     icicle-Completions-mouse-3-menu:
+;;       icicle-retrieve-(next|previous)-input, not icicle-retrieve-last-input.
+;;     Redefined next-history-element, instead of using defadvice.
+;; 2007/06/23 dadams
+;;     icicle-search-define-replacement: Use icicle-completing-read-history, not read-string.
+;;                                       Use icicle-search-replacement-history.
+;; 2007/06/17 dadams
+;;     Added: icicle-toggle-WYSIWYG-Completions.
+;;     icicle-switch-to-Completions-buf, icicle-move-to-next-completion:
+;;       Added priority in call to icicle-place-overlay.
+;; 2007/06/13 dadams
+;;     Added: icicle-candidate-set-save-more.
+;;     icicle-candidate-set-save: Unify messages.
+;; 2007/06/12 dadams
+;;     Added: icicle(-mouse)-save-candidate.
+;;     icicle-candidate-set-retrieve: Insert candidate if there is only one retrieved.
+;;     icicle-insert-completion: Added optional completion arg for non-interactive insertion.
+;; 2007/06/10 dadams
+;;     icicle-candidate-action-1: Treat icicle-require-match-p.
+;; 2007/06/09 dadams
+;;     icicle-candidate-action-1, icicle-mouse-candidate-action-1:
+;;       Remove candidate if icicle-use-candidates-only-once-flag.
+;;     icicle-candidate-action-1:
+;;       Let users act on non-candidate too (arbitrary input).
+;; 2007/06/07 dadams
+;;     Renamed: icicle-function-history to icicle-function-name-history,
+;;              icicle-variable-history to  icicle-variable-name-history.
+;;     Use standard history variable if bound, else use Icicles history variable:
+;;       function-name-history, variable-name-history
+;; 2007/06/01 dadams
+;;     icicle-erase-minibuffer-or-history-element, icicle-history:
+;;       Ensure value of minibuffer-history-variable is bound.
+;;     icicle-keep-only-past-inputs: If value of minibuffer-history-variable unbound, set nil.
+;;     icicle-keep-only-past-inputs, icicle-history:
+;;       Assume value of minibuffer-history-variable is a symbol - don't test that.
+;; 2007/05/29 dadams
+;;     icicle-insert-thing: Added optional arg no-replace-p.  Make sure end points are defined.
+;;     icicle-insert-string-from-variable: Call icicle-insert-thing with no-replace-p arg.
+;;     icicle-minibuffer-complete-and-exit: Set window-point to end of minibuffer.
+;; 2007/05/15 dadams
+;;     icicle-completion-help and top level:
+;;       Soft require help-mode, not (featurep 'help-mode) and (fboundp 'define-button-type).
+;; 2007/05/08 dadams
+;;     Added: icicle-save-predicate-to-variable.
+;;     icicle-Completions-mouse-3-menu: Added icicle-save-predicate-to-variable to menu.
+;;     icicle-narrow-candidates-with-predicate: Quoted the predicate that is read.
+;; 2007/05/07 dadams
+;;     Added: icicle-narrow-candidates-with-predicate.
+;;     icicle-Completions-mouse-3-menu: Added icicle-narrow-candidates-with-predicate (M-&).
+;; 2007/05/06 dadams
+;;     icicle-completion-help: Updated text at top of help buffer.
+;;     icicle-customize-button: Capitalized group Icicles.
+;;     Changed S-C- to C-S- and M-C- to C-M- in doc.
+;; 2007/05/04 dadams
+;;     icicle-candidate-read-fn-invoke, icicle-keep-only-*-inputs, icicle-retrieve-last-input,
+;;     icicle-candidate-set-(retrieve|save|swap|difference|union|intersection|complement),
+;;     icicle-all-candidates(-alt)-action, icicle-pp-eval-expression,
+;;     icicle-insert-string-from-variable:
+;;       Can call from *Completions* too, so can choose from mouse-3 menu during multi-command.
+;;     icicle-candidate-set-save, icicle-retrieve-last-input, icicle-insert-*-from-variable:
+;;       Select minibuffer window.
+;;     icicle-toggle-case-sensitivity: Use setq-default for case-fold-search.
+;;     icicle-switch-to-Completions-buf:
+;;       Use read-file-name-completion-ignore-case, if completing file name.
+;;     Added empty defvars for Emacs 22 standard vars, to quiet byte compiler.
+;; 2007/05/02 dadams
+;;     Added: icicle-dispatch-M-q, icicle-toggle-search-whole-word.
+;;     Removed: icicle-dispatch-C-backquote.
+;; 2007/04/29 dadams
+;;     Added: icicle-sort-by-last-file-modification-time (sort order).
+;; 2007/04/19 dadams
+;;     icicle-successive-action: No longer interactive.  Moved barfing to calling commands.
+;; 2007/04/17 dadams
+;;     Added: icicle-dispatch-M-comma, icicle-search-define-replacement,
+;;            icicle-dispatch-C-backquote, icicle-toggle-literal-replacement.
+;; 2007/04/08 dadams
+;;     Added: icicle-all-candidates-alt-action, icicle-all-candidates-action-1.
+;;     icicle-candidate-action-1, icicle-delete-candidate-object, icicle-help-on-candidate,
+;;     icicle-candidate-read-fn-invoke:
+;;       Use negative test for prefix mode, not positive test for apropos.
+;; 2007/04/07 dadams
+;;     Added: icicle-successive-action, icicle-toggle-search-replace-whole,
+;;            icicle-dispatch-C-comma.
+;;     Defined navigating action and help functions using icicle-successive-action.
+;; 2007/03/31 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Accept sole completion if icicle-top-level-when-sole-completion-flag.
+;;     icicle-narrow-candidates:
+;;       Use read-file-name only for Emacs 22 or later.
+;;       Accept sole completion only if icicle-top-level-when-sole-completion-flag.
+;;     icicle-apropos-complete-and-narrow: Bind icicle-top-level-when-*-flag to t.
+;; 2007/03/30 dadams
+;;     icicle-narrow-candidates: Suppress sole-completion minibuffer-message.
+;; 2007/03/23 dadams
+;;     Added: icicle-apropos-complete-and-narrow.  Thx to Marian Schubert for the suggestion.
+;;     icicle-narrow-candidates: Use icicle-require-match-p as REQUIRE-MATCH arg.
+;; 2007/03/09 dadams
+;;     Changed require to eval-when-compile require for icicles-mac.el.
+;; 2007/03/08 dadams
+;;     icicle-delete-current-candidate-object: Rewrote.
+;;       Value of var can be an arbitrary alist, a list of strings, or a list of symbols.
+;;     icicle-remove-candidate-display-others: Rewrote.
+;;       Set icicle-last-completion-candidate based on icicle-candidate-nb or 0.
+;;       Delete icicle-last-completion-candidate completely from icicle-completion-candidates.
+;;       Update minibuffer-completion-predicate or read-file-name-predicate to remove for
+;;         completion.
+;;       Use with-current-buffer, not save-window-excursion, to visit *Completions*.
+;;     icicle-remove-candidate:
+;;       Updated doc string to mention Emacs < 22 limitation for file-name candidates.
+;;     icicle-retrieve-last-input: Don't reset icicle-last-completion-command if interactive.
+;; 2007/03/07 dadams
+;;     icicle-switch-to-Completions-buf, icicle-remove-candidate-display-others,
+;;     icicle-help-on-candidate, icicle-delete-windows-on:
+;;       Use 0, not t, as frame arg to get-buffer-window.
+;; 2007/03/06 dadams
+;;     icicle-remove-candidate: Don't reset to first cand matching input if no last cand.
+;;     icicle-change(alternative)-sort-order, icicle-reverse-sort-order,
+;;       icicle-keep-only-past-inputs, icicle-toggle-sorting: Respect icicle-inhibit-sort-p.
+;;     Renamed icicle-get-current-candidate to icicle-get-alist-candidate.
+;; 2007/03/04 dadams
+;;     icicle-remove-candidate-display-others:
+;;       Use local var for cand-nb, because icicle-candidate-nb can change.
+;;       If no last candidate, reset to first candidate matching input.
+;;       Allow for icicle-candidate-nb not being defined here:
+;;         Use icicle-get-current-candidate.  Move to next completion only if cand-nb defined.
+;;       Use mapconcat only when delete multi-completion.
+;;       Move to next completion in *Completions* only if icicle-candidate-nb was defined.
+;;       Insert default-directory too, if icicle-file-name-input-p.
+;;     icicle-insert-completion: Insert default-directory too, if icicle-file-name-input-p.
+;;     icicle-(apropos|prefix)-complete-1, icicle-keep-only-past-inputs:
+;;       Don't include directory when set icicle-last-completion-candidate.
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Don't include directory when testing input membership in icicle-completion-candidates.
+;; 2007/03/02 dadams
+;;     icicle-delete-candidate-object:
+;;       Corrected message target (object).  Added sit-for.
+;;       Use local var for cand-nb, because icicle-candidate-nb can change.
+;; 2007/02/27 dadams
+;;     icicle-delete-candidate-object: Added message.
+;;     icicle-delete-current-candidate-object: Don't erase minibuffer or update completions.
+;; 2007/02/24 dadams
+;;     Added: icicle(-mouse)-candidate-alt-action, icicle(-mouse)-candidate-action-1,
+;;            icicle-(previous|next)-(apropos|prefix)-candidate-alt-action,
+;;            icicle(-mouse)-remove-candidate, icicle-remove-candidate-display-others,
+;;            icicle-delete-candidate-object, icicle-delete-current-candidate-object.
+;;     icicle-insert-completion:
+;;       Invoke icicle-transform-multi-completion.  Use with-current-buffer (window-buffer).
+;;     icicle(-mouse)-candidate-action: Use icicle(-mouse)-candidate-action-1.
+;; 2007/02/06 dadams
+;;     icicle-completion-help: Added extra help if completing and if multi-command.
+;; 2007/02/03 dadams
+;;     Renamed icicle-icompleting-p to icicle-edit-update-p.
+;; 2007/02/02 dadams
+;;     Updated doc strings of toggle commands to mention the minibuffer bindings.
+;; 2007/01/29 dadams
+;;     icicle-change-sort-order: Don't sort icicle-sort-functions-alist entries for use.
+;;     Define alphabetical sort order using icicle-case-string-less-p, not string-lessp.
+;; 2007/01/23 dadams
+;;     Added: icicle-toggle-highlight-historical-candidates.
+;;     icicle-Completions-mouse-3-menu: Updated wrt toggles.
+;; 2007/01/21 dadams
+;;     icicle-narrow-candidates:
+;;       Use minibuffer-history-variable, not regexp-history.  Thx to Jost for bug report.
+;; 2007/01/20 dadams
+;;     icicle-mouse-(choose-completion|candidate-action):
+;;       Use icicle-transform-multi-completion.
+;; 2007/01/15 dadams
+;;     Added: icicle-change(-alternative)-sort-order, icicle-reverse-sort-order,
+;;            icicle-current-sort-order, icicle-sort-*.
+;;     icicle-transform-sole-candidate: Set icicle-last-*-candidate to transformed cand.
+;;     icicle-help-on-candidate: Use icicle-transform-multi-completion.
+;;     icicle-Completions-mouse-3-menu: Updated with new sort-order bindings.
+;;     icicle-toggle-alternative-sorting: Better message.
+;;     Require icicles-mac.el.
+;; 2007/01/14 dadams
+;;     Added: icicle-transform-multi-completion, icicle-transform-sole-candidate.
+;;     icicle-(apropos|prefix)-complete-1: Use icicle-transform-sole-candidate.  Thx Rubikitch.
+;;     icicle-help-on-candidate(-symbol):
+;;       Use with-current-buffer to describe mode in Emacs 20 also.
+;; 2007/01/13 dadams
+;;     Added: icicle-describe-file, icicle-help-on-candidate-symbol.
+;;     icicle-help-on-candidate:
+;;       If existing symbol, describe it.  Else if buffer or file, describe it.  Else, convert
+;;         string to symbol and describe it.  Use icicle-help-on-candidate-symbol.
+;; 2007/01/10 dadams
+;;     icicle-switch-to/from-minibuffer: Error message if minibuffer is not active.
+;; 2007/01/06 dadams
+;;     icicle-(apropos|prefix)-complete-1:
+;;       expand-file-name -> icicle-abbreviate-or-expand-file-name.
+;;     Added: icicle-toggle-~-for-home-dir.
+;;     icicle-prefix-complete-1:
+;;       Set icicle-default-directory only if also icicle-file-name-input-p.
+;; 2007/01/01 dadams
+;;     icicle-add/update-saved-completion-set: Use icicle-assoc-delete-all, not delete of assoc.
+;;     Runtime, not compile-time, require of icicles-var.el, icicles-opt.el.
+;; 2006/12/29 dadams
+;;     icicle-insert-string-at-point:
+;;       Treat nil return of alternative text-grabbing function.
+;;       Echo the text-grabbing function when icicle-default-thing-insertion = alternatives.
+;;     icicle-ensure-overriding-map-is-bound: Separate treatment for diff Emacs versions.
+;; 2006/12/25 dadams
+;;     icicle-keep-only-past-inputs:
+;;       Added optional recent-first arg: Use icicle-most-recent-first-p as sort function.
+;;       Update cands list if repeat.  Do not scroll Completions; update it unconditionally.
+;;     Added: icicle-candidate-set-truncate.
+;;     Uncommented describe-mode code, since RMS fixed Emacs bug that caused infinite recursion.
+;; 2006/12/24 dadams
+;;     Added: icicle-Completions-mouse-3-menu.
+;; 2006/12/23 dadams
+;;     icicle-narrow-candidates: Bug fix: Treat file-name completion with read-file-name.
+;;     icicle-help-on-candidate: Call non-nil icicle-candidate-help-fn on candidate.
+;; 2006/12/18 dadams
+;;     icicle-apply-to-saved-candidate: Remove print arg and use current-prefix-arg instead.
+;;     icicle-ensure-overriding-map-is-bound: Protect overriding-map-is-bound with boundp.
+;;     Bug fix for Emacs 21: protect help-xref with get type button-category-symbol.
+;; 2006/12/17 dadams
+;;     Added: icicle(-mouse)-candidate-read-fn-invoke, icicle-apply-to-saved-candidate.
+;; 2006/12/10 dadams
+;;     Created from minibuffer and *Completions* commands in icicles-cmd.el.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-mode.el'")
+;;
+;; 2011/09/08 dadams
+;;     icicle-bind-isearch-keys: Replace lambda with icicle-search-w-isearch-string.
+;; 2011/09/06 dadams
+;;     icicle-define-minibuffer-maps, icicle-(bind|restore)-completion-keys:
+;;       Bind icicle-resolve-file-name to C-x C-f.
+;; 2011/09/05 dadams
+;;     icicle-mode: Update doc string: icicle-toggle-hiding-non-matching-lines.
+;;     icicle-define-icicle-maps: Added icicle-toggle-hiding-non-matching-lines to menus.
+;;     icicle-bind-completion-keys: Bind C-x . to icicle-dispatch-C-x. (new).
+;; 2011/09/02 dadams
+;;     icicle-(bind|restore)-other-keymap-keys:
+;;       Test fn memq in icicle-functions-to-redefine, not just non-nil icicle-functions-to-redefine.
+;;       Removed remap/unmap of Info commands.
+;;       Restore completion-at-point, not comint-dynamic-complete, for Emacs 24.
+;;     At end: defalias old-Info commands (instead of remapping in icicle-(bind|restore)-*-keys).
+;; 2011/08/13 dadams
+;;     Bound icicle-toggle-search-complementing-domain to C-M-~ and added to menus.
+;; 2011/08/12 dadams
+;;     icicle-define-minibuffer-maps: Removed code that binds C-x m, C-backspace, C-c +.
+;;       Do that in icicle-bind-file-candidate-keys now.
+;; 2011/08/07 dadams
+;;     icicle-mode: Updated doc string for bookmark commands.
+;; 2011/05/22 dadams
+;;     Added defvars for free vars to quiet byte compiler.
+;; 2011/05/07 dadams
+;;     Changed key for icicle-regexp-quote-input from C-M-; to M-% everywhere.
+;;     Bound icicle-toggle-ignoring-comments to C-M-;.
+;;     icicle-mode doc string, icicle(-options)-menu-map: Added icicle-toggle-ignoring-comments.
+;; 2011/05/03 dadams
+;;     icicle-define-icicle-maps: Add icicle-toggle-highlight-saved-candidates to menus.
+;;     icicle-(bind|restore)-completion-keys: Bind icicle-plus-saved-sort to C-M-+.
+;;                                            Bind icicle-toggle-highlight-saved-candidates to S-pause.
+;;     icicle-mode doc string: Mention icicle-toggle-highlight-saved-candidates.
+;; 2011/04/12 dadams
+;;     icicle-define-icicle-maps: Added Icicles submenu for Bookmark+ menu.
+;;     icicle-(bind|restore)-other-keymap-keys:
+;;       Bound icicle-bookmark-save-marked-files(-as-project|-more) in bookmark-bmenu-mode-map.
+;; 2011/03/29 dadams
+;;     icicle-define-minibuffer-maps, icicle-bind-completion-keys:
+;;       Bound C-M-(v|V) to icicle-scroll-(forward|backward).
+;;     Applied renaming: icicle-scroll-Completions(-up) to icicle-scroll-Completions-(back|for)ward.
+;; 2011/03/26 dadams
+;;     icicle-define-icicle-maps: Added tags commands.
+;; 2011/03/06 dadams
+;;     icicle-define-icicle-maps:
+;;       Added to Options (sub)menu: icicle-toggle-search-whole-word.
+;;       Removed from Options: icicle-toggle-highlight-all-current, icicle-regexp-quote-input.
+;;       Removed redundant :visible icicle-mode's for icicle-menu-map.
+;;       Added :help entries.
+;;       Corrected: icicle-bookmark-bookmark-list, icicle-bookmark-desktop: not other-window.
+;;     icicle-define-minibuffer-maps, icicle-(bind|restore)-completion-keys:
+;;       Added: icicle-toggle-highlight-all-current, icicle-regexp-quote-input,
+;;              icicle-erase-minibuffer-or-history-element (2), icicle-insert-list-join-string,
+;;              icicle-insert-key-description, icicle-insert-string-from-variable (2),
+;;              icicle-insert-string-at-point.
+;; 2011/02/22 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind C-x t to icicle-cycle-image-file-thumbnail.
+;;     icicle-mode: Do not add icicle-fit-completions-window to temp-buffer-show-hook.
+;;                  Do it explicitly in icicle-display-candidates-in-Completions now.
+;;     Renamed: icicle-*-standard-commands to icicle-(redefine|restore)-standard-functions.
+;;              And rewrote them to just use new option icicle-functions-to-redefine.
+;;     Replaced: icicle-redefine-standard-commands-flag with icicle-functions-to-redefine everywhere.
+;;     Added: old-comint-dynamic-complete-filename.
+;; 2011/02/17 dadams
+;;     icicle-(redefine|restore)-standard-commands: Use icicle-read-color for read-color.
+;; 2011/01/20 dadams
+;;     icicle-define-minibuffer-maps, icicle-(bind|restore)-completion-keys:
+;;       Bind/restore keys C-M-S-[cf] (*-completing-read+insert-keys, *-read+insert-file-name-keys).
+;; 2011/01/18 dadams
+;;     Require advice.el.
+;; 2011/01/01 dadams
+;;     icicle-define-icicle-maps: Typo: icicle-search-tags-menu-map -> icicle-menu-map.  Thx Le Wang.
+;; 2010/12/26 dadams
+;;     Added autoload cookies to load icicles.el when command icicle-mode is invoked.
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     Added more autoload cookies for commands.  Thx to Richard Kim.
+;; 2010/11/23 dadams
+;;     icicle-define-icicle-maps: Added "in minibuf" to :key for C-?.  Thx to Michael Heerdegen.
+;; 2010/11/21 dadams
+;;     icicle-(redefine|restore)-standard-commands:
+;;       defalias lisp-complete-symbol unconditionally (it's still needed in some places for Emacs 23).
+;; 2010/11/20 dadams
+;;     For eval-after-load's:
+;;       Protect eval of icicle-mode with boundp.
+;;       If the library is already loaded, then add the eval-after-load to icicles-mode.el instead.
+;;       Uncommented the code for simple.el for Emacs 23+.
+;;     dolist eval-after-load at end: Removed test for icicles-mode feature.
+;; 2010/11/10 dadams
+;;     Define lisp-completion-at-point to return Icicles fn (don't defalias).  Thx to M. Heerdegen.
+;; 2010/11/06 dadams
+;;     icicle-top-level-prep: Reset current TAB and S-TAB methods, if temporary.
+;; 2010/11/03 dadams
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Updated for Emacs 23.2+: defalias lisp-completion-at-point instead.  Thx to Michael Heerdegen.
+;; 2010/10/21 dadams
+;;     icicle-minibuffer-setup:: Revert last change: this must NOT be local.
+;; 2010/10/19 dadams
+;;     icicle-minibuffer-setup: Use non-nil LOCAL arg to add-hook for icicle-top-level-prep.
+;; 2010/10/09 dadams
+;;     icicle-define-cycling-keys:
+;;       Define modal keys uncondiationally (no icicle-cycling-respects-completion-mode).
+;;       Define modal keys first, then non-modal.  Remove no bindings (make no bindings to nil).
+;;       Removed hard-coded bindings for mouse wheel - handled by vars now, as before.
+;;     icicle-define-minibuffer-maps:
+;;       Hard-code down/up in completion-list-mode-map - do not reuse prefix completion keys.
+;;     Applied renaming of icicle-cycling-respects-completion-mode to icicle-default-cycling-mode.
+;; 2010/10/08 dadams
+;;     icicle-minibuffer-setup: Don't set icicle-current-completion-mode in recursive minibuffer.
+;;     icicle-define-cycling-keys: Unconditionally define mouse wheel for modal cycling.
+;; 2010/10/07 dadams
+;;     Use icicle-current-TAB-method function, not variable, everywhere.
+;; 2010/10/06 dadams
+;;     icicle-define-cycling-keys:  Let all non-conflicting non-modal keys remain: modal just
+;;                                  overwrites the conflicting non-modal.  Thx to Michael Heerdegen.
+;; 2010/07/17 dadams
+;;     w3m - > url.  Add URL jump bindings.  Replace w3m by url otherwise.
+;; 2010/06/11 dadams
+;;     icicle-define-minibuffer-maps: Bind/restore C-c + to icicle-make-directory in file-name maps.
+;; 2010/06/04 dadams
+;;     icicle-mode doc string: Mention missing doremi commands.
+;;     icicle-define-icicle-maps: Added Swank items and Max # of Completions, :visible for separator.
+;;     icicle-(bind|restore)-completion-keys: Bind icicle-doremi-increment-max-candidates+ to C-x #.
+;;     Apply renamings of icicle-doremi* (added +).
+;; 2010/05/26 dadams
+;;     Add to command-history only if an interned symbol.  Thx to Michael Heerdegen.
+;; 2010/05/22 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind icicle-candidate-read-fn-invoke to ESC C-m also.
+;; 2010/05/17 dadams
+;;     icicle-define-icicle-maps: Changed :enable conditions for *-goto*-marker.  Thx to M. Heerdegen.
+;; 2010/05/15 dadams
+;;     icicle-mode: Updated doc string for bookmark commands.
+;; 2010/05/09 dadams
+;;     Key-binding changes: icicle-change-sort-order is C-, icicle-dispatch-M-_ is M-_.
+;; 2010/04/21 dadams
+;;     icicle-(redefine|restore)-std-completion-fns: Added icicle-sit-for for Emacs 23.
+;; 2010/04/02 dadams
+;;     icicle-mode: Updated doc string: list of commands.
+;; 2010/04/02 dadams
+;;     icicle-mode: Update doc string for change from regions to bookmarks.
+;;     icicle-define-icicle-maps:
+;;       Remove Icicles region stuff from menus.
+;;       Added to menus: icicle-search-bookmarks-together, icicle-search-bookmark,
+;;                       icicle-select-bookmarked-region.
+;; 2010/03/28 dadams
+;;     Applied renaming: icicle-search-all-regions to icicle-search-region.
+;;     Use icicle-search-region-bookmark in menus.
+;; 2010/03/14 dadams
+;;     icicle-define-minibuffer-maps: Use featurep, not soft-require, for bookmark+.el.
+;;     Added bookmark+ to final dolist for eval-after-load.
+;; 2010/03/13 dadams
+;;     icicle-define-icicle-maps:
+;;       Bound icicle-toggle-show-multi-completion to M-m in minibuffer, and added to menus.
+;;     Applied renaming of icicle-add-buffer-name-flag to icicle-show-multi-completion-flag.
+;; 2010/02/17 dadams
+;;     Applied rename of icicl-redefined-functions to icicle-inhibit-advice-functions.
+;; 2010/02/13 dadams
+;;     icicle-mode:
+;;       Fill icicle-advice-info-list from advised fns among icicle-redefined-functions.
+;;       Reactivate advised fns (in icicle-advice-info-list) when turn mode off.
+;;       Added to doc string: icicle-bookmark-(dired|desktop|bookmark-list|man)-other-window.
+;;     icicle-define-icicle-maps: Use (featurep 'recentf) instead of soft-requiring it.
+;;     icicle(-bookmark)-menu-map: Added type-specific bookmark jump commands.
+;;     eval-after-load's: Add (when (featurep 'icicles-mode)...) to ensure this file was loaded.
+;; 2010/01/28 dadams
+;;     icicle-define-minibuffer-maps, icicle-restore-completion-keys:
+;;       Restore C-g correctly if delete-selection-mode.
+;; 2009/12/25 dadams
+;;     icicle-mode: Call completion-ignored-build-disable to disable the advice.
+;; 2009/12/21 dadams
+;;     Final dolist: Move loaded-library test outside of eval-after-load.
+;;                   Update the test for Emacs 22+ (not just assoc).  Thx to Kevin Ryde.
+;;     Combine eval-after-load's for dired-x.  Remove eval-after-load for simple.el (preloaded).
+;;     fset -> defalias.
+;; 2009/12/13 dadams
+;;     icicle-define-minibuffer-maps:
+;;       Bind C-x m to icicle-bookmark-file-other-window in file-name completion maps.
+;; 2009/11/29 dadams
+;;     Don't reference minibuffer-local-must-match-filename-map unless bound (obsolete in 23.2).
+;; 2009/11/27 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind/restore C-x 1, C-x 2.
+;; 2009/11/07 dadams
+;;     Applied doremi cmd renamings (added +).
+;; 2009/10/25 dadams
+;;     icicle-mode, icicle-define-icicle-maps, icicle-bind-completion-keys:
+;;       Updated doc string, menus, keys for completion-method command renamings.
+;; 2009/09/26 dadams
+;;     icicle-minibuffer-setup: Don't complete if icicle-progressive-completing-p.
+;; 2009/09/16 dadams
+;;     icy-mode: Add icicle-insert-buffer to doc string.
+;;     icicle-define-icicle-maps: Added icicle-insert-buffer to icicle-menu-map.
+;; 2009/09/10 dadams
+;;     icicle-bind-key-completion-keys-in-keymaps-from: Don't exclude menu maps.
+;; 2009/09/03 dadams
+;;     icicle-add-menu-item-to-cmd-history: Wrap in condition-case, since on pre-command-hook.
+;; 2009/08/18 dadams
+;;     icicle-add-menu-item-to-cmd-history:
+;;       Ensure this-command-keys-vector is not empty.  Thx to Kai Tetzlaff and Lennart Borgman.
+;; 2009/08/09 dadams
+;;     icicle-minibuffer-setup: Set region background for recursive minibuffers too.
+;;     icicle-restore-region-face: Don't restore unless going back to top level.
+;; 2009/08/01 dadams
+;;     Added: icicle-add-menu-item-to-cmd-history.  Thx to Lennart Borgman.
+;;     icy-mode: add/remove pre-command-hook, respecting icicle-menu-items-to-history-flag.
+;;     call-interactively defadvice: Do not save let savehist save icicle-interactive-history.
+;; 2009/07/29 dadams
+;;     Change advice for call-interactively:
+;;       Use it only for Emacs 23+.  Disable it to begin with.  
+;;       Add only (non-mouse command) symbols to history.
+;;     icy-mode (Emacs 23+):
+;;       Enable/disable advice icicle-save-to-history when mode is turned on/off.
+;;       Enable the advics only if non-nil icicle-populate-interactive-history-flag.
+;;     icy-mode (Emacs 20-21): Remove advice icicle-save-to-history.
+;; 2009/07/26 dadams
+;;     Advise call-interactively to save command to icicle-interactive-history.
+;;     icicle-(bind|restore)-completion-keys: Bind/restore C-M-pause as icicle-other-history.
+;; 2009/07/13 dadams
+;;     Emacs 22+:
+;;       Added describe-face defadvice (icicle-respect-WYSIWYG).  icicle-mode: (de)activate it.
+;; 2009/06/18 dadams
+;;     icicle-mode: Added icicle-doremi-zoom-Completions to doc string.
+;; 2009/06/17 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind icicle-doremi-zoom-Completions to C-x -.
+;;     icicle-define-icicle-maps:
+;;       Add icicle-doremi-zoom-Completions to Options menu.
+;;       Change visible condition for all doremi stuff to ensure *Completions* is showing.
+;; 2009/05/27 dadams
+;;     icicle-retrieve-(next|previous)-input: Removed unused (always nil) arg DONT-COMPLETE-P.
+;; 2009/05/22 dadams
+;;     icicle-define-icicle-maps: Added icicle-Info-virtual-book to menu.
+;;     Require icicles-cmd[12].el.
+;; 2009/05/17 dadams
+;;     dolist eval-after-load at end: Use icicle-toggle-icicle-mode-twice, not icy-mode calls.
+;; 2009/05/09 dadams
+;;     icicle-define-icicle-maps: Added icicle-toggle-dot to options menu.  Updated C-x . key.
+;;     icicle-(bind|restore)-completion-keys:
+;;       Bind *-toggle-dot to C-M-., *-toggle-hiding-common-match to C-x .,
+;;            *-insert-dot-command to ..
+;;     icy-mode: Mention icicle-toggle-dot in doc string.
+;; 2009/05/02 dadams
+;;     icicle-minibuffer-setup: Set icicle-cmd-reading-input to this-command.
+;; 2009/04/30 dadams
+;;     icicle-minibuffer-setup: Reset icicle-next-(prefix|apropos)-complete-cycles-p to nil.
+;; 2009/04/20 dadams
+;;     icicle-bind-completion-keys: Don't bind C-S-(up|down|next|prior) explicitly.
+;;     icicle-restore-completion-keys:
+;;       Restore: icicle-(prefix|apropos)-cycle-(previous|next)-alt-action-keys,
+;;                icicle-modal-cycle-(up|down)-alt-action-keys.
+;;       Don't restore C-S-(up|down|next|prior) explicitly.
+;;     icicle-define-cycling-keys:
+;;       Bind/Restore: icicle-(prefix|apropos)-cycle-(previous|next)-alt-action-keys,
+;;                     icicle-modal-cycle-(up|down)-alt-action-keys.
+;; 2009/04/19 dadams
+;;     icicle-redefine-standard-commands: Added defalias for customize-apropos-options-of-type.
+;;     eval-after-loads: Use when/unless instead of and/or for fset's. (cosmetic)
+;; 2009/04/18 dadams
+;;     icicle-mode: Mention in doc string: you might want to customize keys if no window mgr.
+;; 2009/04/16 dadams
+;;     icicle-restore-completion-keys, icicle-define-cycling-keys:
+;;       Use icicle-(prefix|apropos)-cycle-(previous|next)-help-keys.
+;; 2009/04/15 dadams
+;;     icicle-bind-completion-keys: Removed bindings for C-M-(up|down|prior|next).
+;;     icicle-restore-completion-keys: Unbind icicle-modal-cycle-(up|down)-help-keys.
+;;     icicle-define-cycling-keys: Bind/unbind all help keys (including modal ones).
+;; 2009/03/27 dadams
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Added icicle-minibuffer-default-add-completions.
+;; 2009/03/16 dadams
+;;     icicle-define-icicle-maps: Use :visible for Icicle submenus themselves.
+;;     icicle-(redefine|restore)-standard-commands: Added icicle-recentf-make-menu-items.
+;;     Added eval-after load for recentf.el.
+;; 2009/03/15 dadams
+;;     icicle-mode: Added to doc string: icicle-recompute-shell-command-candidates,
+;;                                       icicle-remove-file-from-recentf-list.
+;;     icicle-define-icicle-maps: Added icicle-remove-file-from-recentf-list to menus.
+;; 2009/03/10 dadams
+;;     icicle-mode: Don't reset icicle-shell-*-cache if icicle-guess-commands-in-path is load.
+;;     Applied renaming: icicle-shell-command-candidates to *-cache
+;; 2009/03/01 dadams
+;;     icicle-define-minibuffer-maps:
+;;       Bind icicle-completing-read+insert, icicle-read+insert-file-name.  Add to Minibuf menu.
+;; 2009/02/28 dadams
+;;     fset old-dired-smart-shell-command after load Dired-X.
+;; 2009/02/20 dadams
+;;     icicle-mode: Reset icicle-shell-command-candidates to nil.
+;;     icicle-minibuffer-setup:
+;;       Use function icicle-require-match-p, not var.
+;;       Do not reset icicle-completing-p to nil (reset by icicle-require-match-p).
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Redefine dired-read-shell-command, not dired-guess-shell-command.
+;;       Redefine: dired-smart-shell-command, shell-command(-on-region).
+;;     Added eval-after load for dired-read-shell-command for dired-aux.el (and for dired-x.el).
+;;     eval-after-load for read-shell-command: Don't do it only when mailcap can be loaded.
+;; 2009/02/01 dadams
+;;     icicle-define-minibuffer-maps: Bind C-backspace to icicle-up-directory.
+;; 2009/01/25 dadams
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Aliases for dired-guess-shell-command, read-shell-command.  Also eval-after-load's.
+;; 2009/01/23 dadams
+;;     icicle-(bind|restore)-other-keymap-keys:
+;;       For sh-mode-map, remap comint-dynamic-complete, don't (un)bind TAB.  Thx to Seb Luque.
+;; 2009/01/18 dadams
+;;     Renamed Open Dired for Saved Completion Candidates to Open Dired for Chosen Files.
+;; 2009/01/06 dadams
+;;     Added to dolist of eval-after-load's: net-utils, rlogin, idlw-shell.
+;; 2009/01/05 dadams
+;;     icicle-(bind|restore)-other-keymap-keys: Treat keys for Shell Script, Ielm, Tcl, and GUD.
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Handle: comint-dynamic-complete-filename, gud-gdb-complete-command.
+;;     Added eval-after-load for gud.
+;;     Added to dolist of eval-after-load's: ielm, gud, sh-script, tcl.
+;; 2009/01/04 dadams
+;;     Added ESS support:
+;;       icicle-(redefine|restore)-standard-commands:
+;;         Added: (icicle|old)-comint-replace-by-expanded-filename,
+;;                (icicle|old)-ess-complete-object-name.
+;;       Added eval-after-load for ess-site and for old-comint-replace-by-expanded-filename.
+;;       Thx to Sebastian Luque.
+;; 2008/12/30 dadams
+;;     icicle-mode: Don't add/remove hook icicle-shell-hook-fn.
+;;                  Don't call icicle-(un)bind-isearch-keys.
+;;     Renamed: icicle-rebind-other-keymap-keys to icicle-bind-other-keymap-keys.
+;;     icicle-(bind|restore)-other-keymap-keys:
+;;       Call icicle-(un)bind-isearch-keys here.
+;;       Bind/restore icicle-comint-command here.
+;;       Don't use eval-after-load.  Instead, define keys if the maps are defined.
+;;       Bind/restore shell keys only if icicle-redefine-standard-commands-flag is true.
+;;     icicle-minibuffer-setup:
+;;       Remove redundant code that calls icicle-define-cycling-keys for each minibuffer map.
+;;     icicle-define-minibuffer-maps:
+;;       Restore C-g to abort-recursive-edit in minibuffer-local-must-match-map.
+;;     icicle-(redefine|restore)-standard-commands:
+;;       Test fboundp of old-*, not *, for bbdb and comint.
+;;       Do not defalias comint-dynamic-complete-filename or shell-dynamic-complete-*.
+;;     icicle-remap: Moved to icicles-opt.el.
+;;     At end of file:
+;;       eval-after-load comint and bbdb: Turn off icy-mode before fset old-*.
+;;       eval-after-load each of the other keymap libraries: Toggle icy-mode.
+;; 2008/12/26 dadams
+;;     Bind icicle-widen-candidates to M-+, and add it to Minibuf menu.
+;;     Bind icicle-apropos-complete-and-widen to S-backspace.
+;; 2008/12/22 dadams
+;;     Forgot to add/remove icicle-shell-hook-fn to shell-mode-hook for Emacs 20.
+;;     icicle-bind-completion-keys, icicle-define-icicle-maps: Added icicle-regexp-quote-input.
+;; 2008/12/21 dadams
+;;     icicle-(redefine|restore)-standard-commands: Added comint-*, shell-*.
+;;     Renamed *-(rebind|restore)-non-completion-keys to *-(rebind|restore)-other-keymap-keys.
+;;     icy-mode: Add/remove icicle-shell-hook-fn to shell-mode-hook.
+;;     icicle--(rebind|restore)-other-keymap-keys:
+;;       Don't rebind Info keys unless icicle-redefine-standard-commands-flag.
+;;       Wrap Dired key bindings in eval-after-load.
+;;     icicle-restore-other-keymap-keys: Corrected (updated) Dired keys.
+;; 2008/12/07 dadams
+;;     icicle-minibuffer-setup:
+;;       Add completing prompt prefix here, using icicle-completion-prompt-overlay.
+;;       Removed icicle-prompt.
+;; 2008/12/05 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind C-v, M-v to scroll *Completions* window.
+;; 2008/11/14 dadams
+;;     icicle-toggle-hiding-common-match:
+;;       icy-mode: Mention it in doc string, icicle-define-icicle-maps: Add it to menus.
+;;       icicle-bind-completion-keys: Bind it to C-M-.
+;;     icicle-minibuffer-setup:
+;;       Use (cadr (buffer-list)), not other-buffer, for icicle-pre-minibuffer-buffer
+;; 2008/11/04 dadams
+;;     icicle-define-icicle-maps: No longer bind icicle-generic-S-tab keys (obsolete).
+;;     Renamed:
+;;       *-(un)bind-S-TAB-in-keymaps-from to *-(un)bind-key-completion-keys-in-keymaps-from,
+;;       *-(un)bind-S-TAB-for-map-variable to *-(un)bind-key-completion-keys-for-map-var.
+;;     icicle-(un)bind-key-completion-keys-in-keymaps-from:
+;;       icicle-generic-S-tab-keys -> icicle-key-complete-keys.
+;;       Respect icicle-complete-key-anyway-flag.
+;;     icicle-define-minibuffer-maps: *-generic-S-tab-keys -> *-previous-candidate-keys.
+;;     icicle-(bind|restore)-completion-keys: *-generic-S-tab-keys -> *-apropos-complete-keys.
+;;     icicle-(un)bind-isearch-keys: *-generic-S-tab-keys -> *-search-from-isearch-keys.
+;; 2008/11/03 dadams
+;;     Applied renamings from icicles-cmd.el.
+;; 2008/11/01 dadams
+;;     Require cl.el at compile time for all Emacs versions, not just 20.
+;; 2008/10/14 dadams
+;;     icy-mode: No longer call icicle-update-help-string.
+;;     Renamed: *-update-help-string to *-help-string-completion and moved to icicles-mcmd.el.
+;;     Renamed: icicle-rebind-completion-maps to icicle-define-minibuffer-maps.
+;;     Applied renaming from icicles-mcmd.el: icicle-completion-help to icicle-minibuffer-help.
+;;     icicle-define-minibuffer-maps:
+;;       Bound icicle-minibuffer-help also in non-completion minibuffer maps and *Completions*.
+;;       Bound icicle-yank-secondary in minibuffer-local-isearch-map also.
+;;     icicle-(bind|restore)-completion-keys: Only bind icicle-minibuffer-help if not inherited.
+;; 2008/10/12 dadams
+;;     icicle-rebind-non-completion-keys (and undo in icicle-restore-non-completion-keys):
+;;       Ibuffer mode: Bind M-s i to icicle-search-ibuffer-marked and add to Operate menu.
+;;       Buffer Menu mode: Bind M-s i to icicle-search-buff-menu-marked.
+;;       Dired mode: Change binding of icicle-search-dired-marked from M-s to M-s i.
+;;                   Removed vestigial binding to C-M-r.
+;;       Make eval-after-load for "info" unconditional.
+;; 2008/10/11 dadams
+;;     icicle-update-help-string, icicle-(bind|restore)-completion-keys:
+;;       icicle-kill-failed-input -> icicle-goto/kill-failed-input.
+;;     icicle-define-cycling-keys: Typo: icicle-apropos-cycle-previous-keys -> *-action*.
+;; 2008/10/10 dadams
+;;     icicle-minibuffer-setup:
+;;       Make icicle-current-completion-mode respect *-cycling-respects-completion-mode-flag.
+;;       Initial *Completions* display respects icicle-cycling-respects-completion-mode-flag.
+;;     icicle-minibuffer-setup, icicle-bind-completion-keys: Use icicle-define-cycling-keys.
+;;     icicle-restore-completion-keys: Restore (C-)up, (C-)down, (C-)next, (C-)prior.
+;;     Added: icicle-define-cycling-keys.
+;; 2008/10/08 dadams
+;;     icicle-bind-completion-keys:
+;;       Bind icicle-candidate-set-retrieve-more to C-<.  Add to Minibuf menu.
+;;     icicle-define-icicle-maps, icicle-update-help-string: Remove C-< for angle brackets.
+;;     icicle-minibuffer-setup:
+;;       Set icicle-pre-minibuffer-buffer to (other-buffer nil t), not (cadr (buffer-list).
+;; 2008/10/04 dadams
+;;     icicle-(redefine|restore)-std-completion-fns:
+;;       Substitute Icicles version of completing-read-multiple and maps.  Thx to Per Nordlow.
+;;     icy-mode doc string: Typo - thx to Richard Kim.
+;; 2008/10/01 dadams
+;;     icicle-update-help-string: Added current values for toggles.  Moved toggles near top.
+;;     Added: icicle-S-iso-lefttab-to-S-TAB.
+;; 2008/09/30 dadams
+;;     icicle-bind-isearch-keys: For icicle-generic-S-tab-keys, read the search string using
+;;       icicle-isearch-complete-past-string.
+;; 2008/09/13 dadams
+;;     Use renamings from icicles-mcmd.el:
+;;       icicle-candidate-set-save-to-cache-file to icicle-candidate-set-save-persistently,
+;;       icicle-candidate-set-retrieve-from-cache-file to *-candidate-set-retrieve-persistent.
+;; 2008/09/11 dadams
+;;     icicle-define-icicle-maps: Added icicle-grep-saved-file-candidates to menus.
+;; 2008/09/09 dadams
+;;     Use renamings from icicles-cmd.el:
+;;       icicle-candidate-set-dired-marked-save-* to icicle-dired-save-marked-*.  
+;;     Bind: icicle-dired-save-marked-* to C(-M)->, not C(-M)-),
+;;           icicle-dired-saved-file-candidates-other-window to C-M-<, not C-M-r,
+;;           icicle-dired-save-marked-(to-variable|as-project) to C-M-}, C-},
+;;           icicle-dired-project-other-window to C-{.
+;;     Add to Dired > Multiple (or Operate) > Icicles menu: icicle-dired-save-marked-as-project.
+;;     Add to Dired > Dir and File > Icicles menus: icicle-dired-project-other-window.
+;;     Removed from File > Icicles menu: icicle-dired-saved-file-candidates.
+;; 2008/08/22 dadams
+;;     icicle-update-help-string: Removed mention of icicle-Completions-window-default-width.
+;; 2008/08/21 dadams
+;;     icicle-define-icicle-maps: Replace icicle-find-file(-*) with icicle-file.
+;;     icicle-mode doc string, icicle-update-help-string: Updated for new cmds icicle-file etc.
+;;     Define BBDB aliase only if BBDB is loaded. 
+;; 2008/08/17 dadams
+;;     icicle-rebind-completion-maps: Bind mouse wheel for completion-list-mode-map.
+;; 2008/08/12 dadams
+;;     icicle-define-icicle-maps: Add :keys for icicle-goto(-global)-marker.
+;; 2008/08/08 dadams
+;;     icicle-define-icicle-maps:
+;;       Added icicle-goto(-global)-marker to icicle-(bookmark|search)-menu-map.
+;;     Soft require of menu-bar+.el, instead of just eval-when-compile.
+;; 2008/08/07 dadams
+;;     icicle-(redefine|restore)-*: Don't use symbol-function for target of defalias.
+;; 2008/08/04 dadams
+;;     Use condition-case when require mb-depth+.el.
+;;     icicle-(rebind|restore)-completion-maps, icicle-bind-completion-keys:
+;;       Updated Minibuf menu to add icicle-clear-current-history.
+;;     icicle-restore-completion-keys:
+;;       Added: (alt-)action(-list)-all, icicle-save-predicate-to-variable.
+;; 2008/08/03 dadams
+;;     icicle-mode: Updated doc string.
+;;     icicle-update-help-string: Added clear-history stuff and changed bindings.
+;;     icicle-rebind-completion-maps: Added binding: icicle-clear-current-history (M-i).
+;;     icicle-bind-completion-keys:
+;;       Added to Minibuf menu: icicle-all-candidates(-list)(-alt)-action.
+;;       Added bindings: icicle-all-candidates-list-action (M-!),
+;;                       icicle-all-candidates-list-alt-action (M-|),
+;;                       icicle-clear-current-history (M-i).
+;;       Changed bindings:
+;;         icicle-all-candidates-alt-action (C-S-insert to C-|)
+;;         icicle-toggle-expand-to-common-match (C-| to C-;),
+;;         icicle-toggle-search-replace-common-match (C-M-| to M-;),
+;;       
+;; 2008/08/01 dadams
+;;     icicle-mode: Std mb-depth.el renamed *-indicate-depth-mode  to *-depth-indicate-mode.
+;; 2008/07/30 dadams
+;;     icicle-update-help-string: Make C-M-) more obvious for clearing saved candidates.
+;; 2008/07/23 dadams
+;;     Renamed: icicle-map to icicle-apply.
+;; 2008/07/21 dadams
+;;     icicle-(redefine|restore)-standard-commands: Added icicle-bbdb-complete.
+;; 2008/06/03 dadams
+;;     icy-mode: Added icicle-toggle-C-for-actions to doc string.
+;;     icicle-define-icicle-maps: Added icicle-toggle-C-for-actions to menus.
+;;     icicle-update-help-string:
+;;       Mention icicle-insert-history-element, icicle-toggle-C-for-actions.
+;;     icicle-bind-completion-keys: Bindings according to icicle-use-C-for-actions-flag.
+;;     icicle-(bind|restore)-completion-keys: Bind/unbind M-g.
+;; 2008/05/27 dadams
+;;     Renamed: icicle-(un)bind-isearch-completion-keys to icicle-(un)bind-isearch-keys.
+;;     icicle-bind-isearch-keys: Bind S-TAB to icicle-search, C-o to isearch-(m)occur.
+;;                               Likewise, icicle-unbind-isearch-keys.
+;; 2008/05/25 dadams
+;;     Renamed: icicle-bind-isearch-keys to icicle-bind-isearch-completion-keys.
+;;     Added: icicle-unbind-isearch-completion-keys.
+;;     icy-mode: icicle-(un)bind-isearch-completion-keys instead of updating isearch-mode-hook.
+;;     icicle-bind-isearch-completion-keys:
+;;       Don't bind anything in minibuffer-local-isearch-map (overridden by icicle-mode-map).
+;; 2008/05/22 dadams
+;;     icicle-update-help-string: Mention C-u for read-file-name-completion-ignore-case.
+;; 2008/05/11 dadams
+;;     Moved icicle-bind-top-level-commands to icicles-opt.el (and added optional arg).
+;;     Renamed icicle-fit-Completions-window to icicle-fit-completions-window.
+;; 2008/05/10 dadams
+;;     Renamed: icicle-bind-top-level-commands-alist to icicle-top-level-key-bindings.
+;;     icicle-bind-top-level-commands: Don't eval the key (binding).
+;; 2008/05/07 dadams
+;;     icicle-define-icicle-maps: Use icicle-bind-top-level-commands instead of hard-coding.
+;;     icicle-update-help-string: icicle-bind-*-flag -> icicle-bind-*-alist.
+;; 2008/04/25 dadams
+;;     icicle-(redefine|restore)-std-completion-fns:
+;;       Never set icicle-old-read-file-name-fn to icicle-read-file-name.
+;;         Thx to Alexey Romanov and Per Nordlow.
+;;     icicle-define-icicle-maps, icicle-(bind|restore)-completion-keys:
+;;       Bound icicle-toggle-remote-file-testing (C-^).
+;;       icicle-toggle-ignored-space-prefix is now bound to M-_, not C-^.
+;;     icicle-update-help-string: Updated bindings accordingly.
+;; 2008/04/18 dadams
+;;     Renamed icicle-init-value-flag to icicle-default-value.
+;; 2008/03/30 dadams
+;;     icicle-(redefine|restore)-std-completion-fns:
+;;       Set and swap read-file-name-function and icicle-old-read-file-name-fn for Emacs 22+.
+;;     Top-level:
+;;       Moved fset old-read-file-name here, renamed it orig-read-file-name.  Not for Emacs 22.
+;; 2008/03/29 dadams
+;;     icicle-mode: No longer use icicle-control-reminder-prompt on kill-emacs-hook.
+;;     icicle-update-help-string:
+;;       Removed: icicle-completing(-mustmatch)-prompt-prefix, icicle-reminder-prompt-flag.
+;;     icicle-rebind-completion-maps: Remove code setting icicle-prompt-suffix (removed).
+;; 2008/03/26 dadams
+;;     Added icicle-Info-menu to icicle-mode doc string and icicle-update-help-string.
+;;     icicle-define-icicle-maps: Added icicle-Info-menu to menus.
+;;     icicle-(rebind|restore)-non-completion-keys: Bind/restore icicle-Info-menu-cmd.
+;; 2008/03/23 dadams
+;;     Added: icicle-handle-switch-frame.
+;;     icicle-(rebind|restore)-non-completion-keys:
+;;       Bind switch-frame to icicle-handle-switch-frame globally, and restore.
+;; 2008/03/19 dadams
+;;     Remap (pp-)eval-expression to new icicle-pp-eval-expression.
+;;     Replace lambdas by icicle-pp-eval-expression-in-minibuffer.
+;;     Use icicle-pp-eval-expression-in-minibuffer (new) in help string.
+;;     icicle-rebind-completion-maps: Bind M-: to icicle-pp-eval-expression-in-minibuffer.
+;;       Bind icicle-insert-newline-in-minibuffer in all minibuffer maps (likewise, non-icy).
+;;       Bind C-g in minibuffer-local-must-match-map, even if inherit.
+;;     icicle-bind-completion-keys: Don't bind in must-match if it inherits:
+;;       C-a, C-e, C-=, M-k, M-o, M-., M-:, C-M-y, M-S-(backspace|delete)
+;; 2008/03/09 dadams
+;;     icicle-mode: Add icicle-unhighlight-lighter to minibuffer-exit-hook.
+;; 2008/03/07 dadams
+;;     icicle-abort-minibuffer-input:  Thx to Damon Permezel.
+;;       Make it always call abort-recursive-edit.  Renamed to icicle-abort-recursive-edit.
+;; 2008/02/28 dadams
+;;     icicle-define-icicle-maps: Don't bind pop-tag-mark (M-*) in icicle-mode-map for Emacs 21.
+;; 2008/02/26 dadams
+;;     Remapped where-is to icicle-where-is.
+;;     Added to Describe > Icicles menu: icicle-describe-option-of-type, icicle-where-is.
+;;     Bound icicle-select-frame to C-x 5 o in Icicle mode.
+;; 2008/02/24 dadams
+;;     icicle-define-icicle-maps: Bound icicle-next-apropos-match-function to M-(.
+;;     Add icicle-next-apropos-match-function to icicle-update-help-string and mode doc string.
+;; 2008/02/23 dadams
+;;     Renamed: icicle-search-tag to icicle-find-tag,
+;;              icicle-find-tag(-other-window) to icicle-find-first-tag(-other-window).
+;;     icicle-define-icicle-maps: Added icicle-tags-search to Tags menu and Search menu.
+;; 2008/02/22 dadams
+;;     Renamed: icicle(-mouse)-save-candidate to icicle(-mouse)-save/unsave-candidate.
+;; 2008/02/13 dadams
+;;     Remapped: find-tag (M-.) to icicle-search-tag, instead of icicle-find-tag
+;;               pop-tag-mark (M-*) to icicle-pop-tag-mark.
+;;     icicle-define-icicle-maps:
+;;       Added icicle-search-tag and icicle-pop-tag-mark to menus.
+;;       Removed icicle-find-tag from menu.  Renamed icicle-find-tag-other-window menu item.
+;; 2008/02/07 dadams
+;;     icicle-(redefine|restore)-std-completion-fns: Protect read-number with fboundp.
+;; 2008/02/03 dadams
+;;     icicle-(redefine|restore)-std-completion-fns: Added (icicle|old)-choose-completion.
+;; 2008/01/30 dadams
+;;     Bound icicle-yank-secondary and icicle-mouse-yank-secondary.
+;; 2008/01/15 dadams
+;;     Require dired.el.  Soft-require dired+.el. Thx to Fabrice Knevez.
+;; 2008/01/13 dadams
+;;     icicle-(rebind|restore)-non-completion-keys:
+;;       Bound [handle-switch-frame] to icicle-skip-this-command globally.
+;;     Added: icicle-skip-this-command.
+;; 2008/01/02 dadams
+;;     icicle-(rebind|restore)-non-completion-keys: Bound icicle-search-dired-marked to M-s.
+;;     icicle-define-icicle-maps: Added icicle-search-dired-marked to Dired>Multiple>Icicles.
+;; 2008/01/01 dadams
+;;     icicle-*-non-completion-keys: Bound icicle-candidate-set-dired-marked-save(-more).
+;;     icicle-define-icicle-maps: Added Icicles submenu for Dired > Multiple (Operate) menu.
+;; 2007/12/31 dadams
+;;     Bound icicle-insert-list-join-string to C-M-j.  Update icicle-update-help-string.
+;; 2007/12/24 dadams
+;;     icicle-rebind-completion-maps: Bound C-j to also refit the minibuffer frame.
+;; 2007/12/20 dadams
+;;     Bound icicle-dired-saved-file-candidates-other-window in Dired to C-M-r.
+;;     Bound icicle-describe-option-of-type to C-h C-o, not C-h M-o.
+;; 2007/12/18 dadams
+;;     icicle-define-icicle-maps: Bind icicle-describe-option-of-type to C-h M-o.
+;; 2007/12/14 dadams
+;;     icicle-mode: Only add to kill-emacs-hook if icicle-customize-save-flag is non-nil.
+;; 2007/12/13 dadams
+;;     icicle-update-help-string: spell out options, don't abbreviate using *.
+;; 2007/12/08 dadams
+;;     Bound icicle-(beginning|end)-of-line+.
+;; 2007/12/07 dadams
+;;     icicle-rebind-completion-maps: Removed obsolete stuff from doc string.
+;; 2007/12/03 dadams
+;;     Renamed longest common match (lcm) to expanded common match (ecm).
+;; 2007/11/29 dadams
+;;     icicle-minibuffer-setup: If icicle-add-proxy-candidates-flag is nil, swap candidate sets.
+;;                              Reset icicle-saved-proxy-candidates to nil.
+;; 2007/11/27 dadams
+;;     icicle-(redefine|restore)-std-completion-fns: Added read-number.
+;; 2007/11/25 dadams
+;;     icicle-define-icicle-maps: Bound icicle-command-abbrev to C-x SPC.
+;;     icicle-mode: Use icicle-command-abbrev-save on kill-emacs-hook.
+;;     Changed binding of icicle-doremi-inter-candidates-min-spaces from C-x SPC to C-x |.
+;; 2007/11/23 dadams
+;;     icicle-rebind-completion-maps:
+;;       Use icicle-prefix-cycle-(next|previous)-keys, instead of hardcoding.
+;;     icicle-(bind|restore)-completion-keys:
+;;       Use icicle-(apropos|prefix)-cycle-(next|previous)-keys, instead of hardcoding.
+;;       Restore explicit vanilla bindings last.
+;; 2007/11/22 dadams
+;;     icicle-(bind|restore)-completion-keys:
+;;       Explicitly bind/restore (C-)up, (C-)down, (C-)next, (C-)(C-)prior, instead of
+;;         remapping next-line etc.
+;; 2007/11/21 dadams
+;;     icicle-rebind-completion-maps: Explicitly bind C-j to icicle-self-insert.
+;;     icicle-(bind|restore)-completion-keys, icicle-update-help-string:
+;;       Removed C-o binding for icicle-candidate-action.
+;; 2007/11/17 dadams
+;;     Added doc, menus, bindings (C-M-_): icicle-toggle--proxy-candidates.
+;; 2007/11/05 dadams
+;;     icicle-define-icicle-maps: Moved [Icy] items to Icicles submenus.
+;;     Added: icicle-(bookmark|custom|describe|edit|file|frames|info|search(-tags))-menu-map.
+;; 2007/11/03 dadams
+;;     icicle-define-icicle-maps, icicle-bind-S-TAB-in-keymaps-from,
+;;       icicle-unbind-S-TAB-in-keymaps-from, icicle-rebind-completion-maps,
+;;       icicle-bind-completion-keys:
+;;         Bind icicle-generic-S-tab-keys instead of hard-coded S-(iso-left)tab.
+;;     icicle-(bind|restore)-completion-keys:
+;;       Bind/restore icicle-prefix-complete-keys,
+;;         icicle-(apropos|prefix)-complete-keys-no-display, not hard-coded keys.
+;;     icicle-bind-isearch-keys: Bind icicle-isearch-complete-keys, not hard-coded.
+;;     Renamed icicle-modal-cycle-(up|down)-key to icicle-modal-cycle-(up|down)-keys,
+;;             icicle-word-completion-key to icicle-word-completion-keys.
+;; 2007/10/31 dadams
+;;     icicle-define-icicle-maps:
+;;       Moved options to new Icicles submenu of Options menu, and removed [Icy].  Added :keys.
+;;     Added: icicle-options-menu-map.
+;; 2007/10/28 dadams
+;;     Added doc, menus, bindings (C-|, C-M-|):
+;;       icicle-toggle-(expand-to-common-match|search-replace-common-match).
+;; 2007/10/21 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind C-x w and C-x SPC.
+;;     icicle-define-icicle-maps: Add Do Re Mi items.
+;;     icicle-mode, icicle-update-help-string: Mention C-x w and C-x SPC.
+;; 2007/09/29 dadams
+;;     icicle-mode, icicle-define-icicle-maps, icicle-update-help-string:
+;;       Added icicle-toggle-fuzzy-completion (and icicle-fuzzy-completion-flag to help string).
+;;     icicle-(bind|restore)-completion-keys: Bind/unbind icicle-toggle-fuzzy-completion to C-(.
+;; 2007/09/20 dadams
+;;     icicle-(bind|restore)-completion-keys: Bind C-j to icicle-self-insert / exit-minibuffer.
+;; 2007/09/18 dadams
+;;     Added: icicle-update-help-string.  Use in icy-mode, not in icicle-rebind-completion-maps.
+;;            Removed icicle-toggle-WYSIWYG-Completions (it has no minibuffer binding).
+;; 2007/08/25 dadams
+;;     icy-mode, icicle-completion-help-string:
+;;       icicle-clear-option -> clear-option.  Added toggle alias.
+;; 2007/08/21 dadams
+;;     icicle-completion-help-string: Mention C-M-l.
+;; 2007/08/19 dadams
+;;     icicle-minibuffer-setup: Reset icicle-input-fail-pos.
+;;     icicle-(bind|restore)-completion-keys:
+;;       (Re|un)map reposition-window to icicle-kill-failed-input.
+;; 2007/08/03 dadams
+;;     icicle-mode: Remove icicle* hooks from local, not global, hooks.
+;; 2007/07/22 dadams
+;;     icicle-(redefine|restore)-standard-commands: Added customize-face(-other-window).
+;;     Moved icicle-completing-p to icicles-fn.el.
+;;     Require icicles-cmd.el.
+;; 2007/07/06 dadams
+;;     icicle-rebind-completion-maps:
+;;       Moved icicle-Completions-mouse-3-menu to C-mouse-3.
+;;       Added icicle(-mouse)-candidate-set-save(-more)-selected, icicle-candidate-set-retrieve,
+;;             icicle-retrieve-previous-input.
+;;     icicle-completion-help-string: Added icicle-candidate-set-save(-more)-selected.
+;;     icicle-bind-completion-maps:
+;;       Removed icicle-insert-history-element (inherited).
+;;       Added: icicle-candidate-set-save-more(-selected), icicle-mouse-save-then-kill.
+;; 2007/07/04 dadams
+;;     icicle-rebind-completion-maps, icicle-(bind|restore)-completion-keys:
+;;       Added icicle-insert-history-element to Minibuf menu.
+;;     icicle-(bind|restore)-completion-keys:
+;;       Added icicle-retrieve-(next|previous)-input to Minibuf menu.
+;; 2007/07/03 dadams
+;;     icicle-rebind-completion-maps, icicle-bind-completion-keys:
+;;       Bind icicle-insert-history-element to M-o in all minibuffer maps.
+;;     icicle-bind-completion-keys, icicle-completion-help-string:
+;;       icicle-retrieve-(next|previous)-input, not icicle-retrieve-last-input.
+;;     icicle-(redefine|restore)-std-completion-fns:
+;;       defalias next-history-element to icicle-next-history-element.
+;;     Removed defadvice for next-history-element.  Redefine in icicles-mcmd.el instead.
+;; 2007/06/22 dadams
+;;     Bound icicle-search-keywords and added to menus and help strings.
+;; 2007/06/20 dadams
+;;     Removed M-o binding for icicle-toggle-WYSIWYG-Completions.
+;; 2007/06/19 dadams
+;;     icicle-bind-completion-keys: Add icicle-save-predicate-to-variable to menus.
+;;     icicle-completion-help-string:
+;;       Mention icicle-save-predicate-to-variable and icicle-insert-string-from-variable.
+;; 2007/06/18 dadams
+;;     icy-mode doc string, icicle-completion-help-string: Added icicle-customize-face.
+;;     icicle-define-icicle-maps: Added icicle-customize-face to menus.
+;; 2007/06/17 dadams
+;;     Bound icicle-toggle-WYSIWYG-Completions to M-o.
+;;     icicle-minibuffer-setup: Reinitialize icicle-saved-candidate-overlays.
+;; 2007/06/16 dadams
+;;     icicle-(bind|restore)-completion-keys: Bound C-M-(help|f1).
+;; 2007/06/15 dadams
+;;     icicle-completion-help-string: Added and cleaned up set stuff.
+;;     icicle-(bind|restore)-completion-keys: Cleanup.  Added menu items.
+;; 2007/06/14 dadams
+;;     Swap bindings for C-insert and insert.
+;; 2007/06/13 dadams
+;;     Bound C-insert and C-> to icicle-save-candidate and icicle-candidate-set-save-more.
+;; 2007/06/12 dadams
+;;     icicle-rebind-completion-maps: Bound icicle-mouse-save-candidate to M-S-mouse-2.
+;; 2007/06/10 dadams
+;;     icicle-mode: comint-mode-hook, compilation(-minor)-mode-hook, temp-buffer-show-hook.
+;; 2007/06/08 dadams
+;;     icy-mode: Added icicle-find-tag* to doc string.
+;;     icicle-define-icicle-maps:
+;;       Added icicle-find-tag*.  Remap find-tag* to icicle-find-tag*.
+;;       Corrected Info menu.
+;;     icicle-completion-help-string: Added icicle-find-tag*.
+;; 2007/05/28 dadams
+;;     icicle-restore-non-completion-keys: Unbind S-tab.
+;;     Added: icicle-unbind-S-TAB-for-map-variable, icicle-unbind-S-TAB-in-keymaps-from.
+;;     icicle-bind-S-TAB-in-keymaps-from: Treat S-tab and S-iso-lefftab separately.
+;;     icicle-define-icicle-maps: Added icicle-imenu-* to Icicles/Search menus.
+;; 2007/05/22 dadams
+;;     Make [Icy] menu items invisible when not in Icicle mode.  Add :keys where appropriate.
+;;     icicle-define-icicle-maps, icicle-rebind-completion-maps,
+;;     icicle-(bind|restore)-completion-keys:
+;;       icicle-menu-item-any-version -> menu-item.  Explicit put of enable property -> :enable.
+;;     Don't require icicles-mac.el.
+;;     icicle-bind-completion-keys: Added icicle-narrow-candidates, and corrected :enable forms.
+;; 2007/05/21 dadams
+;;     icicle-define-icicle-maps:
+;;       Remap minibuffer-keyboard-quit to icicle-abort-minibuffer-input.  Needed, even though
+;;         local-must-match inherits from local-completion in Emacs 22, because delsel.el binds
+;;         C-g to minibuffer-keyboard-quit in minibuffer maps.
+;;     menu-item-any-version -> icicle-menu-item-any-version.
+;;     Added Icicles/Search menu items:
+;;       Search (Buffer|File|Saved Region|All Saved Regions|Definition|Text Property).
+;;     Renamed: Search a Region -> Search Saved Region, Choose a Region -> Choose Saved Region,
+;;              Add Current Region to List -> Save Current Region.
+;; 2007/05/20 dadams
+;;     Enable menu-bar Minibuf:
+;;       icicle-rebind-completion-maps:
+;;         Use menu-item-any-version.
+;;         Don't define menu for maps if it is defined by parent map.
+;;         Add Enter and Help items for *-local-map.
+;;         Add Enter, Help and Quit items for *-local-(ns|isearch)-map.
+;;       icicle-bind-completion-keys:
+;;         Use menu-item-any-version.
+;;         Add Enter item for *-local-completion-map, unless defined by parent map.
+;;       icicle-restore-completion-keys:
+;;         Use menu-item-any-version.
+;;         Add Enter and Quit items for *-local-completion-map, unless defined by parent map.
+;;         Do not unmap kill-region(-wimpy).
+;;         Bind [(control pause)] to nil.
+;; 2007/05/13 dadams
+;;     icicle-restore-completion-keys: Restore some forgotten minibuf menu items.
+;; 2007/05/08 dadams
+;;     Bound icicle-save-predicate-to-variable to C-M-&.
+;; 2007/05/06 dadams
+;;     icicle-rebind-completion-maps: Updated icicle-completion-help-string.
+;;     Added defvars to quiet byte compiler.
+;;     Changed S-C- to C-S- and M-C- to C-M- in doc.
+;; 2007/05/03 dadams
+;;     Remap icicle-yank-function, not yank.
+;;     icicle-define-icicle-maps: Bind icicle-search-word.
+;;     icicle-mode, icicle-completion-help-string: Add icicle-search-word to doc.
+;; 2007/05/02 dadams
+;;     Bound M-q to icicle-dispatch-M-q, not to icicle-insert-key-description.
+;;     Bound C-` to icicle-toggle-regexp-quote, not to icicle-dispatch-C-backquote.
+;;     Bound C-M-` to icicle-toggle-literal-replacement.
+;;     Update icicle-completion-help-string.
+;; 2007/04/20 dadams
+;;     icicle-minibuffer-setup: Don't reset icicle-search-context-level here.
+;; 2007/04/17 dadams
+;;     Bound M-, to icicle-dispatch-M-comma, not to icicle-change-alternative-sort-order.
+;;     Bound C-` to icicle-dispatch-C-backquote, not to icicle-toggle-regexp-quote.
+;; 2007/04/10 dadams
+;;     icicle-minibuffer-setup: Initialize icicle-search-context-level.
+;; 2007/04/09 dadams
+;;     Bound icicle-imenu to C-c =.
+;; 2007/04/08 dadams
+;;     Bound icicle-all-candidates-alt-action to C-S-insert.
+;; 2007/04/07 dadams
+;;     icicle-completion-help-string: Updated.
+;;     Bound icicle-dispatch-C-comma to C-,.
+;;     Bound in menu: icicle-toggle-search-replace-whole.
+;;     Bound icicle-(next|previous)-(apropos|prefix)-candidate-alt-action (forgot).
+;; 2007/04/02 dadams
+;;     Bound icicle-search-text-property to C-c ".  Added it to icicle-completion-help-string.
+;; 2007/03/23 dadams
+;;     Bound icicle-apropos-complete-and-narrow to S-SPC.  Mention in *-completion-help-string.
+;; 2007/03/14 dadams
+;;     Added: icicle-top-level-prep.
+;;     Removed: icicle-reset-candidates-alist.
+;;     Do top-level stuff in icicle-minibuffer-setup, not in icicle-mode.
+;;     icicle-minibuffer-setup: Add icicle-top-level-prep to pre-command-hook.
+;;     icicle-mode: Remove icicle-top-level-prep from pre-command-hook.
+;; 2007/03/07 dadams
+;;     icicle-cancel-Help-redirection: Use 0, not t, as frame arg to get-buffer-window.
+;; 2007/03/02 dadams
+;;     icicle-bind-S-TAB-in-keymaps-from: Bound S-iso-lefttab also.
+;; 2007/03/02 dadams
+;;     icicle-define-icicle-maps:
+;;       Bound S-iso-lefttab also to icicle-generic-S-tab.  Thx to Shreevatsa R.
+;; 2007/02/28 dadams
+;;     Added: icicle-reset-candidates-alist.
+;;     icicle-mode: Use icicle-reset-candidates-alist.
+;; 2007/02/27 dadams
+;;     icicle-minibuffer-setup: Wait icicle-incremental-completion-delay before initial display.
+;; 2007/02/24 dadams
+;;     Bound: delete, S-mouse-2 to icicle(-mouse)-remove-candidate,
+;;            C-S-RET, C-S-mouse-2 to icicle(-mouse)-candidate-alt-action,
+;;            S-delete to icicle-delete-candidate-object.
+;;     Don't remap icicle-kill-region(-wimpy) to delete key.
+;; 2007/02/17 dadams
+;;     Added: icicle-bind-S-TAB-in-keymaps-from, icicle-bind-S-TAB-for-map-variable.
+;;     icicle-rebind-non-completion-keys:
+;;       Bind S-TAB to keymaps in icicle-keymaps-for-key-completion.
+;; 2007/02/02 dadams
+;;     icicle-completing-p: Cache the value in variable icicle-completing-p.
+;;     icicle-minibuffer-setup: Reset icicle-completing-p to nil.
+;;     icicle-activate-mark: Use var, not function, icicle-completing-p, but after minibuf test.
+;; 2007/01/23 dadams
+;;     icicle-(redefine|restore)-std-completion-fns:
+;;       Added icicle-read-face-name, icicle-face-valid-attribute-values.
+;;     icicle-define-icicle-maps, icicle-rebind-completion-maps:
+;;       Updated wrt toggles.  Added icicle*-highlight-historical-candidates*.
+;;     icicle-bind-completion-keys: Added icicle-toggle-highlight-historical-candidates.
+;; 2007/01/22 dadams
+;;     Renamed icicle-regions to icicle-region-alist (forgot occurrences here).
+;; 2007/01/20 dadams
+;;     icicle-(redefine|restore)-std-completion-fns: Added icicle-display-completion-list.
+;; 2007/01/15 dadams
+;;     Moved C-, binding from icicle-toggle-sorting to icicle-change-sort-order.
+;;     Moved icicle-toggle-alternative-sorting from M-, to C-M-,.
+;;     Bound icicle-change-alternative-sort-order to M-,.
+;;     Updated list of options in icicle-completion-help-string.
+;; 2007/01/12 dadams
+;;     Removed: icicle-override-maps-w-minibuffer-map, icicle-restore-overriding-local-map.
+;;              Not used in minibuffer hooks.
+;;     Removed [pause] bindings from minibuffer maps.
+;;     Removed remap of yank in minibuffer maps.
+;;     No longer bind icicle-remove-Completions-window in minibuffer maps.
+;; 2007/01/11 dadams
+;;     Renamed: icicle-define-icicle-mode-map to icicle-define-icicle-maps.
+;;     icicle-define-icicle-maps: Use icicle-menu-map.  Don't recreate it.
+;;     Bound [pause] to icicle-switch-to/from-minibuffer in all minibuffer maps.
+;; 2007/01/10 dadams
+;;     Added: icicle-override-maps-w-minibuffer-map, icicle-restore-overriding-local-map,
+;;            icicle-(rebind|restore)-non-completion-keys.
+;;     Added: icicle-rebind-global: This used to be called icicle-remap.
+;;     icicle-(remap|unmap): Different purpose and use now.  Redefined to use remapping when
+;;        available (as was done before for self-insert-command).
+;;     icicle-mode:
+;;       Add, remove as minibuffer setup and exit hooks: icicle-override-maps-w-minibuffer-map,
+;;                                                       icicle-restore-overriding-local-map.
+;;       Call icicle-(rebind|restore)-non-completion-keys.
+;;     icicle-define-icicle-mode-map:
+;;       Use icicle-remap where previously used substitute-key-definition for top-level cmds.
+;;       Moved to icicle-(rebind|restore)-non-completion-keys:
+;;         binding of Info commands in Info map and S-tab in all keymaps (to *-rebind-* only).
+;;     icicle-(bind|restore)-completion-keys: Use new icicle-(remap|unmap) where possible.
+;;       Use icicle-rebind-global and substitute-key-definition for keys defined in vanilla
+;;         completion maps.
+;; 2007/01/06 dadams
+;;     icicle-mode: Update doc and bind icicle-toggle-~-for-home-dir to M-~.
+;; 2007/01/01 dadams
+;;     Moved assq-delete-all to icicles-fn.el.
+;;     Require at runtime, not compile-time: icicles-var.el, icicles-fn.el.
+;; 2006-12-31 dadams
+;;     icicle-define-icicle-mode-map: Delete icicle-mode entry from minor-mode-map-alist.
+;;     icicle-mode: Unbind icicle-mode-map when the mode is turned off.
+;;     Added assq-delete-all for Emacs 20.
+;;     Use current-global-map function, not global-map variable.
+;; 2006/12/25 dadams
+;;     Bound icicle-candidate-set-truncate to M-$.
+;; 2006/12/24 dadams
+;;     icicle-bind-completion-keys: transpose-yank(-pop) -> yank(-pop): typo.
+;;     Bound mouse-3 to icicle-Completions-mouse-3-menu in completion-list-mode-map.
+;; 2006/12/22 dadams
+;;     Bound icicle-exchange-point-and-mark.
+;;     :group 'icicles -> :group 'Icicles-Miscellaneous.
+;; 2006/12/17 dadams
+;;     Bound icicle(-mouse)-candidate-read-fn-invoke.
+;; 2006/12/16 dadams
+;;     icicle-define-icicle-mode-map: Protect icicle-kmacro with fboundp.
+;; 2006/12/12 dadams
+;;     Added icicle-customize-*-group, icicle-kill-buffer, icicle-delete-windows to I. menu.
+;;     Added + to multi-command menu items.
+;; 2006/12/11 dadams
+;;     Added icicle-customize-apropos* and icicle-Info-* to menu-bar menus.
+;; 2006/12/10 dadams
+;;     Updated user options list in icicle-completion-help-string.
+;;     Updated list of icicle-opt stuff used here.
+;; 2006/12/06
+;;     icicle-select-minibuffer-contents:
+;;       Use icicle-minibuffer-prompt-end, not point-min.  Thx to Erik Postma.
+;; 2006/11/26 dadams
+;;     Added icicle-regions stuff.
+;; 2006/11/24 dadams
+;;     icicle-redefine-standard-options: Treat icicle-kmacro-ring-max.
+;;     Bind icicle-kmacro to f5
+;;     Replaced icicle-select-window-or-frame by icicle-other-window-or-frame.
+;;     Removed binding of icicle-select-frame.
+;;     Do not require mb-depth+.el for Emacs 21 (do it only for Emacs 22).
+;; 2006/11/23 dadams
+;;     Bound icicle-execute-named-keyboard-macro to C-x M-e.
+;; 2006/11/18 dadams
+;;     Soft require mb-depth+.el instead of minibuf-depth.el.
+;; 2006/11/17 dadams
+;;     Bind icicle-select-window-or-frame to whatever other-window(-or-frame) is bound to.
+;;     Bind icicle-select-frame to whatever other-frame is bound to.
+;; 2006/11/09 dadams
+;;     Bind icicle-dispatch-C-^, not icicle-toggle-ignored-space-prefix, to C-^.
+;;     icicle-rebind-completion-maps: Updated doc string for icicle-dispatch-C-^.
+;; 2006/11/05 dadams
+;;     Bound icicle-occur to C-c '.  Added it to menu-bar menus.
+;; 2006/10/18 dadams
+;;     icy-mode: Invoke icicle-define-icicle-mode-map unconditionally, not just first time.
+;; 2006/10/16 dadams
+;;     icicle-define-icicle-mode-map: Try to avoid binding S-TAB to menu maps.
+;; 2006/10/15 dadams
+;;     icicle-define-icicle-mode-map: Simplified, corrected binding of S-TAB for key completion.
+;;                                    Use a separate map for the menu bar.
+;;     Moved here from icicles-fn.el:
+;;       icicle-bind-isearch-keys, icicle-rebind-completion-maps,
+;;       icicle-(redefine|restore)-standard-(commands|options),
+;;       icicle-(redefine|restore)-std-completion-fns, icicle-(re|un)map,
+;;       icicle-(bind|restore)-completion-keys, icicle-minibuffer-setup,
+;;       icicle-cancel-*Help*-redirection, icicle-activate-mark,
+;;       icicle-run-icicle-(pre|post)-command-hook, icicle-set-calling-cmd,
+;;       icicle-undo-std-completion-faces icicle-update-ignored-extensions-regexp,
+;;       icicle-completing-p, icicle-restore-region-face.
+;;     Renamed: icicle-cancel-*Help*-redirection to icicle-cancel-Help-redirection.
+;;     Moved here from icicles-cmd.el: icicle-select-minibuffer-contents, next-history-element.
+;;     Moved to icicles-cmd.el: icicle-generic-S-tab.
+;;     Require icicles-opt.el.
+;;     Added eval-when-compile's and defvars to quite byte compiler.
+;; 2006/09/23 dadams
+;;     icicle-define-icicle-mode-map: Corrected binding of icicle-yank-insert.
+;; 2006/09/22 dadams
+;;     icicle-minibuffer-setup: Set this-command and last-command, for scrolling *Completions*.
+;; 2006/09/18 dadams
+;;     icicle-mode: Picked up all global prefixes for S-TAB.
+;; 2006/09/17 dadams
+;;     Added: icicle-generic-S-tab.  Bound to S-TAB.
+;;     icicle-mode:
+;;       Bound icicle-complete-keys to prefix keys followed by S-TAB.
+;;       Added run-hooks for Emacs 22 version.
+;; 2006/09/12 dadams
+;;     Bound icicle-switch-to/from-minibuffer to [pause].
+;; 2006/08/27 dadams
+;;     Bound icicle-abort-minibuffer-input to what abort-recursive-edit is normally bound to.
+;;       And add it to Icicle menu.
+;; 2006/08/23 dadams
+;;     Bound icicle-delete-window to what delete-window and delete-windows-for are normally
+;;       bound to.
+;;     Put use of Info-mode-map inside an eval-after-load.
+;; 2006/08/18 dadams
+;;     Added icicle-Info-goto-node-cmd to icicle-mode doc string.
+;;       Substitute it for Info-goto-node binding.
+;; 2006/08/13 dadams
+;;     Added icicle-Info-index-cmd to icicle-mode doc string.
+;;       Substitute it for Info-index binding.
+;; 2006/08/04 dadams
+;;     Added icicle-plist to menus.
+;;     icicle-doc treats faces too now.
+;; 2006/08/03 dadams
+;;     Bound icicle-insert-yank to what yank is normally bound to.
+;;     icicle-mode: Updated doc string.
+;; 2006/07/29 dadams
+;;     icy-mode, icicle-define-icicle-mode-map: Added missing toggle commands.
+;; 2006/07/22 dadams
+;;     Changed binding of C-c C-s for icicle-search to C-c ` for icicle-search-generic.
+;;     Removed: add-hooks for icicle-compilation-search - see icicles-cmd.el.
+;; 2006/06/08 dadams
+;;     Converted global bindings in icicles-keys.el to icicle-mode-map bindings here.
+;;     Added f10 binding for icicle-execute-menu-command.
+;; 2006/05/19 dadams
+;;     icicle-mode: (add-hook 'kill-emacs-hook 'icicle-control-reminder-prompt).
+;; 2006/05/18 dadams
+;;     Change :init-value to nil, per new Emacs convention.
+;; 2006/05/13 dadams
+;;     icicle-mode: Updated doc string.
+;; 2006/05/10 dadams
+;;     icicle-define-icicle-mode-map: Added menu item Send Bug Report.
+;; 2006/04/03 dadams
+;;     icicle-define-icicle-mode-map: Added icicle-toggle-(regexp-quote|incremental-completion).
+;; 2006/03/16 dadams
+;;     icicle-mode: Turn on minibuffer-indicate-depth-mode (Emacs 22 only).
+;;     Added soft require of minibuf-depth.el for Emacs 22.
+;; 2006/03/14 dadams
+;;     Do not use icicle-reset-icicle-completing-p as minibuffer-exit-hook.
+;; 2006/03/07 dadams
+;;     Corrected menu items for icicle-doc (no name regexp input, just doc regexp).
+;; 2006/03/05 dadams
+;;     Moved here from icicle-opt.el: icicle-mode, icicle-mode-hook.
+;;     Moved here from icicle-fn.el: icicle-mode-map.
+;;     Added: icicle-define-icicle-mode-map.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-opt.el'")
+;;
+;; 2011/09/05 dadams
+;;     Added: icicle-hide-non-matching-lines-flag.
+;;     icicle-Completions-toggle-submenu: Added icicle-toggle-hiding-non-matching-lines to menu.
+;;     icicle-hide-common-match-in-Completions-flag: Updated doc string (new toggle key).
+;; 2011/09/04 dadams
+;;     Renamed: icicle-complete-keys-self-insert-flag to icicle-complete-keys-self-insert-ranges.
+;;       Define it only for Emacs 22+.
+;;       Made it an alist of char ranges, for Emacs 23+.
+;; 2011/09/02 dadams
+;;     icicle-functions-to-redefine: Added: Info-goto-node, Info-index, Info-menu.
+;; 2011/08/30 dadams
+;;     icicle-thing-at-point-functions:
+;;       symbol-name-nearest-point -> icicle-thing-at-point-functions
+;;       region-or-word-nearest-point -> word-nearest-point
+;; 2011/08/13 dadams
+;;     icicle-top-level-key-bindings: Map bmkp-autofile-set to icicle-bookmark-a-file.
+;; 2011/08/07 dadams
+;;     icicle-top-level-key-bindings: Bind icicle-find-file-tagged(-other-window) to C-x j t a a.
+;; 2011/07/30 dadams
+;;     Moved icicle-increment-color-value to icicles-face.el.
+;;     Require icicles-face.el only if hexrgb.el has been loaded.
+;; 2011/07/27 dadams
+;;     icicle-completions-format, icicle-search-whole-word-flag: Updated doc string.
+;; 2011/07/26 dadams
+;;     Removed: icicle-list-end-string (no longer needed).  Thx to Michael Heerdegen.
+;; 2011/07/06 dadams
+;;     Renamed icicle-Completions-frame-at-right-flag to icicle-move-Completions-frame.
+;;     icicle-move-Completions-frame: Allow for moving frame to the left also.
+;; 2011/06/03 dadams
+;;     Renamed icicle-help-in-mode-line-flag to icicle-help-in-mode-line-delay and changed to 5 secs.
+;; 2011/05/24 dadams
+;;     icicle-functions-to-redefine: Removed (dired-)read-shell-command - turned off by default now.
+;; 2011/05/22 dadams
+;;     icicle-init-value-flag/icicle-default-value: Added 3rd arg for make-obsolete-variable.
+;; 2011/05/14 dadams
+;;     Removed: icicle-thing-types.  Better to get the list dynamically.
+;; 2011/05/13 dadams
+;;     Added: icicle-thing-types.
+;; 2011/05/07 dadams
+;;     Added: icicle-ignore-comments-flag.
+;; 2011/05/03 dadams
+;;     Added: icicle-highlight-saved-candidates-flag.
+;;     icicle-Completions-toggle-submenu: Added icicle-toggle-highlight-saved-candidates to menu.
+;; 2011/04/26 dadams
+;;     icicle-top-level-key-bindings:
+;;       Added icicle-(un)tag-a-file, icicle-find-file-(all|some)-tags-*.
+;;       If you have customized it, re-customize it from scratch or you will miss the new bindings.
+;; 2011/04/02 dadams
+;;     NOTE: IF you customized icicle-top-level-key-bindings and you use Bookmark+, then you will want
+;;           to REMOVE THAT CUSTOMIZATION AND CUSTOMIZE AGAIN.  Otherwise, you will miss Icicles
+;;           multi-command versions of the new Bookmark+ commands.
+;;     icicle-top-level-key-bindings:
+;;       Added icicle-bookmark-file-this-dir-((all|some)-tags(-regexp))(-other-window).
+;; 2011/03/31 dadams
+;;     Renamed icicle-target-window-recenter-amount to icicle-recenter & moved from icicles-var.el.
+;; 2011/03/26 dadams
+;;     icicle-top-level-key-bindings:
+;;       Added: bmkp-file-(all|some)-tags(-regexp)-jump(-other-window).
+;;       Fixed typos: bmkp-(all|some)-tags-regexp-jump (forgot -regexp).  Use fboundp, not featurep. 
+;; 2011/03/22 dadams
+;;     Added autoload cookies for defconsts.
+;; 2011/02/26 dadams
+;;     Added: icicle-Completions-(misc|save/retrieve|sets|sorting|this-candidate|toggle)-submenu,
+;;            icicle-Completions-mouse-3-menu-entries.
+;; 2011/02/22 dadams
+;;     Added: icicle-image-files-in-Completions, icicle-functions-to-redefine.
+;;     Removed: icicle-redefine-standard-commands-flag.
+;; 2011/01/17 dadams
+;;     Added runtime require of cl.el for Emacs 20.  (Emacs 20 does not handle defcustom well.)
+;; 2011/01/12 dadams
+;;     Changed default value of icicle-Completions-text-scale-decrease from 0.66 to 0.75.
+;; 2011/01/02 dadams
+;;     icicle-region-background:
+;;       Use frame param background-mode, not frame-background-mode.  Thx to Le Wang.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/12/18 dadams
+;;     Added some missing autoload cookies.
+;; 2010/12/17 dadams
+;;     icicle-thing-at-point-functions: Added to default: list-nearest-point-as-string (1,2,3).
+;; 2010/11/12 dadams
+;;     Added: icicle-(S-)TAB-completion-methods-per-command.
+;; 2010/11/10 dadams
+;;     icicle-top-level-key-bindings: In :set, protect icicle-mode-map with boundp.
+;; 2010/10/25 dadams
+;;     Removed: icicle-search-context-match-predicate (was not used).
+;;     icicle-(buffer|file)-predicate: Mention that they (now) apply after matching.
+;; 2010/10/24 dadams
+;;     icicle-S-TAB-completion-methods-alist: Added ("Jaro-Winkler" . fuzzy-match).
+;; 2010/10/09 dadams
+;;     Corrections per move to emphasize modal cycling:
+;;      Renamed: icicle-cycling-respects-completion-mode to icicle-default-cycling-mode.
+;;      icicle-default-cycling-mode: Default value is prefix, not nil.  New value descriptions and doc.
+;;      icicle-modal-cycle-*-keys: Put back wheel keys.  Removed mention of *-cycling-respects-*-mode.
+;;      icicle-prefix-cycle-*-keys: Use end/home, not down/up as default values.
+;;                                  No mention of being used also for *Completions*.
+;;      icicle-act-before-cycle-flag: Updated doc string.
+;; 2010/10/08 dadams
+;;     icicle-modal-cycle-*-keys: Removed mouse-wheel keys - they are added systematically now.
+;; 2010/10/07 dadams
+;;     icicle-TAB-completion-methods: Removed :set, :initialize (handle it differently now).
+;; 2010/10/06 dadams
+;;     icicle-TAB-completion-methods: Added :set and :initialize.  Thx to Michael Heerdegen.
+;;     icicle-modal-cycle-(up|down)((-alt)-action|-help)-keys: Bound mouse wheel also (Emacs 22+).
+;; 2010/07/17 dadams
+;;     icicle-top-level-key-bindings: Added *url-jump(-other-window).
+;; 2010/06/18 dadams
+;;     Renamed: bookmarkp-* to bmkp-*.
+;; 2010/06/09 dadams
+;;     icicle-isearch-complete-keys:
+;;       Added [escape tab] to default binding (isearch bizarrie).  Added C-M-TAB for all platforms.
+;; 2010/06/08 dadams
+;;     icicle-bookmark-refresh-cache-flag: Changed the default value to t to avoid confusion.
+;; 2010/06/05 dadams
+;;     Set icicle-top-level-when-sole-completion-delay to 0.7 from 0.0.
+;; 2010/06/04 dadams
+;;     Added: icicle-(buffers|files)-ido-like-flag, icicle-max-candidates.
+;;     icicle-ignored-directories: Protect default value with boundp.
+;;     icicle-type-actions-alist: Added (maximize|restore|toggle-max)-frame(-horizontally|-vertically).
+;; 2010/05/30 dadams
+;;     Added: icicle-ignored-directories.
+;; 2010/05/15 dadams
+;;     icicle-top-level-key-bindings: Updated Icicles versions of bookmark jump commands.
+;;     icicle-keymaps-for-key-completion: Added bookmarkp-jump-map bookmarkp-jump-other-window-map.
+;; 2010/04/30 dadams
+;;     Added: icicle-no-match-hook.
+;; 2010/04/09 dadams
+;;     Remap find-file-read-only(-other-window) to icicle-find-file-read-only(-other-window).
+;; 2010/04/02 dadams
+;;     Removed: icicle-region-alist, icicle-region-auto-open-files-flag,
+;;              icicle-region-bookmarks-flag, icicle-regions-name-length-max.
+;;     icicle-top-level-key-bindings: Removed bookmarkp-bookmark-list-jump-other-window.
+;;       bookmarkp*: Use condition (featurep 'bookmark+).
+;; 2010/03/31 dadams
+;;     Removed extra code redefining some bookmark commands.
+;; 2010/03/28 dadams
+;;     Removed: icicle-region-alist, icicle-region-auto-open-files-flag,
+;;              icicle-region-bookmarks-flag, icicle-regions-name-length-max.
+;; 2010/03/14 dadams
+;;     Added: icicle-bookmark-refresh-cache-flag.
+;; 2010/03/13 sadams
+;;     Renamed icicle-add-buffer-name-flag to icicle-show-multi-completion-flag.  Doc string.
+;; 2010/03/09 dadams
+;;     icicle-color-themes: Initialize to ().  Do real init in cmd icicle-color-theme.
+;; 2010/03/03 dadams
+;;     Renamed: icicle-sort-function to icicle-sort-comparer,
+;;              icicle-sort-functions-alist to icicle-sort-orders-alist
+;;              icicle-alternative-sort-function to icicle-alternative-sort-comparer.
+;;     Redefined to allow multi-sorting: icicle-sort-comparer, icicle-sort-orders-alist.
+;; 2010/02/17 dadams
+;;     Moved icicle-redefined-functions here from icicles-var.el
+;;       and renamed to icicle-inhibit-advice-functions.
+;;     Moved to icicles-face.el: icicle-increment-color-(hue|saturation).
+;;     So now require icicles-face.el.
+;;     Corrected alphabetical order.
+;; 2010/02/13 dadams
+;;     icicle-top-level-key-bindings: Bound icicle-bookmark-*-jump-other-window.
+;; 2010/01/24 dadams
+;;     icicle-thing-at-point-functions:
+;;       Use region-or-word-nearest-point, not word-nearest-point.  Change order.
+;; 2010/01/17 dadams
+;;     icicle-top-level-key-bindings: Added Icicles remappings for bookmarkp-*-jump-other-*.
+;; 2009/12/25 dadams
+;;     icicle-top-level-key-bindings: Bind ESC-M-x to lacarte-execute-command.
+;; 2009/12/13 dadams
+;;     icicle-top-level-key-bindings: Map dired(-other-window) to icicle-dired(-other-window).
+;; 2009/12/07 dadams
+;;     icicle-guess-commands-in-path: Changed default value to nil.
+;; 2009/11/27 dadams
+;;     Added: icicle-swank-prefix-length, icicle-swank-timeout.
+;;     icicle-TAB-completion-methods: Treat swank method also.
+;; 2009/11/24 dadams
+;;     Added: icicle-completions-format.
+;;     icicle-color-themes: Fix: delete singleton list with string, not symbol bury-buffer.
+;; 2009/11/22 dadams
+;;     icicle-color-themes: Use color-theme-initialize instead of load-library, to load themes.
+;; 2009/11/21 dadams
+;;     icicle-color-themes: (load-library "color-theme-library"), for color theme version 6.6.0.
+;; 2009/10/25 dadams
+;;     Added: icicle-TAB-completion-methods.
+;;     Removed: icicle-fuzzy-completion-flag, icicle-prefix-completion-is-basic-flag.
+;;     Renamed: icicle-apropos-match-fns-alist to icicle-S-TAB-completion-methods-alist.
+;; 2009/10/12 dadams
+;;     icicle-top-level-key-bindings: Added bindings for icicle-bookmark(-other-window).
+;;     icicle-prefix-completion-is-basic-flag: Make it a constant for pre-Emacs 23.
+;; 2009/10/06 dadams
+;;     icicle-keymaps-for-key-completion: Added bookmark-bmenu-mode-map to default value.
+;;     icicle-sort-functions-alist: Use a separate defcustom for Emacs 20, since no :type alist.
+;; 2009/09/25 dadams
+;;     Added: icicle-prefix-completion-is-basic-flag.
+;;     Changed default value of:
+;;       icicle-candidate-width-factor          from 70  to 80
+;;       icicle-Completions-text-scale-decrease from 0.8 to 0.66.
+;; 2009/09/16 dadams
+;;     icicle-top-level-key-bindings: Added remap for icicle-insert-buffer.
+;; 2009/09/05 dadams
+;;     icicle-keymaps-for-key-completion: Added facemenu-keymap.
+;;     icicle-search-replace-common-match-flag: Fixed doc string: C-M-| -> M-;.
+;;     icicle-expand-input-to-common-match-flag: Fixed doc string: C-| -> C-;.
+;; 2009/09/02 dadams
+;;     Added: icicle-region-bookmarks-flag, icicle-top-level-when-sole-completion-delay.
+;;     icicle-region-alist: Updated doc string. Added :group Icicles-Searching.
+;; 2009/08/19 dadams
+;;     icicle-bookmark-name-length-max:
+;;       Changed default value from 40 to 70.  It is now the total name length.  Updated doc.
+;; 2009/08/01 dadams
+;;     Added: icicle-menu-items-to-history-flag.
+;; 2009/07/29 dadams
+;;     Added: icicle-populate-interactive-history-flag.
+;; 2009/06/17 dadams
+;;     Added: icicle-Completions-text-scale-decrease.
+;; 2009/05/20 dadams
+;;     icicle-keymaps-for-key-completion: Added prefix-key maps senator-mode-map,
+;;       srecode-mode-map, jde-mode-map, jde-jdb-mode-map.  Thx to Daniel Clemente.
+;; 2009/05/17 dadams
+;;     icicle-type-actions-alist: Updated to reflect thumb-frm.el name changes.
+;; 2009/05/10 dadams
+;;     icicle-list-join-string: Don't set display property for Emacs 21 (Emacs bug).
+;; 2009/05/09 dadams
+;;     Added: icicle-dot-string, icicle-dot-show-regexp-flag, icicle-anychar-regexp, 
+;; 2009/05/07 dadams
+;;     icicle-list-join-string: Use copy-sequence in default value, so users see original sexp.
+;; 2009/05/02 dadams
+;;     Added: icicle-alternative-actions-alist.
+;; 2009/05/01 dadams
+;;     Added function to icicle-type-actions-alist: icicle-shell-command-on-file.
+;; 2009/04/26 dadams
+;;     Added: icicle-type-actions-alist, icicle-use-anything-candidates-flag.
+;; 2009/04/20 dadams
+;;     Added: icicle-(prefix|apropos)-cycle-(next|previous)-alt-action-keys,
+;;            icicle-modal-cycle-(down|up)-alt-action-keys.
+;; 2009/04/18 dadams
+;;     Soft-require hexrgb.el unconditionally, not just when there is a window-system.
+;;     icicle-region-background: If frame background is unspecified, consider it white.
+;;                               Don't use frame background unless it is a valid color name.
+;;                               Use region background if cannot compute saturation.
+;; 2009/04/16 dadams
+;;     Added: icicle-(prefix|apropos)-cycle-(next|previous)-help-keys.
+;; 2009/04/15 dadams
+;;     Added: icicle-modal-cycle-(up|down)-help-keys.
+;; 2009/04/05 dadams
+;;     Added: icicle-help-in-mode-line-flag.
+;; 2009/03/10 dadams
+;;     Moved here from icicles-fn.el: icicle-shell-command-candidates.
+;;     Moved here from icicles-var.el: icicle-shell-command-candidates.
+;;     Renamed: icicle-shell-command-candidates (fn) to icicle-compute-shell-command-candidates,
+;;              icicle-shell-command-candidates (var) to icicle-shell-command-candidates-cache,
+;;              icicle-guess-cmds-in-path-flag to icicle-guess-commands-in-path.
+;;     icicle-guess-commands-in-path: Boolean -> choice.  Default is now first-use.
+;;     icicle-compute-shell-command-candidates: Don't update cache variable here.
+;;     icicle-shell-command-candidates-cache: Initialize per icicle-guess-commands-in-path.
+;; 2009/03/08 dadams
+;;     Added: icicle-quote-shell-file-name-flag.
+;; 2009/03/01 dadams
+;;     Added: icicle-completing-read+insert-keys, icicle-read+insert-file-name-keys.
+;;     Removed: icicle-complete-on-demand-keys.
+;; 2009/02/20 dadams
+;;     Added: icicle-complete-on-demand-keys (not yet used).
+;;     Renamed: icicle-dired-guess-all-shell-cmds-flag to icicle-guess-cmds-in-path-flag.
+;; 2009/01/25 dadams
+;;     Added: icicle-dired-guess-all-shell-cmds-flag.
+;; 2009/01/17 dadams
+;;     Added: icicle-levenshtein-distance.
+;;     icicle-apropos-match-fns-alist: Added icicle-levenshtein(-strict)-match.
+;; 2009/01/05 dadams
+;;     Added ess-complete-* to icicle-comint-dynamic-complete-replacements.
+;; 2009/01/01 dadams
+;;     Added: icicle-comint-dynamic-complete-replacements.
+;; 2008/12/30 dadams
+;;     Moved icicle-remap here from icicles-mode.el.
+;; 2008/12/06 dadams
+;;     icicle-incremental-completion-flag: Changed :type to choice from boolean.
+;; 2008/12/02 dadams
+;;     Removed: icicle-file-ignore-space-prefix-flag.
+;; 2008/11/28 dadams
+;;     Moved here from icicles-var.el: icicle-apropos-match-fns-alist.
+;; 2008/11/14 dadams
+;;     Added: icicle-hide-common-match-in-Completions-flag.
+;; 2008/11/04 dadams
+;;     Removed: icicle-generic-S-tab-keys.
+;;     Added (split icicle-generic-S-tab-keys in 4):
+;;       icicle-apropos-complete-keys, icicle-key-complete-keys, icicle-previous-candidate-keys,
+;;       icicle-search-from-isearch-keys.
+;;     Added: icicle-complete-key-anyway-flag.
+;; 2008/11/03 dadams
+;;     Applied renamings from icicles-cmd.el.
+;; 2008/10/26 dadams
+;;     Added: icicle-file-*.
+;; 2008/10/18 dadams
+;;     Added: icicle-customize-save-variable-function.
+;; 2008/10/17 dadams
+;;     Added: icicle-bookmark-name-length-max.
+;;     icicle-top-level-key-bindings: Remapped bookmark-set to icicle-bookmark-cmd.
+;; 2008/10/11 dadams
+;;     icicle-highlight-input-completion-failure: Updated doc string.
+;; 2008/10/10 dadams
+;;     Added: icicle-(apropos|prefix)-cycle-(next|previous)-action-keys,
+;;            icicle-modal-cycle-(down|up)-action-keys.
+;;     icicle-cycling-respects-completion-mode-flag:
+;;       Renamed to icicle-cycling-respects-completion-mode.
+;;       It's now a choice of nil, t, apropos, prefix.  Thx to Andrey Zhdanov.
+;; 2008/09/30 dadams
+;;     icicle-highlight-input-completion-failure: Changed default value to implicit-strict.
+;; 2008/09/13 dadams
+;;     Added: icicle-filesets-as-saved-completion-sets-flag.
+;; 2008/08/28 dadams
+;;     icicle-top-level-key-bindings:
+;;       Renamed alacarte-execute-menu-command to lacarte-execute-menu-command.
+;; 2008/08/22 dadams
+;;     Removed: icicle-Completions-window-default-width (obsolete).
+;; 2008/08/21 dadams
+;;     icicle-top-level-key-bindings:
+;;       Replace icicle-find-file(-other-window) with icicle-file(-other-window).
+;;     icicle-generic-S-tab-keys: Mention bug workaround in doc string.  Thx to Kevin Rodgers.
+;; 2008/08/20 dadams
+;;     Added: icicle-inhibit-ding-flag.
+;; 2008/08/12 dadams
+;;     icicle-top-level-key-bindings:
+;;       Remap set-mark-command (C-SPC) and pop-global-mark (C-x C-SPC).
+;; 2008/08/11 dadams
+;;     icicle-key-definition, icicle-top-level-key-bindings:
+;;       Change :match-alternatives to (symbolp) from (commandp).
+;;     icicle-top-level-key-bindings: Added condition for minibuffer-keyboard-quit.
+;; 2008/08/06 dadams
+;;     Bind icicle-kmacro to S-f4, not f5.  Thx to Andrew Hyatt.
+;; 2008/06/22 dadams
+;;     Added: icicle-unpropertize-completion-result-flag.
+;; 2008/06/03 dadams
+;;     Added: icicle-use-C-for-actions-flag.
+;; 2008/05/27 dadams
+;;     icicle-isearch-complete-keys: Removed S-TAB, added M-o.
+;; 2008/05/25 dadams
+;;     icicle-isearch-complete-keys: Added M-TAB and C-M-TAB (if Windows).
+;;     Change [] notation to `' notation for keys in doc strings.
+;; 2008/05/24 dadams
+;;     icicle-isearch-complete-keys: Use explicit ([S-tab] [S-iso-lefttab]) for Emacs < 22.
+;; 2008/05/19 dadams
+;;     icicle-generic-S-tab-keys: Use explicit ([S-tab] [S-iso-lefttab]) for Emacs < 22.
+;; 2008/05/11 dadams
+;;     icicle-top-level-key-bindings: Added :set and :initialize.
+;;     Moved icicle-bind-top-level-commands here from icicles-mode.el, and added optional arg.
+;; 2008/05/10 dadams
+;;     Added widget icicle-key-definition (new custom type).
+;;     Renamed: icicle-bind-top-level-commands-alist to icicle-top-level-key-bindings.
+;;     icicle-top-level-key-bindings:
+;;       Redefined:  New :type, using icicle-key-definition or choice of restricted-sexp.
+;;         Changed order of entry elements.  Use kbd.  No eval for command to be remapped.
+;;         Don't bind f5 unless have kmacro.
+;;     Moved icicle-yank-function before icicle-top-level-key-bindings (needed by it).
+;; 2008/05/07 dadams
+;;     icicle-region-alist, icicle-sort-functions-alist:
+;;       Removed Emacs 20 version (alist works for Emacs 20 also).
+;;     Replaced icicle-bind-top-level-commands-flag with icicle-bind-top-level-commands-alist.
+;;     icicle-isearch-complete-keys:
+;;       Changed default value from ([S-tab] [S-iso-lefttab]) to ([backtab]).
+;; 2008/05/05 dadams
+;;     icicle-generic-S-tab-keys:
+;;       Changed default value from ([S-tab] [S-iso-lefttab]) to ([backtab]).
+;; 2008/04/26 dadams
+;;     Added: icicle-test-for-remote-files-flag.  Updated C-^ to M-_
+;;     icicle-ignore-space-prefix-flag: Update doc string: M-_, not C-^.
+;; 2008/04/18 dadams
+;;     Renamed icicle-init-value-flag to icicle-default-value.
+;;     icicle-default-value: Updated to reflect t value.
+;; 2008/04/13 dadams
+;;     Added: icicle-pp-eval-expression-print-(length|level).
+;; 2008/03/30 dadams
+;;     Added: icicle-highlight-lighter-flag.
+;; 2008/03/29 dadams
+;;     Removed: icicle-completing(-mustmatch)-prompt-prefix, icicle-reminder-prompt-flag.
+;;     Updated doc string of icicle-customize-save-flag.
+;; 2008/03/21 dadams
+;;     icicle-reminder-prompt-flag: Changed default value to nil.
+;; 2008/02/23 dadams
+;;     icicle-init-value-flag: Added insert-start value.  Renamed insert value to insert-end.
+;; 2008/02/06 dadams
+;;     Added: icicle-highlight-input-completion-failure-(delay|threshold).
+;; 2008/01/29 dadams
+;;     Removed: icicle-max-chars-noncompletion-highlight.
+;;     Renamed: icicle-*-input-completion-failure-flag to icicle-*-input-completion-failure.
+;;     icicle-*-input-completion-failure: Added values (implicit*, always) and renamed others.
+;; 2007/12/31 dadams
+;;     icicle-list-join-string: Add display property to hide the ^G.
+;; 2007/12/26 dadams
+;;     icicle-region-background:
+;;       Put initialization back inside defcustom.
+;;       Change test for color from Emacs version to widget test.
+;; 2007/12/24 dadams
+;;     Added: icicle-option-type-prefix-arg-list.
+;; 2007/12/14 dadams
+;;     Added: icicle-customize-save-flag.
+;; 2007/12/09 dadams
+;;     Added: icicle-max-chars-noncompletion-highlight.
+;; 2007/12/03 dadams
+;;     Renamed longest common match (lcm) to expanded common match (ecm).
+;; 2007/11/25 dadams
+;;     Added: icicle-command-abbrev-(alist|match-all-parts-flag|priority-flag).
+;; 2007/11/23 dadams
+;;     Added: icicle-(apropos|prefix)-cycle-(next|previous)-keys.
+;; 2007/11/17 dadams
+;;     Added: icicle-add-proxy-candidates-flag.
+;; 2007/11/02 dadams
+;;     Added: icicle-generic-S-tab-keys, icicle-prefix-complete-keys,
+;;            icicle-(apropos|prefix)-complete-no-display-keys, icicle-isearch-complete-keys.
+;;     Renamed icicle-modal-cycle-(up|down)-key to icicle-modal-cycle-(up|down)-keys,
+;;             icicle-word-completion-key to icicle-word-completion-keys.
+;; 2007/10/29 dadams
+;;     icicle-define-alias-commands-flag, icicle-deletion-action-flag,
+;;       icicle-list-nth-parts-join-string: Added type and group.
+;; 2007/10/28 dadams
+;;     Added: icicle-search-replace-common-match-flag.
+;; 2007/10/23 dadams
+;;     icicle-highlight-input-initial-whitespace-flag:
+;;       Mention icicle-highlight-input-completion-failure-flag in doc string.
+;; 2007/10/21 dadams
+;;     icicle-candidate-width-factor, icicle-inter-candidates-min-spaces: Mention Do Re Mi.
+;; 2007/10/14 dadams
+;;     icicle-act-before-cycle-flag: Default value is now nil.
+;; 2007/10/07 dadams
+;;     Added: icicle-deletion-action-flag.
+;; 2007/09/28 dadams
+;;     Added: icicle-fuzzy-completion-flag.
+;; 2007/08/25 dadams
+;;     Added: icicle-anything-transform-candidates-flag, icicle-define-alias-commands-flag.
+;; 2007/08/19 dadams
+;;     Added: icicle-highlight-input-completion-failure-flag.
+;; 2007/08/16 dadams
+;;     icicle-region-alist, icicle-sort-functions-alist: Use alist as :type for recent Emacs.
+;; 2007/07/27 dadams
+;;     Added: Moved icicle-act-first-then-navigate-p here from icicles-var.el, as option *-flag.
+;;            Thx to Juri Linkov for suggestion.
+;; 2007/07/03 dadams
+;;     Added: icicle-completion-history-max-length, icicle-C-l-uses-completion-flag.
+;;     icicle-expand-input-to-common-match-flag: Updated doc string accordingly.
+;; 2007/06/20 dadams
+;;     icicle-WYSIWYG-Completions-flag: Use string value, not whole number, for sample text.
+;; 2007/06/19 dadams
+;;     icicle-WYSIWYG-Completions-flag: Allow also a whole-number value, for separate swatch.
+;; 2007/06/17 dadams
+;;     Added: icicle-WYSIWYG-Completions-flag.
+;; 2007/06/12 dadams
+;;     icicle-region-background: Use different value for dark-background frames.
+;; 2007/06/09 dadams
+;;     Added: icicle-use-candidates-only-once-flag.
+;; 2007/06/05 dadams
+;;     Don't require hexrgb.el if no window system.
+;;     icicle-increment-color-*: Protected with featurep hexrgb and error message.
+;; 2007/05/06 dadams
+;;     Added: icicle-search-context-match-predicate.
+;; 2007/05/02 dadams
+;;     Added: icicle-search-whole-word-flag, icicle-yank-function.
+;;     icicle-regexp-quote-flag: Updated doc string to mention search.
+;; 2007/04/20 dadams
+;;     Added: icicle-search-highlight-context-levels-flag, icicle-increment-color-saturation.
+;; 2007/04/17 dadams
+;;     Added: icicle-search-replace-literally-flag.
+;; 2007/04/15 dadams
+;;     icicle-search-replace-whole-candidate-flag: Changed default value to t.
+;; 2007/04/07 dadams
+;;     Added: icicle-search-replace-whole-candidate-flag.
+;; 2007/03/31 dadams
+;;     Added: icicle-top-level-when-sole-completion-flag.
+;;     icicle(-regexp)-search-ring-max: Default is 1/10th what it was.
+;; 2007/03/30 dadams
+;;     Added: icicle-candidate-width-factor, icicle-inter-candidates-min-spaces.
+;; 2007/03/12 dadams
+;;     Added: icicle-Completions-window-max-height.
+;;     icicle-show-Completions-help-flag: defvaralias it to completion-show-help (if bound).
+;; 2007/03/10 dadams
+;;     Added: icicle-Completions-window-default-width.
+;; 2007/02/27 dadams
+;;     Changed default value of icicle-incremental-completion-delay to 0.7.
+;; 2007/02/22 dadams
+;;     icicle-buffer-sort: Use icicle-buffer-sort-*...*-last, not nil, as default value.
+;; 2007/02/20 dadams
+;;     Changed icicle-region-auto-open-files-flag default value to nil.
+;; 2007/02/19 dadams
+;;     icicle-region-alist: Added buffer's file to alist entry.
+;;     Added: icicle-region-auto-open-files-flag.
+;; 2007/02/17 dadams
+;;     Added: icicle-keymaps-for-key-completion.
+;; 2007/02/06 dadams
+;;     Added: icicle-add-buffer-name-flag.
+;; 2007/01/29 dadams
+;;     icicle-sort-function: Use icicle-case-string-less-p as value, not string-lessp.
+;; 2007/01/23 dadams
+;;     Added: icicle-highlight-historical-candidates-flag.
+;;     Updated doc strings of *-flag to mention toggles.
+;; 2007/01/18 dadams
+;;     Renamed: icicle-regions to icicle-region-alist.
+;; 2007/01/15 dadams
+;;     Added: icicle-change-sort-order-completion-flag, icicle-sort-functions-alist.
+;;     icicle-cycle-into-subdirs-flag, icicle-sort-function: Updated doc string.
+;; 2007/01/14 dadams
+;;     Added: icicle-list-nth-parts-join-string.
+;; 2007/01/08 dadams
+;;     icicle-reminder-prompt-flag: Reduced default value from 20 to 7 Emacs sessions.
+;; 2007/01/06 dadams
+;;     Added: icicle-use-~-for-home-dir-flag.  Thanks to Timothy Stotts for the suggestion.
+;; 2006/12/29 dadams
+;;     icicle-thing-at-point-functions: Added ffap-guesser as first alternative text grabber.
+;;     icicle-default-thing-insertion: Changed default value to icicle-default-thing-insertion.
+;; 2006/12/25 dadams
+;;     Moved to icicles-fn.el: icicle-historical-alphabetic-p.
+;; 2006/12/22 dadams
+;;     Assigned Icicles subgroups, instead of group Icicles.
+;; 2006/12/10 dadams
+;;     icicle-regions: Corrected (forgot repeat).
+;; 2006/11/26 dadams
+;;     Added: icicle-regions(-name-length-max).
+;; 2006/11/24 dadams
+;;     Added: icicle-kmacro-ring-max.
+;; 2006/11/23 dadams
+;;     Added: icicle-TAB-shows-candidates-flag.  Thx to Tamas Patrovics for the suggestion.
+;; 2006/11/09 dadams
+;;     icicle-search-highlight-all-flag -> icicle-search-highlight-threshold.
+;;     Added: icicle-search-highlight-all-current-flag.
+;; 2006/10/28 dadams
+;;     icicle-region-background: Changed :type to 'color for Emacs 21+.
+;;     icicle(-alternative)-sort-function, icicle-buffer-sort, icicle-transform-function:
+;;       function -> choice of nil or function.
+;;     icicle-buffer-configs: Added :tag's.
+;;     icicle-saved-completion-sets: Corrected doc string.
+;; 2006/10/21 dadams
+;;     Added: icicle-complete-keys-self-insert-flag.
+;; 2006/10/14 dadams
+;;     icicle-list-end-string: Added :type and :group.
+;;     Moved conditional eval-when-compile to top level.
+;; 2006/10/04 dadams
+;;     Added: icicle-special-candidate-regexp.
+;; 2006/10/03 dadams
+;;     icicle-list-join-string: Replaced ^G^J by \007\012, to be able to upload to Emacs Wiki.
+;; 2006/10/01 dadams
+;;     icicle-alternative-sort-function: Updated doc string - it's now a general toggle.
+;; 2006/09/30 dadams
+;;     Added: icicle-key-descriptions-use-*-flag.
+;; 2006/09/16 dadams
+;;     Added: icicle-list-end-string.
+;; 2006/09/03 dadams
+;;     Renamed icicle-show-Completions-help to icicle-show-Completions-help-flag.
+;; 2006/08/13 dadams
+;;     Added: icicle-completing(-mustmatch)-prompt-prefix.
+;; 2006/07/28 dadams
+;;     icicle-change-region-background-flag:
+;;       Default value takes no account of delete-selection mode.  Improved doc string.
+;;     icicle-region-background:
+;;       Don't make region invisible if hexrgb.el was not loaded.
+;;       Change value, not hue, if grayscale frame background.  Improved doc string.
+;; 2006/07/23 dadams
+;;     Added: icicle-transform-function.
+;;     icicle-sort-function: Added Note to doc string.
+;; 2006/07/20 dadams
+;;     Added: icicle-modal-cycle-(up|down)-key.
+;;     Renamed icicle-arrows-respect-* to icicle-cycling-respects-completion-mode-flag.
+;; 2006/07/19 dadams
+;;     Applied patch from Damien Elmes :
+;;       Added: icicle-show-completions-help.  Renamed it to icicle-show-Completions-help.
+;; 2006/07/18 dadams
+;;     Added: icicle-Completions-display-min-input-chars.  Thx to Damien Elmes.
+;; 2006/07/10 dadams
+;;     icicle-historical-alphabetic-p: Fallback directory if no previous input.
+;; 2006/07/07 dadams
+;;     Added: icicle-alternative-sort-function, icicle-historical-alphabetic-p.
+;; 2006/07/04 dadams
+;;     icicle-expand-input-to-common-match-flag: Updated doc string.
+;; 2006/06/09 dadams
+;;     icicle-region-background: Use nil in defcustom.  Initialize separately.
+;; 2006/06/08 dadams
+;;     icicle-bind-top-level-commands-flag: Updated doc string.
+;; 2006/05/19 dadams
+;;     Renamed icicle-inhibit-reminder* to icicle-reminder*.
+;;       Changed its functionality to use a countdown.
+;; 2006/05/16 dadams
+;;     Added: icicle-bind-top-level-commands-flag.
+;; 2006/05/15 dadams
+;;     Renamed: icicle-completion-nospace-flag to icicle-ignore-space-prefix-flag.
+;;     Added: icicle-buffer-ignore-space-prefix-flag.
+;;     icicle-ignore-space-prefix-flag: Changed default value to nil.
+;; 2006/05/09 dadams
+;;     icicle-incremental-completion-threshold: Updated doc string (msg "Displaying...").
+;; 2006/04/28 dadams
+;;     Added: icicle-highlight-input-initial-whitespace-flag.
+;; 2006/04/14 dadams
+;;     Added: icicle-input-string, icicle-search-cleanup-flag, icicle-update-input-hook.
+;;     icicle-list-join-string: Added :type and :group.
+;; 2006/04/09 dadams
+;;     Added: icicle-arrows-respect-completion-type-flag.
+;; 2006/04/07 dadams
+;;     Added: icicle-search-highlight-all-flag.
+;; 2006/04/02 dadams
+;;     Added: icicle-regexp-quote-flag.
+;; 2006/03/24 dadams
+;;     Added: icicle-incremental-completion-(delay|threshold).
+;; 2006/03/20 dadams
+;;     icicle-expand-input-to-common-match-flag: Changed default value to t.
+;; 2006/03/19 dadams
+;;     Added: icicle-expand-input-to-common-match-flag.
+;; 2006/03/17 dadams
+;;     Removed: icicle-cache-file.
+;;     Added: icicle-saved-completion-sets.
+;; 2006/03/13 dadams
+;;     Added: icicle-cache-file.
+;; 2006/03/08 dadams
+;;     icicle-default-thing-insertion: Use substitute-command-keys in :tag.
+;; 2006/03/05 dadams
+;;     Moved from here to icicle-mode.el: icicle-mode, icicle-mode-hook.
+;;     Added: icicle-touche-pas-aux-menus-flag.
+;; 2006/03/03 dadams
+;;     icicle-list-join-string: Changed value to ^G^J.  Clarified doc string.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-var.el'")
+;;
+;; 2011/09/05 dadams
+;;     icicle-general-help-string: Added icicle-hide-non-matching-lines-flag.
+;;                                 Removed -other-window from *-bookmark-(bookmark-list|desktop).
+;; 2011/08/13 dadams
+;;     Added: icicle-search-complement-domain-p.
+;; 2011/08/12 dadams
+;;     Added: icicle-full-cand-fn.
+;; 2011/08/07 dadams
+;;     icicle-abs-file-candidates: Update doc string: now an alist (for COLLECTION arg).
+;; 2011/07/27 dadams
+;;     Removed icicle-completions-format-internal.
+;; 2011/07/26 dadams
+;;     Removed: icicle-list-end-string (no longer needed).  Thx to Michael Heerdegen.
+;; 2011/07/24 dadams
+;;     Updated icicle-general-help-string for new commands.
+;; 2011/07/06 dadams
+;;     Applied renaming of icicle-Completions-frame-at-right-flag to icicle-move-Completions-frame.
+;; 2011/05/03 dadams
+;;     icicle-general-help-string: Mention icicle-toggle-highlight-saved-candidates.
+;; 2011/04/29 dadams
+;;     Added: icicle-buffer-sort-first-time-p, icicle-file-sort-first-time-p, icicle-new-last-cmd,
+;;              icicle-orig-must-pass-after-match-pred.
+;; 2011/04/02 dadams
+;;     Added: icicle-bufflist, icicle-pref-arg, icicle-scan-fn-or-regexp.
+;;     Moved to icicles-cmd2.el:
+;;       icicle-orig-(buff|win)-key-complete, icicle-orig-extra-cands, icicle-orig-menu-bar,
+;;       icicle-orig-(font|frame|pixelsize|pointsize), icicle-orig-show-initially-flag,
+;;       icicle-orig-sort-orders-alist, icicle-this-cmd-keys.
+;; 2011/03/31 dadams
+;;     Renamed icicle-target-window-recenter-amount to icicle-recenter & moved to icicles-opt.el.
+;; 2011/03/29 dadams
+;;     Added: icicle-key-prefix-description, icicle-orig-(buff|window|font|frame|pixelsize|pointsize),
+;;            icicle-orig-(buff|win)-key-complete, icicle-completing-keys-p, icicle-prompt,
+;;            icicle-orig-(pt|win)-explore, icicle-orig-show-initially-flag, icicle-orig-extra-cands,
+;;            icicle-other-window, icicle-target-window-recenter-amount, icicle-this-cmd-keys.
+;;     Renamed: icicle-scroll-Completions-backward-p to icicle-scroll-Completions-reverse-p.
+;;     icicle-complete-keys-alist: Removed conditional definition (just don't use it before Emacs 22).
+;; 2011/01/17 dadams
+;;     Removed compile-time require of cl.el.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2010/11/07 dadams
+;;     Renamed: icicle-all-candidates-action-p to icicle-all-candidates-action.  Now can cache action.
+;; 2010/10/25 dadams
+;;     Removed mention of icicle-search-context-match-predicate (no longer exists).
+;; 2010/10/24 adams
+;;     Added: icicle-must-pass-after-match-predicate.
+;;     icicle-must-pass-predicate: Clarified doc string.
+;; 2010/10/09 dadams
+;;     icicle-general-help-string:
+;;       Applied renaming of icicle-cycling-respects-completion-mode to icicle-default-cycling-mode.
+;; 2010/10/07 dadams
+;;     icicle-current-TAB-method: Use nil, not basic, as default value.
+;; 2010/06/18 dadams
+;;     Added: icicle-completions-format-internal.
+;; 2010/06/08 dadams
+;;     Added: icicle-nb-candidates-before-truncation.
+;; 2010/06/04 dadams
+;;     Added: icicle-lighter-truncation.
+;;     icicle-general-help-string: Mention missing doremi commands.
+;; 2010/04/29 dadams
+;;     Added: icicle-remove-icicles-props-p.
+;; 2010/04/02 dadams
+;;     icicle-general-help-string: Updated.
+;; 2010/04/02 dadams
+;;     Added: icicle-bookmark-types.
+;;     icicle-general-help-string: Updated to reflect move from saved regions to bookmarks.
+;; 2010/03/13 dadams
+;;     Added: icicle-transform-before-sort-p.
+;;     Removed: icicle-sorted-bookmark-alist.
+;;     Applied renaming of icicle-add-buffer-name-flag to icicle-show-multi-completion-flag.
+;; 2010/03/03 dadams
+;;     Added: icicle-sorted-bookmark-alist, icicle-reverse-multi-sort-p.
+;;     Renamed: icicle-last-sort-function to icicle-last-sort-comparer.
+;;     icicle-general-help-string: Applied renaming to icicle-sort-orders-alist.
+;;     Applied renamings: icicle-sort-function to icicle-sort-comparer,
+;;                        icicle-sort-functions-alist to icicle-sort-orders-alist,
+;;                        icicle-alternative-sort-function to icicle-alternative-sort-comparer.
+;; 2010/02/17 dadams
+;;     Moved icicle-redefined-functions to icicles-opt.el
+;;       and renamed to icicle-inhibit-advice-functions
+;; 2010/02/14 dadams
+;;     Added: icicle-advice-info-list, icicle-redefined-functions.
+;; 2009/11/07 dadams
+;;     Applied doremi cmd renamings (added +) to help text.
+;; 2009/10/25 dadams
+;;     Added: icicle-current-TAB-method.
+;;     Updated icicle-general-help-string with new command names.
+;; 2009/09/26 dadams
+;;     Added: icicle-progressive-completing-p.
+;; 2009/09/25 dadams
+;;     Removed: icicle-respect-completion-styles-p.  See option *-TAB-respects-*-styles-flag.
+;; 2009/09/05 dadams
+;;     Added: icicle-minibuffer-message-ok-p.
+;;     Renamed icicle-acting-on-next/prev-p to icicle-acting-on-next/prev.
+;; 2009/07/26 dadams
+;;     Added: icicle-command-abbrev-history (belated), icicle-interactive-history.
+;; 2009/05/17 dadams
+;;     icicle-predicate-types-alist: Updated to reflect thumb-frm.el name changes.
+;; 2009/05/11 dadams
+;;     Added: icicle-hist-cands-no-highlight.
+;; 2009/05/09 dadams
+;;     Added: *-input-completion-fail-overlay, *-anychar-regexp, *-dot-string-internal.
+;; 2009/05/02 dadams
+;;     Added: icicle-cmd-reading-input.
+;; 2009/04/28 dadams
+;;     Renamed: icicle-object-predicate-types to icicle-predicate-types-alist.
+;;     icicle-predicate-types-alist:
+;;       Converted to alist, with cdr's from icicle-type-actions-alist.  Added more entries.
+;;     Removed: icicle-object-named-types.
+;; 2009/04/03 dadams
+;;     Added: icicle-filtered-default-value.
+;; 2009-03/16 dadams
+;;     Added: icicle-use-candidates-only-once-alt-p.
+;; 2009/03/15 dadams
+;;     icicle-general-help-string: Added: icicle-recompute-shell-command-candidates,
+;;                                        icicle-remove-file-from-recentf-list.
+;; 2009/03/10 dadams
+;;     Moved icicle-shell-command-candidates to icicles-opt.el and renamed: *-cache.
+;; 2009/03/01 dadams
+;;     Added: icicle-completing-read+insert-candidates.
+;;     Removed: icicle-complete-on-demand-cmd.
+;; 2009/02/23 dadams
+;;     Added: icicle-extra-candidates-dir-insert-p.
+;; 2009/02/20 dadams
+;;     Added: icicle-shell-command-candidates, icicle-complete-on-demand-cmd.
+;; 2009/02/04 dadams
+;;     Added: icicle-next-prefix-complete-cycles-p, icicle-next-apropos-complete-cycles-p.
+;; 2009/01/24 dadams
+;;     Added: icicle-last-apropos-complete-match-fn.
+;; 2009/01/13 dadams
+;;     Added: icicle-respect-completion-styles-p (internal var, for now).
+;; 2008/12/25 dadams
+;;     Added: icicle-cycling-p.
+;; 2008/12/07 dadams
+;;     Added: icicle-completion-prompt-overlay.  Removed: icicle-prompt.
+;; 2008/12/02 dadams
+;;     Added: icicle-confirm-exit-commands.
+;; 2008/11/28 dadams
+;;     Moved to icicles-opt.el: icicle-apropos-match-fns-alist.
+;; 2008/11/22 dadams
+;;     Added: icicle-fancy-candidates-p, icicle-fancy-cands-internal-p.
+;; 2008/11/03 dadams
+;;     Applied renamings from icicles-cmd.el.
+;; 2008/11/02 dadams
+;;     Added: icicle-(doc|vardoc|fundoc|plist)-last-initial(-option)-cand-set.
+;; 2008/10/14 dadams
+;;     Added: icicle-general-help-string.
+;;     Removed: icicle-completion-help-string.
+;; 2008/10/06 dadams
+;;     icicle-ms-windows-drive-hash: Set it to nil if make-hash-table is undefined.
+;; 2008/09/30 dadams
+;;     Added: icicle-ms-windows-drive-hash.
+;; 2008/09/20 dadams
+;;     icicle-ignored-extensions-regexp: Append $ to each extension.
+;;     Added: icicle-abs-file-candidates.
+;; 2008/08/28 dadams
+;;     Renamed: alacarte-menu-items-alist to lacarte-menu-items-alist.
+;; 2008/08/18 dadams
+;;     Added: icicle-inhibit-try-switch-buffer.
+;; 2008/08/12 dadams
+;;     Added: icicle-apply-nomsg.
+;; 2008/08/10 dadams
+;;     Added: icicle-explore-final-choice, icicle-explore-final-choice-full.
+;; 2008/08/03 dadams
+;;     Added: icicle-all-candidates-list-alt-action-fn.
+;;     Renamed: icicle-all-candidates-action-fn to icicle-all-candidates-list-action-fn,
+;;              icicle-candidate-alternative-action-fn to icicle-candidate-alt-action-fn.
+;; 2008/03/30 dadams
+;;     Added: icicle-old-read-file-name-fn.
+;; 2008/03/29 dadams
+;;     Removed: icicle-prompt-suffix.
+;; 2008/03/23 dadams
+;;     Added: icicle-scroll-Completions-backward-p.
+;; 2008/03/19 dadams
+;;     Added: icicle-read-expression-map.
+;; 2008/03/10 dadams
+;;     Added: icicle-frame-alist.
+;; 2008/02/24 dadams
+;;     Added: icicle-apropos-match-fns-alist.
+;; 2008/02/21 dadams
+;;     Added: icicle-Info-only-rest-of-book-p.
+;; 2008/02/03 dadams
+;;     Added: icicle-comp-base-is-default-dir-p, icicle-dir-candidate-can-exit-p.
+;; 2008/01/18 dadams
+;;     Moved icicle-complete-keys-alist here from icicles-cmd.el
+;; 2008/01/04 dadams
+;;     Added: icicle-doc-history.
+;; 2007/12/27 dadams
+;;     Added: icicle-apropos-complete-match-fn.
+;; 2007/12/05 dadams
+;;     icicle-proxy-candidate-regexp: Removed * doc-string prefix.
+;; 2007/11/25 dadams
+;;     Added: icicle-commands-for-abbrev.
+;; 2007/11/17 dadams
+;;     Added: icicle(saved)-proxy-candidates, icicle-proxy-candidate-regexp.
+;; 2007/10/06 dadams
+;;     icicle-object-named-types: Added file type.
+;; 2007/08/19 dadams
+;;     Added: icicle-input-fail-pos.
+;; 2007/08/18 dadams
+;;     Added: icicle-whole-candidate-as-text-prop-p.
+;; 2007/07/29 dadams
+;;     Added: icicle-object-named-types, icicle-object-predicate-types.
+;; 2007/07/27 dadams
+;;     Moved icicle-act-first-then-navigate-p to icicles-opt.el as icicle-act-before-cycle-flag.
+;; 2007/07/08 dadams
+;;     Added: icicle-all-candidates(-alternative)-action-fn.
+;; 2007/07/03 dadams
+;;     Added: icicle-previous-raw(-non)-file-name-inputs.
+;; 2007/06/23 dadams
+;;     Added: icicle-search-replacement-history.
+;; 2007/06/17 dadams
+;;     Added: icicle-saved-candidate-overlays.
+;; 2007/06/07 dadams
+;;     Added: icicle-face-name-history.
+;;     Renamed: frame-name-history to icicle-frame-name-history,
+;;              icicle-font-history to icicle-font-name-history,
+;;              icicle-function-history to icicle-function-name-history,
+;;              icicle-variable-history to icicle-variable-name-history.
+;; 2007/05/29 dadams
+;;     icicle-insert-string-at-pt-*: Initialize to nil, not 0.
+;; 2007/05/25 dadams
+;;     Added: icicle-char-property-value-history.
+;; 2007/05/06 dadams
+;;     Added defvars to quiet byte compiler.
+;; 2007/04/28 dadams
+;;     Added: icicle-search-in-context-fn.
+;; 2007/04/20 dadams
+;;     Added: icicle-search-level-overlays.
+;; 2007/04/15 dadams
+;;     Added: icicle-search-context-regexp.
+;; 2007/04/10 dadams
+;;     Added: icicle-search-context-level.
+;; 2007/04/08 dadams
+;;     Added: icicle-all-candidates-action-p.
+;;     icicle-candidate-action-fn: Corrected doc string: reversed success and failure values.
+;; 2007/04/07 dadams
+;;     Added: icicle-search-replacement, icicle-searching-p, icicle-act-first-then-navigate-p.
+;; 2007/04/02 dadams
+;;     Added: icicle-text-property-value-history.
+;;     Added: icicle-text-properties-alist (commented out).
+;; 2007/03/23 dadams
+;;     Added: icicle-require-match-p.
+;; 2007/03/14 dadams
+;;     Added: icicle-last-top-level-command.
+;; 2007/03/06 dadams
+;;     Added: icicle-inhibit-sort-p.
+;;     icicle-candidates-alist: Improved doc string.
+;; 2007/02/20 dadams
+;;     Added: icicle-delete-candidate-object, icicle-candidate-alternative-action-fn.
+;; 2007/02/03 dadams
+;;     Renamed icicle-icompleting-p to icicle-edit-update-p.
+;; 2007/02/02 dadams
+;;     Added: icicle-completing-p.
+;; 2007/01/29 dadams
+;;     icicle-last-sort-function: Use icicle-case-string-less-p, not string-lessp.
+;; 2007/01/19 dadams
+;;     Added: icicle-candidate-properties-alist.
+;; 2007/01/15 dadams
+;;     Added: icicle-reverse-sort-p.
+;; 2007/01/14 dadams
+;;     icicle-list-use-nth-parts: Updated doc string for new icicle-list-nth-parts-join-string.
+;; 2007/01/12 dadams
+;;     Added: icicle-list-use-nth-parts.
+;;     Removed icicle-saved-overriding-local-map.
+;; 2007/01/11 dadams
+;;     Added: icicle-menu-map, icicle-minor-mode-map-entry.
+;; 2007/01/10 dadams
+;;     Added: icicle-saved-overriding-local-map.
+;; 2007/01/05 dadams
+;;     icicle-initial-value: Updated doc string to mention you can bind it.
+;; 2006/12/25 dadams
+;;     Added: icicle-saved-completion-candidates-internal.
+;; 2006/12/23 dadams
+;;     Added: icicle-candidate-help-fn.
+;; 2006/12/17 dadams
+;;     Added: icicle-saved-completion-candidate.
+;; 2006/11/24 dadams
+;;     Added: icicle-universal-argument-map, icicle-kmacro-alist, icicle-saved-kmacro-ring-max,
+;;            icicle-kmacro-history.
+;; 2006/11/18 dadams
+;;     Added: frame-name-history, icicle-bookmark-history, icicle-buffer-config-history,
+;;            icicle-color-history, icicle-color-theme-history, icicle-completion-set-history,
+;;            icicle-dictionary-history, icicle-font-history, icicle-function-history,
+;;            icicle-kill-history, icicle-search-history, icicle-variable-history,
+;; 2006/11/09 dadams
+;;     icicle-search-refined-overlays: Updated doc string: icicle-search-highlight-threshold.
+;; 2006/10/14 dadams
+;;     Moved conditional eval-when-compile to top level.
+;; 2006/09/24 dadams
+;;     icicle-last-transform-function: Corrected default value.
+;; 2006/09/12 dadams
+;;     Added: icicle-pre-minibuffer-buffer.
+;; 2006/08/20 dadams
+;;     icicle-current-completion-mode: Updated doc string.
+;; 2006/08/04 dadams
+;;     Removed icicle-apropos-completing-p (not used).
+;; 2006/07/23 dadams
+;;     Added: icicle-last-transform-function.
+;; 2006/07/22 dadams
+;;     Added: icicle-search-command, icicle-search-final-choice.
+;; 2006/07/20 dadams
+;;     Renamed icicle-arrows-respect-* to icicle-cycling-respects-completion-mode-flag.
+;; 2006/07/19 dadams
+;;     Applied patch from Damien Elmes : Added: icicle-current-completion-type.
+;;     Renamed: icicle-current-completion-type to icicle-current-completion-mode.
+;; 2006/07/05 dadams
+;;     Renamed: icicle-current-regexp-input to icicle-current-raw-input.
+;; 2006/06/18 dadams
+;;     Added: icicle-apropos-completing-p.
+;; 2006/04/30 dadams
+;;     Added: icicle-candidate-entry-fn.
+;;     Renamed: icicle-search-candidates to icicle-candidates-alist.
+;; 2006/04/14 dadams
+;;     Renamed icicle-search-refined-overlay to icicle-search-refined-overlays.
+;;     Added: icicle-search-candidates.
+;; 2006/04/07 dadams
+;;     Added: icicle-search-overlays.
+;;     Renamed icicle-search-overlay to icicle-search-current-overlay.
+;; 2006/03/27 dadams
+;;     Added: icicle-search-refined-overlay.
+;; 2006/03/26 dadams
+;;     Added: icicle-search-overlay.
+;; 2006/03/25 dadams
+;;     Added: icicle-saved-candidates-variables-obarray.
+;; 2006/03/20 dadams
+;;     Added: icicle-common-match-string, icicle-current-regexp-input.
+;; 2006/03/14 dadams
+;;     Removed: icicle-icicle-completing-p.
+;; 2006/03/13 dadams
+;;     Added: icicle-re-no-dot.
+;; 2006/03/05 dadams
+;;     Moved to icicles-mode.el: icicle-mode-map.
+;; 2006/03/04 dadams
+;;     Moved options stuff to Options menu, when available.
+;;     Moved apropos stuff to Apropos menu, when available.
+;;     Moved describe stuff to Describe menu, when available.
+;; 2006/03/03 dadams
+;;     Added to Icicles menu: icicle-complete-thesaurus-entry, icicle-apropos*,
+;;       option-setting cmds, buffer-config cmds icicle-(var|fun)doc.
+;;     Require apropos-fn+var.el.
+ 
+;;;(@* "CHANGE LOG FOR `icicles.el'")
+;;
+;; 2011/06-24 dadams
+;;     Updated load order: mac, face, opt, var, fn, mcmd, cmd1, cmd2, mode.
+;; 2010/12/26 dadams
+;;     Removed autoload cookies except simple ones & ones with sexp on same line.  Thx to Richard Kim.
+;; 2009/05/22 dadams
+;;     Require icicles-cmd[12].
+;; 2009/04/13 dadams
+;;     Removed the part of Thierry's text that mentioned emacsclient (no relation to Icicles).
+;; 2008/12/02 dadams
+;;     Don't warn, if daemonp.  Thx to Thierry Volpiatto.
+;; 2007/07/22 dadams
+;;     Require icicles-cmd.el before icicles-mode.el.
+;; 2007/06/07 dadams
+;;     Moved all doc to new files icicles-doc1.el and icicles-doc2.el.
+;; 2007/05/12 dadams
+;;     Moved Search Enhancements subsections to top level: Isearch Completion,
+;;       Icicles Search Commands, Overview, Search and Replace.
+;; 2007/05/06 dadams
+;;     Changed S-C- to C-S- and M-C- to C-M- in doc.
+;; 2007/04/20 dadams
+;;     Require icicles-face.el after icicles-opt.el.
+;; 2007/03/09 dadams
+;;     Renamed sections .*Removal of Duplicates to .*Removing Duplicates and
+;;                      More on Multi-Commands to More About Multi-Commands.
+;; 2007/02/24 dadams
+;;     Added section More on Multi-Commands.
+;;     Added subsection Chipping Away the Non-Elephant to Nutshell View.
+;; 2007/02/03 dadams
+;;     Updated section Sorting Candidates and Removal of Duplicates.
+;; 2007/01/28 dadams
+;;     Added: subsection Using Progressive ... Process of Elimination.
+;; 2007/01/21 dadams
+;;     Added: section Text Properties in *Completions*.
+;; 2007/01/19 dadams
+;;     Added: section Programming Multi-Completions.
+;; 2007/01/16 dadams
+;;     Added linkd links.  Cleanup.
+;; 2007/01/15 dadams
+;;     Added: section Sorting Candidates and Removal of Duplicates.
+;;     Renamed:
+;;      icicle-sort-and-strip-ignored to icicle-strip-ignored-files-and-sort,
+;;      icicle-dirs-last-p to icicle-dirs-last-p,
+;;      icicle-sort-case-insensitively to *-case-insensitive-string-lessp.
+;; 2007/01/12 dadams
+;;     Updated section Multi-Completions for icicle-list-use-nth-parts.
+;; 2007/01/06 dadams
+;;     File-Name and Directory-Name Completion Tips: Mention icicle-use-~-for-home-dir-flag.
+;; 2006/11/23 dadams
+;;     Added icicle-TAB-shows-candidates-flag.
+;; 2006/11/10 dadams
+;;     Multi-Commands: Mention prompt prefix +.
+;; 2006/11/05 dadams
+;;     icicle-occur is bound to C-c '.  Search commands use multiple buffers.
+;;     Added Nutshell subsection Perform Multiple Operations In One Command.
+;; 2006/10/19 dadams
+;;     Added Goggle Matching section.
+;; 2006/10/16 dadams
+;;     Added key completion to Nutshell View.
+;; 2006/10/14 dadams
+;;     Renamed: icicle-cancel-*Help*-* to icicle-cancel-Help-*.
+;;     Moved conditional eval-when-compile to top level.
+;; 2006/10/01 dadams
+;;     Updated for new alternative-sort toggle:
+;;       History Enhancements, Key Completion, Customization *, Key Bindings.
+;; 2006/09/30 dadams
+;;     Changed bindings of icicle-candidate-set-(save|retrieve) from C-<, C-> to C-M-<, C-M->.
+;;     Added icicle-key-descriptions-use-<>-flag in Customization section.
+;; 2006/09/17 dadams
+;;     Added section Key Completion.
+;; 2006/09/12 dadams
+;;     Added section Moving Between the Minibuffer and Other Buffers.
+;; 2006/08/23 dadams
+;;     Added sections Icicles Mult M-x and Defining Icicles Multi M-x.
+;; 2006/08/18 dadams
+;;     Added section Icicles Info Enhancements.
+;; 2006/08/13 dadams
+;;     Documented icicle-completing(-mustmatch)-prompt-prefix.
+;; 2006/06/17 dadams
+;;     Rewrote Multi-Commands, Defining Icicles Commands (Including Multi-Commands), and
+;;             Defining Multi-Commands the Hard Way.
+;;     Renamed: Defining Icicles Commands: + (Including Multi-Commands).
+;;              Defining Multi-Commands: + the Hard Way.
+;;     Added: Defining Multiple-Choice Menus.
+;; 2006/06/08 dadams
+;;     Removed require of icicle-keys.el (obsolete).
+;; 2006/05/26 dadams
+;;     Mention M-k as icicle-erase-minibuffer-or-history-element.
+;;     Don't mention M-S-backspace and M-S-delete any more.
+;; 2006/05/19 dadams
+;;     Renamed icicle-inhibit-reminder* to icicle-reminder*.
+;;       Updated its doc to reflect new functionality.
+;; 2006/05/18 dadams
+;;     Change install instructions to include turning on Icicle mode.
+;; 2006/05/16 dadams
+;;     Require icicles-keys.el when icicle-bind-top-level-commands-flag.
+;;     Updated doc to reflect new library icicles-keys.el.
+;; 2006/05/15 dadams
+;;     Renamed: ici*-nospace-flag to icicle-ignore-space-prefix-flag.
+;;     Updated doc of icicle-ignore-space-prefix-flag.
+;;     Added doc of icicle-buffer-ignore-space-prefix-flag.
+;; 2006/04/14 dadams
+;;     Added section Inserting a Regexp from a Variable.
+;; 2006/04/09 dadams
+;;     Added descriptions of icicle-arrows-respect-completion-type-flag.
+;; 2006/03/19 dadams
+;;     Added description of icicle-expand-input-to-common-match-flag.
+;; 2006/03/07 dadams
+;;     Correct the description of icicle-doc - match against only the doc, not the symbol name.
+;; 2006/03/06 dadams
+;;     Reordered Commentary sections, putting Emacs-Lisp stuff later.
+;; 2006/03/05 dadams
+;;     Mention icicle-touche-pas-aux-menus-flag.
+;; 2006/03/03 dadams
+;;     Clarified Multi-Completions description.
+;; 2006/03/01 dadams
+;;     Added: icicle-(complete|insert)-thesaurus-entry.
+;; 2006/02/27 dadams
+;;     Split into multiple libraries: *-cmd, *-face, *-fn, *-mac, *-mode, *-opt, *-var.
+;; 2006/02/25 dadams
+;;     Added: icicle-narrow-candidates (bound to M-*), icicle-icicle-completing-p,
+;;            icicle-set-calling-cmd, icicle-reset-icicle-completing-p,
+;;            icicle-run-icicle-(pre|post)-command-hook.
+;;     Add all hooks in icicle-mode only, except for minibuffer-local hooks (pre- and
+;;       post-command).
+;;     Remove all hooks when exit Icicle mode.
+;;     icicle-completing-read, icicle-read-file-name:
+;;       Add catch icicle-read-top.  Set icicle-icicle-completing-p.
+;;       Separate case of not Icicle mode from other no-prompt cases.
+;;     Reordered some groups of functions.
+;; 2006/02/24 dadams
+;;     icicle-candidate-set-1: Treat empty set.
+;; 2006/02/21 dadams
+;;     icicle-prefix-complete: Implemented icompletion here, like icicle-apropos-complete-1.
+;;     icicle-call-then-update-Completions:
+;;       Use icicle-last-completion-command, not icicle-apropos-complete.
+;;     Renamed icicle-apropos-icompleting-p to icicle-icompleting-p.
+;;     Added: icicle-(kill|delete)(-backward)-*, icicle-yank etc.  Bound them.
+;;     Added: icicle-call-then-update-Completions.
+;;     Added: icicle-incremental-completion-p.
+;;       Use instead of icicle-incremental-completion-flag everywhere.
+;;       Upgrade from t in icicle-display-candidates-in-Completions.
+;;       Reset in icicle-minibuffer-setup.
+;;     icicle-isearch-complete: Use search-ring symbol as history arg to completing-read.
+;;     icicle-display-candidates-in-Completions, icicle-keep-only-past-inputs, icicle-history:
+;;       Ensure that minibuffer-history-variable is a list.
+;;     Fixed typos: icicle-keep-past-inputs -> icicle-keep-only-past-inputs.
+;; 2006/02/20 dadams
+;;     icicle-insert-string-at-point: Treat negative prefix arg.
+;;     Added: icicle-signum.
+;;     icicle-insert-thing: Remove text properties of string to insert.
+;; 2006/02/19 dadams
+;;     icicle-thing-at-point-functions: Added function to grab successive text.
+;;     icicle-insert-string-at-point: Treat successive-grab fn and prefix arg.
+;;     Added: icicle-default-thing-insertion, icicle-default-thing-insertion-flipped-p,
+;;            icicle-insert-string-at-pt-(start|end), icicle-successive-grab-count,
+;;            icicle-insert-thing.
+;;     Renamed: icicle-insert-string-near-point to icicle-insert-string-at-point.
+;; 2006/02/18 dadams
+;;     icicle-retrieve-last-input: Don't reset icicle-last-completion-command if not interactive
+;;     icicle-candidate-set-complement, icicle-keep-only-past-inputs:
+;;       Use icicle-retrieve-last-input.
+;;     icicle-keep-only-past-inputs:
+;;       Rewrote modeled on icicle-apropos-complete:
+;;        Take into account singleton and empty candidate set.
+;;        Provide input to icicle-display-ca*.
+;;        Set icicle-last-completion-command.
+;;     icicle-history: Force redisplay of *Completions*.  Don't set this-command.
+;;     icicle-completing-read: Ensure icicle-initial-value is not nil.
+;;     icicle-save-or-restore-input: Don't restore empty input.
+;;     icicle-recompute-candidates:
+;;       Don't recompute if last completion cmd was icicle-keep-only-past-inputs.
+;;     Added: icicle-historical-candidate, icicle-keep-only-past-inputs.
+;;     icicle-display-candidates-in-Completions: Use icicle-historical-candidate.
+;;     Bind icicle-keep-only-past-inputs to M-pause in minibuffer completion maps.
+;; 2006/02/17 dadams
+;;     Added: icicle-complete-input-overlay, icicle-highlight-complete-input,
+;;            icicle-complete-input.
+;;     icicle-(prefix|apropos)-complete(-1): Use icicle-highlight-complete-input.
+;;     Added icicle-inhibit-reminder-prompt-flag.  Thx to Jonathan Simms for the suggestion.
+;;     icicle-completing-read, icicle-read-file-name: Use icicle-inhibit-reminder-prompt-flag.
+;; 2006/02/12 dadams
+;;     icicle-read-string: Finished bug fix of 2/11.  Thx to Andrey Zhdanov.
+;; 2006/02/11 dadams
+;;     icicle-insert-string-near-point: Always start with first function.
+;;     read-from-minibuffer: Bug fix: don't use def if init is consp.  Thx to Andrey Zhdanov.
+;; 2006/02/09 dadams
+;;     Added: icicle-insert-string-near-point, icicle-thing-at-point-functions,
+;;            icicle-thing-at-pt-fns-pointer.
+;;     Bound icicle-insert-string-near-point.
+;;     Added Commentary section "Inserting Text Found Near the Cursor"
+;;     Require: thingatpt+.el, thingatpt.el.
+;;     Bug fix: icicle-execute-extended-command(-1): Take care of last-command and this-command.
+;; 2006/02/08 dadams
+;;     icicle-completing-read: Treat consp case of initial-input.
+;;     icicle-read-file-name: Fixed bug introduced 02/02:
+;;       Don't ensure initial-input is not null.
+;; 2006/02/07 dadams
+;;     Bug fix: Files menu find-file stuff was bound to *recent-file*.
+;; 2006/02/03 dadams
+;;     icicle-init-value-flag: Use nil as the default value.
+;;     Added: icicle-read-from-minibuffer, icicle-read-string.
+;;              Use in icicle-(redefine|restore)-standard-commands.
+;; 2006/02/02 dadams
+;;     icicle-completing-read, read-file-name:
+;;       Respect icicle-init-value-flag only if default value not nil.
+;;     read-file-name: Ensure initial-value is not null.  Initialize icicle-initial-value.
+;;                     Respect icicle-init-value-flag.
+;; 2006/01/29 dadams
+;;     icicle-completing-read, icicle-read-file-name: Remove binding of ESC-TAB.
+;;     icicle-lisp-complete-symbol: Enable recursive minibuffers if in minibuffer.
+;;     Commentary: Combine lisp-complete-symbol with dabbrev.
+;;     Updated bindings listed in icicle-completion-help-string.
+;; 2006/01/28 dadams
+;;     New feature: icicle-lisp-complete-symbol (added).  Added to Commentary and moved section.
+;;     Corrected fix of 2005/12/14:
+;;       icicle-minibuffer-setup: Save region background at recursion level 1.
+;;       icicle-saved-region-background: defvar to nil.
+;;     Added: icicle-increment-color-hue.  Use in icicle-region-background.
+;;     Added: icicle-(re)set-option-to-(nil|t), icicle-clear-option, icicle-toggle-option,
+;;            icicle-binary-option-p.
+;; 2006/01/26 dadams
+;;     Added: icicle(-saved)(-regexp)-search-ring-max,
+;;            icicle-(redefine|restore)-standard-options.
+;;     icicle-mode: Use icicle-(redefine|restore)-standard-options.
+;;                  Use icicle-(redefine|restore)-standard-commands for Emacs 21+ also (forgot?)
+;;     icicle-(redefine|restore)-*: Use defalias, not fset.
+;; 2006/01/24 dadams
+;;     New feature: icicle-isearch-complete.
+;;       Added: icicle-isearch-complete, icicle-isearch-resume, icicle-bind-isearch-keys.
+;;       icicle-mode: add/remove isearch-mode-hook.
+;;     Minor bug fix: initial value was treated as icicle-last-completion-candidate.
+;;       Added: icicle-initial-value.
+;;       icicle-completing-read, icicle-read-file-name:
+;;         Set icicle-initial-value, not icicle-last-completion-candidate.
+;;       icicle-next-candidate:
+;;         Initialize icicle-last-completion-candidate to icicle-initial-value.
+;;       icicle-save-or-restore-input:
+;;         Don't change icicle-current-input if = icicle-initial-value
+;;       Renamed: icicle-init-value to icicle-init-value-flag.
+;; 2006/01/23 dadams
+;;     Use command remapping for self-insert-command in Emacs 22.
+;;     Changed icicle-(re|un)map to defsubst.
+;;     Removed Commentary section on icicle-execute-extended-command.
+;;     icicle-apropos-complete-and-exit, icicle-apropos-complete-1:
+;;       Use flag icicle-apropos-complete-and-exit-p to suppress minibuffer-message.
+;; 2006/01/22 dadams
+;;     Added: icicle-execute-extended-command*.
+;;     completing-read, icicle-read-file-name:
+;;       Corrected nil case for icicle-require-match-flag (bug fix).
+;;       Hard-code bindings, instead of using \\[...], so the simpler bindings are shown.
+;;     Changed C-o to C-RET for consistency (C-o still works too).
+;;       icicle-(bind|restore)-completion-keys: Added C-RET binding.
+;; 2006/01/21 dadams
+;;     icicle-mouse-choose-completion:
+;;       Don't save selected window if it's *Completions*.
+;;     Added more Commentary about icicle-retrieve-last-input.
+;; 2006/01/20 dadams
+;;     icicle-sort-and-strip-ignored: Don't ignore names if only ignored extensions match.
+;;     Added: icicle-apropos-complete-and-exit.  Bound it in icicle-rebind-completion-maps.
+;;     icicle-minibuffer-setup: Don't reset icicle-require-match-flag.
+;;     icicle-apropos-complete: Return the list of candidates.
+;; 2006/01/19 dadams
+;;     Added: icicle(-buffer)-require-match-flag.  Thanks to Mathias Dahl for feedback.
+;;            Use in completing-read, read-file-name, and icicle-minibuffer-setup.
+;;     Re-alphabetized defcustoms.
+;; 2006/01/07 dadams
+;;     Added :link.
+;; 2005/12/31 dadams
+;;     Added: icicle-fix-default-directory.
+;;     icicle-read-file-name: Use icicle-fix-default-directory hack to fix bug.
+;; 2005/12/26 dadams
+;;     Added icicle-sort-case-insensitively.
+;;     Added more parent groups for icicles group.
+;; 2005/12/14 dadams
+;;     icicle-minibuffer-setup: Only save region background when at top level.
+;;     Added: icicle-Completions-frame-at-right-flag.  Use in icicle-candidate-action.
+;;     Added: defvars for font-lock-keyword-face, font-lock-function-name-face.
+;; 2005/12/09 dadams
+;;     Fontify icicle-define* in emacs-lisp-mode.
+;; 2005/12/02 dadams
+;;     Added: icicle-customize-apropos*.  Use in icicle-(redefine|restore)-standard-commands.
+;; 2005/12/01 dadams
+;;     Added: icicle-repeat-complex-command, icicle-redefine-standard-commands-flag,
+;;            icicle-(redefine|restore)-standard-commands.
+;; 2005/11/30 dadams
+;;     Added: icicle-apropos-zippy.
+;;     icicle-apropos-command, icicle-apropos-variable:
+;;       Corrected completing-read for do-all arg.
+;;     icicle-apropos-command, *-apropos-option: My version must not respect apropos-do-all.
+;; 2005/11/29 dadams
+;;     Added: icicle-apropos*.
+;;     icicle-help-on-candidate: Treat plists.  Message "No help" is the default.
+;; 2005/11/25 dadams
+;;     Added: icicle-dabbrev-completion.
+;;     Renamed names with "*Completions*" to use "Completions", for coherence with XEmacs port.
+;; 2005/11/24 dadams
+;;     icicle-mouse-choose-completion: Delete *Completions* window systematically.
+;; 2005/11/21 dadams
+;;     icicle-delete-windows-on: Avoid error Attempt to delete minibuffer or sole ... window.
+;;     icicle-prefix-complete, icicle-apropos-complete-1, icicle-next-candidate:
+;;       Use icicle-delete-windows-on, not delete-window.
+;;     icicle-candidate-set-save: Use map in doc string.
+;;     icicle-compilation-search: Tidied up doc string.
+;;     Use #' for clarity.
+;; 2005/11/20 dadams
+;;     icicle-completing-read: Added treatment of completions that are lists of strings.
+;;     Updated Commentary: new section on completions that are lists.
+;;     Added: icicle-list-join-string, icicle-doc, icicle-fundoc, icicle-vardoc.
+;; 2005/11/15 dadams
+;;     Temporarily removed defadvice of next-history-element for Emacs 22.  Bug reported.
+;;     icicle-minibuffer-prompt-end: Changed from defsubst to defun.
+;; 2005/11/13 dadams
+;;     icicle-mouse-candidate-action: buffer-substring -> buffer-substring-no-properties.
+;;     icicle-completing-read: Bind, don't set, minibuffer-completion-table.
+;;     icicle-buffer*: Use other buffer for DEF, not INIT-VALUE.
+;;     Added: icicle-preselect-init-value-flag, icicle-(add|remove)-buffer-*,
+;;            icicle-read-from-minibuf-nil-default, icicle-buffer-list,
+;;            icicle-select-minibuffer-contents, icicle-completing-p.
+;;     icicle-minibuffer-setup:
+;;       Select minibuf contents if icicle-preselect-init-value-flag.
+;;       Only display *Completions* if icicle-completing-p.
+;;     Advised next-history-element.
+;; 2005/11/11 dadams
+;;     Added: icicle-show-*Completions*-initially-flag, icicle-display-*Completions*.
+;;     icicle-minibuffer-setup: If icicle-show-*Completions*-initially-flag, display it.
+;; 2005/11/09 dadams
+;;     Added: icicle-mouse-candidate-action.  Bind in icicle-rebind-completion-maps.
+;;     icicle-buffer(-other-window): Use buffer-name-history as HIST arg to completing-read.
+;; 2005/11/08 dadams
+;;     Add/remove hook icicle-cancel-*Help*-redirection in icicle-mode, not at top level.
+;;     Removed icicle-reset-icicle-menu-items-alist.
+;;     Reset icicle-menu-items-alist in icicle-execute-menu-command of icicles-menu.el.
+;; 2005/11/06 dadams
+;;     Include minibuffer-local-filename-completion-map.
+;; 2005/11/05 dadams
+;;     icicle-display-candidates-in-*Completions*: Don't try to highlight root if it is "".
+;;     icicle-help-on-candidate:
+;;       Test null, not boundp icicle-menu-items-alist.
+;;       If menu item's command is a lambda, set cand-symb to nil.
+;;     icicle-mode: Use icicle-reset-icicle-menu-items-alist on minibuffer-exit-hook.
+;;     Added: icicle-reset-icicle-menu-items-alist.
+;;     Added defvar for icicle-menu-items-alist.
+;;     Added byte-compiler comments and defvars to quiet byte-compile.
+;; 2005/11/04 dadams
+;;     icicle-display-candidates-in-*Completions:
+;;       Bug fix - use (functionp minibuffer-completion-table), not (icicle-file-name-input-p).
+;; 2005/11/03 dadams
+;;     Added: icicle-filter-wo-input and vars icicle-must-*, icicle-extra*, icicle-buffer-*,
+;;            icicle-buffer-config*, icicle-buffer-sort*.
+;;     icicle-unsorted-*: Use icicle-filter-wo-input and icicle-extra-candidates.
+;;     Added Commentary section Global Filters.
+;;     icicle-buffer* commands: Added filter bindings.
+;;     icicle-define(-file)-command: Minor bug fix: Ensure buffer is live before switching back.
+;; 2005/11/01 dadams
+;;     Added: icicle-must(-not)-match-regexp.  Use in icicle-unsorted-*-candidates.
+;; 2005/10/31 dadams
+;;     Added: icicle-use-default-as-init-value-flag.  Use in completing-read.
+;;     icicle-find-file*: Minor bug fix - REQUIRE-MATCH should be nil.
+;; 2005/10/29 dadams
+;;     icicle-display-candidates-in-*Completions: Minor bug fix - wrap in save-window-excursion.
+;;     icicle-minibuffer-contents-from-minibuffer:
+;;       Minor bug fix - do nothing if file & user erased minibuffer.
+;;     Menu-bar menus:
+;;       Enable Icicles menu items only in Icicle mode.  Put search
+;;       stuff on Search menu, if available.   Use "[Icy]" prefix for
+;;       Icicles items in menus other than "Icicles".
+;; 2005/10/28 dadams
+;;     Added: icicle-define-file-command.
+;;            Use it to define icicle-delete-file, icicle-find-file*.
+;;     icicle-(next|previous)-(apropos|prefix)-candidate-action:
+;;       Do action before moving to next|prev.
+;;     icicle-candidate-action: Raise *Completions* frame, to keep it on top.
+;; 2005/10/27 dadams
+;;     Added: icicle-define-command, icicle-find-file*, select-frame-set-input-focus.
+;;     Redefined using icicle-define-command:
+;;       icicle-bookmark, icicle-buffer*, icicle-color-theme, icicle-delete-file,
+;;       icicle-find-file*, icicle-font, icicle-frame-*, icicle-recent-file*.
+;;     icicle-all-candidates-action: Report failures, not successes.  Use error msg.
+;;     Added Commentary sections: Special-Character Conflicts, Defining Icicles Commands.
+;;     Commentary section Act on All Candidates: Added delete-one-or-more-files example.
+;;     Added icicle-find-file* to menu-bar menus.
+;;     Inactivated top-level menu items when minibuffer is active.
+;;     Renamed: icicle-delete-file-1 to icicle-delete-file-or-directory.
+;; 2005/10/25 dadams
+;;     Thx to Lennart Borgman for suggestion about select-frame-set-input-focus.
+;; 2005/10/24 dadams
+;;     icicle-search:
+;;       1) Bug fix - need to have mouse-choose-completion set icicle-candidate-nb.
+;;       2) Show error message.
+;;     Default value of icicle-candidate-nb is now nil, not -1.
+;;     Added: icicle-mouse-choose-completion, icicle-nb-of-candidate-in-*Completions*.
+;;     icicle-move-to-(next|previous)-completion, icicle-increment-cand-nb+signal-end:
+;;       Reset candidate number to 0 if nil.
+;;     icicle-(redefine|restore)-std-completion-fns: Use icicle-mouse-choose-completion.
+;; 2005/10/23 dadams
+;;     Added: icicle-mode-map.
+;;     icicle-(bind|restore)-completion-keys: Updated menu-bar menu.
+;;     icicle-compilation-search: Error if not in a compilation buffer.
+;; 2005/10/21 dadams
+;;     icicle-remove-duplicates: redefined.
+;; 2005/10/18 dadams
+;;     icicle-file-name-input-p doc string:
+;;       Mention why don't use minibuffer-completing-file-name.
+;; 2005/10/16 dadams
+;;     Added: icicle-compilation-search, icicle-search-hook.
+;;     icicle-search: Run icicle-search-hook.  Added optional sit-for-period arg.
+;;     icicle-mode: Added list of top-level commands to doc string.
+;;     icicle-scroll-or-update-*Completions*: Added msg arg - only display msg if don't scroll.
+;; 2005/10/14 dadams
+;;     Allow for multisets of candidates.
+;;     Added: icicle-search, icicle-completion-nospace-flag, icicle-candidate-nb,
+;;            icicle-filter-alist, icicle-increment-cand-nb+signal-end.
+;;     Commentary: Updated for icicle-search.
+;;     icicle-next-candidate: Major rewrite.
+;;       Uses icicle-candidate-nb, icicle-increment-cand-nb+signal-end,
+;;            icicle-move-to-next-completion.
+;;     Use icicle-completion-nospace-flag in calls to all-completions.
+;;     icicle-previous-(apropos|prefix)-candidate,
+;;     icicle-(next|previous)-(apropos|prefix)-candidate-action: Added optional arg.
+;;     icicle-apropos-complete-1, icicle-next-candidate, icicle-recompute-candidates:
+;;       Added *-action commands to memq test.
+;;     icicle-move-to-next-completion: Added optional no-minibuffer-follow-p arg.
+;;     icicle-scroll-or-update-*Completions*: Update display even if handle-switch-frame.
+;; 2005/10/12 dadams
+;;     Added: icicle-redefine-std-completion-fns,
+;;            icicle-restore-std-completion-fns,
+;;            icicle-delete-windows-on, icicle-frames-on.
+;;     icicle-mode: Use icicle-redefine-std-completion-fns,
+;;                  icicle-restore-std-completion-fns.
+;;     Renamed to use icicle- prefix: choose-completion-string,
+;;       completing-read, completion-setup-function, exit-minibuffer,
+;;       minibuffer-complete-and-exit, read-file-name,
+;;       switch-to-completions.  Added these and also old- versions.
+;;     icicle-history: Treat file names also.
+;;     remove-windows-on -> icicle-delete-windows-on.
+;; 2005/10/11 dadams
+;;     Added: icicle-history, icicle-scroll-or-update-*Completions*,
+;;            icicle-undo-std-completion-faces.
+;;     Minor bug fixes:
+;;       icicle-remove-dots: Also match against "." and ".." (lack of slash in Emacs 21+).
+;;       icicle-save-or-*: Don't reset to last input if icicle-last-completion-candidate is "".
+;;                         Update icicle-last-completion-candidate also to use current input.
+;;       Reset icicle-last-input in icicle-minibuffer-setup, not in
+;;         completing-read and read-file-name.
+;;       icicle-display-candidates-in-*Completions*, icicle-next-candidate:
+;;         Put candidate in consp before applying predicate.
+;;       icicle-recompute-candidates: Don't recompute unless icicle-last-completion-command.
+;;       icicle-retrieve-last-input: Use icicle-current-input, not icicle-last-input.
+;;       icicle-self-insert: Update icicle-current-input and set this-command to
+;;                           icicle-apropos-complete.
+;;       icicle-apropos-complete: Use error-message-string.
+;;       icicle-apropos-complete-1:
+;;         Protect icicle-file-directory-p with
+;;         icicle-file-name-input-p.  Unconditionally update
+;;         icicle-last-completion-command.
+;;     Moved undoing of std completion faces to icicle-mode.
+;;     Use icicle-scroll-or-update-*Completions* in icicle-candidate-set-1.
+;; 2005/10/06 dadams
+;;     icicle-prefix-complete, icicle-apropos-complete-1:
+;;       Removed vestigial slash cruft - should have been removed in 2005/09/01 fix.
+;;     Added: icicle-remove-dots.  Use in icicle-save-or-restore-input.
+;; 2005/10/05 dadams
+;;     icicle-msg-maybe-in-minibuffer: use format-string arg.
+;; 2005/10/04 dadams
+;;     Replace use of minibuffer-completion-help by
+;;       icicle-apropos-complete.
+;;     Added: icicle-recent-file*, icicle-toggle-ignored-extensions,
+;;            icicle-update-completions, icicle-msg-maybe-in-minibuffer,
+;;            icicle-saved-ignored-extensions.
+;;     Bound icicle-toggle-*.
+;;     icicle-toggle-sorting: Use icicle-update-completions, icicle-msg-maybe-in-minibuffer.
+;;     icicle-sort-and-strip-ignored:
+;;       icicle-ignored-extensions-regexp nil => nothing is ignored.
+;;     Reorder key bindings, so prompt shows S-tab, not S-iso-lefttab.
+;;     icicle-next-candidate: Fixed code to highlight candidate in *Completions*: restriction.
+;; 2005/10/03 dadams
+;;     Regexps can now use backslash (it is no longer a directory separator on MS Windows).
+;;       icicle-minibuffer-contents-from-minibuffer, icicle-file-name-directory-w-default:
+;;         Escape backslash, so not used as directory separator on MS Windows.
+;;       Added: icicle-apropos-complete-1, icicle-file-name-nondirectory.
+;;       icicle-apropos-complete: Use icicle-apropos-complete-1.
+;;                                Treat regexp error via message.
+;;       Use icicle-file-name-nondirectory everywhere, instead of file-name-nondirectory.
+;;     Can now use "?" for regexps; it no longer shows completion list.
+;;     Do icicle-update-ignored-extensions-regexp inside icicle-minibuffer-setup.
+;;     Added and bound: icicle-retrieve-last-input.
+;;     Updated icicle-completion-help-string with recent bindings.
+;;     Renamed: icicle-last-command to icicle-last-completion-command.
+;;              icicle-candidate-set-restore to icicle-candidate-set-retrieve.
+;; 2005/10/01 dadams
+;;     Added: icicle-candidate-set-(define|restore|swap).
+;;     Changed binding of icicle-candidate-set-save to C->.
+;;     Bound new commands.
+;; 2005/10/01 dadams
+;;     Major rewrite to add set operations: complement, difference, union, intersection.
+;;       Added: icicle-completion-candidates, icicle-current-input, icicle-candidate-set-*,
+;;              icicle-set-*, icicle-save-or-restore-input, icicle-recompute-candidates.
+;;       Bound icicle-candidate-set*.
+;;       Added Commentary for Sets of Completion Candidates.
+;;       icicle-(apropos|prefix)-complete: Update icicle-completion-candidates, only as needed.
+;;       icicle-next-candidate:
+;;         Reverse candidates only if switched to opposite-direction command of same type.
+;;         Likewise, for refresh of *Completions*.
+;;         Protect put-text-property for root (e.g. no match for complement).
+;;       icicle-(apropos|prefix)-complete,
+;;       icicle-prefix-word-complete, icicle-next-candidate: Use icicle-completion-candidates.
+;;       icicle-all-candidates-action: Use icicle-completion-candidates, not *-apropos-complete.
+;;       icicle-display-candidates-in-*Completions*:
+;;         Removed first arg (candidates).  Update icicle-completion-candidates.
+;;    icicle-all-candidates-action:
+;;      Use icicle-completion-candidates, so act on completions of either kind.
+;; 2005/09/30 dadams
+;;     Commented out resetting of minibuffer-completion-table to nil for icompletion.
+;;     Thx to Andrey for bug report on M-x M-r problem.
+;; 2005/09/27 dadams
+;;     icicle-(bind|restore)-completion-keys: Bound [S-iso-lefttab] like [S-tab].
+;; 2005/09/26 dadams
+;;     Bug fix: Changed "\C-!"  to [(control ?!)] (others similarly).
+;;     Bound [S-iso-lefttab] like [S-tab].
+;; 2005/09/16 dadams
+;;     Added: icicle-all-candidates-action, icicle-delete-file*,
+;;     icicle-rebind-completion-maps: Bound icicle-all-candidates-action to C-!.
+;;     icicle-(apropos|prefix)-complete: Return candidates list.
+;;     icicle-bookmark, icicle-buffer*, icicle-color-theme,
+;;     icicle-font, icicle-frame*: Return t for success, nil for failure.
+;;     Commentary: Added section Choose All Completion Candidates.
+;; 2005/09/14 dadams
+;;     icicle-rebind-completion-maps: Bound TAB and S-TAB for navigation.
+;;     icicle-move-to-(next|previous)-completion, icicle-(next|previous)-line: Wrap around.
+;; 2005/09/13 dadams
+;;     Major rewrite of file treatment, to treat directory candidates similarly to files.
+;;     Added: icicle-default-directory, icicle-file-directory-p, icicle-sort-function,
+;;            icicle-toggle-sorting, toggle-icicle-sorting.
+;;     Use icicle-file-directory-p everywhere, except choose-completion-string.
+;;     Removed: icicle-nondirectory-*.
+;;     icicle-next-candidate: If not icicle-cycle-into-subdirs-flag, then use relative
+;;                            file/dir name, not nondirectory part.
+;;     icicle-(apropos|prefix)-complete:
+;;       Set icicle-default-directory if sole completion is a subdirectory.
+;;     icicle-sort-and-strip-ignored: Removed optional arg and treatment of subdirs.
+;;     icicle-next-(apropos|prefix)-candidate, icicle-(apropos|prefix)-complete:
+;;       Don't treat icicle-cycle-into-subdirs-flag here.
+;;     icicle-(apropos|prefix)-complete, icicle-next-candidate:
+;;       Set icicle-default-directory, if directory candidate.
+;;     icicle-minibuffer-setup: Set icicle-default-directory.
+;;     icicle-apropos-complete: Different message if icicle-apropos-icompleting-p.
+;;     icicle-sort-dirs-last: Treat other kinds of candidates, besides files and dirs.
+;;     Commentary and doc strings: Updated for icicle-sort-function, icicle-cycle-into-subdirs.
+;;     Let delete-selection mode work with icicle-self-insert.
+;;     icicle-display-candidates-in-*Completions*: Make *Completions* read-only.
+;; 2005/09/09 dadams
+;;     choose-completion-string: bug fix for Emacs 21.3.1 - use Emacs 20 version for 21.3.1.
+;; 2005/09/08 dadams
+;;     completion-setup-function: bug fix for Emacs 21.3.1 - use Emacs 20 version for 21.3.1.
+;;     Added: icicle-remap, icicle-unmap, icicle-(bind|restore)-completion-keys.
+;;     completing-read: Do not append suffix if not in Icicle mode.
+;;     icicle-rebind-completion-maps:
+;;       Clean-up.  Use icicle-(bind|restore)-completion-keys.
+;;       Don't (suppress-keymap completion-list-mode-map).
+;; 2005/09/06 dadams
+;;     Provided apropos icompletion.
+;;     Added: icicle-self-insert, icicle-incremental-completion-flag,
+;;            icicle-apropos-icompleting-p.
+;;     icicle-apropos-complete: Respect icicle-apropos-icompleting-p.
+;;     Commentary: Updated Icompletion and Customization sections.
+;;                 Added Apropos Icompletion.
+;;     Changed default value of icicle-word-completion-key to M-SPC.
+;;     icicle-rebind-completion-maps:
+;;       Bind icicle-self-insert. Use self-insert for SPC.
+;;       Updated icicle-completion-help-string.  Treat menu-bar menu for the minibuffer.
+;;     completion-setup-function: Add instruction2 only when icicle-mode.
+;;     icicle-display-candidates-in-*Completions*: Use save-restriction.
+;;     icicle-minibuffer-contents-from-minibuffer:
+;;       Allow for mixing $ of environment vars with $ of regexps.
+;; 2005/09/02 dadams
+;;     Added: icicle-bookmark, icicle-buffer(-other-window), icicle-candidate-action,
+;;            icicle-candidate-action-fn, icicle-color-theme(s), icicle-font,
+;;            icicle-frame-(b|f)g.
+;;     Renamed: icicle-(next|previous)-(apropos|prefix)-*-help to
+;;              icicle-(next|previous)-(apropos|prefix)-*-action.
+;;     icicle-(apropos|prefix)-complete: Set icicle-last-completion-candidate.
+;;     In renamed functions:  Use icicle-candidate-action, not icicle-help-on-candidate.
+;;     icicle-rebind-completion-maps: Bound C-o to icicle-candidate-action.
+;;     Added Commentary section on actions on candidates.
+;;     icicle-move-to-next-completion: Test line num, not char position (fix).
+;;     icicle-previous-line: 3 or 4, not 4 or 5 (fix).
+;; 2005/09/01 dadams
+;;     Fixed major bug: file-name completion did not work at all in non-MS Windows!
+;;       icicle-file-name-(apropos|prefix)-candidates:
+;;         Removed code for case where input starts with "/".
+;;       icicle-nondirectory-file-name-(apropos|prefix)-candidates:
+;;         Removed code for case where input starts with "/".  Bind default-directory.
+;;       icicle-(apropos|prefix)-complete: Treat case when icicle-cycle-into-subdirs-flag = nil.
+;;     icicle-next-candidate: Took out code that moved point when line is too long.
+;;     icicle-minibuffer-setup: Reset icicle-prompt.
+;; 2005/08/23 dadams
+;;     Added: icicle-help-on-candidate, icicle-cancel-*Help*-redirection,
+;;            icicle-(previous|next)-(prefix|apropos)-candidate-help.  Bound them all.
+;;     icicle-rebind-completion-maps:
+;;       Bound icicle-help-on-candidate, icicle-(previous|next)-(prefix|apropos)-candidate-help.
+;; 2005/08/22 dadams
+;;     Unconditionally require cl.el when compile (because of case).
+;; 2005/08/19 dadams
+;;     Renamed icicle-cursor-position-in-candidate to icicle-point-position-in-candidate.
+;;     Added: icicle-mark-position-in-candidate, icicle-minibuffer-prompt-end.
+;;     icicle-place-cursor: Position both point and mark.
+;;     icicle-point-position-in-candidate: Change values from bob, eob to input-start/end.
+;;     Removed: icicle-select-rest-of-completion-flag.
+;;     Use inequality test on point and mark.
+;; 2005/08/16 dadams
+;;     Minbuffer messages: Differentiate prefix from apropos completion.
+;;     completing-read, read-file-name: Append icicle-prompt-suffix for Emacs 20 (oversight).
+;; 2005/08/15 dadams
+;;     Bug fix: Only use face-spec-reset-face if target faces defined.
+;;     read-file-name: bug fix:
+;;       Use condition-case to get the correct number of args for
+;;       old-read-file-name. Thx to Mathias Dahl for both bug reports.
+;; 2005/08/14 dadams
+;;     icicle-place-cursor: Narrow region to exclude minibuffer-prompt
+;; 2005/08/13 dadams
+;;     Add regexp support (removed it when introduced highlighting).
+;;       icicle-next-candidate: Added regexp-p arg.  Use in icicle-next-apropos-candidate.
+;;       icicle-place-cursor: Use regexp search.  For root-start, go to match-beginning.
+;;       icicle-unsorted-file-name-apropos-candidates: Don't use regexp-quote.
+;;     icicle-switch-to-*Completions*:
+;;       Search in restriction of mouse-face zone; repeat.
+;;       Treat file case (use nondirectory part).  Bind case-fold-search.
+;;     Protect (aref  0) against empty string.
+;;     member -> memq, for symbols.
+;; 2005/08/12 dadams
+;;     Added: icicle-word-completion-key, icy-mode, icicle-insert-a-space.
+;;     icicle-rebind-completion-maps: Use icicle-word-completion-key and icicle-insert-a-space.
+;;     completing-read, icicle-rebind-completion-maps: Corrected bindings in doc string.
+;; 2005/07/29 dadams
+;;     Added: icicle-change-region-background-flag, icicle-increment-color-value,
+;;            icicle-region-background, icicle-saved-region-background,
+;;            icicle-restore-region-face.
+;;     Added icicle-restore-region-face to minibuffer-exit-hook.
+;;     Require hexrgb.el.
+;;     Removed: icicle-select-rest-of-completion.
+;;     icicle-minibuffer-setup:
+;;       Save icicle-saved-region-background and use icicle-region-background.
+;; 2005/07/28 dadams
+;;     Added: icicle-*Completions*-instruction-*.
+;;     completion-setup-function:
+;;       Use icicle-*Completions*-instruction-*.
+;;       Remove ? from instruction2.  Put both instr on same line.
+;;       Use put-text-property, not *-w-face*.
+;;     ------
+;;     Move all completion stuff here, from simple+.el:
+;;       choose-completion-string, completion-setup-function, switch-to-completions.
+;;     Wrap *Completions* window deletion in save-selected-window.
+;;     Added icicle-prefix-word-complete, and bound it to SPC.
+;;     completion-setup-function:
+;;       Renamed icicle-completing-read-prompt-suffix to icicle-prompt-suffix.
+;; 2005/07/27 dadams
+;;     Renamed: icicle-completing-read-prompt* to icicle-prompt*.
+;;     Added: read-file-name, face
+;;            icicle-completing-read-prompt-suffix, icicle-remove-property,
+;;            icicle-select-rest-of-completion (simple, for now).
+;;     completing-read: Apply faces to prompt.
+;;     icicle-place-cursor: Use icicle-select-rest-of-completion.
+;;     Added (if icicle-mode (icicle-mode 1)) at end.
+;;     Reworded Commentary in terms of "input completion", not just completing-read.
+;; 2005/07/26 dadams
+;;     rebind-minibuffer-completion-maps: Minor bug fix.
+;;     icicle-mode: Added " Icy" to mode line.
+;;     Wrapped Emacs 21 version of icicle-mode (with define-minor-mode) in (eval (quote...)),
+;;       so byte-compiling in Emacs 20 will produce a *.elc that works in Emacs 21.
+;; 2005/07/25 dadams
+;;     Added: icicle-mode, icicle-*-hook, icicle-minibuffer-setup, icicle-activate-mark.
+;;     rebind-minibuffer-completion-maps:
+;;       Restore bindings when exit Icicle mode.
+;;       Added argument.  Pick up everything bound to help-command.
+;;       Message only when mode is turned on.
+;; 2005/07/24 dadams
+;;     Now leave region from end of root to end of completion, so you can easily replace it,
+;;       especially if you use delete-selection mode.  (Suggestion by Lennart Borgman.)
+;;     Added: icicle-select-rest-of-completion-flag.
+;;     icicle-place-cursor: Create active region if icicle-select-rest-of-completion-flag
+;;     icicle-completion-help: Removed icicle-abort-minibuffer-input.
+;;     icicle-abort-minibuffer-input: Removed obsolete code & comment on icomplete-inhibit.
+;; 2005/07/22 dadams
+;;     Major fixup: Treat file and directory names well, respect standard user options, more.
+;;     Renamed:
+;;       icicle-(next|previous)?-completion-candidate to icicle-*-prefix-candidate(s),
+;;       icicle*filename* to icicle*file-name*,
+;;       icicle-descend-into-subdirs to icicle-cycle-into-subdirs-flag.
+;;     Added: icicle-file-name-apropos-candidates, icicle-file-name-directory-w-default,
+;;            icicle-file-name-input-p, icicle-file-name-prefix-candidates,
+;;            icicle-nondirectory-file-name-apropos-candidates,
+;;            icicle-nondirectory-file-name-prefix-candidates,
+;;            icicle-sort-dirs-last, icicle-unsorted-apropos-candidates,
+;;            icicle-unsorted-file-name-apropos-candidates,
+;;            icicle-unsorted-file-name-prefix-candidates, icicle-unsorted-prefix-candidates,
+;;            icicle-last-command.
+;;     Respect insert-default-directory and completion-auto-help.
+;;     Use minibuffer-message instead of message.
+;;     Commentary: Added Customization & Tips section.
+;;     completing-read: Save icicle-last-input.  Reset icicle-nb-of-other-cycle-candidates.
+;;     icicle-next-*-candidate: Branch to file-specific functions.
+;;     icicle-*-candidates: Use icicle-unsorted-*-candidates.
+;;     icicle-next-candidate:
+;;       Delete *Completions* window if no candidates.
+;;       Use icicle-file-name-directory, not file-name-directory.
+;;     icicle-minibuffer-contents-from-minibuffer: Use substitute-in-file-name.
+;;     icicle-*-complete:
+;;       Treat slashed file names (e.g. "/foo").
+;;       Use icicle-file-name-*-candidates, icicle-file-name-directory-w-default for files.
+;;       Added messages [No completion], [Sole completion], [Complete, but not unique].
+;;       Use icicle-last-command for repetition test. And set it.
+;;     icicle-rebind-completion-maps: Updated icicle-completion-help-string and message.
+;; 2005/07/21 dadams
+;;     icicle-apropos-candidates: Use, not apropos, but delete-if-not on string-match.
+;;                                Treat files too.
+;;     Removed icicle-intersection.
+;;     Added: icicle-descend-into-subdirs.
+;;     icicle-sort-and-strip-ignored: Use icicle-descend-into-subdirs.  Don't use "." and "..".
+;;     icicle-next-candidate:
+;;       File names w/o dir.
+;;       Use regexp-quote on root for underlining file-name root.
+;;       Insert directory name for file.
+;;     icicle-place-cursor: Search past dir, then search for file-name w/o dir.
+;;     icicle-prefix-complete, icicle-apropos-complete,
+;;     icicle-switch-to-*Completions*: Use icicle-minibuffer-contents-from-minibuffer.
+;;     icicle-prefix-complete, icicle-apropos-complete: Insert dir when single candidate.
+;;     icicle-display-candidates-in-*Completions*: Underline file-name w/o dir.
+;; 2005/07/20 dadams
+;;     icicle-next-candidate, *-display-candidates-in-*Completions*: Use set-buffer-modified-p.
+;;     icicle-next-candidate: Use ding when hit end of cycle.
+;;     Added: icicle-cursor-position-in-candidate, icicle-place-cursor.
+;;            Use in icicle-next-candidate to position cursor.
+;;     Added: defgroup icicles.
+;; 2005/07/19 dadams
+;;     Initialize icicle-ignored-*.
+;;     Added: icicle-nb-of-other-cycle-candidates, icicle-minibuffer-contents-from-minibuffer.
+;;     completing-read: Reset icicle-last-completion-candidate to nil.
+;;     icicle-next-candidate:
+;;       Use icicle-minibuffer-contents-from-minibuffer.
+;;       Save icicle-nb-of-other-cycle-candidates for icomplete-completions (icomplete+).
+;;       Use copy of "next" string since change its text properties.
+;;       Use regexp-quote for underlined root.
+;;       Use put-text-property, so works in Emacs 20.
+;;       Update *Completions*, even if last command is repeated.
+;;     icicle-*-complete: Complete rewrite.
+;;     icicle-display-candidates-in-*Completions*: Do even if last command is repeated.
+;; 2005/07/18 dadams
+;;     icicle-display-*: Highlight only first occurrence in each candidate.
+;;     icicle-next-candidate: Use completion-ignore-case.
+;; 2005/07/17 dadams
+;;     Treat file names also.
+;;     Added: icicle-delete-if*, and use instead of delete-if-*.  Removed require cl.el.
+;;     Added: icicle-ignored-extensions*, icicle-sort-and-strip-ignored,
+;;            icicle-filename-input-p, icicle-update-ignored-extensions-regexp,
+;;            icicle-prefix-complete.  Bound icicle-prefix-complete.
+;;     Use icicle-update-ignored-extensions-regexp as minibuffer-setup-hook.
+;;     icicle-*-candidates: Use icicle-sort-and-strip-ignored.
+;;     icicle-next-candidate, icicle-display-candidates-in-*Completions*:
+;;       Don't use predicate on file-name candidates (icicle-filename-input-p).
+;;     icicle-next-candidate:
+;;       Use read-file-name-completion-ignore-case (Emacs 22) and file-name-nondirectory.
+;;     icicle-apropos-complete: Return t/nil. Treat single candidate as no-op.
+;;     Reset std completions-* faces, so they don't interfere with apropos highlighting.
+;; 2005/07/16 dadams
+;;     Added: icicle-display-*, icicle-apropos-complete.
+;;     Use icicle-display-* in icicle-next-candidate and icicle-apropos-complete.
+;;     Bound icicle-apropos-complete to S-tab in completion maps.
+;;     icicle-switch-to-*Completions*:
+;;       Move to start of candidate.  Highlight candidate, not regexp.
+;;     icicle-next-candidate: Underline the root that was completed.
+;;     Added: faces icicle-root-highlight-*.
+;;     Removed: faces: icicle-completion-help*.
+;;     Removed (not used): require of strings.el.
+;;     Commentary: Added Nutshell View.
+;; 2005/07/15 dadams
+;;     Renamed: icicle-completion-help+ to icicle-completion-help.
+;;     Replaced: icicle-delete-lines by icicle-erase-minibuffer.
+;;     icicle-next-candidate:
+;;       Wrapped display-* and re-search-forward in condition-case.  Use icicle-place-overlay.
+;;     Changed icicle-completion-help bindings to [f1].
+;;     Added: icicle-*-line, icicle-switch-to-*, icicle-move-to-*-completion,
+;;            icicle-current-completion-in-*Completions*, icicle-place-overlay.
+;;     Added bindings for icicle-*-line, icicle-switch-to-*, icicle-move-to-*.
+;;     Bound q to icicle-abort-minibuffer-input in completion-list-mode-map.
+;;     icicle-completing-read-prompt-suffix: Mention both [f1] and ?.
+;;     Removed: icicle-fit-frame.
+;;     Commentary: Added How...Improves...(5).  Updated Key Bindings.
+;; 2005/07/14 dadams
+;;     icicle-next-candidate:
+;;       Update *Completions*, if displayed, to reflect current
+;;       candidates, but don't do it if this-command = last-command.
+;;       Reverse list as needed, to keep same order.   Ensure current
+;;       *Completions* choice shows in window (recenter as needed).
+;;       For highlighting: Search with re-search-forward to be sure to get the right one.
+;;       Took test for presence of predicate out of loop.
+;;     Commentary: Added Note on pop-up-frames = t.
+;; 2005/07/13 dadams
+;;     Rewrote icicle-apropos-candidates.
+;;     Added: icicle-intersection.
+;; 2005/07/12 dadams
+;;     Added: icicle-(next|previous)-apropos-candidate, icicle-next-candidate,
+;;            icicle-apropos-candidates, icicle-completion-candidates.
+;;     Bound: icicle-(next|previous)-apropos-candidate.
+;;     Renamed: icicle-completion-help-(title-)face: Removed "-face".
+;;     icicle-next-completion-candidate: Redefined to use icicle-next-candidate.
+;;     icicle-rebind-completion-maps: Updated text to mention apropos completion.
+;;     icicle-completion-help+: Use icicle-abort-minibuffer-input, not abort-recursive-edit.
+;; 2005/07/10 dadams
+;;     First version of icicles.el (previously called elect-mbuf.el).
+;;     Renamed: minibuffer-completion-help-string to icicle-completion-help-string,
+;;              completing-read-prompt to icicle-completing-read-prompt,
+;;              completing-read-prompt-suffix to icicle-completing-read-prompt-suffix,
+;;              mbuf-completion-help-face to icicle-completion-help-face,
+;;              mbuf-completion-help-title-face to icicle-completion-help-title-face,
+;;              minibuffer-last-default to icicle-last-completion-candidate,
+;;              command-calling-for-completion to icicle-cmd-calling-for-completion,
+;;              minibuffer-completion-help+ to icicle-completion-help+,
+;;              abort-minibuffer-input to icicle-abort-minibuffer-input,
+;;              next-default-input to icicle-next-completion-candidate,
+;;              previous-default-input to icicle-previous-completion-candidate,
+;;              rebind-minibuffer-completion-maps to icicle-rebind-completion-maps,
+;;     Added: minibuffer-complete-and-exit, icicle-fit-frame, icicle-last-input.
+;;     Moved delete-lines here from and renamed to icicle-delete-lines.
+;;     Removed: mod+ (unused).
+;;     icicle-completion-help+: Use *Help*, not *Completions*.  Don't show completions.
+;;     icicle-next-completion-candidate: Use insert, not insert-string.
+;;     icicle-rebind-completion-maps: Made it interactive.
+;; 2005/07/09 dadams
+;;     Removed: buffer-alist (not used).
+;; 2005/05/15 dadams
+;;     Renamed: flash-ding-minibuffer-frame to 1on1-flash-ding-minibuffer-frame.
+;; 2005/05/10 dadams
+;;     Hacked completing-read to remove *Completions* window at end if require-match is non-nil.
+;;       (Don't know why/when this became a problem.)
+;; 2004/09/21 dadams
+;;     Updated to work in Emacs 21 (and 20):
+;;       next-default-input uses delete-minibuffer-contents for 21, but erase-buffer for 20.
+;;       minibuffer-completion-help+: bind inhibit-read-only to t around erase-buffer.
+;; 2001/01/10 dadams
+;;     Protected remove-windows-on via fboundp.
+;; 1999/09/03 dadams
+;;     Added: mbuf-completion-help-face, mbuf-completion-help-title-face.
+;;     minibuffer-completion-help+: Use mbuf-*-face's instead of hard-coding.
+;;     minibuffer-completion-help-string, completing-read-prompt-suffix: defconst -> defvar.
+;; 1999/08/26 dadams
+;;     Protected faces via boundp.
+;; 1999/04/13 dadams
+;;     Bound delete-lines to M-S-DEL and M-S-backspace.
+;; 1999/03/17 dadams
+;;     protect calls with test fboundp.
+;; 1996/04/26 dadams
+;;     Put escaped newlines on long-line strings.
+;; 1996/03/26 dadams
+;;     minibuffer-completion-help+: concat -> concat-w-faces (color).
+;; 1995/12/20 dadams
+;;     exit-minibuffer: Iconify *Completion* frame.
+;; 1995/12/15 dadams
+;;     abort-minibuffer-input: Reset minibuffer-completion-table to avoid icompletion.
+;;     Defined replacement exit-minibuffer to do the same as #1.
+;; 1995/12/01 dadams
+;;     abort-minibuffer-input: Incorporated delete-selection-mode code
+;;     rebind-minibuffer-completion-maps:
+;;       Added C-g bindings for minibuffer-local-map, minibuffer-local-ns-map,
+;;         minibuffer-local-isearch-map.
+;; 1995/10/25 dadams
+;;     Put defvar of minibuffer-completion-help-string after do
+;;       rebind-minibuffer-completion-maps, so its doc string gives bindings.
+;; 1995/10/24 dadams
+;;     Mention ESC-TAB completion in completing-read.
+;; 1995/10/17 dadams
+;;     Let minibuffer use ESC-TAB for completion (Lisp symbols etc.)
+;;     completing-read: Minibuffer adopts current buffer's ESC-TAB binding.
+;;     Added command-calling-for-completion to memorize current command (done in
+;;       completion-setup-hook).
+;; 1995/09/12 dadams
+;;     Added abort-minibuffer-input.
+;;     Define C-g as abort-minibuffer-input in completion-list-mode-map and
+;;       minibuffer-local-* maps.
+;;     No self-insertion for completion-list-mode-map.
+;; 1995/08/16 dadams
+;;     next-default-input: Fixed bug - skip repeated alist entries.
+;; 1995/08/10 dadams
+;;     Rewrote minibuffer-completion-help+: Provide help even if no completions.
+;;     So, added minibuffer-completion-help-string.
+;;     `?' defined correctly for minibuffer-local-must-match-map.
+;; 1995/08/08 dadams
+;;     next-default-input: error msg: no hard coding of key seq.
+;; 1995/08/02 dadams
+;;     Major rewrite.
+;;       No reminders in prompts.  Added minibuffer-completion-help+ to provide help info for
+;;         *Completions*.
+;;     Log for functions that were previously in simple+.el:
+;;       choose-completion-string, completion-setup-function, switch-to-completions.
+;; 2005/07/28 dadams
+;;     completion-setup-function:
+;;       Renamed icicle-completing-read-prompt-suffix to icicle-prompt-suffix.
+;; 2005/07/15 dadams
+;;     choose-completion-string, completion-setup-function: Updated for Emacs 21+.
+;; 2005/07/10 dadams
+;;     Renamed: command-calling-for-completion to icicle-cmd-calling-for-completion.
+;; 2004/09/21 dadams
+;;     Only redefine choose-completion-string if prior to Emacs 21.
+;; 1999/03/17 dadams
+;;     choose-completion-string:
+;;       Added doc string.  Updated to correspond to Emacs 34.1.
+;;     completion-setup-function: diff prompt setups.  face1 & face2 tests.
+;;     Added: switch-to-completions.
+;; 1996/04/26 dadams
+;;     Put escaped newlines on long-line strings.
+ 
+;;;(@* "CHANGE LOG FOR `icicles-cmd.el'" - Deprecated file)
+;;
+;; 2009/05/22 dadams
+;;     Split in two: icicles-cmd1.el, icicles-cmd2.el.  File too large to upload to Emacs Wiki.
+;; 2009/05/20 dadams
+;;     Renamed: *-Info-build-node-completions-fix-* to *-Info-build-node-completions-1.
+;;     icicle-Info-goto-node: Plain C-u now prepends Info file name to candidates.
+;;     icicle-Info-goto-node-1: swapped arg order in call to Info-goto-node nodename (bug fix).
+;;     icicle-Info-read-node-name, icicle-Info-build-node-completions(-1):
+;;       Added optional arg INCLUDE-FILE-P.
+;; 2009/05/11 dadams
+;;     icicle-complete-keys: Use icicle-local-keys-first-p as icicle-sort-function.
+;;                           Bind icicle-hist-cands-no-highlight to ("..").
+;;     icicle-keys+cmds-w-prefix: Propertize candidate "..".
+;;     icicle-dabbrev-completion: Use icicle-upcase.
+;; 2009/05/10 dadams
+;;     Added: icicle-search-(defs|lines|paragraphs|sentences|pages).
+;;     icicle-plist: Pretty-print, unless negative prefix arg (or Emacs 20).
+;;     icicle-search-regexp-scan: Fix to pick up candidate at eob: removed (not (eobp)) test.
+;; 2009/05/05 dadams
+;;     icicle-find-file-(absolute|in-tags-table)(-other-window),
+;;       icicle-(recent|locate)-file(-other-window), icicle-describe-option-of-type,
+;;       icicle-(vardoc|fundoc|doc|plist), icicle-goto-global-marker:
+;;         Remove quote before face name, for icicle-candidate-properties-alist value.
+;;     icicle-buffer(-other-window|-list), icicle-kill-buffer, icicle-choose-candidate-of-type:
+;;       Bind completion-ignore-case, based on read-buffer-completion-ignore-case.
+;; 2009/05/01 dadams
+;;     Added: icicle-shell-command-on-file.
+;;     Bind both icicle-all-candidates-list-alt-action-fn and icicle-candidate-alt-action-fn
+;;       to icicle-alt-act-fn-for-type for appropriate type - same commands as for 2009/04/26,
+;;       except removed these for *recent* (mistaken).
+;;     Use renaming from icicles-fn.el: *-choose-action-for-type -> *-alt-act-fn-for-type.
+;; 2009/04/28 dadams
+;;     icicle-object-action: 
+;;       At end, just apply the fn returned by icicle-choose-action-for-type to chosen object.
+;;       Use icicle-type-actions-alist, not icicle-object-named-types.
+;;       Update to use with icicle-predicate-types-alist (not flat list of preds).
+;;     icicle-choose-candidate-of-type: Handle color type too.
+;;     icicle-get-anything-actions-for-type:
+;;       Highlight Anything actions using face icicle-special-candidate.
+;; 2009/04/26 dadams
+;;     icicle-marker+text, icicle-compilation-search-in-context-fn:
+;;       Bind inhibit-field-text-motion to t, to ensure real end-of-line.
+;;     Load icicles-mac (at compile time) using load-library, to ensure latest .elc.
+;;     Bind icicle-candidate-alt-action-fn, where appropriate, to icicle-choose-action-for-type:
+;;       *-lisp-complete-symbol, *-customize-face(-other-window), *-execute-extended-command,
+;;       *-command-abbrev, *-command-abbrev-command, *-execute-named-keyboard-macro,
+;;       *-set-option-to-t, *-reset-option-to-nil, *-toggle-option, *-select-frame,
+;;       *-delete-windows, *-kill-buffer, icicle-buffer(-other-window),
+;;       *-(add|remove)-buffer-candidate, *-(buffer|face|file|directory)-list,
+;;       *-find-file(-absolute|-in-tags-table)(-other-window),
+;;       *-(recent|locate)-file(-other-window), *-frame-(bg|fg), *-where-is,
+;;       *-apropos(-variable|option|function|command), *-apply, *-save-string-to-variable,
+;;       *--choose-candidate-of-type, *-read-var-value-satisfying, *-read-color. 
+;;     icicle-execute-extended-command-1, icicle-command-abbrev-action:
+;;       Rebind icicle-candidate-alt-action-fn to nil so we don't override it for invoked cmd.
+;;     icicle-object-action: Respect icicle-use-anything-candidates-flag.
+;; 2009/04/25 dadams
+;;     icicle-find-file-in-tags-table(-other-window): Fixed copy+paste typo.
+;; 2009/04/24 dadams
+;;     Added: icicle-find-file-in-tags-table(-other-window).
+;; 2009/04/19 dadams
+;;     icicle-customize-apropos-options-of-type, icicle-dabbrev-completion:
+;;       Don't fset unless standard function is defined.
+;;     Use when/unless instead of or for fset's. (cosmetic)
+;; 2009/04/18 dadams
+;;     Soft-require hexrgb.el unconditionally, not just when there is a window-system.
+;;     icicle-read-color: Error if hexrgb is not loaded.
+;; 2009/04/11 dadams
+;;     Added: icicle-region-add-short-help.
+;;     icicle-font-w-orig-size: Construct short help only if user will see it.
+;;     icicle-describe-opt-of-type-complete, icicle-marker+text,
+;;       icicle-(select|search|remove)-region, icicle-search-(regexp|char-property)-scan:
+;;         Add short help for mode-line and tooltip.
+;;     icicle-region-help: Corrected start/end order.
+;;     icicle-region-help, icicle-search-help: Removed unused help: No help.
+;; 2009/04/10 dadams
+;;     icicle-font-w-orig-size: Provide help string.  Set font to use orig-pointsize also.
+;;     icicle-font: Modify frame - don't use menu-bar-mode.  Get orig menu-bar info from frame.
+;;                  Save orig-pointsize also.
+;;     icicle-frame-(bg|fg):
+;;       Incorporate behavior of icicle-read-color: multi-completion etc.  Added short help.
+;;       (Use icicle-make-color-candidate, icicle-color-completion-setup.)
+;;     icicle-read-color:
+;;       Factored out stuff as new function icicle-color-completion-setup.
+;;       Corrected handling of ARG > 2.
+;;     Moved to icicles-fn.el:
+;;       icicle-color-help, icicle-make-color-candidate, icicle-remove-color-duplicates.
+;; 2009/04/09 dadams
+;;     Added: icicle-font-w-orig-size.
+;;     icicle-font: Use icicle-font-w-orig-size.  No menu bar, to avoid Emacs frame-sizing bug.
+;; 2009/04/04 dadams
+;;     icicle-kill-buffer, icicle-buffer(-other-window|-list), icicle-choose-candidate-of-type:
+;;       Bind icicle-sort-functions-alist for buffer names.
+;; 2009/03/29 dadams
+;;     icicle-make-color-candidate: Use white or black foreground, depending on color value.
+;; 2009/03/27 dadams
+;;     Renamed: icicle-default-buffer-name to icicle-default-buffer-names.
+;;     icicle-buffer(-other-window):
+;;       Bind bufflist, to make it available also to icicle-default-buffer-names.
+;;     icicle-default-buffer-names: Emacs 23: Provide first 4 buffers from bufflist.
+;; 2009/03/26 dadams
+;;     Added: icicle-default-buffer-name.
+;;     icicle-buffer(-other-window), icicle-add-buffer-candidate:
+;;       Use icicle-default-buffer-name.
+;; 2009/03/16 dadams
+;;     icicle-buffer(-other-window), icicle-buffer-list, icicle-kill-buffer,
+;;       icicle-add-buffer-candidate: Treat prefix arg buffers visiting files or frame-local.
+;;     icicle-recent-file(-other-window): Bind icicle-use-candidates-only-once-alt-p to t.
+;; 2009/03/15 dadams
+;;     Added: icicle-remove-file-from-recentf-list, icicle-remove-from-recentf-candidate-action.
+;;     icicle-recent-file(-other-window):
+;;       Bind icicle-candidate-alt-action-fn  to icicle-remove-from-recentf-candidate-action.
+;; 2009/03/10 dadams
+;;     Added: icicle-recompute-shell-command-candidates.
+;; 2009/02/28 dadams
+;;     icicle-find-file-absolute(-other-window):
+;;       Treat directory candidates as special candidates.
+;;     icicle-apropos: Treat functions as special candidates.
+;;     icicle-apropos-variable: Treat user options as special candidates.
+;;     icicle-apropos-function: Treat commands as special candidates.
+;;     icicle-apropos-command (non-apropos-fn+var version): Treat cmds as special candidates.
+;; 2009/02/23 dadams
+;;     icicle-Info-goto-node-action:
+;;       Protect dir insertion with icicle-extra-candidates-dir-insert-p.
+;; 2009/02/17 dadams
+;;     icicle-lisp-complete-symbol:
+;;       Added predicate arg.  Updated wrt Emacs 23 (better var completion).
+;; 2009/02/01 dadams
+;;     icicle-(find-file-absolute|(recent|locate)-file)(-other-window):
+;;       Bind C-backspace to icicle-up-directory.
+;; 2009/01/18 dadams
+;;     icicle-dired-saved-file-candidates(-other-window):
+;;       If there is no saved set, then use icicle-file-list to let user choose a set.
+;;     Added: icicle-dired-chosen-files(-other-window), as aliases.
+;; 2009/01/14 dadams
+;;     Same commands as yesterday: icicle-remove-duplicates -> icicle-remove-dups-if-extras.
+;; 2009/01/13 dadams
+;;     icicle-kill-buffer, icicle-buffer(-other-window), icicle-(buffer|file|directory)-list,
+;;       icicle-find-file(-absolute)(-other-window), icicle-(recent|locate)-file(-other-window),
+;;       icicle-choose-candidate-of-type:
+;;         Bind icicle-transform-function to icicle-remove-duplicates.
+;; 2009/01/05 dadams
+;;     Added: icicle-gud-gdb-complete-command.
+;;     icicle-shell-dynamic-complete(-as)-environment-variable: (require 'shell)
+;;     icicle-shell-dynamic-complete-as-command: Added candidate help for shell commands.
+;; 2009/01/04 dadams
+;;     Added ESS support:
+;;       Added: icicle-comint-replace-by-expanded-filename, icicle-ess-complete-filename,
+;;              icicle-ess(-internal)-complete-object-name, icicle-ess-R-complete-object-name.
+;;       Thx to Sebastian Luque.
+;;     Improved some doc strings.
+;; 2009/01/02 dadams
+;;     icicle-comint-dynamic-complete-as-filename, icicle-comint-dynamic-simple-complete:
+;;       Fixed for comint-completion-autolist, absolute directories.  Thx to Sebastian Luque.
+;; 2009/01/01 dadams
+;;     icicle-comint-replace-orig-completion-fns:
+;;       Use icicle-comint-dynamic-complete-replacements instead of hard-coded list.
+;;     icicle-comint-dynamic-simple-complete: Fix for Emacs 20: map #'list over completions.
+;; 2008/12/30 dadams
+;;     Removed: shell-hook-fn.
+;;     Removed fset here for: old-comint-dynamic-*, old-shell-dynamic-*, old-bbdb-complete-name.
+;;     icicle-comint-dynamic-simple-complete: Map #'list over candidates (for Emacs 20).
+;;     icicle-comint-hook-fn:
+;;       Don't bind icicle-comint-command here - do it in icicle-bind-other-keymap-keys.
+;; 2008/12/27 dadams
+;;     Removed: icicle-find-file(-other-window)-w-wildcards.
+;;     Removed soft require of dired+.el.
+;;     icicle-find-file(-other-window):
+;;       Use just find-file* with wildcards arg, not *-w-wildcards, as action fn.
+;;       Bind icicle-default-value so that it won't insert the default value.
+;;     icicle-find-file(-other-window), icicle-choose-candidate-of-type:
+;;       Use nil as 3rd read-file-name arg, if not in Dired on a file name.
+;; 2008/12/23 dadams
+;;     icicle-comint-dynamic-complete-as-filename: Bind use-dialog-box to nil.
+;; 2008/12/22 dadams
+;;     icicle-comint-dynamic-complete-as-filename: Use INIT and PRED in read-file-name call.
+;; 2008/12/21 dadams
+;;     Added: icicle-shell-hook-fn, (icicle|old)-comint-dynamic-complete(-filename),
+;;            (icicle|old)-shell-dynamic-complete-(command|filename|environment-variable), 
+;;            icicle-comint-replace-orig-completion-fns, icicle-comint-dynamic-simple-complete,
+;;            icicle-comint-dynamic-complete-as-filename,
+;;            icicle-shell-dynamic-complete-as-(command|environment-variable).
+;;     Renamed: icicle-comint-send-input to icicle-comint-search-send-input,
+;;              icicle-comint-get-final-choice to icicle-comint-search-get-final-choice,
+;;              icicle-comint-get-minibuffer-input to icicle-comint-search-get-minibuffer-input.
+;;     Require shell.el at compile time.
+;;     Use fn, not var, confirm-nonexistent-file-or-buffer.  Thx to Daniel Clemente.
+;; 2008/12/02 dadams
+;;     Removed all use of icicle-file-ignore-space-prefix-flag (removed).
+;; 2008/11/23 dadams
+;;     Updated wrt Emacs 23:
+;;       find-file-confirm-nonexistent-file -> confirm-nonexistent-file-or-buffer.
+;;       icicle-buffer*, icicle-add-buffer-candidate, icicle-choose-candidate-of-type:
+;;         Added confirm-nonexistent-file-or-buffer.
+;; 2008/11/22 dadams
+;;     icicle-command-abbrev, icicle-remove-buffer-config-action, icicle-find-file-absolute*,
+;;       icicle-(recent|locate)-file*, icicle-describe-option-of-type,
+;;       icicle-(vardoc|fundoc|plist|doc), icicle-complete-keys-1, icicle-read-color:
+;;         Put icicle-fancy-candidates property on prompt when appropriate.
+;;     icicle-(find|recent|locate)-file(-absolute)(-other-window):
+;;       Support find-file-confirm-nonexistent-file (Emacs 23).
+;; 2008/11/17 dadams
+;;     Added: icicle-find-first-tag-action, icicle-find-first-tag-other-window-action.
+;;     icicle-find(-first)-tag(-other-window), icicle-find-tag-action: Crosshairs highlighting.
+;;     icicle-find-first-tag(-other-window): Use icicle-find-first-tag(-other-window)-action.
+;;     Mention crosshairs.el in doc strings of commands that use it.
+;; 2008/11/14 dadams
+;;     icicle-locate-file*: Use face icicle-candidate-part only for negative prefix arg.
+;; 2008/11/09 dadams
+;;     icicle-explore: When only 1 candidate, no completion.  Thx to Hannes Janetzek.
+;; 2008/11/04 dadams
+;;     Removed compile-time require of palette.el or eyedropper.el.  Thx to Andrey Zhdanov.
+;;     icicle-read-color: Moved soft require of palette.el or eyedropper.el to beginning.
+;;     Removed: icicle-generic-S-tab.
+;;     icicle-add-key+cmd: Removed test for icicle-generic-S-tab.
+;; 2008/11/03 dadams
+;;     icicle-insert-for-yank: push-mark first.  Thx to Fabrice Knevez.
+;;     Renamed: icicle-insert-kill to icicle-completing-yank,
+;;              icicle-yank-insert to icicle-yank-maybe-completing.
+;;     icicle-search: Restored binding of icicle-searching-p (somehow, accidentally removed it).
+;; 2008/11/02 dadams
+;;     icicle-(doc|vardoc|fundoc|plist):
+;;       Prefix arg uses candidates cache.  Tighten scope of condition-case.
+;;     icicle-doc:
+;;       Show all of fn, var, and face doc that are available.  Thx to Fabrice Knevez.
+;;       Use multi-completion: added symbol name and type.
+;;     icicle-doc-action: (intern (icicle-transform-multi-completion...)), not assoc.
+;; 2008/10/27 dadams
+;;     icicle-find(-first)-tag*: Bind case-fold-search too.
+;; 2008/10/26 dadams
+;;     icicle-(file|directory)-list, icicle-find-file(-absolute)(-other-window),
+;;       icicle-(locate|recent)-file(-other-window): Bind to icicle-file-* options.
+;;     icicle-locate-file*, icicle-recent-file*:
+;;       Bind icicle-abs-file-candidates, icicle-delete-candidate-object.
+;;       Move init code into bindings.
+;;     icicle-find-first-tag*: Move init code into bindings.
+;; 2008/10/24 dadams
+;;     Find-tag fixes.  Thx to Per Nordlow.
+;;       icicle-find-tag: Bind completion-ignore-case also for call to icicle-explore.
+;;       icicle-find-tag-define-candidates-1:
+;;         Look for regexp followed by DEL, through eol.  Move to bol, then next line.
+;;     icicle-explore: Call icicle-get-alist-candidate with NO-ERROR-P arg.
+;; 2008/10/23 dadams
+;;     icicle-find-tag: Use nil for REQUIRE-MATCH in call to icicle-explore.
+;; 2008/10/21 dadams
+;;     icicle-search-read-context-regexp: Bound icicle-candidate-(action|help)-fn to nil.
+;;     icicle-search-define-candidates-1: Added error message - better than generic explore msg.
+;;     Moved enable-recursive-minibuffers from *-search-region to *-search-region-action.
+;;     icicle-search-region-action: Added message if no such file.
+;; 2008/10/18 dadams
+;;     Replaced customize-save-variable by funcall icicle-customize-save-variable-function.
+;;     icicle-bookmark(-other-window): Use icicle-bookmark-cleanup.  Removed completion default.
+;;     Added: icicle-bookmark-cleanup: Select orig-window at end.  Thx to Andrey Zhdanov.
+;; 2008/10/17 dadams
+;;     Added: icicle-bookmark-cmd.
+;; 2008/10/16 dadams
+;;     icicle-bookmark-jump-1: Fixed for Emacs 23.  Thx to Andrey Zhdanov.
+;; 2008/10/12 dadams
+;;     Added: icicle-search-ibuffer-marked, icicle-search-buff-menu-marked.
+;;     icicle-search-dired-marked: Removed unused let binding.
+;; 2008/10/11 dadams
+;;     icicle-Info-index-20: Use symbol at point as default index topic.
+;; 2008/10/05 dadams
+;;     icicle-Info-read-node-name: Use lax completion.  Thx to Richard Kim.
+;; 2008/09/22 dadams
+;;     icicle-dired-project(-other-window):
+;;       Map expand-file-name over absolute file names, to expand ~ in fileset entries.
+;; 2008/09/20 dadams
+;;     icicle-find-file-absolute(-other-window): abs-file-list -> icicle-abs-file-list.
+;; 2008/09/19 dadams
+;;     icicle-add-entry-to-saved-completion-set:
+;;       Use only the fileset name, not the whole fileset, in the (:fileset...) entry.
+;;     icicle-remove-entry-from-saved-completion-set: Rewrote.
+;;       Either the entry to remove or the set to remove it from can now be a fileset.
+;;     icicle-dired-save-marked-persistently: Added FILESETP arg, so you can save in a fileset.
+;;     icicle-dired-project(-other-window): Include filesets as project candidates.
+;;     Renamed: icicle-dired-save-marked-to-cache-file to icicle-dired-save-marked-persistently.
+;;     Moved icicle-kill-a-buffer to icicles-fn.el.
+;; 2008/09/15 dadams
+;;     icicle-(add|remove)-candidate-(to|from)-saved-completion-set: Use :fileset keyword.
+;;     icicle-search-where-arg, icicle-search-where-arg:
+;;       Wrap icicle-(file|buffer)-list with save-selected-window.
+;; 2008/09/14 dadams
+;;     Renamed: icicle-(add|remove)-candidate-(to|from)-saved-completion-set to
+;;              icicle-(add|remove)-entry-(to|from)-saved-completion-set.
+;;     icicle-add-entry-to-saved-completion-set: Treat fileset entries, not just strings.
+;;     icicle-(add|remove)-entry-(to|from)-saved-completion-set,
+;;       icicle-remove-saved-completion-set, icicle-dired-project(-other-window):
+;;         No default value for completing-read.
+;; 2008/09/13 dadams
+;;     Use renamings from icicles-mcmd.el:
+;;       icicle-candidate-set-save-to-cache-file to icicle-candidate-set-save-persistently,
+;;       icicle-candidate-set-retrieve-from-cache-file to *-candidate-set-retrieve-persistent.
+;; 2008/09/11 dadams
+;;     Added: icicle-grep-saved-file-candidates.
+;; 2008/09/09 dadams
+;;     Added: icicle-remove-saved-set-action: No longer set minibuffer-completion-table or call
+;;                                            icicle-complete-again-update.
+;;            icicle-dired-save-marked-(to-(variable|cache-file)|as-project),
+;;            icicle-dired-project(-other-window).
+;;     Renamed: icicle-candidate-set-dired-marked-save(-more) to icicle-dired-save-marked(-more)
+;;     icicle-remove-saved-completion-set:
+;;       Prompt and delete cache file.  Use icicle-remove-saved-set-action as action function.
+;;       Bind: icicle-whole-candidate-as-text-prop-p, icicle-use-candidates-only-once-flag.
+;;       Remove *Completions* window at end.
+;; 2008/09/08 dadams
+;;     icicle-dired-saved-file-candidates(-other-window):
+;;       Don't change to relative file names - use whichever form (abs, rel) is saved.
+;;     icicle-find-tag-define-candidates-1: Make sure tag is not empty before (aref tag 0).
+;;     icicle-find-file-absolute(-other-window):
+;;       Use default-directory as init value and default value.
+;; 2008/09/03 dadams
+;;     icicle-bookmark(-other-window), icicle-goto-marker-1:
+;;       Use crosshairs-unhighlight, not icicle-unhighlight-crosshairs+cleanup.
+;;     icicle-goto-marker-1: Bind orig-buff.
+;;     *-bookmark-jump-1, *-goto-marker-1-action, *-compilation-search-in-context-fn:
+;;       Use crosshairs-highlight, not icicle-highlight-crosshairs.
+;; 2008/09/02 dadams
+;;     Added: icicle-dabbrev--abbrev-at-point.
+;;     icicle-dabbrev-completion: Use icicle-dabbrev--abbrev-at-point.  Thx to Tomer Levin.
+;; 2008/09/01 dadams
+;;     Added: icicle-bookmark-jump(-other-window), icicle-bookmark-jump-1.
+;;     Removed: icicle-bookmark-other-window-action.
+;;     icicle-bookmark(-other-window): Use icicle-bookmark-jump(-other-window) as action fn.
+;;                                     Clean up crosshairs highlighting at end.
+;;     icicle-goto-marker-1:
+;;       Don't bind minibuffer-exit-hook.  Don't require crosshairs.el or hl-line+.el.
+;;       Use icicle-unhighlight-crosshairs+cleanup for the cleanup.
+;;     icicle-compilation-search: Don't require hl-line+.el.
+;;     icicle-compilation-search-in-context-fn: Use icicle-highlight-crosshairs.
+;; 2008/08/31 dadams
+;;     icicle-goto-marker-1-action:
+;;       Use col-highlight-(un)highlight, not crosshairs-flash.  Force redisplay.
+;;       Add col-highlight-unhighlight to pre-command-hook.
+;;       Use hl-line-highlight-now, not hl-line-flash.
+;;     icicle-goto-marker-1: Remove col-highlight-unhighlight from pre-command-hook at end.
+;;     icicle-customize-face(-other-window, icicle-execute-extended-command-1,
+;;       icicle-find-tag-action, icicle-insert-thesaurus-entry, icicle-apply(-list)-action,
+;;       icicle-search-action, icicle-tags-search, icicle-choose-anything-candidate:
+;;         Select window before call select-frame-set-input-focus.
+;; 2008/08/25 dadams
+;;     icicle-find-file-absolute(-other-window), icicle-(recent|locate)-file(-other-window):
+;;       Use lax completion and provide WILDCARDS arg to find-file.
+;; 2008/08/24 dadams
+;;     Use renaming from icicles-fn.el: icicle-minibuffer-contents to icicle-minibuf-input.
+;; 2008/08/23 dadams
+;;     icicle-clear-history: Wrap default value, minibuffer-history-variable, with symbol-name.
+;; 2008/08/21 dadams
+;;     Added: icicle-file(-other-*), icicle-find-file-absolute(-other-*).  Thx to Glauber M4.
+;;     Soft-require bbdb-com.el at compile time.  Don't require bbdb.el at load time - define
+;;       old-bbdb-* only if original is already defined.
+;;     icicle-bbdb-complete-name: Raise error if BBDB not loaded.
+;; 2008/08/20 dadams
+;;     icicle-bbdb-complete-name, icicle-clear-current-history: Replaced ding by icicle-ding.
+;; 2008/08/18 dadams
+;;     icicle-clear-history:
+;;       Moved icicle-use-candidates-only-once-flag binding to icicle-clear-history-1.
+;;     icicle-delete-windows: Bind icicle-inhibit-try-switch-buffer.
+;;     icicle-insert-kill: Bind icicle-sort-function to nil.
+;;     icicle-recent-file(-other-window):
+;;       Bind *-candidate-properties-alist and *-list-use-nth-parts to nil if no prefix arg.
+;;     icicle-goto(-global)-marker:
+;;       Bind icicle-sort-function(s-alist) differently in each - don't bind in *-goto-marker-1.
+;;     icicle-remove-region: Use just icicle-delete-region-from-alist as action function.
+;;     icicle-delete-region-from-alist:
+;;       Use the propertized region name, not just reg-name in the cons to delete.
+;;     Moved icicle-cdr-less-p to icicles-fn.el and renamed to icicle-cdr-lessp.
+;;     Moved icicle-remove-candidate-display-others to icicles-mcmd.el.
+;;     Use renamings from icicles-fn.el: icicle-complete-again-update, icicle-remove-if-not.
+;;     icicle-explore, icicle-find-tag, icicle-complete-keys:
+;;       Renamed local orig-* vars.  Use explore's in *-search-(quit-or-error|cleanup|action).
+;; 2008/08/14 dadams
+;;     icicle-apply: Handle multi-completion alist entries.
+;;     icicle-goto-global-marker: Treat icicle-add-buffer-name-flag: Use multi-completions.
+;;     icicle-marker+text: Added optional arg.  Annotate text with buffer name if appropriate.
+;;     icicle-goto-marker-1: Pass global-ring-p to icicle-marker+text, so it can annotate.
+;; 2008/08/13 dadams
+;;     icicle-goto-marker-1: Don't add marker to ring markers if global ring.
+;;     icicle-goto-marker-1-action: select-frame-set-input-focus.
+;;     icicle-bbdb-complete-name: let -> let* (duh!) for completing-read.
+;; 2008/08/12 dadams
+;;     Added: icicle-goto(-global)-marker-or-(set-mark-command|pop-global-mark),
+;;            icicle-goto-marker-1-action (factored out from icicle-goto-marker-1).
+;;     icicle-goto-marker-1:
+;;       Add mark-marker to list of markers in ring.
+;;       Use icicle-goto-marker-1-action.
+;;       Go directly to marker if only one.  Message if same as point.
+;;       Better test for type of ring, for error msg.
+;;     icicle-apply: Use icicle-explore-final-choice-full in final result (not void var).
+;;                   Added optional arg NOMSG; bind icicle-apply-nomsg.
+;;     icicle-apply-action: Respect icicle-apply-nomsg.  Removed vestigial cruft.
+;;     icicle-bbdb-complete-name: Bind icicle-bbdb-complete-name to t and use strict completion.
+;; 2008/08/11 dadams
+;;     icicle-search-highlight-context-levels: Increase overlay priority for each context level.
+;;     icicle-search-highlight-all-input-matches, icicle-search-highlight-input-matches-here:
+;;       Made of current-input overlay higher than any context-level overlay: 204 -> 220.
+;; 2008/08/10 dadams
+;;     Added: icicle-explore, icicle-find-tag-define-candidates (renamed old to *-1),
+;;            icicle-search-define-candidates (renamed old to *-1), icicle-search-cleanup,
+;;            icicle-(find-tag|search)-(final-act|quit-or-error).
+;;     Renamed: icicle-find-tag-define-candidates to icicle-find-tag-define-candidates-1,
+;;              icicle-search-define-candidates to icicle-search-define-candidates-1.
+;;     Redefined to use icicle-explore: icicle-find-tag, icicle-apply, icicle-search.
+;;     icicle-comint-get-final-choice: Use icicle-explore-final-choice (not icicle-search-*).
+;; 2008/08/08 dadams
+;;     Added: icicle-goto-marker-1 (from icicle-goto-marker):
+;;       Use unwind-protect and minibuffer-exit-hook to unhighlight crosshairs.
+;;       Provide S-delete: bind icicle-delete-candidate-object.
+;;       Require crosshairs.el, hl-line+.el.  Use crosshairs-flash.
+;;     icicle-goto(-global)-marker: Use icicle-goto-marker-1.
+;; 2008/08/06 dadams
+;;     icicle-kmacro(-action):
+;;       Better prefix arg treatment.
+;;       kmacro-end-or-call-macro if still defining.
+;;       No-exit require-match.
+;;       Default value if only one.
+;;       Minor bug fix (extra candidate).
+;;       Name macros just 1, 2..., not macro #1, macro #2...
+;; 2008/08/03 dadams
+;;     Added: icicle-clear(-current)-history(-1|-entry), icicle-apply-list-action.
+;;     icicle-apply: Bind icicle-all-candidates-list-action-fn to icicle-apply-list-action.
+;;     Renamed: icicle-all-candidates-action-fn to icicle-all-candidates-list-action-fn,
+;;              icicle-candidate-alternative-action-fn to icicle-candidate-alt-action-fn.
+;; 2008/07/27 dadams
+;;     icicle-recent-file*, icicle-locate-file*: Added date multi-completion, with prefix arg.
+;;     Added: icicle-make-file+date-candidate.
+;; 2008/07/23 dadams
+;;     Renamed: icicle-map(-action) to icicle-apply(-action).  Added defalias for icicle-map.
+;; 2008/07/21 dadams
+;;     Added: icicle-bbdb-complete-name.  Thx to Ian Swainson.  require of bbdb.el for compile.
+;; 2008/07/19 dadams
+;;     icicle-Info-menu: Corrected regexp to pick up menu-item default, for Emacs 20.
+;; 2008/07/15 dadams
+;;     eval-when-compile require of: anything, cookie1, etags, eyedropper/palette, yow.
+;;     icicle-customize-apropos-options-of-type: Typo: help-remove-duplicates -> icicle-*.
+;;     icicle-send-bug-report: Include emacs-version.
+;; 2008/05/16 dadams
+;;     icicle-find-first-tag*, icicle-find-tag: Use tags-lazy-completion-table for Emacs 23.
+;; 2008/04/25 dadams
+;;     icicle-execute-extended-command-1:
+;;       Add msg about binding if suggest-key-bindings.  Thx to Jonathan Arkell.
+;; 2008/04/14 dadams
+;;     icicle-pp-eval-expression: Treat negative prefix arg.
+;; 2008/04/13 dadams
+;;     icicle-pp-eval-expression:
+;;       Treat prefix arg (added optional arg).
+;;       Respect eval-expression-debug-on-error and icicle-pp-eval-*.
+;; 2008/04/09 dadams
+;;     icicle-apropos-(function|command), icicle-imenu-non-interactive-function-p,
+;;       icicle-complete-keys-help: Use fboundp, not functionp, to also pick up macros.
+;; 2008/04/04 dadams
+;;     icicle-bookmark: Bind completion-ignore-case to bookmark-completion-ignore-case.
+;;     Added: icicle-bookmark-other-window(-action).
+;; 2008/04/01 dadams
+;;     icicle-describe-option-of-type: Bind icicle-apropos-complete-match-fn to nil.
+;;     icicle-describe-opt-of-type-complete:
+;;       Moved icicle-current-completion-mode test out of icicle-delete-if-not (iterates).
+;; 2008/03/31 dadams
+;;     icicle-locate-file(-other-window), icicle-plist, icicle-describe-option-of-type,
+;;       icicle-(var|fun)doc: icicle-highlight-lighter, before gather candidates.
+;;     icicle-plist, icicle-describe-option-of-type, icicle-vardoc, icicle-fundoc:
+;;       Simplified doc string and prompt wrt C-M-j.
+;; 2008/03/30 dadams
+;;     icicle-Info-menu: Treat also pseudo-menu at Top.  Thx to William Xu.
+;; 2008/03/26 dadams
+;;     Added: icicle-Info-menu(-cmd).
+;; 2008/03/22 dadams
+;;     icicle-other-window-or-frame: Rewrote to use icicle-select-window for all frames or one.
+;;     icicle-select-window:
+;;       Rewrote: Similar to icicle-select-frame (unique window names).  All frames or one.
+;;     Added: icicle-select-window-by-name, icicle-make-window-alist.
+;; 2008/03/19 dadams
+;;     Added: icicle-pp-eval-expression (old version in icicles-mcmd.el was renamed).
+;; 2008/03/11 dadams
+;;     icicle-repeat-complex-command: Rewrote doc string.
+;; 2008/03/10 dadams
+;;     icicle-select-frame: Rewrote to use icicle-select-frame-by-name (unique frame names).
+;;     icicle-choose-candidate-of-type: Use icicle-make-frame-alist, not make-frame-alist.
+;;     Added: icicle-select-frame-by-name, icicle-make-frame-alist.
+;; 2008/03/09 dadams
+;;     icicle-dabbrev-completion, icicle-find-tag-define-candidates,
+;;       icicle-Info-build-node-completions, icicle-search, icicle-read-color:
+;;         Call icicle-highlight-lighter.
+;; 2008/03/05 dadams
+;;     icicle-map: Don't inhibit sorting.
+;;     icicle-goto(-global)-marker: Provide sorting choices.  Highlight target line.
+;;     Added: icicle-cdr-less-p.
+;; 2008/02/26 dadams
+;;     Added: icicle-where-is.
+;; 2008/02/23 dadams
+;;     icicle-lisp-complete-symbol:
+;;       Wrap completing-read in save-excursion, because of icicle-top-level-*-completion-flag.
+;;     icicle-search: Use NOWARN arg with find-file-noselect.
+;;     Added: icicle-tags-search.
+;;     Renamed: icicle-search-tag* to icicle-find-tag*,
+;;              icicle-find-tag(-other-window) to icicle-find-first-tag(-other-window).
+;; 2008/02/21 dadams
+;;     icicle-Info-goto-node: Added .. node for book order.
+;;       Use global var icicle-Info-only-rest-of-book-p.  Call icicle-Info-goto-node-1.
+;;     icicle-Info-read-node-name: Remove REST-P arg.
+;;     icicle-Info-goto-node-action: When rest-of-book-p:
+;;       Update node completion table and then completions, and set current candidate number. 
+;;     Added: icicle-Info-goto-node-1, icicle-Info-build-node-completions(-fix-*).
+;; 2008/02/17 dadams
+;;     icicle-Info-goto-node:
+;;       Moved let to interactive spec, and added two args.  Use icicle-Info-read-node-name.
+;;       Negative prefix arg means completions are limited to rest of book.
+;;       Add icicle-Info-book-order-p to icicle-sort-functions-alist.
+;;       New doc string, to explain everything.
+;;     Added: icicle-Info-book-order-p, icicle-Info-read-node-name.
+;; 2008/02/16 dadams
+;;     icicle-(select|remove|search)-region:
+;;       Removed extraneous (setq icicle-candidates-alist) in let binding.
+;; 2008/02/13 dadams
+;;     Added: icicle-search-tag, icicle-search-tag-define-candidates, icicle-search-tag-action,
+;;       icicle-search-tag-help, icicle-pop-tag-mark.
+;;     Updated doc string of icicle-find-tag(-other-window).
+;; 2008/02/08 dadams
+;;     icicle-compilation-search-in-context-fn:
+;;       Simplified and corrected.  Dropped let, with-current-buffer.  Narrow to whole line.
+;;       Different code for Emacs 22+: Set current error; call compilation-next-error-function.
+;;     Removed: icicle-compilation-search-hl-line.
+;;     icicle-compilation-search: Soft require hl-line+.
+;;                                Don't bind next-error-hook to icicle-*-search-hl-line.
+;;     Renamed: icicle-directories-list to icicle-directory-list.
+;; 2008/02/07 dadams
+;;     icicle-search-action:
+;;       Moved icicle-highlight-candidate-* to after icicle-search-in-context-fn call.
+;;     icicle-compilation-search-in-context-fn:
+;;       Use buffer of marker.  Removed code using overlay buffer.
+;;     icicle-compilation-search: Bound icicle-compilation-search-hl-line as next-error-hook.
+;;     Added: icicle-compilation-search-hl-line.
+;; 2008/02/03 dadams
+;;     icicle-file-list: Rewrote using icicle-define-file-command.
+;;     icicle-(re)set-option-*: Added boundp before user-variable-p and icicle-binary-option-p.
+;;     Added: icicle-directories-list.
+;; 2008/01/18 dadams
+;;     Moved icicle-complete-keys-alist to icicles-var.el
+;; 2008/01/13 dadams
+;;     icicle-customize-face(-other-window), icicle-face-list, icicle-read-color:
+;;       Use icicle-transform-multi-completion.
+;;     icicle-(vardoc|fundoc): Use icicle-funvardoc-action as action fn and as help fn.
+;;     icicle-doc: Use icicle-doc-action as action fn and as help fn.
+;;     Added: icicle-funvardoc-action, icicle-doc-action.
+;;     icicle-search-replace-search-hit: Simplified bind/restore of Icicles completion vars.
+;; 2008/01/11 dadams
+;;     icicle-search-highlight-and-maybe-replace:
+;;       Don't call icicle-update-completions or icicle-display-candidates-in-Completions here.
+;;     icicle-search-in-context-default-fn, icicle-compilation-search-in-context-fn:
+;;       Call icicle-update-completions (at the end), since not done in i*-and-maybe-replace.
+;; 2008/01/08 dadams
+;;     icicle-describe-opt-of-type-complete: Treat 3rd arg.  Treat prefix completion.
+;; 2008/01/06 dadams
+;;     icicle-read-color: Provide color help for C-M-.  Added: icicle-color-help.
+;; 2008/01/04 dadams
+;;     icicle-doc, icicle-fundoc, icicle-vardoc: Use history variable icicle-doc-history.
+;; 2008/01/02 dadams
+;;     Added: icicle-search-dired-marked.
+;; 2008/01/01 dadams
+;;     icicle-(buffer|face|file)-list: Reverse list, so C-! keeps order.
+;;     icicle-dired-saved-file-candidates(-other-window):
+;;       Convert candidates to relative file names before opening Dired using them.
+;;       Error if any candidate is not a file in directory.
+;;     Added: icicle-candidate-set-dired-marked-save(-more).
+;; 2007/12/31 dadams
+;;     Added: icicle-fn-doc-minus-sig.
+;;     icicle-fundoc, icicle-doc: Use icicle-fn-doc-minus-sig.
+;;     icicle-doc: Bind icicle-transform-function, not icicle-whole-candidate-as-text-prop-p.
+;; 2007/12/27 dadams
+;;     icicle-describe-option-of-type:
+;;       Bind icicle-apropos-complete-match-fn to nil to prevent automatic input match.
+;; 2007/12/26 dadams
+;;     icicle-describe-opt-of-type-complete: Pretty-print types.  Bind icicle-candidate-help-fn.
+;;     Added: icicle-describe-opt-action.
+;; 2007/12/24 dadams
+;;     icicle-describe-option-of-type:
+;;       Rewrote for different kinds of type matching.  TYPE can be a regexp or type sexp.
+;;         Diff prefix args for diff behaviors. Handle type inheritance and value-checking.
+;;     Added: icicle-describe-opt-of-type-complete.
+;; 2007/12/21 dadams
+;;     icicle-customize-apropos-options-of-type: help-var-is-* -> icicle-var-is-*.
+;; 2007/12/20 dadams
+;;     icicle-dired-saved-file-candidates(-*):
+;;       Use substitute-command-keys in error msg.  Use generate-new-buffer name, not y-or-n-p.
+;; 2007/12/15 dadams
+;;     Added: icicle-customize-apropos-options-of-type.
+;; 2007/12/11 dadams
+;;     icicle-read-color: Don't leave out variable proxies if don't have eyedropper.
+;; 2007/12/07 dadams
+;;     Added: icicle-describe-option-of-type.
+;;     icicle-doc:
+;;       Choose kind of doc, instead of showing all (overwriting).
+;;       Removed binding of icicle-candidate-properties-alist.
+;;     icicle-read-color: Single-quote proxies, don't wrap with `_'.
+;; 2007/12/06 dadams
+;;     icicle-doc: Forgot to include face doc.
+;; 2007/12/03 dadams
+;;     Renamed icicle-longest-common-match to icicle-expanded-common-match.
+;; 2007/12/02 dadams
+;;     icicle-read-color: Include color-valued variables as proxy candidates.
+;; 2007/11/30 dadams
+;;     icicle-command-abbrev:
+;;       Use only membership in icicle-proxy-candidates, not icicle-proxy-candidate property.
+;;       So predicate is just commandp, since proxies are not part of regular candidates.
+;;     icicle-command-abbrev-action:
+;;       Bind to save/restore: icicle-add-proxy-candidates-flag, icicle-proxy-candidates.
+;;     icicle-command-abbrev-command: Bind icicle-add-proxy-candidates-flag to nil, to reset.
+;; 2007/11/29 dadams
+;;     icicle-command-abbrev: Treat icicle-add-proxy-candidates-flag, icicle-proxy-candidates.
+;;     icicle-read-color: Don't test icicle-add-proxy-candidates-flag.
+;; 2007/11/27 dadams
+;;     icicle-command-abbrev: Remove icicle-proxy-candidate property in unwind-protect.
+;; 2007/11/26 dadams
+;;     icicle-get-anything-candidates: Fixed for try-completion and test-completion cases.
+;;     icicle-choose-anything-candidate: Bind icicle-candidates-alist to actions (two places).
+;; 2007/11/25 dadams
+;;     Added: icicle-command-abbrev(-action|-command|-matching-commands|-record|regexp).
+;; 2007/11/24 dadams
+;;     icicle-execute-extended-command: Bind use-file-dialog to nil.
+;; 2007/11/17 dadams
+;;     icicle-read-color:
+;;       Respect icicle-add-proxy-candidates-flag.  Convert proxy multi-completions to strings.
+;; 2007/11/03 dadams
+;;     icicle-generic-S-tab: Doc string - mention icicle-generic-S-tab-keys.
+;; 2007/10/28 dadams
+;;     icicle-search: Don't bind icicle-expand-input-to-common-match-flag.  Updated doc string.
+;;     icicle-search-highlight-all-input-matches:
+;;       Don't set icicle-search-lcm unless icicle-expand-input-to-common-match-flag.
+;;     icicle-search-highlight-and-maybe-replace:
+;;       Match the lcm if icicle-search-replace-common-match-flag is non-nil.
+;;       Save icicle-candidate-nb around icicle-update-completions.
+;;       Set icicle-candidate-nb to 0 if nil.
+;;     icicle-search-highlight-input-matches-here:
+;;       Don't delete icicle-search-refined-overlays if icicle-*-all-current-flag.
+;; 2007/10/26 dadams
+;;     icicle-search-highlight-all-input-matches: Loop through overlays twice, to get the lcm.
+;;     icicle-search-highlight-input-matches-here: Highlight the lcm, if available.
+;;     icicle-search: Bind icicle-search-lcm.
+;; 2007/10/22 dadams
+;;    icicle-read-color: Use special-candidate face for pseudo color candidates.
+;;    icicle-add-key+cmd: Don't include keys bound to undefined.
+;; 2007/10/20 dadams
+;;    icicle-read-color, icicle-remove-color-duplicates:
+;;      Treat pseudo colors too (e.g. *point foreground*).
+;;    icicle-make-color-candidate: Added optional HEX-RGB arg.
+;; 2007/10/16 dadams
+;;     icicle-vardoc: Prefix arg means use only user options.
+;; 2007/10/14 dadams
+;;     Updated doc strings to reflect new icicle-act-before-cycle-flag change.
+;; 2007/10/13 dadams
+;;     icicle-get-anything-candidates:
+;;       If candidates is a fn, return fn that's useful for all-completions.  Filter by input.
+;;     icicle-choose-anything-candidate:
+;;       Don't sort or transform cands.  Respect Anything's require-pattern and delayed
+;;       settings.  Bind icicle-candidates-alist to candidates, if that's a function.
+;;     icicle-get-anything-candidates-of-type: Don't use mapcar if candidates is a function.
+;;     Added: icicle-get-anything-req-pat-chars, icicle-get-anything-input-delay.
+;; 2007/10/06 dadams
+;;     icicle-choose-candidate-of-type: Added entry for file type.
+;; 2007/09/25 dadams
+;;     icicle-doc: Bind icicle-whole-candidate-as-text-prop-p to treat full candidates.
+;; 2007/09/04 dadams
+;;     icicle-read-color: Added optional PROMPT arg.
+;; 2007/08/31 dadams
+;;     icicle-buffer-list: Prefix arg means only buffers visiting files are candidates.
+;;     icicle-search-where-arg, icicle-occur:
+;;       Prefix arg 99 means only buffers visiting files are candidates.
+;;     Added: icicle-search-choose-buffers.
+;; 2007/08/27 dadams
+;;     icicle-search-action: Fixed for return value.  Display the error message.
+;; 2007/08/25 dadams
+;;     icicle-choose-candidate-of-type: Removed (> emacs-major-version 21) restriction.
+;; 2007/08/25 dadams
+;;     Added: a, any, buffer, file, icicle-get-anything-(types|(default-)actions-for-type|
+;;            candidates-of-type|(cached-)candidates), icicle-anything(-candidate-value),
+;;            what-which-how, icicle-choose-anything-candidate.
+;;     Renamed icicle-clear-option to clear-option.
+;;     icicle-object-action: Treat Anything stuff.
+;;       Added optional type arg.  Use vars icicle-object-(named|predicate)-types.
+;;       Move icicle-read-var-value-satisfying call here from icicle-choose-candidate-of-type.
+;;     icicle-choose-candidate-of-type: Create buffer if needed.
+;;     Protected alias definitions with icicle-define-alias-commands-flag.
+;;     icicle-map(-action):
+;;       Use icicle-whole-candidate-as-text-prop-p and new icicle-get-alist-candidate.
+;;     icicle-(select|remove|search)-region, icicle-search:
+;;       Bind/use icicle-whole-candidate-as-text-prop-p.
+;;     icicle-occur: Require buffer names to match existing buffers.  Thx to Hadron Quark.
+;; 2007/08/15 dadams
+;;     Added command toggle as alias for icicle-toggle-option.
+;; 2007/08/09 dadams
+;;     Soft require kmacro.  Define icicle-kmacro* if kmacro gets loaded.
+;; 2007/07/27 dadams
+;;     icicle-search: Renamed icicle-act-first-then-navigate-p to icicle-act-before-cycle-flag.
+;; 2007/07/22 dadams
+;;     icicle-customize-face: Added prefix arg to give vanilla completion.
+;;     Added: icicle-customize-face-other-window.
+;;     Replace standard customize-face(-other-window) by icicle-customize-face(-other-window).
+;;     No longer require icicles-mode.el.
+;;     Require cus-edit.el (not just at compile time).
+;; 2007/07/08 dadams
+;;     Added: icicle-customize-faces.
+;;     icicle-customize-face: Bind icicle-all-candidates-action-fn to icicle-customize-faces.
+;; 2007/06/23 dadams
+;;     icicle-search-read-context-regexp, icicle-search-read-word, icicle-search-property-args,
+;;      icicle-add-region, icicle-save-string-to-variable:
+;;        Use icicle-completing-read-history, not read-from-minibuffer or read-string.
+;;     icicle-face-list: Bound icicle-list-nth-parts-join-string etc.
+;;     Moved to icicles-fn.el: icicle-read-from-minibuf-nil-default.
+;; 2007/06/22 dadams
+;;     Added: icicle-group-regexp, icicle-keyword-list, icicle-search-keywords.
+;; 2007/06/21 dadams
+;;     icicle-plist, icicle-(var|fun)doc, icicle-region-add-buffers, icicle-search-regexp-scan,
+;;      icicle-search-char-property-scan:
+;;        Use face icicle-candidate-part, not icicle-special-candidate.
+;;     icicle-add-key+cmd: Highlight key side of the pair (key  =  binding).
+;; 2007/06/18 dadams
+;;     Added: icicle-customize-face.
+;; 2007/06/17 dadams
+;;     icicle-make-color-candidate: Respect icicle-WYSIWYG-Completions-flag.
+;;     icicle-search-action: Added priority in call to icicle-place-overlay.
+;; 2007/06/12 dadams
+;;     icicle-execute-extended-command(-1):
+;;       i-e-e-c-1 prepares the new last command, but i-e-e-c sets it, at end, to this-command.
+;; 2007/06/10 dadams
+;;     Added: icicle-comint-hook-fn, icicle-compilation-hook-fn.
+;;     Removed unconditional add-hooks for comint-mode-hook and compilation(minor)-mode-hook.
+;; 2007/06/09 dadams
+;;     icicle-set-option-to-t, icicle-reset-option-to-nil, icicle-delete-windows,
+;;      icicle-add-buffer-candidate, icicle-remove-buffer-candidate, icicle-buffer-list,
+;;      icicle-remove-buffer-config, icicle-face-list, icicle-file-list,
+;;      icicle-remove-all-regions-in-buffer, icicle-delete-file:
+;;        Bind icicle-use-candidates-only-once-flag to t.
+;;     icicle-set-option-to-t, icicle-clear-option: Candidate vars must have value nil/non-nil.
+;;     icicle-search-regexp-scan: Added eobp test and empty hit-string test.
+;;     icicle-select-(frame|window), icicle-delete-windows:
+;;       Removed extra t arg to icicle-define-command.
+;; 2007/06/08 dadams
+;;     Added icicle-find-tag(-other-window).
+;; 2007/06/07 dadams
+;;     Renamed: icicle-font-history to icicle-font-name-history,
+;;              icicle-function-history to icicle-function-name-history,
+;;              icicle-variable-history to  icicle-variable-name-history.
+;;     Use standard history variable if bound, else use Icicles history variable:
+;;       bookmark-history, color-history, color-theme-history, face-name-history,
+;;       font-name-history, frame-name-history, function-name-history, variable-name-history
+;; 2007/06/05 dadams
+;;     Don't require hexrgb.el if no window system.
+;;     icicle-read-color: Use featurep, not require, for hexrgb.
+;;     icicle-make-color-candidate: Error if hexrgb is not loaded.
+;; 2007/05/31 dadams
+;;     icicle-execute-extended-command-1: Set, don't bind this-command.
+;;     icicle-execute-extended-command, icicle-execute-named-keyboard-macro:
+;;       Simpler save and restore of last-command.
+;; 2007/05/28 dadams
+;;     icicle-imenu: Use same prefix-arg behavior as icicle-search (search multiple...).
+;;     Added: icicle-imenu-(command|non-interactive-function(-p)).
+;;     icicle-search-highlight-context-levels:
+;;       Wrapped loop in condition-case.  Took max-levels determination out of loop.
+;; 2007/05/25 dadams
+;;     Added: icicle-face-list, icicle-next-single-char-property-change,
+;;            icicle-search-(where-arg|property-args|char-property(-scan)|overlay-property),
+;;            icicle-char-properties-in-buffer(s).
+;;     Removed: icicle-text-properties-in-buffer(s), icicle-search-text-property-scan.
+;;     icicle-search(-word): Use icicle-search-where-arg.
+;; 2007/05/21 dadams
+;;     Added: icicle-search-(buffer|file|all-regions).
+;;     icicle-imenu: Fixed treatment of prefix arg.
+;;     icicle-imenu-command-p: Fix to work also with Emacs 22 and  21.
+;; 2007/05/14 dadams
+;;     icicle-execute-extended-command-1: Error if empty command name.
+;; 2007/05/12 dadams
+;;     icicle-imenu: Added prefix arg for search for commands and non-cmds in Emacs-Lisp mode.
+;;     Added: icicle-imenu-command-p.
+;; 2007/05/11 dadams
+;;     icicle-search-define-candidates:
+;;       Move scan-fn-or-regexp to 4th arg from 2nd.  Removed &optional.
+;;       Apply icicle-search-regexp-scan to args also.
+;;     icicle-search-regexp-scan: Treat predicate.
+;;       Move regexp to 3rd arg from 2nd, and add predicate arg.  Removed &optional.
+;;     icicle-search-regexp-scan, icicle-search-text-property-scan:
+;;       Add lengths of temp-list and icicle-candidates-alist.
+;;     icicle-search-text-property(-scan): Added predicate argument.
+;;     icicle-search-region-action: Bind icicle-candidate-action-fn to icicle-search-action.
+;;     icicle-(select|search|remove)-region: Removed temp var bound to (icicle-region-sorted).
+;;     icicle-search: Mention predicate in no-match message.
+;; 2007/05/07 dadams
+;;     icicle-add-buffer-config: Added history args for icicle-read-from-minibuf-nil-default.
+;; 2007/05/06 dadams
+;;     icicle-search: Bind icicle-must-pass-predicate to icicle-search-context-match-predicate.
+;;     icicle-search-read-context-regexp: Don't accept an empty regexp.
+;;     Changed S-C- to C-S- and M-C- to C-M- in doc.
+;; 2007/05/04 dadams
+;;     icicle-(re)set-option-to-(nil|t), icicle-toggle-option: Enable recursive minibuffers.
+;; 2007/05/02 dadams
+;;     icicle-search-read-word: Updated doc string.
+;;     icicle-search: Respect icicle-search-whole-word-flag and icicle-regexp-quote-flag.
+;;                    Single message for non-existent buffers.
+;;     icicle-select-region-action: Message for non-existent file.
+;;     Added empty defvars for Emacs 22 standard vars, to quiet byte compiler.
+;; 2007/05/01 dadams
+;;     icicle-execute-extended-command-1:
+;;       Don't bind icicle-candidate-action-fn if we have already read command name.
+;;     icicle-search-*-scan: Fill, reverse temp list, then append to icicle-candidates-alist.
+;;     Added: icicle-search-word, icicle-search-read-word.
+;; 2007/04/29 dadams
+;;     icicle-search, icicle-search-text-property, icicle-text-properties-in-buffers:
+;;       Allow search of multiple files.  Change prefix arg accordingly.
+;; 2007/04/28 dadams
+;;     Added: icicle-compilation-search-in-context-fn, icicle-search-in-context-default-fn,
+;;            icicle-search-highlight-and-maybe-replace.
+;;     icicle-search-action: Move code to the new functions.  Use icicle-search-in-context-fn.
+;;     icicle-compilation-search: Rewrote.
+;;       No longer use compile-goto-error as icicle-search-hook.
+;;       Use icicle-compilation-search-in-context-fn.
+;;       Cannot-replace error msg if not Emacs 22, since no compilation-highlight-overlay.
+;;       Provide .* regexp and do not highlight - as in icicle-occur.
+;; 2007/04/22 dadams
+;;     icicle-search: Allow for pre-bound icicle-candidate(-alternative)-action-fn.
+;;     icicle-search-replace-search-hit:
+;;       Call icicle-candidate-action-fn, not necessarily icicle-search-action.
+;; 2007/04/20 dadams
+;;     Added: icicle-search-highlight-context-levels.  Use in icicle-search-action.
+;;     icicle-search-highlight-cleanup: Delete icicle-search-level-overlays.
+;;     icicle-search: Set icicle-search-context-regexp nil if scan-fn-or-regexp is not string.
+;;     icicle-search-replace-fixed-case-p: Return nil if arg is nil.
+;;     icicle-search-read-context-regexp: Use default with read-number; protect with fboundp.
+;;     Added soft require of strings.el.
+;; 2007/04/18 dadams
+;;     Added: icicle-search-replace-fixed-case-p.  Use in icicle-search-action.
+;;     icicle-search-action:
+;;       Set match data to region when icicle-search-replace-whole-candidate-flag is t.
+;;       Don't search for icicle-search-context-regexp.
+;;     icicle-search-replace-match: Added fixedcase arg.
+;;                                  Use icicle-search-replace-literally-flag.
+;;     Use replace-match-maybe-edit (Emacs 22), not replace-match, and save and restore stuff.
+;;     icicle-search-replace-search-hit:
+;;       Use regexp-history in read-string.  Use icicle-search-define-replacement.
+;; 2007/04/17 dadams
+;;     Added: icicle-search-replace-match.  Treat Emacs<22 also.  Use in icicle-search-action.
+;;     icicle-search-replace-search-hit: Use regexp-history in read-string.
+;; 2007/04/16 dadams
+;;     icicle-search-action: Use replace-count.
+;;     icicle-search: Initialize replace-count to 0.
+;; 2007/04/15 dadams
+;;     icicle-search-action: Allow \,... etc. replacement.
+;;       Use query-replace-compile-replacement and replace-match, with error treatment.
+;;       Removed unwind-protect.  Removed %s from error-msg return.
+;;     icicle-search: Save search string as icicle-search-context-regexp.
+;;                    Use "%s" for error message in failure error call.
+;;                    Updated doc string for lisp-eval replacement etc.
+;;     *(-all)-input-matches(-here): save-match-data around input matching.
+;;     icicle-search-highlight-input-matches-here: Added not eobp to loop test.
+;; 2007/04/13 dadams
+;;     icicle-search-highlight-input-matches-here: Bound free var ov.
+;; 2007/04/10 dadams
+;;     icicle-search-regexp-scan:
+;;       Use match indicated by icicle-search-context-level as context.
+;;     Added: icicle-search-read-context-regexp.
+;;     icicle-search(-region|-regexp-scan): Use icicle-search-read-context-regexp.
+;; 2007/04/08 dadams
+;;     icicle-map-action, icicle-search-action:
+;;       Return nil for success, error msg for failure (it was reversed).
+;;       Use icicle-highlight-candidate-in-Completions.
+;;     icicle-map-action: Moved minibuffer frame selection to unwind-protect final clause.
+;;     icicle-search: Give focus to original frame, in unwinding clause (C-g).
+;;     Added: icicle-search-highlight-input-matches-here.
+;;     icicle-search-highlight-all-input-matches: Highlight all input matches in candidate.
+;;     icicle-search-replace-search-hit:
+;;       Use 0 if icicle-candidate-nb is nil.  Display completions.
+;;       Save and restore: icicle-last-completion-command, icicle-last-input.
+;;       Prevent using same string as candidate for replacement.
+;;     icicle-search-action: Rewrote.  Enable repeated replacment of input matches.
+;;       Save and restore icicle-candidate-nb.  Wrap it around if at end.
+;;       Warn about empty input for whole-candidate replacement.
+;;       Update icicle-last-completion-candidate.  Display completions.
+;; 2007/04/07 dadams
+;;     icicle-search: Added query-replace functionality.
+;;       Navigate first, then act (C-next).
+;;       Give focus to last frame searched.
+;;       Bind: icicle-candidate-alternative-action-fn, icicle-inhibit-sort-p,
+;;             icicle-searching-p, icicle-expand-input-to-common-match-flag.
+;;       Bind icicle-buffer-require-match-flag to partial-match-ok in interactive spec.
+;;     icicle-search-action:
+;;       Added optional replace arg: if non-nil, then fn becomes a replace action.
+;;     Added: icicle-search-replace-search-hit, icicle-search-replace-candidate,
+;;     icicle-buffer-list: Bind all the stuff that is bound in icicle-buffer.
+;; 2007/04/06 dadams
+;;     icicle-execute-extended-command-1:
+;;       Bind this-command, but only around call to cmd - don't set it.
+;; 2007/04/02 dadams
+;;     Added: icicle-search-text-property, icicle-search-text-property-scan,
+;;            icicle-text-properties-in-buffer(s).
+;;     icicle-search:
+;;       Added &rest args.  Updated doc string.  Don't read regexp or reverse alist here.
+;;       Use icicle-search-define-candidates, not icicle-search-regexp-scan.
+;;     icicle-search-regexp-scan: Read regexp here.  Reverse alist here.
+;;     Moved to icicles-fn.el: icicle-filter-alist, icicle-first-matching-candidate.
+;;     Renamed: icicle-search-region-beg-end to icicle-region-or-buffer-limits.
+;; 2007/04/01 dadams
+;;     icicle-repeat-complex-command:
+;;       Remove duplicates and sort entries, but only for reading command to eval.
+;; 2007/03/31 dadams
+;;     icicle-lisp-complete-symbol: Bind icicle-top-level-when-sole-completion-flag to t.
+;; 2007/03/27 dadams
+;;     icicle-search: Hard-code C-next key in message.
+;;     icicle-search-regexp-scan: Initialize last-beg for first time.
+;; 2007/03/23 dadams
+;;     icicle-execute-extended-command-1:
+;;       Don't restore last-command.  Run (pre|post)-command-hook.  Set, don't bind,
+;;       this-command.  enable-recursive-minibuffers for interactive call of cmd.
+;;     icicle-execute-extended-command, icicle-execute-named-keyboard-macro:
+;;       Restore last-command at end.
+;; 2007/03/20 dadams
+;;     icicle-execute-extended-command-1: When wrong-number-of-args, icicle-help-on-candidate.
+;; 2007/03/14 dadams
+;;     icicle-dired-saved-file-candidates, icicle-buffer, icicle-(find|locate|recent)-file:
+;;       Put 200 as value of property icicle-Completions-window-max-height.
+;;     Added ;;;###autoload for icicle-define*.
+;; 2007/03/09 dadams
+;;     icicle-search, icicle-map, icicle-(remove|search|select)-region, icicle-imenu,
+;;     icicle-occur, icicle-compilation-search:
+;;       Bound icicle-transform-function to nil if interactive-p.
+;;     icicle-comint-search: Updated doc string to mention false positives in command matching.
+;;     Removed eval-when-compile from requires of Icicles libraries (except icicle-mac.el).
+;; 2007/03/08 dadams
+;;     icicle-insert-kill: Bound icicle-delete-candidate-object.
+;; 2007/03/07 dadams
+;;     icicle-delete-windows, icicle-map-action, icicle-search-action,
+;;     icicle-choose-candidate-of-type, icicle-complete-keys-help:
+;;       Use 0, not t, as frame arg to get-buffer-window.
+;; 2007/03/06 dadams
+;;     icicle-search, icicle-map, icicle-(remove|search|select)-region:
+;;       Bind icicle-inhibit-sort-p to non-nil to prevent user sorting.
+;;       Update doc string to mention that you cannot sort candidates.
+;;     icicle-(remove|search|select)-region: Sort candidates by buffer and then by tag.
+;;     icicle-search-region: Bound icicle-delete-candidate-object.
+;;     icicle-search, icicle-map: Don't add or subtract one from candidate # if use action fn.
+;;     icicle-search:
+;;       If require-match, set icicle-completion-candidates and marker to reflect final choice.
+;;     Renamed: icicle-get-current-candidate to icicle-get-alist-candidate.
+;;     Added: icicle-region-sorted, icicle-region-add-buffers.
+;; 2007/03/04 dadams
+;;     icicle-get-current-candidate: Return nil if icicle-candidates-alist is nil.
+;; 2007/03/02 dadams
+;;     icicle-remove-buffer-config, icicle-remove-buffer-candidate: Removed extraneous quote.
+;;     icicle-(find|recent)-file(-other-window): Bound icicle-delete-candidate-object.
+;; 2007/02/28 dadams
+;;     icicle-buffer-list, icicle-color-theme: Bound icicle-delete-candidate-object.
+;; 2007/02/27 dadams
+;;     icicle-recent-file(-other-window): Changed INITIAL-INPUT completing-read arg to nil.
+;; 2007/02/25 dadams
+;;     Added: icicle-remove-buffer-candidate-action, icicle-remove-buffer-config-action.
+;;     icicle-add-buffer-candidate, icicle-bookmark, icicle-buffer-config:
+;;       Bound icicle-delete-candidate-object.
+;; 2007/02/24 dadams
+;;     Added: icicle-kill-a-buffer-and-update-completions (was kill-a-buffer),
+;;            icicle-delete-region-from-alist.
+;;     icicle-delete-window: Use icicle-kill-a-buffer...-completions, not icicle-kill-a-buffer.
+;;     icicle-buffer(-other-window), icicle-choose-candidate-of-type:
+;;       Bind icicle-delete-candidate-object to icicle-kill-a-buffer.
+;;       Bind icicle-sort-function to self if icicle-buffer-sort-function is nil.
+;;     icicle-select-region:
+;;       Bind icicle-delete-candidate-object to icicle-delete-region-from-alist.
+;;     icicle-remove-region: Rewrote.
+;;       Use icicle-delete-region-from-alist.
+;;       Use icicle-remove-candidate-display-others, but don't redisplay unless completing.
+;;       Respect icicle-add-buffer-name-flag (append buffer names).
+;; 2007/02/20 dadams
+;;     Added: icicle-search-region-action.  Open file associated with candidate.
+;;     icicle-search-region:
+;;       Use icicle-search-region-action.  Updated doc string.  Bind icicle-list-*.
+;;       Fix default completing-read value.  Respect icicle-add-buffer-name-flag.
+;;     icicle-select-region-action: Open file associated with candidate.
+;;     icicle-region-open-all-files: Ignore files that are not readable.
+;;     icicle-regions: Remove only non-existent buffers that are not associated with files.
+;; 2007/02/19 dadams
+;;     Added: icicle-region-open-all-files.
+;;     icicle-(search|select)-region, icicle-search: Use icicle-region-open-all-files.
+;;     icicle-add-region: Add file name to region entry in alist.
+;;     icicle-select-region-action, icicle-region-help, icicle-search:
+;;       Updated selectors for point and mark, because of addition of file name.
+;;     icicle-region-help: Add file name to help message.
+;; 2007/02/18 dadams
+;;     Added: icicle-first-matching-candidate.
+;;     icicle-get-current-candidate: Use icicle-first-matching-candidate, not assoc.
+;; 2007/02/07 dadams
+;;     icicle-search-action: Make *Completions* window dedicated.  Thx to Peter Povinec.
+;; 2007/02/07 dadams
+;;     icicle-search: pop-to-buffer and raise frame. Don't select orig-window.
+;; 2007/02/06 dadams
+;;     icicle-search, icicle-select-region, icicle-search-regexp-scan:
+;;       Respect icicle-add-buffer-name-flag.
+;;     icicle-search: Bound icicle-show-Completions-initially-flag to t.
+;;                    Bound icicle-candidate-help-fn to icicle-search-help.
+;;     icicle-search-regexp-scan: nil BUFFER arg means current buffer now.
+;;     icicle-search-action, icicle-filter-alist: Treat multi-completion case also.
+;;     Added: icicle-search-help.
+;;     icicle-map-action, icicle-search-action: Removed unused local var, curr-cand-string.
+;;     icicle-select-region, icicle-remove-region, icicle-search-region:
+;;       Use icicle-candidates-alist, not regions-w-buffers (but bind it locally too).
+;;     Renamed: icicle-get-current-region-candidate to icicle-get-current-candidate.
+;;     icicle-region-help: Provide region limits also.
+;;     Added note to some doc strings that the command is for Icicle mode only.
+;; 2007/02/02 dadams
+;;     icicle-search: Test for buffers, not buffer names, in WHERE.  Thx to Peter Povinec.
+;;     icicle-buffer-list: Return the list of buffers.
+;; 2007/01/28 dadams
+;;     icicle-complete-keys:
+;;       Bind icicle-sort-functions-alist, using icicle-command-names-alphabetic-p.
+;; 2007/01/22 dadams
+;;     icicle-read-color:
+;;       Removed free var NTH-PARTS.
+;;       Bound icicle-list-nth-parts-join-string the same as icicle-list-join-string.
+;;       Remove duplicates: AliceBlue and alice blue etc.: downcase and remove whitespace.
+;;     Added: icicle-remove-color-duplicates.
+;;     Added soft require of hexrgb.el.
+;;     icicle-*doc, icicle-plist: Bound icicle-candidate-properties-alist.
+;; 2007/01/21 dadams
+;;     Added: icicle-read-color, icicle-make-color-candidate.
+;; 2007/01/18 dadams
+;;     Added: icicle-get-current-region-candidate.
+;;       Use current cand if cycled or `mouse-2'.  Else if single match, use that.  Else error.
+;;     icicle-remove-region, icicle-search-region, icicle-region-help:
+;;       Use icicle-get-current-region-candidate.
+;;     icicle-add-region: Added optional TAG arg and prefix arg treatment.
+;;     icicle-remove-region: Update completions list.  Bind regions-w-buffers.
+;;     icicle-remove-all-regions-in-buffer: Use current buffer name as default.
+;;     Added: icicle-select-region-action.
+;;     icicle-select-region: Use icicle-select-region-action.
+;;     Renamed: option icicle-regions to icicle-region-alist.
+;;     icicle-regions: Sort entries.
+;; 2007/01/17 dadams
+;;    icicle-filter-alist: Reversed arg order.  Return alist arg if filter-keys arg is empty.
+;; 2007/01/12 dadams
+;;    icicle-delete-window: Do icicle-remove-Completions-window if in minibuffer.
+;;    icicle-yank-insert: Do icicle-yank if in minibuffer.
+;;    icicle-(fundoc|vardoc|doc|plist): Added condition-case: protect symbols that error.
+;; 2007/01/01 dadams
+;;    Added: icicle-(add|remove)-candidate-(to|from)-saved-completion-set.
+;;    icicle-add-buffer-config: Use nil, not "nil" as default, if icicle-buffer-sort is nil.
+;;                              Use icicle-define-add-to-alist-command to define it.
+;;    icicle-remove-buffer-config, icicle-remove-saved-completion-set:
+;;      Use icicle-assoc-delete-all, not delete of assoc.
+;;    icicle-remove-saved-completion-set: Update display after removal.
+;;    Reformatted icicle-define(-file)-command, based on setup.el's lisp-indentation-hack.
+;; 2006/12/25 dadams
+;;    Bug fix: icicle-search-action: Use icicle-filter-alist on icicle-candidates-alist.
+;;    icicle-(select|search)-region: Use pop-to-buffer and raise-frame, not set-buffer.
+;;    icicle-select-region: Activate the region.
+;; 2006/12/23 dadams
+;;    Added: icicle-region-help.  Use in icicle-*-region.
+;;    Added: icicle-remove-all-regions-in-buffer, icicle-remove-all-regions-action.
+;;    icicle-(select|search)-region: Ignore regions in non-existent buffers.
+;;    icicle-remove-region: Update the persistent value of icicle-regions.
+;; 2006/12/22 dadams
+;;    Added: icicle-exchange-point-and-mark.
+;;    icicle-customize-icicles-group: icicles -> Icicles (group name).
+;; 2006/12/18 dadams
+;;    icicle-object-action: Remove print arg.  icicle-apply-to-* uses current-prefix-arg now.
+;; 2006/12/17 dadams
+;;    Added: icicle-object-action, icicle-choose-candidate-of-type,
+;;           icicle-read-var-value-satisfying.
+;; 2006/12/16 dadams
+;;    icicle-map-action: Bug fix: Use icicle-candidate-nb, not assoc.
+;;    Added: icicle-goto(-global)-marker, icicle-marker+text, icicle-markers.
+;; 2006/12/10 dadams
+;;    Moved minibuffer and *Completions* commands to new file, icicles-mcmd.el.
+;;    Require icicles-opt.el.
+;;    icicle-buffer-list: Added final message.
+;; 2006/11/26 dadams
+;;    icicle-search-action: Bug fix: Use icicle-candidate-nb, not assoc, to get cand+mrker.
+;;    icicle-*-complete-1: Bug fix: Don't set icicle-current-input to icicle-last-input if nil.
+;;    Renamed: icicle-search-region to icicle-search-region-beg-end.
+;;    Added: icicle-(add|remove|select|search)-region.
+;;    icicle-search: Use icicle-regions for numeric prefix arg.  Updated doc string.
+;;    Added: icicle-Info-index-20 - thx to Tamas Patrovics.  Use it in icicle-Info-index.
+;; 2006/11/25 dadams
+;;    icicle-search: After final selection, select orig-window and give its frame input focus.
+;; 2006/11/24 dadams
+;;    Added: icicle-ensure-overriding-map-is-bound, icicle-universal-argument,
+;;           icicle-universal-argument-more, icicle-negative-argument, icicle-digit-argument,
+;;           icicle-universal-argument-other-key, icicle-universal-argument-minus,
+;;           icicle-kmacro(-action).
+;;    icicle-dabbrev-completion: Don't stop at common root, and use lax completion.
+;;    Replaced icicle-select-window-or-frame by icicle-other-window-or-frame (respects C-u 0).
+;; 2006/11/23 dadams
+;;    icicle-prefix-complete-1: Respect icicle-TAB-shows-candidates-flag.
+;;    icicle-execute-extended-command-1: Treat named keyboard macros too.
+;;    Added: icicle-execute-named-keyboard-macro.
+;; 2006/11/18 dadams
+;;    icicle-add/update-saved-completion-set, icicle-apropos*, icicle-bookmark,
+;;    icicle-buffer-config, icicle-candidate-set-retrieve, icicle-candidate-set-save,
+;;    icicle-color-theme, icicle-comint-command, icicle-complete-thesaurus-entry,
+;;    icicle-customize-apropos*, icicle-delete-windows, icicle-font, icicle-frame-bg,
+;;    icicle-frame-fg, icicle-insert-kill, icicle-insert-string-from-variable,
+;;    icicle-insert-thesaurus-entry, icicle-locate-file*, icicle-map, icicle-narrow-candidates,
+;;    icicle-remove-buffer-config, icicle-remove-saved-completion-set,
+;;    icicle-reset-option-to-nil, icicle-save-string-to-variable, icicle-search,
+;;    icicle-select-window, icicle-set-option-to-t, icicle-toggle-option:
+;;      Use a specific history variable.
+;; 2006/11/17 dadams
+;;    Added: icicle-select-(frame|window), icicle-select-window-or-frame.
+;; 2006/11/10 dadams
+;;    icicle-mouse-candidate-action: read-event to swallow mouse up event.
+;;    icicle-map-action:
+;;      Don't use icicle-filter-alist - find string in icicle-candidates-alist.
+;;      Unwind-protect to reselect minibuffer frame.  Don't bind case-fold-search.
+;;    icicle-map: enable-recursive-minibuffers.
+;; 2006/11/09 dadams
+;;    icicle-nb-of-candidate-in-Completions: Redefined using binary search, for performance.
+;;    icicle-toggle-ignored-space-prefix: Update doc string to use icicle-dispatch-C-^.
+;;    icicle-search:
+;;      Bind icicle-update-input-hook unconditionally, after icicle-search-regexp-scan.
+;;    icicle-search-regexp-scan: Highlight up to icicle-search-highlight-threshold.
+;;    icicle-search-highlight-all-input-matches:
+;;      Only update input and highlight if icicle-search-highlight-all-current-flag.
+;;    icicle-search-action:
+;;      Don't use icicle-filter-alist - find string in icicle-candidates-alist.
+;;    icicle-search-highlight-cleanup: Bind inhibit-quit to t.
+;; 2006/11/07 dadams
+;;    Added: icicle-toggle-highlight-all-current.
+;; 2006/11/06 dadams
+;;    icicle-search-action:
+;;      Highlight icicle-current-input, not icicle-current-raw-input (not updated).
+;;    Renamed icicle-search-highlight-all-flag to icicle-search-highlight-threshold.
+;; 2006/11/05 dadams
+;;    Added: icicle-search-regexp-scan.
+;;    icicle-search:
+;;      Added buffers arg.  Updated doc string.
+;;      Use icicle-search-regexp-scan:  Scan each buffer in buffers.
+;;                                      Add marker, not position, to icicle-candidates-alist.
+;;      Go to candidate in its buffer.
+;;      Added progress message.
+;;    icicle-search-action: Pop to buffer of candidate (marker) and raise frame.
+;;    icicle-occur:
+;;      Added buffers arg.  Updated doc string.  Call icicle-search-highlight-cleanup.
+;;    icicle-search-highlight-all-input-matches: set-buffer for each ov in dolist (minor opt.).
+;;    icicle-search-highlight-cleanup: Added progress messages.  Minor optimization.
+;; 2006/10/22 dadams
+;;    icicle-complete-keys-action:
+;;      Set last-nonmenu-event to non-mouse info, to ignore *Completions* click.
+;;    icicle-complete-keys-1: Don't use a default value for completing-read.
+;; 2006/10/21 dadams
+;;    Added: icicle-insert-char.
+;;    icicle-add-key+cmd: Respect icicle-complete-keys-self-insert-flag.
+;; 2006/10/20 dadams
+;;    icicle-map, icicle-delete-window: Corrected doc string.
+;; 2006/10/16 dadams
+;;    icicle-add-key+cmd: Protect :enable's eval with condition-case.
+;;    icicle-complete-keys-1:
+;;      No longer use icicle-extra-candidates.
+;;      Use default value of .. for completing-read (except at top level).
+;;    icicle-complete-keys-action: Correct no-match case: must match whole and part.
+;;    icicle-keys+cmds-w-prefix: Add .. to icicle-complete-keys-alist unless at top level.
+;; 2006/10/15 dadams
+;;    icicle-complete-keys:
+;;      Bind icicle-complete-keys-action, not icicle-complete-keys-help, to icicle-*-action-fn.
+;;      Bind orig-buff, orig-window, and icicle-completing-keys-p, for use elsewhere.
+;;    Added: icicle-complete-keys-action using code from icicle-complete-keys.
+;;    icicle-complete-keys-action:
+;;      Use orig-buff and orig-window; restore to originally selected window.
+;;      Error if candidate doesn't match template xxx  =  yyy.
+;;    icicle-complete-keys-1:
+;;      Call icicle-complete-keys-action on chosen candidate.
+;;    icicle-help-on-candidate: Treat key completion also.
+;;    Added from cus-edit+.el: custom-variable-p.
+;;    Moved to icicles-mode.el: icicle-select-minibuffer-contents, next-history-element.
+;;    Moved here from icicles-mode.el: icicle-generic-S-tab.
+;;    icicle-generic-S-tab (bug fix): Do not set last-command to icicle-apropos-complete.
+;;    Added: eval-when-compile's.
+;; 2006/10/13 dadams
+;;    icicle-add-key+cmd:
+;;      Add actual key to icicle-complete-keys-alist.  Thx to Stefan Monnier.
+;;      Don't filter out index (Imenu) keymap.
+;;      Treat :enable condition.
+;;    icicle-complete-keys-1:
+;;      Use actual key recorded in icicle-*-keys-alist. Don't convert to key description.
+;;      Treat digit-argument and negative-argument.
+;;    icicle-complete-keys-alist: Updated doc string for new structure.
+;; 2006/10/08 dadams
+;;    Added: icicle-add-key+cmd, icicle-read-single-key-description.
+;;    Added: icicle-complete-keys-alist.
+;;           Use in icicle-complete-keys-1, icicle-keys+cmds-w-prefix, icicle-add-key+cmd.
+;;    icicle-add-key+cmd: Update binding, depending on its type (menu item etc.).
+;;      Push (cons candidate binding), not just candidate, onto icicle-complete-keys-alist.
+;;    icicle-complete-keys-1:
+;;      Use binding, not just command name.  Call it and put it in (this|last)-command.
+;;      Flipped (corrected) use of icicle-key-descriptions-use-<>-flag.
+;;      Use icicle-read-single-key-description.
+;;    icicle-prefix-keys-first-p, icicle-complete-keys-1, icicle-complete-keys-help,
+;;      icicle-keys+cmds-w-prefix: Don't use icicle-list-*-string.
+;; 2006/10/05 dadams
+;;    icicle-complete-keys-1: Remove icicle-special-candidate property from all candidates.
+;;    icicle-keys+cmds-w-prefix:
+;;      Intern candidate and, if local binding, put icicle-special-candidate property on it.
+;;      Use single string for candidate (don't use multi-completion).
+;; 2006/10/03 dadams
+;;     icicle-complete-keys-1: Treat "..".
+;;     icicle-complete-keys: Updated doc string accordingly.
+;;     icicle-prefix-keys-first-p: ".." is less than all other strings.  Don't hard-code "= ".
+;;     icicle-keys+cmds-w-prefix:
+;;       Filtered out shadowed bindings, icicle-generic-S-tab, and icicle-complete-keys.
+;;       Use only map-keymap & lookup-key, not accessible-keymaps, current-active-maps,
+;;         map-keymap.
+;; 2006/10/01 dadams
+;;     icicle-complete-keys: Bind sort functions, to put prefix keys first, by default.
+;;                           Set last-command, before recursing.
+;;     Replaced icicle-alternative-sort with icicle-toggle-alternative-sorting (new).
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Ensure icicle-(current|last)-input are strings, before compare.
+;;     icicle-keys+cmds-w-prefix: Tolerate empty local and global maps.
+;; 2006/09/30 dadams
+;;     Added: icicle-read-kbd-macro, icicle-edmacro-parse-keys, icicle-toggle-angle-brackets.
+;;     icicle-complete-keys-1, icicle-dabbrev-completion:
+;;       key-description -> icicle-key-description, with icicle-key-descriptions-use-<>-flag.
+;;     icicle-complete-keys-1:
+;;       read-kbd-macro -> icicle-read-kbd-macro, with icicle-key-descriptions-use-<>-flag.
+;;       Got rid of extra space in prompt before colon, when no prefix.
+;;     icicle-keys+cmds-w-prefix: Use single-key-description with icicle-*-use-<>-flag.
+;;     icicle-insert-key-description:
+;;       Change arg to a toggle, and use icicle-key-descriptions-use-<>-flag.
+;;     Bind icicle-candidate-set-(retrieve|save) to C-M-<, C-M->, not C-<, C->.
+;;     icicle-dired-saved-file-candidates*:
+;;       Changed doc strings and messages to use dynamic binding of icicle-candidate-set-save.
+;; 2006/09/24 dadams
+;;     Added: icicle-complete-keys-help.
+;;     icicle-complete-keys:
+;;       Bind icicle-*-action-fn to icicle-complete-keys-help.  Mention help keys in docstring.
+;;     icicle-complete-keys-1:
+;;       Set last-command to command, so completion doesn't think candidate was last-command.
+;;     icicle-keys+cmds-w-prefix: Provide placeholder for future use of generic characters.
+;; 2006/09/23 dadams
+;;     icicle-complete-keys-1:
+;;       Error if there are no keys for the prefix.
+;;       Error, not self-insert-command, for key read-kbd-macro can't convert. condition-case.
+;;       Report error if calling cmd fails.
+;;       Use vconcat for recursive call.
+;;       Read cmd, don't intern it - it might be a lambda or byte-compiled function.
+;;       Remove duplicates.
+;;       Provide KEYS arg to call-interactively, for error reporting.
+;;       Don't bind icicle-must-not-match-regexp to "^Character set .*=  self-insert-command".
+;;     icicle-keys+cmds-w-prefix:
+;;       Treat also local keymap and current minor maps.
+;;       Do nothing if keys+maps is nil.
+;;       Only map-keymap if the target is a keymap.
+;;       Use keymapp, not functionp, as the binding test.
+;;       Only add binding if it is a command or keymap.
+;;       Only add self-insert-command binding if the key is char-valid-p.
+;;       Use format %S, not %s for a command binding.
+;;     icicle-insert-key-description: Added no-angle-brackets-p arg.
+;; 2006/09/22 dadams
+;;     icicle-complete-keys-1:
+;;       Filter out keys described "Character set ...= self-insert-command".
+;; 2006/09/20 dadams
+;;     icicle-complete-keys-1: Treat self-insert-command specially.
+;; 2006/09/17 dadams
+;;     Added: icicle-complete-keys(-1), icicle-*-keys-prefix, icicle-keys+cmds-w-prefix,
+;;     icicle-doc: Removed one \n from each candidate.
+;; 2006/09/12 dadams
+;;     Renamed icicle-switch-to-minibuffer to icicle-insert-completion.
+;;     Added: icicle-switch-to/from-minibuffer.
+;;     icicle-completion-help: Keep focus in the minibuffer after displaying help.
+;; 2006/09/02 dadams
+;;     icicle-help-on-(next|previous)-(apropos|prefix)-candidate,
+;;       icicle-(next|previous)-(apropos|prefix)-candidate-action:
+;;       Use save-selected-window, not save-window-excursion.
+;;     icicle-find-file*: In Dired, ignore errors picking up current-line's file name.
+;;     icicle-mouse-choose-completion: Error if minibuffer is not active.
+;; 2006/08/27 dadams
+;;     icicle-abort-minibuffer-input: If minibuffer not active, just kill buffer *Completions*.
+;;     icicle-execute-extended-command-1, icicle-insert-thesaurus-entry, icicle-search-action:
+;;       Ensure orig-window is live before using it.
+;; 2006/08/23 dadams
+;;     Added: icicle-delete-window(s).
+;;     Added soft require of frame-cmds.el.
+;; 2006/08/22 dadams
+;;     icicle-execute-extended-command-1: Bind this-command, don't set it (fixes C-next).
+;;     icicle-help-on-candidate: If no last candidate, then reset to first matching candidate.
+;;     icicle-*-candidate-action, icicle-help-on-*-candidate: save-window-excursion.
+;; 2006/08/20 dadams
+;;     icicle-find-file*: Use diredp-find-a-file* in Dired mode (Emacs 22 or later).
+;;     Bug fix: icicle-candidate-action: Use icicle-*-candidates, not icicle-next-*-candidate.
+;;              icicle-next-*-candidate(-action): Set icicle-current-completion-mode.
+;; 2006/08/18 dadams
+;;     Added: icicle-Info-goto-node(-(action|cmd)).
+;;     icicle-candidate-action: If no icicle-last-completion-candidate, use first candidate.
+;; 2006/08/15 dadams
+;;     Added: icicle-help-on-*-*-candidate,icicle-mouse-help-on-candidate.
+;;     No longer put icicle-candidate-action-command property on symbols (not used).
+;;     Added: icicle-raise-Completions-frame.
+;;     icicle*-candidate-action, icicle-help-on-candidate: Use icicle-raise-Completions-frame.
+;;     icicle-help-on-candidate: Can use it from *Completions* too now.
+;;                               Use icicle-barf-if-outside-Completions-and-minibuffer.
+;; 2006/08/13 dadams
+;;     Added: icicle-Info-index(-(action|cmd)).
+;; 2006/08/04 dadams
+;;     icicle-*-complete-1, icicle-prefix-word-complete, icicle-keep-only-past-inputs:
+;;       Set icicle-last-completion-command to the explicit command, not this-command.
+;;     icicle-history: Call icicle-last-completion-command, not icicle-apropos-complete.
+;;     icicle-apropos-complete-1, icicle-narrow-candidates:
+;;       Removed binding of icicle-apropos-completing-p (not used).
+;;     Added: icicle-plist, icicle-remove-Completions-window, icicle-pp-eval-expression.
+;;     Added soft require of pp+.el.
+;;     icicle-exit-minibuffer, icicle-minibuffer-complete-and-exit,
+;;       icicle-mouse-choose-completion, icicle-abort-minibuffer-input,
+;;       icicle-(apropos|prefix)-complete-1, icicle-keep-only-past-inputs,
+;;       icicle-insert-thesaurus-entry-cand-fn: Use icicle-remove-Completions-window.
+;;     icicle-doc: Treat doc of faces also.
+;;     icicle-non-whitespace-string-p: Added doc string.
+;; 2006/08/03 dadams
+;;     Added:
+;;       icicle-comint-command, icicle-insert-kill, icicle-insert-for-yank,icicle-yank-insert.
+;;     Bound icicle-comint-command to C-c TAB in comint-mode.
+;;     icicle-search, icicle-comint-search: Cleaned up doc string.
+;; 2006/08/02 dadams
+;;     icicle-comint-search: Mention *-prompt-pattern.  Thx to Kevin Rodgers.
+;;     icicle-insert-string-from-variable: Added more variables to the completing-read alist.
+;; 2006/07/29 dadams
+;;     Added: icicle-dispatch-C-., toggle-icicle-search-cleanup, icicle-toggle-search-cleanup.
+;; 2006/07/23 dadams
+;;     Added: icicle-toggle-transforming.
+;;     icicle-comint-search: Bind icicle-transform-function to icicle-remove-duplicates.
+;; 2006/07/22 dadams
+;;     Added: icicle-comint-search, icicle-comint-send-input, icicle-comint-get-*-input,
+;;            icicle-comint-get-final-choice, icicle-search-generic.
+;;     icicle-search: Added require-match arg for non-interactive calls.
+;;                    Run the hooks if no match and no match required, and if we didn't cycle.
+;;                    Return final choice as value (not used yet).
+;;     icicle-insert-string-from-variable: Use buffer-local value of variable, if there is one.
+;;     icicle-insert-string-from-variable:
+;;       Make sure we use the buffer-local value of the variable, if there is one
+;;       Added comint-prompt-regexp to regexp list.
+;;     Added mode hooks for icicle-compilation-search and icicle-comint-send-input.
+;; 2006/07/20 dadams
+;;     Renamed icicle-arrows-respect-* to icicle-cycling-respects-completion-mode-flag.
+;; 2006/07/19 dadams
+;;     Applied patch from Damien Elmes :
+;;       Added: icicle-(next|previous)-context-candidate, icicle-scroll-completions.
+;;       icicle-switch-to-completions, icicle-switch-to-Completions-buf,
+;;         icicle-move-to-next-completion, icicle-map-action, icicle-search-action:
+;;           Use icicle-start-of-completions.
+;;       icicle-(apropos|prefix)-complete-1:
+;;         Set icicle-current-completion-type vs use icicle-arrows-respect-*-flag.
+;;         Use icicle-scroll-completions.
+;;       icicle-current-completion-in-Completions: Use point-min if no previous prop change.
+;;       icicle-keep-only-past-inputs: Use icicle-scroll-completions.
+;;     Renamed icicle-start-of-completions to icicle-start-of-candidates-in-Completions,
+;;             icicle-current-completion-type to icicle-current-completion-mode,
+;;             icicle-*-context-candidate to icicle-(next|previous)-candidate-per-mode,
+;;             icicle-scroll-completions to icicle-scroll-Completions.
+;;     icicle-(next|previous)-context-candidate: Use icicle-barf-if-outside-minibuffer.
+;;     icicle-scroll-Completions: Changed with-selected-window to Emacs 20 equivalent.
+;; 2006/07/18 dadams
+;;     icicle-search: Bind completion-ignore-case to case-fold-search.
+;;     icicle-search-highlight-all-input-matches, icicle-search-action:
+;;       Put search inside condition-case, for bad regexp.
+;;     Added: icicle-toggle-case-sensitivity, toggle-icicle-case-sensitivity.
+;; 2006/07/10 dadams
+;;     Added: icicle-search-region.  Use in search functions.  Thx to Le Wang.
+;; 2006/07/08 dadams
+;;     icicle-search-highlight-all-input-matches: Use *-current-*, not *-current-raw-*.
+;;     icicle-execute-extended-command-1:
+;;       First try a string candidate as arg, then read it to convert it to symbol or number.
+;;       Reset focus back to the minibuffer, in action function.
+;; 2006/07/07 dadams
+;;     Added: icicle-alternative-sort.
+;;     icicle-imenu: Show *Completions* initially for submenu choice (only).
+;;     icicle-execute-extended-command:
+;;       Echo prefix arg in prompt.  Thx: *.dhcp.mdsn.wi.charter.com
+;; 2006/07/06 dadams
+;;     Added (eval-when-compile (require 'icicles-mac)).
+;; 2006/07/05 dadams
+;;     Renamed: icicle-current-regexp-input to icicle-current-raw-input.
+;;     icicle-prefix-complete-1: Don't set icicle-current-raw-input.
+;; 2006/07/04 dadams
+;;     icicle-prefix-complete-1: No longer calculate common prefix and set current input to it.
+;;     Added plist entries to categorize commands:
+;;       icicle-(cycling|completing|candidate-action)-command.
+;;     icicle-(apropos|prefix)-complete-1, icicle-prefix-word-complete,
+;;     icicle-switch-to-Completions-buf, icicle-keep-only-past-inputs, icicle-history:
+;;       Use icicle-cycling-command property.
+;;     icicle-apropos-complete-1: Removed regexp-p arg in call to icicle-save-or-restore-input.
+;; 2006/07/03 dadams
+;;     icicle-(apropos|prefix)-complete-1: deactivate mark after inserting current input.
+;; 2006/06/18 dadams
+;;     icicle-apropos-complete-1, icicle-narrow-candidates: Bind icicle-apropos-completing-p.
+;; 2006/06/09 dadams
+;;     Bug fixes: Picked up matching subdir as default dir, even if there other files match.
+;;                  Thx to Andrey Zhdanov.
+;;                Empty directory not treated as a match.
+;;     icicle-(apropos|prefix)-complete-1:
+;;       If input matches an empty directory, then use that directory as the sole completion.
+;;       Do not expand file-name input before call icicle-file-name-*-candidates.
+;;     icicle-retrieve-last-input: Use insert, not icicle-insert-input (no longer used).
+;;                                 (Input backslashes reverted to slashes.)
+;; 2006/06/08 dadams
+;;     Bug fix: Could not complete after cycling file names.  Thx to Andrey Zhdanov.
+;;     icicle-insert-input: Use icicle-expand-file-name.
+;;     icicle-prefix-complete-1:
+;;       Expand file-name input before call icicle-file-name-prefix-candidates.
+;;       Expand icicle-last-completion-candidate if it is a directory name.
+;; 2006/05/30 dadams
+;;     icicle-erase-minibuffer-or-history-element: Fix for consecutive deletions.
+;; 2006/05/26 dadams
+;;     Added: icicle-erase-minibuffer-or-history-element.
+;; 2006/05/19 dadams
+;;     Renamed icicle-inhibit-reminder* to icicle-reminder*.
+;;     icicle-narrow-candidates: Bind icicle-reminder-prompt-flag to nil, not t.
+;; 2006/05/16 dadams
+;;     Added: icicle-kill(-a)-buffer.
+;; 2006/05/15 dadams
+;;     Renamed: icicle-completion-nospace-flag to icicle-ignore-space-prefix-flag.
+;;     icicle-candidate-set-complement: Put back icicle-ignore-space-prefix-flag.
+;;     icicle-buffer(-other-window): Bind icicle-buffer-ignore-space-prefix-flag.
+;;     Added: icicle-toggle-ignored-space-prefix, toggle-icicle-ignored-space-prefix.
+;; 2006/05/13 dadams
+;;     icicle-occur: Make icicle-search-main-regexp-others unnoticeable instead of
+;;                   setting icicle-search-highlight-all-flag to nil.
+;;     icicle-candidate-set-complement: Use nil, not icicle-completion-nospace-flag.
+;;     Renamed: icicle-search-imenu to icicle-imenu,
+;;              icicle-search-imenu-in-buffer-p to icicle-imenu-in-buffer-p.
+;; 2006/05/12 dadams
+;;     icicle-search-imenu: Remove unmatched submenus.  Error if no imenu for the buffer.
+;;     Added: icicle-search-imenu-in-buffer-p.
+;;     icicle-insert-string-at-point: Use icicle-barf-if-outside-minibuffer.
+;;     Moved to icicles-fn.el: icicle-barf-if-outside-*.
+;;     Moved some commands to minibuffer-cmds section from top-level cmds section.
+;; 2006/05/09 dadams
+;;     Added: icicle-customize-icicles-group, icicle-send-bug-report, icicle-customize-button.
+;; 2006/04/30 dadams
+;;     Added: icicle-map, icicle-map-action.
+;;     icicle-filter-alist: Corrected and simplified.
+;;     icicle-search: Corrected cand-nb adjustment when cycle with action fns.
+;;     Renamed: icicle-search-action-fn to icicle-search-action,
+;;              icicle-search-candidates to icicle-candidates-alist.
+;; 2006/04/28 dadams
+;;     icicle-retrieve-last-input, icicle-(apropos|prefix)-complete-1:
+;;       Use icicle-highlight-initial-whitespace.
+;; 2006/04/25 dadams
+;;     icicle-completion-help: Emacs 21.3's help-insert-xref-button signature is different.
+;; 2006/04/16 dadams
+;;     Added: icicle-search-imenu.
+;;     icicle-search: Bug fixes:
+;;       Treat completion without cycling: error or singleton go-to.
+;;       Only subtract one from candidate number for C- cycling, not regular cycling.
+;; 2006/04/14 dadams
+;;     icicle-search:
+;;       Bug fix: Position was off by one.
+;;       Highlight input match inside each main regexp match (or not).
+;;         Bind icicle-update-input-hook and icicle-incremental-completion-flag.
+;;       Extract code to define icicle-search-action-fn.
+;;       Use icicle-search-candidates instead of local variable search-candidates.
+;;       Respect icicle-search-cleanup-flag.
+;;     Added: icicle-search-highlight-*, icicle-search-action-fn,
+;;            icicle-(insert|save)-text-(from|to)-variable.
+;;     Renamed icicle-search-refined-regexp to icicle-search-current-input.
+;; 2006/04/09 dadams
+;;     icicle-(apropos|prefix)-complete-1: Deal with icicle-arrows-respect-*-flag.
+;;     Moved here from icicles-fn.el: icicle-customize-apropos*, icicle-repeat-complex-command.
+;; 2006/04/07 dadams
+;;     icicle-search: Highlight all occurrences at once (like isearch highlight, but not lazy).
+;;                    Error if no match for initial regexp.
+;;     icicle-occur: Bind icicle-search-highlight-all-flag to nil: don't highlight each line.
+;; 2006/04/02 dadms
+;;     Added: icicle-toggle-regexp-quote, icicle-find-file*-w-wildcards.
+;;     icicle-find-file*: Use icicle-find-file*-w-wildcards.
+;; 2006/03/31 dadams
+;;     icicle-search: Wrap action function with unwind-protect to select minibuffer frame.
+;;                    Use completion-ignore-case when highlighting search hits.
+;;                    Protect delete-overlay with overlayp.
+;;                    Turn off region highlighting (so can see highlighting done here).
+;;                    Removed sit-for-period argument.
+;;     icicle-candidate-set-save: Use prin1 instead of pp.
+;; 2006/03/27 dadams
+;;     Added: icicle-occur.
+;;     icicle-search: Highlight also match of current regexp, inside that of regexp arg.
+;;                    Use new faces icicle-search-*-regexp.
+;;     icicle-search, icicle-switch-to-Completions-buf, icicle-move-to-next-completion:
+;;       Use new, generic icicle-place-overlay.
+;;     Removed icicle-place-search-overlay.
+;; 2006/03/26 dadams
+;;     icicle-search: Use icicle-search-overlay.  Ensure don't match twice at same position.
+;;                    Added regexp arg.  Use 0 as sit-for default.
+;;     Added: icicle-place-search-overlay.
+;; 2006/03/25 dadams
+;;     icicle-prefix-complete: Minor bug fix: Don't save try-completion if not a string.
+;;     icicle-candidate-set-(save|retrieve): Allow use of a variable to save/retrieve.
+;;     Added: icicle-candidate-set-(retrieve-from|save-to)-variable, icicle-*-no-display,
+;;            icicle-prefix-complete-1.
+;;     icicle-apropos-complete-1: Added no-display-p optional arg.
+;;     Use no-display-p arg in calls to icicle-display-candidates-in-Completions.
+;;     icicle-candidate-set-(retrieve-from|save-to)-cache-file: Pass a consp, not t.
+;;     icicle-candidate-set-retrieve: Don't display *Completions*.
+;; 2006/03/24 dadams
+;;     Added icicle-delete-char.
+;; 2006/03/23 dadams
+;;     icicle-candidate-set-define: Rewrote.  Can also use at top level.
+;;       Error if wrong result type.  Sort result.  Use display-completion-list and
+;;       icicle-narrow-candidates (unless at top level).
+;;     icicle-narrow-candidates: Can call from top-level (but not interactively).
+;;     icicle-candidate-set-complement: Use icicle-maybe-sort-and-strip-candidates.
+;;     Mention in doc strings of minibuffer and *Completions* functions: where, key.
+;; 2006/03/22 dadams
+;;     icicle-find-file*: Use default-directory as default, so opens directory on empty input.
+;;     icicle-prefix-complete:
+;;       Save icicle-current-regexp-input.
+;;       Set icicle-current-input to common prefix.  Use it everywhere here.
+;;     Calls to icicle-display-candidates-in-Completions: no root arg now.
+;; 2006/03/21 dadams
+;;     icicle-insert-input: Bug fix: Use directory of input, not default-directory.
+;;                                   Append a slash if input itself is a directory.
+;; 2006/03/20 dadams
+;;     icicle-retrieve-last-input: Insert icicle-current-regexp-input if repeat C-l.
+;;     Added: icicle-insert-input.
+;; 2006/03/19 dadams
+;;     icicle-apropos-complete-1: Call icicle-save-or-restore-input with non-nil regexp-p arg.
+;; 2006/03/17 dadams
+;;     Added: icicle-add/update-saved-completion-set, icicle-remove-saved-completion-set,
+;;            icicle-retrieve-candidates-from-set.
+;;     Removed: icicle-cache-file.
+;;     icicle-candidate-set-retrieve: Read candidates set and use its cache file.
+;;                                    Enable recursive minibuffers.
+;;     icicle-candidate-set-save: Read candidates set and cache-file names.
+;;                                Use icicle-add/update-saved-completion-set.
+;;     icicle-barf-if-outside-minibuffer: Move interactive test to calling functions.
+;;     icicle-files-within: Moved to icicle-fn.el.
+;; 2006/03/16 dadams
+;;     Added: icicle*-saved-completion-set.
+;; 2006/03/14 dadams
+;;     icicle-narrow-candidates: Handle no-catch error.  Don't use icicle-completing-p.
+;;     icicle-candidate-set-complement:
+;;       Do what we do in icicle-candidate-set-retrieve: call icicle-narrow-candidates.
+;;     icicle-candidate-set-(retrieve|complement): Msg when display.
+;;     icicle-(apropos|prefix)-complete-1:
+;;       Removed test for last-command = icicle-candidate-set-complement.
+;; 2006/03/13 dadams
+;;     Added: icicle-candidate-set-(retrieve-from|save-to)-cache-file.
+;;     icicle-candidate-set-(retrieve|save): C-u uses cache file.
+;; 2006/03/12 dadams
+;;     Added: icicle-dired-saved-file-candidates(-other-window), icicle-locate-file*,
+;;            icicle-files-within.
+;; 2006/03/11 dadams
+;;     icicle-find-file*, icicle-delete-file*:
+;;       Reverted to simple form (moved directory control to icicles-mac.el).
+;;     icicle-keep-only-past-inputs: Expand file name relative to directory of last input.
+;; 2006/03/10 dadams
+;;     icicle-find-file*, icicle-delete-file*: Expand file name relative to dir of last input.
+;;     Renamed icicle-minibuffer-contents to icicle-minibuffer-contents-from-minibuffer.
+;; 2006/03/09 dadams
+;;     icicle-barf-if-outside-*: Removed argument - use this-command instead.
+;; 2006/03/08 dadams
+;;     icicle-bookmark: Use default value, not init value, for completing-read.
+;; 2006/03/07 dadams
+;;     icicle-doc: Save table in minibuffer-completion-table, so can access via C-RET too.
+;;     icicle-insert-thesaurus-entry, icicle-*doc:
+;;       Removed binding of icicle-incremental-completion-flag to nil.
+;;     Added: icicle-barf-if-outside-(minibuffer|Completions).  Use in appropriate commands.
+;;     Added: icicle-non-whitespace-string-p.  Use in icicle-*doc.
+;; 2006/03/06 dadams
+;;     Update doc strings of *-thesaurus*.
+;; 2006/03/05 dadams
+;;     Added: icicle-toggle-incremental-completion, toggle-icicle-incremental-completion.
+;; 2006/03/03 dadams
+;;     icicle-*doc: Clarified doc strings.  Updated prompts.
+;;     Added: icicle-help-button.  Use in icicle-completion-help.
+;; 2006/03/02 dadams
+;;     icicle-insert-thesaurus-entry, icicle-complete-thesaurus-entry:
+;;       Use synonyms-ensure-synonyms-read-from-cache.  Clarified doc strings.
+;;     icicle-complete-thesaurus-entry: Error if no word at point.  Correct looking-at regexp.
+;; 2006/03/01 dadams
+;;     Added: icicle-insert-thesaurus-entry, icicle-insert-thesaurus-entry-cand-fn,
+;;            icicle-complete-thesaurus-entry.
+;;     icicle-(previous|next)-(apropos|prefix)-candidate-action: Wrap in save-excursion.
+;;     Use icicle-clear-minibuffer instead of icicle-erase-minibuffer non-interactively.
+;;     icicle-erase-minibuffer: Use icicle-call-then-update-Completions.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; You need not load this file.  It contains only documentation.
+
+(provide 'icicles-chg)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-chg.el ends here
diff --git a/auto-install/icicles-cmd1.el b/auto-install/icicles-cmd1.el
new file mode 100644
index 0000000..d63ccaf
--- /dev/null
+++ b/auto-install/icicles-cmd1.el
@@ -0,0 +1,6407 @@
+;;; icicles-cmd1.el --- Top-level commands for Icicles
+;;
+;; Filename: icicles-cmd1.el
+;; Description: Top-level commands for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:25:04 2006
+;; Version: 22.0
+;; Last-Updated: Fri Sep  2 16:25:27 2011 (-0700)
+;;           By: dradams
+;;     Update #: 22215
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-cmd1.el
+;; Keywords: extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos-fn+var', `avoid', `backquote', `bytecomp',
+;;   `cl', `cus-edit', `cus-face', `cus-load', `cus-start', `doremi',
+;;   `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
+;;   `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-face',
+;;   `icicles-fn', `icicles-mac', `icicles-mcmd', `icicles-opt',
+;;   `icicles-var', `image-dired', `kmacro', `levenshtein',
+;;   `misc-fns', `mouse3', `mwheel', `pp', `pp+', `regexp-opt',
+;;   `ring', `ring+', `strings', `thingatpt', `thingatpt+',
+;;   `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  top-level commands (and a few non-interactive functions used in
+;;  those commands).  Library `icicles-cmd2.el' is a continuation of
+;;  this file (a single file for all top-level commands would be too
+;;  large to upload to Emacs Wiki).
+;;
+;;  For commands to be used mainly in the minibuffer or buffer
+;;  `*Completions*', see `icicles-mcmd.el'.
+;;
+;;  For Icicles documentation, see `icicles-doc1.el' and
+;;  `icicles-doc2.el'.
+;;
+;;  If you use the byte-compiled version of this library,
+;;  `icicles-cmd1.elc', in Emacs 23, then it must be byte-compiled
+;;  using Emacs 23.  Otherwise, Icicles key completion (and perhaps
+;;  other things?) will not work correctly.
+;;
+;;  Macros defined here:
+;;
+;;    `icicle-define-bookmark-command',
+;;    `icicle-define-bookmark-command-1',
+;;    `icicle-define-bookmark-other-window-command'.
+;;
+;;  Commands defined here - (+) means a multi-command:
+;;
+;;    (+)`clear-option', (+)`icicle-add-buffer-candidate',
+;;    (+)`icicle-add-buffer-config',
+;;    `icicle-add-entry-to-saved-completion-set',
+;;    `icicle-bbdb-complete-name', (+)`icicle-bookmark',
+;;    (+)`icicle-bookmark-all-tags',
+;;    (+)`icicle-bookmark-all-tags-other-window',
+;;    (+)`icicle-bookmark-all-tags-regexp',
+;;    (+)`icicle-bookmark-all-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-bookmark-list',
+;;    `icicle-bookmark-bookmark-list-narrow',
+;;    (+)`icicle-bookmark-cmd', (+)`icicle-bookmark-desktop',
+;;    `icicle-bookmark-desktop-narrow', (+)`icicle-bookmark-dired',
+;;    (+)`icicle-bookmark-dired-other-window',
+;;    `icicle-bookmark-dired-narrow',
+;;    (+)`icicle-bookmarked-buffer-list',
+;;    (+)`icicle-bookmarked-file-list', (+)`icicle-bookmark-file',
+;;    (+)`icicle-bookmark-file-all-tags',
+;;    (+)`icicle-bookmark-file-all-tags-other-window',
+;;    (+)`icicle-bookmark-file-all-tags-regexp',
+;;    (+)`icicle-bookmark-file-all-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-file-other-window',
+;;    `icicle-bookmark-file-narrow',
+;;    (+)`icicle-bookmark-file-some-tags',
+;;    (+)`icicle-bookmark-file-some-tags-other-window',
+;;    (+)`icicle-bookmark-file-some-tags-regexp',
+;;    (+)`icicle-bookmark-file-some-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-file-this-dir',
+;;    (+)`icicle-bookmark-file-this-dir-other-window',
+;;    (+)`icicle-bookmark-file-this-dir-all-tags',
+;;    (+)`icicle-bookmark-file-this-dir-all-tags-other-window',
+;;    (+)`icicle-bookmark-file-this-dir-all-tags-regexp',
+;;    (+)`icicle-bookmark-file-this-dir-all-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-file-this-dir-some-tags',
+;;    (+)`icicle-bookmark-file-this-dir-some-tags-other-window',
+;;    (+)`icicle-bookmark-file-this-dir-some-tags-regexp',
+;;    (+)`icicle-bookmark-file-this-dir-some-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-gnus',
+;;    (+)`icicle-bookmark-gnus-other-window',
+;;    `icicle-bookmark-gnus-narrow',
+;;    (+)`icicle-bookmark-info-other-window',
+;;    `icicle-bookmark-info-narrow', `icicle-bookmark-jump',
+;;    `icicle-bookmark-jump-other-window', (+)`icicle-bookmark-list',
+;;    (+)`icicle-bookmark-local-file',
+;;    (+)`icicle-bookmark-local-file-other-window',
+;;    `icicle-bookmark-local-file-narrow', (+)`icicle-bookmark-man',
+;;    (+)`icicle-bookmark-man-other-window',
+;;    `icicle-bookmark-man-narrow', (+)`icicle-bookmark-non-file',
+;;    (+)`icicle-bookmark-non-file-other-window',
+;;    `icicle-bookmark-non-file-narrow',
+;;    (+)`icicle-bookmark-other-window', (+)`icicle-bookmark-region',
+;;    (+)`icicle-bookmark-region-other-window',
+;;    `icicle-bookmark-region-narrow',
+;;    (+)`icicle-bookmark-remote-file',
+;;    (+)`icicle-bookmark-remote-file-other-window',
+;;    `icicle-bookmark-remote-file-narrow',
+;;    `icicle-bookmark-save-marked-files',
+;;    `icicle-bookmark-save-marked-files-as-project',
+;;    `icicle-bookmark-save-marked-files-more',
+;;    `icicle-bookmark-save-marked-files-persistently',
+;;    `icicle-bookmark-save-marked-files-to-variable',
+;;    `icicle-bookmark-set', (+)`icicle-bookmark-some-tags',
+;;    (+)`icicle-bookmark-some-tags-other-window',
+;;    (+)`icicle-bookmark-some-tags-regexp',
+;;    (+)`icicle-bookmark-some-tags-regexp-other-window',
+;;    (+)`icicle-bookmark-specific-buffers',
+;;    `icicle-bookmark-specific-buffers-narrow',
+;;    (+)`icicle-bookmark-specific-buffers-other-window',
+;;    (+)`icicle-bookmark-specific-files',
+;;    `icicle-bookmark-specific-files-narrow',
+;;    (+)`icicle-bookmark-specific-files-other-window',
+;;    (+)`icicle-bookmark-this-buffer',
+;;    `icicle-bookmark-this-buffer-narrow',
+;;    (+)`icicle-bookmark-this-buffer-other-window',
+;;    (+)`icicle-bookmark-url', `icicle-bookmark-url-narrow',
+;;    (+)`icicle-bookmark-url-other-window', (+)`icicle-bookmark-w3m',
+;;    (+)`icicle-bookmark-w3m-other-window',
+;;    `icicle-bookmark-w3m-narrow', (+)`icicle-buffer',
+;;    (+)`icicle-buffer-config', (+)`icicle-buffer-list',
+;;    (+)`icicle-buffer-other-window', `icicle-cd-for-abs-files',
+;;    `icicle-cd-for-loc-files', (+)`icicle-clear-history',
+;;    (+)`icicle-clear-current-history', (+)`icicle-color-theme',
+;;    `icicle-comint-dynamic-complete',
+;;    `icicle-comint-dynamic-complete-filename',
+;;    `icicle-comint-replace-by-expanded-filename',
+;;    (+)`icicle-command-abbrev', (+)`icicle-command-abbrev-command',
+;;    (+)`icicle-completing-yank', `icicle-customize-apropos',
+;;    `icicle-customize-apropos-faces',
+;;    `icicle-customize-apropos-groups',
+;;    `icicle-customize-apropos-options',
+;;    `icicle-customize-apropos-options-of-type',
+;;    (+)`icicle-customize-face',
+;;    (+)`icicle-customize-face-other-window',
+;;    `icicle-customize-icicles-group', `icicle-dabbrev-completion',
+;;    (+)`icicle-delete-file', (+)`icicle-delete-window',
+;;    (+)`icicle-delete-windows', (+)`icicle-directory-list',
+;;    (+)`icicle-dired', `icicle-dired-chosen-files',
+;;    `icicle-dired-chosen-files-other-window',
+;;    (+)`icicle-dired-other-window', `icicle-dired-project',
+;;    `icicle-dired-project-other-window',
+;;    `icicle-dired-saved-file-candidates',
+;;    `icicle-dired-saved-file-candidates-other-window',
+;;    `icicle-dired-save-marked',
+;;    `icicle-dired-save-marked-as-project',
+;;    `icicle-dired-save-marked-more',
+;;    `icicle-dired-save-marked-persistently',
+;;    `icicle-dired-save-marked-to-variable',
+;;    `icicle-doremi-increment-variable+',
+;;    `icicle-ess-complete-filename',
+;;    `icicle-ess-complete-object-name',
+;;    `icicle-ess-internal-complete-object-name',
+;;    `icicle-ess-R-complete-object-name',
+;;    (+)`icicle-execute-extended-command',
+;;    (+)`icicle-execute-named-keyboard-macro', (+)`icicle-face-list',
+;;    (+)`icicle-file', (+)`icicle-file-list',
+;;    (+)`icicle-file-other-window', (+)`icicle-find-file',
+;;    (+)`icicle-find-file-absolute',
+;;    (+)`icicle-find-file-absolute-other-window',
+;;    (+)`icicle-find-file-in-tags-table',
+;;    (+)`icicle-find-file-in-tags-table-other-window',
+;;    (+)`icicle-find-file-other-window',
+;;    (+)`icicle-find-file-read-only',
+;;    (+)`icicle-find-file-read-only-other-window',
+;;    (+)`icicle-find-first-tag',
+;;    (+)`icicle-find-first-tag-other-window', (+)`icicle-find-tag',
+;;    `icicle-grep-saved-file-candidates',
+;;    `icicle-gud-gdb-complete-command', (+)`icicle-increment-option',
+;;    (+)`icicle-increment-variable', (+)`icicle-insert-buffer',
+;;    (+)`icicle-kill-buffer', (+)`icicle-kmacro',
+;;    `icicle-lisp-complete-symbol', (+)`icicle-locate-file',
+;;    (+)`icicle-locate-file-no-symlinks',
+;;    (+)`icicle-locate-file-no-symlinks-other-window',
+;;    (+)`icicle-locate-file-other-window',
+;;    (+)`icicle-other-window-or-frame', `icicle-pop-tag-mark',
+;;    `icicle-pp-eval-expression', (+)`icicle-recent-file',
+;;    (+)`icicle-recent-file-other-window',
+;;    `icicle-recompute-shell-command-candidates',
+;;    (+)`icicle-remove-buffer-candidate',
+;;    (+)`icicle-remove-buffer-config',
+;;    `icicle-remove-entry-from-saved-completion-set',
+;;    (+)`icicle-remove-file-from-recentf-list',
+;;    (+)`icicle-remove-saved-completion-set',
+;;    `icicle-repeat-complex-command',
+;;    (+)`icicle-reset-option-to-nil',
+;;    (+)`icicle-select-bookmarked-region', (+)`icicle-select-frame',
+;;    `icicle-select-frame-by-name', (+)`icicle-select-window',
+;;    `icicle-select-window-by-name', `icicle-send-bug-report',
+;;    (+)`icicle-set-option-to-t',
+;;    `icicle-shell-dynamic-complete-command',
+;;    `icicle-shell-dynamic-complete-environment-variable',
+;;    `icicle-shell-dynamic-complete-filename',
+;;    (+)`icicle-toggle-option', (+)`icicle-yank-maybe-completing',
+;;    (+)`toggle'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `custom-variable-p', `icicle-binary-option-p',
+;;    `icicle-bookmark-cleanup', `icicle-bookmark-cleanup-on-quit',
+;;    `icicle-bookmark-delete-action', `icicle-bookmark-help-string',
+;;    `icicle-bookmark-jump-1', `icicle-clear-history-1',
+;;    `icicle-clear-history-entry',
+;;    `icicle-comint-dynamic-complete-as-filename',
+;;    `icicle-comint-dynamic-simple-complete',
+;;    `icicle-comint-replace-orig-completion-fns',
+;;    `icicle-command-abbrev-action',
+;;    `icicle-command-abbrev-matching-commands',
+;;    `icicle-command-abbrev-record', `icicle-command-abbrev-regexp',
+;;    `icicle-customize-faces', `icicle-dabbrev--abbrev-at-point',
+;;    `icicle-default-buffer-names',
+;;    `icicle-delete-file-or-directory',
+;;    `icicle-execute-extended-command-1', `icicle-explore',
+;;    `icicle-find-first-tag-action',
+;;    `icicle-find-first-tag-other-window-action',
+;;    `icicle-find-tag-action', `icicle-find-tag-define-candidates',
+;;    `icicle-find-tag-define-candidates-1',
+;;    `icicle-find-tag-final-act', `icicle-find-tag-help',
+;;    `icicle-find-tag-quit-or-error', `icicle-insert-for-yank',
+;;    `icicle-kill-a-buffer-and-update-completions',
+;;    `icicle-kmacro-action', `icicle-lisp-completion-at-point',
+;;    (+)`icicle-locate-file-1', `icicle-locate-file-action',
+;;    `icicle-locate-file-other-window-action',
+;;    `icicle-make-file+date-candidate', `icicle-make-frame-alist',
+;;    `icicle-make-window-alist',
+;;    `icicle-bookmark-propertize-candidate',
+;;    `icicle-pp-display-expression',
+;;    `icicle-remove-buffer-candidate-action',
+;;    `icicle-remove-buffer-config-action',
+;;    `icicle-remove-from-recentf-candidate-action',
+;;    `icicle-remove-saved-set-action',
+;;    `icicle-shell-command-on-file',
+;;    `icicle-shell-dynamic-complete-as-command',
+;;    `icicle-shell-dynamic-complete-as-environment-variable'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `icicle-locate-file-action-fn',
+;;    `icicle-locate-file-no-symlinks-p'.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `dabbrev.el' have
+;;              been REDEFINED HERE:
+;;
+;;  `dabbrev-completion' - Use Icicles minibuffer completion when there
+;;                         are multiple candidates.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `bbdb-com.el' have
+;;              been REDEFINED HERE:
+;;              (BBDB is available here: http://bbdb.sourceforge.net/.)
+;;
+;;  `bbdb-complete-name' - Use Icicles minibuffer completion when there
+;;                         are multiple candidates.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `lisp.el' have
+;;              been REDEFINED in Icicles:
+;;
+;;  `lisp-complete-symbol' - Selects `*Completions*' window even if on
+;;                           another frame.
+;;
+;;
+;;  ***** NOTE: The following function defined in `simple.el' has
+;;              been REDEFINED HERE:
+;;
+;;  `repeat-complex-command' - Use `completing-read' to read command.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `cus-edit.el' have
+;;              been REDEFINED HERE:
+;;
+;;  `customize-apropos', `customize-apropos-faces',
+;;  `customize-apropos-groups', `customize-apropos-options' -
+;;     Use `completing-read' to read the regexp.
+;;  `customize-face', `customize-face-other-window' - Multi-commands.
+;;
+;;
+;;  Key bindings made by Icicles: See "Key Bindings" in
+;;  `icicles-doc2.el'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Icicles Top-Level Commands, Part 1")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;; pushnew
+                                  ;; plus, for Emacs < 21: dolist, push
+(eval-when-compile (when (>= emacs-major-version 21) (require 'recentf))) ;; recentf-mode
+(eval-when-compile (require 'dabbrev))
+  ;; dabbrev-case-fold-search, dabbrev-upcase-means-case-search, dabbrev--last-obarray,
+  ;; dabbrev--last-completion-buffer, dabbrev--last-abbreviation, dabbrev--check-other-buffers,
+  ;; dabbrev-case-replace, dabbrev--reset-global-variables, dabbrev--minibuffer-origin,
+  ;; dabbrev--find-all-expansions, dabbrev--substitute-expansion
+(eval-when-compile (require 'bookmark))
+  ;; bookmark-all-names, bookmark-buffer-name, bookmark-current-bookmark
+(eval-when-compile (require 'comint))
+  ;; comint-completion-addsuffix, comint-completion-autolist, comint-completion-fignore,
+  ;; comint-completion-recexact, comint-directory, comint-dynamic-complete-filename,
+  ;; comint-dynamic-complete-functions, comint-line-beginning-position,
+  ;; comint-match-partial-filename, comint-quote-filename
+(eval-when-compile (require 'shell)) ;; shell-backward-command, shell-completion-execonly,
+  ;; shell-dynamic-complete-command, shell-dynamic-complete-environment-variable,
+  ;; shell-dynamic-complete-filename, shell-match-partial-variable
+(eval-when-compile (require 'etags))
+  ;; file-of-tag, find-tag, find-tag-default, find-tag-default-function,
+  ;; find-tag-marker-ring, find-tag-other-window, goto-tag-location-function, snarf-tag-function,
+  ;; tag-find-file-of-tag-noselect, tags-case-fold-search,
+  ;; tags-lazy-completion-table, tags-table-files, visit-tags-table-buffer
+
+;; Commented out because `synonyms.el' soft-requires Icicles.
+;; (eval-when-compile (require 'synonyms nil t)) ;; (no error if not found):
+  ;; synonyms-ensure-synonyms-read-from-cache, synonyms-obarray
+(eval-when-compile (require 'misc-cmds nil t)) ;; (no error if not found):
+  ;; kill-buffer-and-its-windows
+(eval-when-compile (require 'bbdb nil t) (require 'bbdb-com nil t)) ;; (no error if not found):
+  ;; bbdb-auto-fill-function, bbdb-complete-name, bbdb-complete-name-allow-cycling,
+  ;; bbdb-complete-name-cleanup, bbdb-complete-name-hooks, bbdb-completion-display-record,
+  ;; bbdb-completion-predicate, bbdb-completion-type, bbdb-display-records-1,
+  ;; bbdb-dwim-net-address, bbdb-expand-mail-aliases, bbdb-extract-address-components-func,
+  ;; bbdb-gag-messages, bbdb-hashtable, bbdb-mapc, bbdb-pop-up-bbdb-buffer, bbdb-record-aka,
+  ;; bbdb-record-name, bbdb-record-net, bbdb-search-intertwingle, bbdb-string-trim
+(require 'cus-edit)
+  ;; customize-apropos, customize-apropos-faces, customize-apropos-groups,
+  ;; customize-apropos-options, custom-buffer-create, custom-buffer-order-groups, customize-face,
+  ;; customize-face-other-window, custom-sort-items
+(require 'misc-fns nil t)   ;; (no error if not found): another-buffer
+(require 'frame-cmds nil t) ;; (no error if not found): delete-windows-on (my version)
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "icicles-mac")   ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'icicles-mac)))           ; Require, so can load separately if not on `load-path'.
+  ;; icicle-assoc-delete-all, icicle-bind-file-candidate-keys, icicle-buffer-bindings,
+  ;; icicle-condition-case-no-debug, icicle-define-command, icicle-define-file-command,
+  ;; icicle-define-add-to-alist-command, icicle-file-bindings, icicle-unbind-file-candidate-keys
+(require 'icicles-mcmd)
+  ;; icicle-yank
+(require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
+  ;; icicle-add-proxy-candidates-flag, icicle-buffer-configs, icicle-buffer-extras,
+  ;; icicle-buffer-ignore-space-prefix-flag, icicle-buffer-match-regexp,
+  ;; icicle-buffer-no-match-regexp, icicle-buffer-predicate, icicle-buffer-require-match-flag,
+  ;; icicle-buffer-sort, icicle-color-themes, icicle-saved-completion-sets,
+  ;; icicle-sort-comparer, icicle-transform-function
+(require 'icicles-var)                  ; (This is required anyway by `icicles-fn.el'.)
+  ;; icicle-candidate-action-fn, icicle-candidate-nb, icicle-candidates-alist,
+  ;; icicle-completion-candidates, icicle-current-input, icicle-extra-candidates,
+  ;; icicle-get-alist-candidate-function, icicle-incremental-completion-p, icicle-kmacro-alist,
+  ;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate,
+  ;; icicle-re-no-dot, icicle-saved-completion-candidates
+(require 'icicles-fn)                   ; (This is required anyway by `icicles-mcmd.el'.)
+  ;; icicle-delete-dups, icicle-highlight-lighter, icicle-read-from-minibuf-nil-default
+
+
+
+;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
+;; These are probably benign - ignore them.  Icicles is designed to work with multiple
+;; versions of Emacs, and that fact provokes compiler warnings.  If you get byte-compiler
+;; errors (not warnings), then please report a bug, using `M-x icicle-send-bug-report'.
+
+;;; Some defvars to quiet byte-compiler a bit:
+
+(when (< emacs-major-version 21)
+  (defvar eval-expression-debug-on-error))
+
+(when (< emacs-major-version 22)
+  (defvar icicle-kmacro-alist)          ; In `icicles-var.el'
+  (defvar kmacro-ring)                  ; In `kmacro.el'
+  (defvar read-file-name-completion-ignore-case) ;  In `minibuffer.el'
+  (defvar recentf-list)                 ; In `recentf.el'
+  (defvar tags-case-fold-search))       ; In `etags.el'
+
+(when (< emacs-major-version 23)
+  (defvar read-buffer-completion-ignore-case))
+
+(defvar bbdb-complete-name-allow-cycling) ; In `bbdb-com.el'
+(defvar bbdb-extract-address-components-func) ; In `bbdb-com.el'
+(defvar bbdb-expand-mail-aliases)       ; In `bbdb-com.el'
+(defvar bbdb-complete-name-hooks)       ; In `bbdb-com.el'
+(defvar bbdb-completion-display-record) ; In `bbdb.el'
+(defvar bbdb-completion-type)           ; In `bbdb.el'
+(defvar bbdb-hashtable)                 ; In `bbdb.el'
+(defvar bmkp-bookmark-name-length-max)  ; In `bookmark+-1.el'
+(defvar bmkp-non-file-filename)         ; In `bookmark+-1.el'
+(defvar bmkp-prompt-for-tags-flag)      ; In `bookmark+-1.el'
+(defvar bmkp-sorted-alist)              ; In `bookmark+-1.el'
+(defvar bookmark-current-point)         ; In `bookmark.el' for Emacs < 
+(defvar color-theme)                    ; In `color-theme.el'
+(defvar color-themes)                   ; In `color-theme.el'
+(defvar color-theme-initialized)        ; In `color-theme.el'
+(defvar ess-current-process-name)       ; In `ess-inf.el'
+(defvar ess-mode-syntax-table)          ; In `ess-cust.el'
+(defvar ess-use-R-completion)           ; In `ess-cust.el'
+(defvar filesets-data)                  ; In `filesets.el'
+(defvar find-tag-default-function)      ; In `etags.el'
+(defvar find-tag-marker-ring)           ; In `etags.el'
+(defvar goto-tag-location-function)     ; In `etags.el'
+(defvar icicle-clear-history-hist)      ; In `icicle-clear-history-1',`icicle-clear-current-history'
+(defvar icicle-window-alist)            ; In `icicle-select-window'
+(defvar shell-completion-execonly)      ; In `shell.el'
+(defvar snarf-tag-function)             ; In `etags.el'
+(defvar w3m-current-title)              ; In `w3m.el'.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Icicles Top-Level Commands, Part 1")
+;;; Icicles Top-Level Commands, Part 1 .   .   .   .   .   .   .   .   .
+
+
+;; REPLACE ORIGINAL `pp-eval-expression' defined in `pp.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; This is essentially the same as `pp-eval-expression' defined in `pp+.el'.
+;;
+;; 1. Read with completion, using `icicle-read-expression-map'.
+;; 2. Progress message added.
+;; 3. Added optional arg and insertion behavior.
+;; 4. Respect `icicle-pp-eval-expression-print-length', `icicle-pp-eval-expression-print-level',
+;;    and `eval-expression-debug-on-error'.
+;; 5. Adjusted to work in different Emacs releases.
+;;
+;;;###autoload
+(defun icicle-pp-eval-expression (expression ; Bound to `M-:' in Icicle mode.
+                                  &optional insert-value)
+  "Evaluate Emacs-Lisp sexp EXPRESSION, and pretty-print its value.
+Add the value to the front of the variable `values'.
+With a prefix arg, insert the value into the current buffer at point.
+ With a negative prefix arg, if the value is a string, then insert it
+ into the buffer without double-quotes (`\"').
+With no prefix arg:
+ If the value fits on one line (frame width) show it in the echo area.
+ Otherwise, show the value in buffer `*Pp Eval Output*'.
+
+This command respects user options
+`icicle-pp-eval-expression-print-length',
+`icicle-pp-eval-expression-print-level', and
+`eval-expression-debug-on-error'.
+
+Emacs-Lisp mode completion and indentation bindings are in effect.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `eval-expression' or `pp-eval-expression' to
+`icicle-pp-eval-expression'.  If you do not want this remapping, then
+customize option `icicle-top-level-key-bindings'."
+  (interactive
+   (list (read-from-minibuffer "Eval: " nil icicle-read-expression-map t 'read-expression-history)
+         current-prefix-arg))
+  (message "Evaluating...")
+  (if (or (not (boundp 'eval-expression-debug-on-error))
+          (null eval-expression-debug-on-error))
+      (setq values  (cons (eval expression) values))
+    (let ((old-value  (make-symbol "t"))
+          new-value)
+      ;; Bind debug-on-error to something unique so that we can
+      ;; detect when evaled code changes it.
+      (let ((debug-on-error  old-value))
+        (setq values     (cons (eval expression) values)
+              new-value  debug-on-error))
+      ;; If evaled code has changed the value of debug-on-error,
+      ;; propagate that change to the global binding.
+      (unless (eq old-value new-value)
+        (setq debug-on-error  new-value))))
+  (let ((print-length  icicle-pp-eval-expression-print-length)
+        (print-level   icicle-pp-eval-expression-print-level))
+    (cond (insert-value
+           (message "Evaluating...done. Value inserted.")
+           (setq insert-value  (prefix-numeric-value insert-value))
+           (if (or (not (stringp (car values))) (wholenump insert-value))
+               (pp (car values) (current-buffer))
+             (princ (car values) (current-buffer))))
+          (t (icicle-pp-display-expression (car values) "*Pp Eval Output*")))))
+
+
+;; REPLACE ORIGINAL in `pp.el':
+;; 1. Use no `emacs-lisp-mode-hook' or `change-major-mode-hook'.
+;; 2. Call `font-lock-fontify-buffer'.
+;;
+(defun icicle-pp-display-expression (expression out-buffer-name)
+  "Prettify and show EXPRESSION in a way appropriate to its length.
+If a temporary buffer is needed for representation, it is named
+OUT-BUFFER-NAME."
+  (let* ((old-show-function  temp-buffer-show-function)
+         ;; Use this function to display the buffer.
+         ;; This function either decides not to display it at all
+         ;; or displays it in the usual way.
+         (temp-buffer-show-function
+          #'(lambda (buf)
+              (with-current-buffer buf
+                (goto-char (point-min))
+                (end-of-line 1)
+                (if (or (< (1+ (point)) (point-max))
+                        (>= (- (point) (point-min)) (frame-width)))
+                    (let ((temp-buffer-show-function  old-show-function)
+                          (old-selected               (selected-window))
+                          (window                     (display-buffer buf)))
+                      (goto-char (point-min)) ; expected by some hooks ...
+                      (make-frame-visible (window-frame window))
+                      (unwind-protect
+                           (progn (select-window window)
+                                  (run-hooks 'temp-buffer-show-hook))
+                        (select-window old-selected)
+                        (message "Evaluating...done. See buffer `%s'."
+                                 out-buffer-name)))
+                  (message "%s" (buffer-substring (point-min) (point))))))))
+    (with-output-to-temp-buffer out-buffer-name
+      (pp expression)
+      (with-current-buffer standard-output
+        (setq buffer-read-only  nil)
+        ;; Avoid `let'-binding because `change-major-mode-hook' is local.
+        ;; IOW, avoid this runtime message:
+        ;; "Making change-major-mode-hook buffer-local while locally let-bound!"
+        ;; Suggestion from Stefan M.: Can just set these hooks instead of binding,
+        ;; because they are not permanent-local.  They'll be emptied and
+        ;; repopulated as needed by the call to emacs-lisp-mode.
+        (set (make-local-variable 'emacs-lisp-mode-hook) nil)
+        (set (make-local-variable 'change-major-mode-hook) nil)
+        (emacs-lisp-mode)
+        (set (make-local-variable 'font-lock-verbose) nil)
+        (font-lock-fontify-buffer)))))
+
+(defun icicle-shell-command-on-file (file)
+  "Read a shell command and invoke it, passing FILE as an argument."
+  (dired-run-shell-command
+   (dired-shell-stuff-it (icicle-read-shell-command (format "! on `%s': " file)) (list file) nil)))
+
+;;;###autoload
+(defun icicle-recompute-shell-command-candidates (&optional savep)
+  "Update option `icicle-shell-command-candidates-cache'.
+Recompute the available shell commands using your search path.
+Return the new option value.
+With a prefix argument, the updated option is saved persistently.
+
+If the value of option `icicle-guess-commands-in-path' is not `load',
+then turning on Icicle mode (again) resets the cache value to ().
+If the value of `icicle-guess-commands-in-path' is `first-use', then
+the cache is updated when you next use it, but it is not saved."
+  (interactive "P")
+  (setq icicle-shell-command-candidates-cache  (icicle-compute-shell-command-candidates))
+  (when savep (funcall icicle-customize-save-variable-function
+                       'icicle-shell-command-candidates-cache
+                       icicle-shell-command-candidates-cache))
+  icicle-shell-command-candidates-cache)
+
+
+;; REPLACE ORIGINAL `comint-dynamic-complete' defined in `comint.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses Icicles completion when there are multiple candidates.
+;;
+;;;###autoload
+(defun icicle-comint-dynamic-complete () ; Bound to `TAB' in Comint (and Shell) mode.
+  "Dynamically perform completion at point.
+Calls the functions in `comint-dynamic-complete-functions', but with
+Icicles functions substituted, to perform completion until a function
+returns non-nil, at which point completion is assumed to have
+occurred.
+
+Uses Icicles completion."
+  (interactive)
+  ;; Need a symbol for `run-hook-with-args-until-success', so bind one.
+  (let ((hook  (icicle-comint-replace-orig-completion-fns)))
+    (run-hook-with-args-until-success 'hook)))
+
+(defun icicle-comint-replace-orig-completion-fns ()
+  "Return `comint-dynamic-complete-functions', but with Icicles functions."
+  (let ((old  comint-dynamic-complete-functions)
+        (new  ())
+        pair)
+    (dolist (fn  old)
+      (if (setq pair  (assoc fn icicle-comint-dynamic-complete-replacements))
+          (push (eval (cadr pair)) new)
+        (push fn new)))
+    (nreverse new)))
+
+;;;###autoload
+(defun icicle-comint-dynamic-complete-filename ()
+  "Dynamically complete the filename at point.
+Completes if after a filename.  See `comint-match-partial-filename' and
+`icicle-comint-dynamic-complete-as-filename'.
+This function is similar to `comint-replace-by-expanded-filename', except that
+it won't change parts of the filename already entered in the buffer; it just
+adds completion characters to the end of the filename.  A completions listing
+may be shown in a help buffer if completion is ambiguous.
+
+Completion is dependent on the value of `comint-completion-addsuffix',
+`comint-completion-recexact' and `comint-completion-fignore', and the timing of
+completions listing is dependent on the value of `comint-completion-autolist'.
+
+Returns t if successful.
+
+Uses Icicles completion."
+  (interactive)
+  (when (comint-match-partial-filename)
+    (unless (window-minibuffer-p (selected-window)) (message "Completing file name..."))
+    (icicle-comint-dynamic-complete-as-filename)))
+
+(defun icicle-comint-dynamic-complete-as-filename ()
+  "Dynamically complete at point as a filename.
+See `icicle-comint-dynamic-complete-filename'.
+Returns t if successful."
+  (let* ((completion-ignore-case         (if (boundp 'read-file-name-completion-ignore-case)
+                                             read-file-name-completion-ignore-case
+                                           (memq system-type '(ms-dos windows-nt cygwin))))
+         (completion-ignored-extensions  comint-completion-fignore)
+         (minibuffer-p                   (window-minibuffer-p (selected-window)))
+         (success                        t)
+         (dirsuffix                      (cond ((not comint-completion-addsuffix)         "")
+                                               ((not (consp comint-completion-addsuffix)) "/")
+                                               (t  (car comint-completion-addsuffix))))
+         (filesuffix                     (cond ((not comint-completion-addsuffix)         "")
+                                               ((not (consp comint-completion-addsuffix)) " ")
+                                               (t  (cdr comint-completion-addsuffix))))
+         (filename                       (comint-match-partial-filename))
+         (filename-beg                   (if filename (match-beginning 0) (point)))
+         (filename-end                   (if filename (match-end 0) (point)))
+         (filename                       (or filename ""))
+         (filedir                        (file-name-directory filename))
+         (filenondir                     (file-name-nondirectory filename))
+         (directory                      (if filedir (comint-directory filedir) default-directory))
+         (completion                     (file-name-completion filenondir directory)))
+    (cond ((null completion)
+           (if minibuffer-p
+               (minibuffer-message (format " [No completions of `%s']" filename))
+             (message "No completions of `%s'" filename))
+           (setq success  nil))
+          ((eq completion t)            ; Already completed: "the-file".
+           (insert filesuffix)
+           (unless minibuffer-p (message "Sole completion")))
+          ((string-equal completion "") ; A directory: "dir/" - complete it.
+           (icicle-condition-case-no-debug nil
+               (let* ((icicle-show-Completions-initially-flag      t)
+                      (icicle-incremental-completion-p             'display)
+                      (icicle-top-level-when-sole-completion-flag  t)
+                      (choice
+                       (save-excursion
+                         (save-window-excursion (read-file-name "Complete: " directory nil t)))))
+                 (when (and choice (not (string= choice directory)))
+                   (insert (comint-quote-filename
+                            (file-name-nondirectory (directory-file-name choice))))
+                   (insert (if (file-directory-p choice) dirsuffix filesuffix))))
+             (error nil)))
+          (t                            ; COMPLETION is the common prefix string.
+           (let ((file            (concat (file-name-as-directory directory) completion))
+                 (use-dialog-box  nil)) ; Inhibit use of open-file dialog box if called from menu.
+             ;; Insert completion.  The completion string might have a different case from
+             ;; what's in the prompt, if `read-file-name-completion-ignore-case' is non-nil.
+             (delete-region filename-beg filename-end)
+             (if filedir (insert (comint-quote-filename filedir)))
+             (insert (comint-quote-filename (directory-file-name completion)))
+             (cond ((symbolp (file-name-completion completion directory))
+                    ;; We inserted a unique completion.  Add suffix.
+                    (insert (if (file-directory-p file) dirsuffix filesuffix))
+                    (unless minibuffer-p (message "Completed")))
+                   ((and comint-completion-recexact comint-completion-addsuffix
+                         (string-equal filenondir completion)
+                         (file-exists-p file))
+                    ;; It's not unique, but user wants shortest match.
+                    (insert (if (file-directory-p file) dirsuffix filesuffix))
+                    (unless minibuffer-p (message "Completed shortest")))
+                   ;; It's not unique.  Let user choose a completion.
+                   ((or comint-completion-autolist (string-equal filenondir completion))
+                    (icicle-condition-case-no-debug nil
+                        (let* ((icicle-show-Completions-initially-flag      t)
+                               (icicle-incremental-completion-p             'display)
+                               (icicle-top-level-when-sole-completion-flag  t)
+                               (choice
+                                (save-excursion
+                                  (save-window-excursion
+                                    (read-file-name
+                                     "Complete: " directory completion nil completion
+                                     (and (> emacs-major-version 21)
+                                          #'(lambda (f) (string-match completion f))))))))
+                          (when choice
+                            (delete-backward-char (length completion))
+                            (insert (comint-quote-filename
+                                     (file-name-nondirectory (directory-file-name choice))))
+                            (insert (if (file-directory-p choice) dirsuffix filesuffix))))
+                      (error nil)))
+                   (t (unless minibuffer-p (message "Partially completed")))))))
+    success))
+
+;;;###autoload
+(defun icicle-shell-dynamic-complete-command ()
+  "Dynamically complete the command at point.
+Similar to `icicle-comint-dynamic-complete-filename', but this
+searches `exec-path' (minus the trailing Emacs library path) for
+completion candidates.  Note that this may not be the same as the
+shell's idea of the path.
+
+Completion is dependent on the value of `shell-completion-execonly',
+plus those that effect file completion.
+See `icicle-shell-dynamic-complete-as-command'.
+
+Returns t if successful.
+
+Uses Icicles completion."
+  (interactive)
+  (let ((filename  (comint-match-partial-filename)))
+    (if (and filename
+             (save-match-data (not (string-match "[~/]" filename)))
+             (eq (match-beginning 0) (save-excursion (shell-backward-command 1) (point))))
+        (prog2 (unless (window-minibuffer-p (selected-window))
+                 (message "Completing command name..."))
+            (icicle-shell-dynamic-complete-as-command)))))
+
+(defun icicle-shell-dynamic-complete-as-command ()
+  "Dynamically complete text at point as a command.
+See `icicle-shell-dynamic-complete-filename'.
+Return t if successful."
+  (let* ((filename       (or (comint-match-partial-filename) ""))
+         (filenondir     (file-name-nondirectory filename))
+         (path-dirs      (cdr (reverse exec-path)))
+         (cwd            (file-name-as-directory (expand-file-name default-directory)))
+         (ignored-extensions
+          (and comint-completion-fignore
+               (mapconcat #'(lambda (x) (concat (regexp-quote x) "$"))
+                          comint-completion-fignore "\\|")))
+         (dir            "")
+         (comps-in-dir   ())
+         (file           "")
+         (abs-file-name  "")
+         (completions    ()))
+    (while path-dirs                    ; Go thru each dir in the search path, finding completions.
+      (setq dir           (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
+            comps-in-dir  (and (file-accessible-directory-p dir)
+                               (file-name-all-completions filenondir dir)))
+      (while comps-in-dir               ; Go thru each completion, to see whether it should be used.
+        (setq file           (car comps-in-dir)
+              abs-file-name  (concat dir file))
+        (when (and (not (member file completions))
+                   (not (and ignored-extensions (string-match ignored-extensions file)))
+                   (or (string-equal dir cwd) (not (file-directory-p abs-file-name)))
+                   (or (null shell-completion-execonly) (file-executable-p abs-file-name)))
+          (setq completions  (cons file completions)))
+        (setq comps-in-dir  (cdr comps-in-dir)))
+      (setq path-dirs  (cdr path-dirs)))
+    (let ((success  (let ((comint-completion-addsuffix  nil)
+                          (icicle-candidate-help-fn
+                           #'(lambda (cand)
+                               (shell-command (concat "apropos " (shell-quote-argument cand))
+                                              "*Help*"))))
+                      (icicle-comint-dynamic-simple-complete filenondir completions))))
+      (when (and (memq success '(sole shortest)) comint-completion-addsuffix
+                 (not (file-directory-p (comint-match-partial-filename))))
+        (insert " "))
+      success)))
+
+;;;###autoload
+(defun icicle-comint-replace-by-expanded-filename ()
+  "`comint-replace-by-expanded-filename', but uses Icicles completion.
+Dynamically complete, expand, and canonicalize the filename at point."
+  (interactive)
+  (let ((filename  (comint-match-partial-filename)))
+    (when filename
+      (replace-match (expand-file-name filename) t t)
+      (icicle-comint-dynamic-complete-filename))))
+
+(defun icicle-comint-dynamic-simple-complete (stub candidates)
+  "Dynamically complete STUB from CANDIDATES list.
+Inserts completion characters at point by completing STUB from the
+strings in CANDIDATES.  Uses Icicles completion if completion is
+ambiguous.
+
+Returns nil if no completion was inserted.
+Returns `sole' if completed with the only completion match.
+Returns `shortest' if completed with the shortest of the completion matches.
+Returns `partial' if completed as far as possible with the completion matches.
+Returns `listed' if a completion listing was shown.
+
+See also `icicle-comint-dynamic-complete-filename'."
+  (let* ((completion-ignore-case  (memq system-type '(ms-dos windows-nt cygwin)))
+         (minibuffer-p            (window-minibuffer-p (selected-window)))
+         (suffix                  (cond ((not comint-completion-addsuffix)         "")
+                                        ((not (consp comint-completion-addsuffix)) " ")
+                                        (t  (cdr comint-completion-addsuffix))))
+         (candidates              (mapcar #'list candidates))
+         (completions             (all-completions stub candidates)))
+    (cond ((null completions)
+           (if minibuffer-p
+               (minibuffer-message (format " [No completions of `%s']" stub))
+             (message "No completions of `%s'" stub))
+           nil)
+          ((= 1 (length completions))
+           (let ((completion  (car completions)))
+             (if (string-equal completion stub)
+                 (unless minibuffer-p (message "Sole completion"))
+               (insert (substring completion (length stub)))
+               (unless minibuffer-p (message "Completed")))
+             (insert suffix)
+             'sole))
+          (t                            ; There's no unique completion.
+           (let ((completion  (try-completion stub candidates)))
+             ;; Insert the longest substring.
+             (insert (substring completion (length stub)))
+             (cond ((and comint-completion-recexact comint-completion-addsuffix
+                         (string-equal stub completion)
+                         (member completion completions))
+                    (insert suffix)     ; User wants shortest match.
+                    (unless minibuffer-p (message "Completed shortest"))
+                    'shortest)
+                   ((or comint-completion-autolist (string-equal stub completion))
+                    (icicle-condition-case-no-debug nil ;  Let user choose a completion.
+                        (let* ((icicle-show-Completions-initially-flag      t)
+                               (icicle-incremental-completion-p             'display)
+                               (icicle-top-level-when-sole-completion-flag  t)
+                               (choice (save-excursion
+                                         (completing-read "Complete: " (mapcar #'list completions)
+                                                          nil t nil nil completion))))
+                          (when choice
+                            (delete-backward-char (length completion))
+                            (insert choice suffix)))
+                      (error nil))
+                    'listed)
+                   (t
+                    (unless minibuffer-p (message "Partially completed"))
+                    'partial)))))))
+
+;;;###autoload
+(defun icicle-shell-dynamic-complete-filename ()
+  "Dynamically complete the filename at point.
+Completes only if point is at a suitable position for a filename
+argument."
+  (interactive)
+  (let ((opoint  (point))
+        (beg     (comint-line-beginning-position)))
+    (when (save-excursion
+            (goto-char (if (re-search-backward "[;|&]" beg t) (match-end 0) beg))
+            (re-search-forward "[^ \t][ \t]" opoint t))
+      (icicle-comint-dynamic-complete-as-filename))))
+
+;;;###autoload
+(defun icicle-shell-dynamic-complete-environment-variable ()
+  "`shell-dynamic-complete-environment-variable' but uses Icicles completion."
+  (interactive)
+  (require 'shell)
+  (let ((variable  (shell-match-partial-variable)))
+    (if (and variable (string-match "^\\$" variable))
+        (prog2 (unless (window-minibuffer-p (selected-window))
+                 (message "Completing variable name..."))
+            (icicle-shell-dynamic-complete-as-environment-variable)))))
+
+(defun icicle-shell-dynamic-complete-as-environment-variable ()
+  "`shell-dynamic-complete-as-environment-variable' but uses Icicles completion."
+  (require 'shell)
+  (let* ((var                          (or (shell-match-partial-variable) ""))
+         (variable                     (substring var (or (string-match "[^$({]\\|$" var) 0)))
+         (variables                    (mapcar #'(lambda (x) (substring x 0 (string-match "=" x)))
+                                               process-environment))
+         (addsuffix                    comint-completion-addsuffix)
+         (comint-completion-addsuffix  nil)
+         (success                      (icicle-comint-dynamic-simple-complete variable variables)))
+    (if (memq success '(sole shortest))
+        (let* ((var           (shell-match-partial-variable))
+               (variable      (substring var (string-match "[^$({]" var)))
+               (protection    (cond ((string-match "{" var) "}")
+                                    ((string-match "(" var) ")")
+                                    (t "")))
+               (suffix        (cond ((null addsuffix) "")
+                                    ((file-directory-p
+                                      (comint-directory (getenv variable))) "/")
+                                    (t " "))))
+          (insert protection  suffix)))
+    success))
+
+;;;###autoload
+(defun icicle-ess-complete-object-name (&optional listcomp)
+  "`ess-complete-object-name', but uses Icicles completion.
+Complete `ess-language' object preceding point.
+This is `icicle-ess-R-complete-object-name' if `ess-use-R-completion',
+and `icicle-ess-internal-complete-object-name' otherwise."
+  (interactive "P")
+  (if ess-use-R-completion
+      (icicle-ess-R-complete-object-name)
+    (icicle-ess-internal-complete-object-name listcomp)))
+
+;;;###autoload
+(defun icicle-ess-internal-complete-object-name (&optional listcomp)
+  "`ess-internal-complete-object-name', but uses Icicles completion.
+Complete `ess-language' object preceding point."
+  (interactive "P")
+  (ess-make-buffer-current)
+  (if (memq (char-syntax (preceding-char)) '(?w ?_))
+      (let* ((comint-completion-addsuffix  nil)
+             (end                          (point))
+             (buffer-syntax                (syntax-table))
+             (beg                          (unwind-protect
+                                                (save-excursion
+                                                  (set-syntax-table ess-mode-syntax-table)
+                                                  (backward-sexp 1)
+                                                  (point))
+                                             (set-syntax-table buffer-syntax)))
+             (full-prefix                  (buffer-substring beg end))
+             (pattern                      full-prefix)
+             (listname                  ; See if we're indexing a list with `$'
+              (and (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$" full-prefix)
+                   (setq pattern  (if (not (match-beginning 2))
+                                      ""
+                                    (substring full-prefix (match-beginning 2) (match-end 2))))
+                   (substring full-prefix (match-beginning 1) (match-end 1))))
+             (classname                 ; Are we trying to get a slot via `@' ?
+              (and (string-match "\\(.+\\)@\\(\\(\\sw\\|\\s_\\)*\\)$" full-prefix)
+                   (setq pattern  (if (not (match-beginning 2))
+                                      ""
+                                    (substring full-prefix (match-beginning 2) (match-end 2))))
+                   (progn (ess-write-to-dribble-buffer (format "(ess-C-O-Name : slots..) : patt=%s"
+                                                               pattern))
+                          (substring full-prefix (match-beginning 1) (match-end 1)))))
+             (components
+              (if listname
+                  (ess-object-names listname)
+                (if classname
+                    (ess-slot-names classname)
+                  ;; Default case: It hangs here when options (error=recoves):
+                  (ess-get-object-list ess-current-process-name)))))
+        ;; Return non-nil to prevent history expansions
+        (or (icicle-comint-dynamic-simple-complete  pattern components) 'none))))
+
+(defun icicle-ess-complete-filename ()
+  "`ess-complete-filename', but uses Icicles completion.
+Do file completion only within strings, or when `!' call is used."
+  (if (comint-within-quotes
+       (1- (process-mark (get-buffer-process (current-buffer)))) (point))
+      (progn (if (featurep 'xemacs)
+                 (icicle-comint-dynamic-complete-filename) ; Work around XEmacs bug.  GNU Emacs and
+               (icicle-comint-replace-by-expanded-filename)) ; a working XEmacs return t in a string
+             t)))
+
+;;;###autoload
+(defun icicle-ess-R-complete-object-name ()
+  "`ess-R-complete-object-name', but uses Icicles completion.
+Completion in R."
+  (interactive)
+  (ess-make-buffer-current)
+  (let* ((comint-completion-addsuffix  nil)
+         (beg-of-line                  (save-excursion (comint-bol nil) (point)))
+         (end-of-line                  (point-at-eol))
+         (line-buffer                  (buffer-substring beg-of-line end-of-line))
+         (NS                           (if (ess-current-R-at-least '2.7.0)
+                                           "utils:::"
+                                         "rcompgen:::"))
+         (token-string                  ; Setup, including computation of the token
+          (progn
+            (ess-command (format (concat NS ".assignLinebuffer('%s')\n") line-buffer))
+            (ess-command (format (concat NS ".assignEnd(%d)\n") (- (point) beg-of-line)))
+            (car (ess-get-words-from-vector (concat NS ".guessTokenFromLine()\n")))))
+         (possible-completions          ; Compute and retrieve possible completions
+          (progn
+            (ess-command (concat NS ".completeToken()\n"))
+            (ess-get-words-from-vector (concat NS ".retrieveCompletions()\n")))))
+    (or (icicle-comint-dynamic-simple-complete token-string possible-completions) 'none)))
+
+;;;###autoload
+(defun icicle-gud-gdb-complete-command (&optional command a b)
+  "`gud-gdb-complete-command', but uses Icicles completion.
+Perform completion on the GDB command preceding point."
+  (interactive)
+  (if command
+      (setq command  (concat "p " command)) ; Used by gud-watch in mini-buffer.
+    (let ((end  (point)))               ; Used in GUD buffer.
+      (setq command  (buffer-substring (comint-line-beginning-position) end))))
+  (let* ((command-word
+          ;; Find the word break.  This match will always succeed.
+          (and (string-match "\\(\\`\\| \\)\\([^ ]*\\)\\'" command)
+               (substring command (match-beginning 2))))
+         (complete-list
+          (gud-gdb-run-command-fetch-lines (concat "complete " command)
+                                           (current-buffer)
+                                           ;; From string-match above.
+                                           (match-beginning 2))))
+    ;; Protect against old versions of GDB.
+    (and complete-list
+         (string-match "^Undefined command: \"complete\"" (car complete-list))
+         (error "This version of GDB doesn't support the `complete' command"))
+    ;; Sort the list like readline.
+    (setq complete-list  (sort complete-list (function string-lessp)))
+    ;; Remove duplicates.
+    (let ((first   complete-list)
+          (second  (cdr complete-list)))
+      (while second
+        (if (string-equal (car first) (car second))
+            (setcdr first (setq second  (cdr second)))
+          (setq first   second
+                second  (cdr second)))))
+    ;; Add a trailing single quote if there is a unique completion
+    ;; and it contains an odd number of unquoted single quotes.
+    (and (= (length complete-list) 1)
+         (let ((str    (car complete-list))
+               (pos    0)
+               (count  0))
+           (while (string-match "\\([^'\\]\\|\\\\'\\)*'" str pos)
+             (setq count  (1+ count)
+                   pos    (match-end 0)))
+           (and (= (mod count 2) 1)
+                (setq complete-list  (list (concat str "'"))))))
+    ;; Let comint handle the rest.
+    (icicle-comint-dynamic-simple-complete command-word complete-list)))
+
+
+;; REPLACE ORIGINAL `dabbrev-completion' defined in `dabbrev.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; You can complete from an empty abbrev also.
+;; Uses Icicles completion when there are multiple candidates.
+;;
+(when (and (fboundp 'dabbrev-completion) (not (fboundp 'old-dabbrev-completion)))
+  (defalias 'old-dabbrev-completion (symbol-function 'dabbrev-completion)))
+
+;;;###autoload
+(defun icicle-dabbrev-completion (&optional arg) ; Bound to `C-M-/' globally.
+  "Completion on current word.
+Like \\[dabbrev-expand], but finds all expansions in the current buffer
+and presents suggestions for completion.
+
+With a prefix argument, it searches all buffers accepted by
+`dabbrev-friend-buffer-function', to find the completions.
+
+If the prefix argument is 16 (which comes from `C-u C-u'), then it
+searches *ALL* buffers.
+
+With no prefix argument, it reuses an old completion list
+if there is a suitable one already."
+  (interactive "*P")
+  (unless (featurep 'dabbrev)
+    (unless (require 'dabbrev nil t) (error "Library `dabbrev' not found"))
+    (icicle-mode 1))                    ; Redefine `dabbrev-completion' to Icicles version.
+  (dabbrev--reset-global-variables)
+  (let* ((dabbrev-check-other-buffers  (and arg t)) ; Must be t
+         (dabbrev-check-all-buffers    (and arg (= (prefix-numeric-value arg) 16)))
+         (abbrev                       (icicle-dabbrev--abbrev-at-point))
+         (ignore-case-p                (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+                                                case-fold-search
+                                              dabbrev-case-fold-search)
+                                            (or (not dabbrev-upcase-means-case-search)
+                                                (string= abbrev (downcase abbrev)))))
+         (my-obarray                   dabbrev--last-obarray)
+         init)
+    ;; If new abbreviation to expand, then expand it.
+    (save-excursion
+      (unless (and (null arg)
+                   my-obarray
+                   (or (eq dabbrev--last-completion-buffer (current-buffer))
+                       (and (window-minibuffer-p (selected-window))
+                            (eq dabbrev--last-completion-buffer (dabbrev--minibuffer-origin))))
+                   dabbrev--last-abbreviation
+                   (>= (length abbrev) (length dabbrev--last-abbreviation))
+                   (string= dabbrev--last-abbreviation
+                            (substring abbrev 0 (length dabbrev--last-abbreviation)))
+                   (setq init  (try-completion abbrev my-obarray)))
+        (setq dabbrev--last-abbreviation  abbrev)
+        (let ((completion-list         (dabbrev--find-all-expansions abbrev ignore-case-p))
+              (completion-ignore-case  ignore-case-p))
+          ;; Make an obarray with all expansions
+          (setq my-obarray  (make-vector (length completion-list) 0))
+          (unless (> (length my-obarray) 0)
+            (error "No dynamic expansion for \"%s\" found%s" abbrev
+                   (if dabbrev--check-other-buffers "" " in this-buffer")))
+          (dolist (string  completion-list)
+            (cond ((or (not ignore-case-p) (not dabbrev-case-replace))
+                   (intern string my-obarray))
+                  ((string= abbrev (icicle-upcase abbrev))
+                   (intern (icicle-upcase string) my-obarray))
+                  ((string= (substring abbrev 0 1) (icicle-upcase (substring abbrev 0 1)))
+                   (intern (capitalize string) my-obarray))
+                  (t (intern (downcase string) my-obarray))))
+          (setq dabbrev--last-obarray            my-obarray
+                dabbrev--last-completion-buffer  (current-buffer)
+                ;; Find the expanded common string.
+                init                             (try-completion abbrev my-obarray)))))
+    ;; Let the user choose between the expansions
+    (unless (stringp init) (setq init  abbrev))
+    (cond
+      ((and (not (string-equal init ""))
+            (not (string-equal (downcase init) (downcase abbrev)))
+            (<= (length (all-completions init my-obarray)) 1))
+       (message "Completed (no other completions)")
+       (if (< emacs-major-version 21)
+           (dabbrev--substitute-expansion nil abbrev init)
+         (dabbrev--substitute-expansion nil abbrev init nil))
+       (when (window-minibuffer-p (selected-window)) (message nil)))
+;;$$       ;; Complete text only up through the common root. NOT USED.
+;;       ((and icicle-dabbrev-stop-at-common-root-p
+;;             (not (string-equal init ""))
+;;             (not (string-equal (downcase init) (downcase abbrev))))
+;;        (message "Use `%s' again to complete further"
+;;                 (icicle-key-description (this-command-keys)
+;;                                         (not icicle-key-descriptions-use-<>-flag)))
+;;        (if (< emacs-major-version 21)
+;;            (dabbrev--substitute-expansion nil abbrev init)
+;;          (dabbrev--substitute-expansion nil abbrev init nil))
+;;        (when (window-minibuffer-p (selected-window)) (message nil))) ; $$ NEEDED?
+      (t
+       ;; String is a common root already.  Use Icicles completion.
+       (icicle-highlight-lighter)
+       (message "Making completion list...")
+       (search-backward abbrev)
+       (replace-match "")
+       (condition-case nil
+           (let* ((icicle-show-Completions-initially-flag  t)
+                  (icicle-incremental-completion-p         'display)
+                  (minibuffer-completion-table             my-obarray)
+                  (choice
+                   (completing-read "Complete: " my-obarray nil nil init nil init)))
+             (when choice (insert choice)))
+         (quit (insert abbrev)))))))
+
+(defun icicle-dabbrev--abbrev-at-point ()
+  "Like `dabbrev--abbrev-at-point', but returns \"\" if there is no match.
+Vanilla `dabbrev--abbrev-at-point' raises an error if no match."
+  (let ((abv ""))
+    (setq dabbrev--last-abbrev-location  (point)) ; Record the end of the abbreviation.
+    (unless (bobp)
+      (save-excursion                   ; Return abbrev at point
+        ;; If we aren't right after an abbreviation, move point back to just after one.
+        ;; This is so the user can get successive words by typing the punctuation followed by M-/.
+        (save-match-data
+          (when (and (save-excursion
+                       (forward-char -1)
+                       (not (looking-at
+                             (concat "\\(" (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") "\\)+"))))
+                     (re-search-backward (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") nil t))
+            (forward-char 1)))
+        (dabbrev--goto-start-of-abbrev) ; Now find the beginning of that one.
+        (setq abv  (buffer-substring-no-properties dabbrev--last-abbrev-location (point)))))
+    abv))
+
+
+;; REPLACE ORIGINAL `bbdb-complete-name' defined in `bbdb-com.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Note: BBDB, the Insidious Big Brother Database, is available here:
+;;       http://bbdb.sourceforge.net/.
+;;
+;; Uses Icicles completion when there are multiple candidates.
+;;
+;; Free vars here: `bbdb-*' are bound in `bbdb-com.el'.
+;;;###autoload
+(defun icicle-bbdb-complete-name (&optional start-pos)
+  "Complete the user full-name or net-address before point.
+Completes only up to the preceding newline, colon, or comma, or the
+value of START-POS.
+
+If what has been typed is unique, insert an entry of the form \"User
+Name \" (but see `bbdb-dwim-net-address-allow-redundancy').
+If it is a valid completion but not unique, you can choose from the
+list of completions using Icicles completion.
+
+If your input is completed and `bbdb-complete-name-allow-cycling' is
+true, then you can repeat to cycle through the nets for the matching
+record.
+
+When called with a prefix arg, display a list of all nets.  You can
+control completion behaviour using `bbdb-completion-type'."
+  (interactive)
+  (unless (and (require 'bbdb nil t) (require 'bbdb-com nil t))
+    (error "`icicle-bbdb-complete-name' requires BBDB"))
+  (let* ((end                  (point))
+         (beg                  (or start-pos (save-excursion (re-search-backward
+                                                              "\\(\\`\\|[\n:,]\\)[ \t]*")
+                                                             (goto-char (match-end 0)) (point))))
+         (orig                 (buffer-substring beg end))
+         (typed                (downcase orig))
+         (pattern              (bbdb-string-trim typed))
+         ;; DADAMS -
+         ;; Replaced `(bbdb-hashtable)' by its expansion (bbdb-with-db-buffer ... bbdb-hashtable),
+         ;; to avoid the silly macro altogether and simplify user byte-compiling a little.
+         (ht                   (bbdb-with-db-buffer (bbdb-records nil t) bbdb-hashtable))
+         ;; Make a list of possible completion strings (all-the-completions), and a flag to
+         ;; indicate if there's a single matching record or not (only-one-p).
+         (only-one-p           t)
+         (all-the-completions  ())
+         (pred
+          #'(lambda (sym)
+              (and (bbdb-completion-predicate sym)
+                   (progn
+                     (when (and only-one-p all-the-completions
+                                (or
+                                 ;; Not sure about this. More than one record attached to the symbol?
+                                 ;; Does that happen?
+                                 (> (length (symbol-value sym)) 1)
+                                 ;; This is the doozy. Multiple syms which all match the same record.
+                                 (delete t (mapcar #'(lambda (x)
+                                                       (equal (symbol-value x) (symbol-value sym)))
+                                                   all-the-completions))))
+                       (setq only-one-p  nil))
+                     (if (memq sym all-the-completions)
+                         nil
+                       (setq all-the-completions  (cons sym all-the-completions)))))))
+         (completion           (progn (all-completions pattern ht pred)
+                                      (try-completion pattern ht)))
+         (exact-match          (eq completion t)))
+    (cond
+      ;; No matches found OR you're trying completion on an already-completed record.
+      ;; In the latter case, we might have to cycle through the nets for that record.
+      ((or (null completion)
+           (and bbdb-complete-name-allow-cycling
+                exact-match             ; Which is a net of the record
+                (member orig (bbdb-record-net (car (symbol-value (intern-soft pattern ht)))))))
+       (bbdb-complete-name-cleanup)     ; Clean up the completion buffer, if it exists
+       (unless (catch 'bbdb-cycling-exit ; Check for cycling
+                 ;; Jump straight out if we're not cycling
+                 (unless bbdb-complete-name-allow-cycling (throw 'bbdb-cycling-exit nil))
+                 ;; Find the record we're working on.
+                 (let* ((addr  (funcall bbdb-extract-address-components-func orig))
+                        (rec  (and (listp addr)
+                                   ;; For now, we ignore the case where this returns more than
+                                   ;; one record.  Ideally, the last expansion would be stored
+                                   ;; in a buffer-local variable, perhaps.
+                                   (car (bbdb-search-intertwingle (caar addr)
+                                                                  (car (cdar addr)))))))
+                   (unless rec (throw 'bbdb-cycling-exit nil))
+                   (if current-prefix-arg
+                       ;; Use completion buffer
+                       (let ((standard-output  (get-buffer-create "*Completions*")))
+                         ;; A previously existing buffer has to be cleaned first
+                         (with-current-buffer standard-output
+                           (setq buffer-read-only  nil)
+                           (erase-buffer))
+                         (display-completion-list
+                          (mapcar #'(lambda (n) (bbdb-dwim-net-address rec n))
+                                  (bbdb-record-net rec)))
+                         (delete-region beg end)
+                         (switch-to-buffer standard-output))
+                     ;; Use next address
+                     (let* ((addrs      (bbdb-record-net rec))
+                            (this-addr  (or (cadr (member (car (cdar addr)) addrs))
+                                            (nth 0 addrs))))
+                       (if (= (length addrs) 1)
+                           (throw 'bbdb-cycling-exit t) ; No alternatives. don't signal an error.
+                         ;; Replace with new mail address
+                         (delete-region beg end)
+                         (insert (bbdb-dwim-net-address rec this-addr))
+                         (run-hooks 'bbdb-complete-name-hooks)
+                         (throw 'bbdb-cycling-exit t))))))
+         ;; FALL THROUGH.  Check mail aliases
+         (when (and (or (not bbdb-expand-mail-aliases) (not (expand-abbrev)))
+                    bbdb-complete-name-hooks)
+           (message "No completion for `%s'" pattern) (icicle-ding)))) ; no matches
+
+      ;; Match for a single record. If cycling is enabled then we don't
+      ;; care too much about the exact-match part.
+      ((and only-one-p (or exact-match bbdb-complete-name-allow-cycling))
+       (let* ((sym   (if exact-match (intern-soft pattern ht) (car all-the-completions)))
+              (recs  (symbol-value sym))
+              the-net match-recs lst primary matched)
+         (while recs
+           (when (bbdb-record-net (car recs))
+             ;; Did we match on name?
+             (let ((b-r-name  (or (bbdb-record-name (car recs)) "")))
+               (if (string= pattern (substring (downcase b-r-name) 0
+                                               (min (length b-r-name) (length pattern))))
+                   (setq match-recs  (cons (car recs) match-recs)
+                         matched     t)))
+             ;; Did we match on aka?
+             (unless matched
+               (setq lst  (bbdb-record-aka (car recs)))
+               (while lst
+                 (if (string= pattern (substring (downcase (car lst)) 0
+                                                 (min (length (downcase (car lst)))
+                                                      (length pattern))))
+                     (setq match-recs  (append match-recs (list (car recs)))
+                           matched     t
+                           lst         ())
+                   (setq lst  (cdr lst)))))
+             ;; Name didn't match name so check net matching
+             (unless matched
+               (setq lst      (bbdb-record-net (car recs))
+                     primary  t)        ; primary wins over secondary...
+               (while lst
+                 (if (string= pattern (substring (downcase (car lst)) 0
+                                                 (min (length (downcase (car lst)))
+                                                      (length pattern))))
+                     (setq the-net     (car lst)
+                           lst         ()
+                           match-recs  (if primary
+                                           (cons (car recs) match-recs)
+                                         (append match-recs (list (car recs))))))
+                 (setq lst      (cdr lst)
+                       primary  nil))))
+           (setq recs     (cdr recs)    ; Next rec for loop.
+                 matched  nil))
+         (unless match-recs (error "Only exact matching record has net field"))
+         ;; Replace the text with the expansion
+         (delete-region beg end)
+         (insert (bbdb-dwim-net-address (car match-recs) the-net))
+         ;; If we're past fill-column, wrap at the previous comma.
+         (when (and (bbdb-auto-fill-function) (>= (current-column) fill-column))
+           (let ((p  (point))
+                 bol)
+             (save-excursion
+               (beginning-of-line)
+               (setq bol  (point))
+               (goto-char p)
+               (when (search-backward "," bol t) (forward-char 1) (insert "\n   ")))))
+         ;; Update the *BBDB* buffer if desired.
+         (when bbdb-completion-display-record
+           (let ((bbdb-gag-messages  t))
+             (bbdb-pop-up-bbdb-buffer)
+             (bbdb-display-records-1 match-recs t)))
+         (bbdb-complete-name-cleanup)
+         ;; Call the exact-completion hook
+         (run-hooks 'bbdb-complete-name-hooks)))
+
+      ;; Partial match.  Note: we can't use the trimmed version of the pattern here or
+      ;; we'll recurse infinitely on e.g. common first names.
+      ((and (stringp completion) (not (string= typed completion)))
+       (delete-region beg end)
+       (insert completion)
+       (setq end  (point))
+       (let ((last                              "")
+             (bbdb-complete-name-allow-cycling  nil))
+         (while (and (stringp completion) (not (string= completion last))
+                     (setq last        completion
+                           pattern     (downcase orig)
+                           completion  (progn (all-completions pattern ht pred)
+                                              (try-completion pattern ht))))
+           (when (stringp completion) (delete-region beg end) (insert completion)))
+         (bbdb-complete-name beg)))     ; RECURSE <================
+
+      ;; Exact match, but more than one record
+      (t
+       (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
+       (let (dwim-completions uniq nets net name akas)
+         ;; Collect all the dwim-addresses for each completion, but only once for each record.
+         ;; Add if the net is part of the completions.
+         (bbdb-mapc #'(lambda (sym)
+                        (bbdb-mapc
+                         #'(lambda (rec)
+                             (unless (member rec uniq)
+                               (setq uniq  (cons rec uniq)
+                                     nets  (bbdb-record-net rec)
+                                     name  (downcase (or (bbdb-record-name rec) ""))
+                                     akas  (mapcar 'downcase (bbdb-record-aka rec)))
+                               (while nets
+                                 (setq net  (car nets))
+                                 (when (cond
+                                         ((and (member bbdb-completion-type ; Primary
+                                                       '(primary primary-or-name))
+                                               (member (intern-soft (downcase net) ht)
+                                                       all-the-completions))
+                                          (setq nets  ())
+                                          t)
+                                         ((and name (member bbdb-completion-type ; Name
+                                                            '(nil name primary-or-name))
+                                               (let ((cname  (symbol-name sym)))
+                                                 (or (string= cname name)
+                                                     (member cname akas))))
+                                          (setq name  nil)
+                                          t)
+                                         ((and (member bbdb-completion-type '(nil net)) ; Net
+                                               (member (intern-soft (downcase net) ht)
+                                                       all-the-completions)))
+                                         ;; (name-or-)primary
+                                         ((and (member bbdb-completion-type
+                                                       '(name-or-primary))
+                                               (let ((cname  (symbol-name sym)))
+                                                 (or (string= cname name)
+                                                     (member cname akas))))
+                                          (setq nets  ())
+                                          t))
+                                   (setq dwim-completions
+                                         (cons (bbdb-dwim-net-address rec net)
+                                               dwim-completions))
+                                   (when exact-match (setq nets  ())))
+                                 (setq nets  (cdr nets)))))
+                         (symbol-value sym)))
+                    all-the-completions)
+         (cond ((and dwim-completions (null (cdr dwim-completions))) ; Insert the unique match.
+                (delete-region beg end) (insert (car dwim-completions)) (message ""))
+               (t                       ; More than one match.  Use Icicles minibuffer completion.
+                (icicle-condition-case-no-debug nil
+                    (let* ((icicle-show-Completions-initially-flag      t)
+                           (icicle-incremental-completion-p             'display)
+                           (icicle-top-level-when-sole-completion-flag  t)
+                           (completion-ignore-case                      t)
+                           (choice
+                            (save-excursion
+                              (completing-read "Complete: " (mapcar #'list dwim-completions)
+                                               nil t pattern nil pattern))))
+                      (when choice
+                        (delete-region beg end)
+                        (insert choice)))
+                  (error nil))
+                (unless (eq (selected-window) (minibuffer-window))
+                  (message "Making completion list...done")))))))))
+
+
+;; REPLACE ORIGINAL `lisp-complete-symbol' (< Emacs 23.2),
+;; defined in `lisp.el', saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Select `*Completions*' window even if on another frame.
+;;
+(unless (fboundp 'old-lisp-complete-symbol)
+  (defalias 'old-lisp-complete-symbol (symbol-function 'lisp-complete-symbol)))
+
+;;;###autoload
+(defun icicle-lisp-complete-symbol (&optional predicate) ; `M-TAB' (`C-M-i', `ESC-TAB'), globally.
+  "Complete the Lisp symbol preceding point against known Lisp symbols.
+If there is more than one completion, use the minibuffer to complete.
+
+When called from a program, optional arg PREDICATE is a predicate
+determining which symbols are considered, e.g. `commandp'.
+
+If PREDICATE is nil, the context determines which symbols are
+considered.  If the symbol starts just after an open-parenthesis, only
+symbols with function definitions are considered.  Otherwise, all
+symbols with function definitions, values or properties are
+considered."
+  (interactive)
+  (let* ((end            (point))
+         (buffer-syntax  (syntax-table))
+         (beg            (unwind-protect
+                              (save-excursion
+                                (set-syntax-table emacs-lisp-mode-syntax-table)
+                                (backward-sexp 1)
+                                (while (= (char-syntax (following-char)) ?\') (forward-char 1))
+                                (point))
+                           (set-syntax-table buffer-syntax)))
+         (pattern       (buffer-substring beg end))
+         (new           (try-completion pattern obarray)))
+    (unless (stringp new) (setq new  pattern))
+    (delete-region beg end)
+    (insert new)
+    (setq end  (+ beg (length new)))
+    (if (and (not (string= new "")) (not (string= (downcase new) (downcase pattern)))
+             (< (length (all-completions new obarray)) 2))
+        (message "Completed (no other completions)")
+      ;; Use minibuffer to choose a completion.
+      (let* ((enable-recursive-minibuffers                (active-minibuffer-window))
+             (icicle-top-level-when-sole-completion-flag  t)
+             (icicle-orig-window                          (selected-window)) ; For alt actions.
+             (alt-fn                                      nil)
+             (icicle-show-Completions-initially-flag      t)
+             (icicle-candidate-alt-action-fn
+              (or icicle-candidate-alt-action-fn
+                  (setq alt-fn  (icicle-alt-act-fn-for-type "symbol"))))
+             (icicle-all-candidates-list-alt-action-fn ; M-|'
+              (or icicle-all-candidates-list-alt-action-fn alt-fn
+                  (icicle-alt-act-fn-for-type "symbol")))
+             (predicate
+              (or predicate
+                  (save-excursion
+                    (goto-char beg)
+                    (if (not (eq (char-before) ?\( ))
+                        #'(lambda (sym) ;why not just nil ?   -sm
+                            (or (boundp sym) (fboundp sym) (symbol-plist sym)))
+                      ;; If first element of parent list is not an open paren, assume that this is a
+                      ;; funcall position: use `fboundp'.  If not, then maybe this is a variable in
+                      ;; a `let' binding, so no predicate: use nil.
+                      (and (not (condition-case nil
+                                    (progn (up-list -2) (forward-char 1) (eq (char-after) ?\( ))
+                                  (error nil)))
+                           'fboundp))))))
+        ;; $$$$$ Could bind `icicle-must-pass-after-match-predicate' to a predicate on interned
+        ;;       candidate and pass nil as PRED to `completing-read'.  Don't bother for now.
+        (setq new  (save-excursion (completing-read "Complete Lisp symbol: "
+                                                    obarray predicate t new)))))
+    (delete-region beg end)
+    (insert new)))
+
+
+;; REPLACE ORIGINAL `lisp-completion-at-point' (>= Emacs 23.2),
+;; defined in `lisp.el', saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Select `*Completions*' window even if on another frame.
+;;
+(when (fboundp 'completion-at-point)    ; Emacs 23.2+.
+  (unless (fboundp 'old-lisp-completion-at-point)
+    (defalias 'old-lisp-completion-at-point (symbol-function 'lisp-completion-at-point))
+    ;; Return a function that does all of the completion.
+    (defun icicle-lisp-completion-at-point () #'icicle-lisp-complete-symbol)))
+
+;;;###autoload
+(defun icicle-customize-icicles-group ()
+  "Customize Icicles options and faces.  View their documentation."
+  (interactive)
+  (customize-group-other-window 'Icicles))
+
+;;;###autoload
+(defun icicle-send-bug-report ()
+  "Send a bug report about an Icicles problem."
+  (interactive)
+  (browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+Icicles bug: \
+&body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'.  \
+Each Icicles file has a header `Update #' that you can use to identify it.\
+%%0A%%0AEmacs version: %s.")
+                      (emacs-version))))
+
+
+;; REPLACE ORIGINAL `customize-face' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Multi-command version.
+;;
+(unless (fboundp 'old-customize-face)
+  (defalias 'old-customize-face (symbol-function 'customize-face)))
+
+;;;###autoload
+(defun icicle-customize-face (face)
+  "Customize face FACE.
+Input-candidate completion and cycling are available.  While cycling,
+these keys with prefix `C-' are active:
+
+`C-mouse-2', `C-RET' - Act on current completion candidate only
+`C-down'  - Move to next completion candidate and act
+`C-up'    - Move to previous completion candidate and act
+`C-next'  - Move to next apropos-completion candidate and act
+`C-prior' - Move to previous apropos-completion candidate and act
+`C-end'   - Move to next prefix-completion candidate and act
+`C-home'  - Move to previous prefix-completion candidate and act
+`M-!'     - Act on *all* candidates (or all that are saved):
+            Customize all in the same buffer.
+`C-!'     - Act on *all* candidates (or all that are saved):
+            Customize each in a separate buffer.
+
+When candidate action and cycling are combined (e.g. `C-next'), option
+`icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
+or `C-g' to quit.
+
+With a prefix argument, you can enter multiple faces at the same time
+with `RET' (in Emacs 22 or later).  This gives you the completion
+behavior of `customize-face' in vanilla Emacs.  The advantage is that
+the default value is the list of all faces under the cursor.  The
+disadvantage is that face candidates are not WYSIWYG in buffer
+`*Completions*'.
+
+This is an Icicles command - see command `icicle-mode'."
+  (interactive
+   (list (let* ((icicle-list-use-nth-parts             '(1))
+                (icicle-candidate-action-fn
+                 #'(lambda (x)
+                     (old-customize-face (intern (icicle-transform-multi-completion x)))
+                     (select-window (minibuffer-window))
+                     (select-frame-set-input-focus (selected-frame))))
+                (icicle-all-candidates-list-action-fn  'icicle-customize-faces)
+                (icicle-orig-window                    (selected-window)) ; For alt actions.
+                (alt-fn                                nil)
+                (icicle-candidate-alt-action-fn
+                 (or icicle-candidate-alt-action-fn
+                     (setq alt-fn  (icicle-alt-act-fn-for-type "face"))))
+                (icicle-all-candidates-list-alt-action-fn ; M-|'
+                 (or icicle-all-candidates-list-alt-action-fn
+                     alt-fn (icicle-alt-act-fn-for-type "face"))))
+           (if (and (> emacs-major-version 21) current-prefix-arg)
+               (read-face-name "Customize face: " "all faces" t)
+             (read-face-name "Customize face: ")))))
+  (old-customize-face face))
+
+
+;; REPLACE ORIGINAL `customize-face-other-window' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Multi-command version.
+;;
+(unless (fboundp 'old-customize-face-other-window)
+  (defalias 'old-customize-face-other-window (symbol-function 'customize-face-other-window)))
+
+;;;###autoload
+(defun icicle-customize-face-other-window (face)
+  "Customize face FACE in another window.
+Same as `icicle-customize-face' except it uses a different window."
+  (interactive
+   (list (let* ((icicle-list-use-nth-parts             '(1))
+                (icicle-candidate-action-fn
+                 #'(lambda (x)
+                     (old-customize-face-other-window (intern (icicle-transform-multi-completion x)))
+                     (select-window (minibuffer-window))
+                     (select-frame-set-input-focus (selected-frame))))
+                (icicle-all-candidates-list-action-fn  'icicle-customize-faces)
+                (icicle-orig-window                    (selected-window)) ; For alt actions.
+                (alt-fn                                nil)
+                (icicle-candidate-alt-action-fn
+                 (or icicle-candidate-alt-action-fn
+                     (setq alt-fn  (icicle-alt-act-fn-for-type "face"))))
+                (icicle-all-candidates-list-alt-action-fn ; M-|'
+                 (or icicle-all-candidates-list-alt-action-fn
+                     alt-fn (icicle-alt-act-fn-for-type "face"))))
+           (if (and (> emacs-major-version 21) current-prefix-arg)
+               (read-face-name "Customize face: " "all faces" t)
+             (read-face-name "Customize face: ")))))
+  (old-customize-face-other-window face))
+
+(defun icicle-customize-faces (faces)
+  "Open Customize buffer on all faces in list FACES."
+  (let ((icicle-list-nth-parts-join-string  ": ")
+        (icicle-list-join-string            ": ")
+        ;; $$$$$$ (icicle-list-end-string             "")
+        (icicle-list-use-nth-parts          '(1)))
+    (custom-buffer-create
+     (custom-sort-items
+      (mapcar #'(lambda (f) (list (intern (icicle-transform-multi-completion f)) 'custom-face))
+              faces)
+      t custom-buffer-order-groups)
+     "*Customize Apropos*")))
+
+
+;; REPLACE ORIGINAL `customize-apropos' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the regexp.
+;;
+(unless (fboundp 'old-customize-apropos)
+  (defalias 'old-customize-apropos (symbol-function 'customize-apropos)))
+
+;;;###autoload
+(defun icicle-customize-apropos (regexp &optional all)
+  "Customize all user options matching REGEXP.
+If ALL is `options', include only options.
+If ALL is `faces', include only faces.
+If ALL is `groups', include only groups.
+If ALL is t (interactively, with prefix arg), include options which
+  are not user-settable, as well as faces and groups.
+
+Use `S-TAB', [next], and [prior], to match regexp input - this lets
+you see what items will be available in the customize buffer."
+  (interactive
+   (let* ((pref-arg  current-prefix-arg)
+          (icicle-must-pass-after-match-predicate
+           #'(lambda (s)
+               (setq s  (intern s))
+               (or (get s 'custom-group)
+                   (custom-facep s)
+                   (and (boundp s) (or (get s 'saved-value)
+                                       (custom-variable-p s)
+                                       (if (null pref-arg)
+                                           (user-variable-p s)
+                                         (get s 'variable-documentation))))))))
+     (list (completing-read "Customize (regexp): " obarray nil nil nil 'regexp-history)
+           pref-arg)))
+  (let ((found  nil))
+    (mapatoms #'(lambda (symbol)
+                  (when (string-match regexp (symbol-name symbol))
+                    (when (and (not (memq all '(faces options))) ; groups or t
+                               (get symbol 'custom-group))
+                      (push (list symbol 'custom-group) found))
+                    (when (and (not (memq all '(options groups))) ; faces or t
+                               (custom-facep symbol))
+                      (push (list symbol 'custom-face) found))
+                    (when (and (not (memq all '(groups faces))) ; options or t
+                               (boundp symbol)
+                               (or (get symbol 'saved-value)
+                                   (custom-variable-p symbol)
+                                   (if (memq all '(nil options))
+                                       (user-variable-p symbol)
+                                     (get symbol 'variable-documentation))))
+                      (push (list symbol 'custom-variable) found)))))
+    (if (not found)
+        (error "No matches")
+      (custom-buffer-create (custom-sort-items found t custom-buffer-order-groups)
+                            "*Customize Apropos*"))))
+
+;; Define this for Emacs 20 and 21
+(unless (fboundp 'custom-variable-p)
+  (defun custom-variable-p (variable)
+    "Return non-nil if VARIABLE is a custom variable."
+    (or (get variable 'standard-value) (get variable 'custom-autoload))))
+
+
+;; REPLACE ORIGINAL `customize-apropos-faces' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the regexp.
+;;
+(unless (fboundp 'old-customize-apropos-faces)
+  (defalias 'old-customize-apropos-faces (symbol-function 'customize-apropos-faces)))
+
+;;;###autoload
+(defun icicle-customize-apropos-faces (regexp)
+  "Customize all user faces matching REGEXP.
+Use `S-TAB', [next], and [prior], to match regexp input - this lets
+you see what items will be available in the customize buffer."
+  (interactive
+   (let ((icicle-must-pass-after-match-predicate #'(lambda (s) (custom-facep (intern s)))))
+     (list (completing-read "Customize faces (regexp): " obarray nil nil nil 'regexp-history))))
+  (customize-apropos regexp 'faces))
+
+
+;; REPLACE ORIGINAL `customize-apropos-groups' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the regexp.
+;;
+(unless (fboundp 'old-customize-apropos-groups)
+  (defalias 'old-customize-apropos-groups (symbol-function 'customize-apropos-groups)))
+
+;;;###autoload
+(defun icicle-customize-apropos-groups (regexp)
+  "Customize all user groups matching REGEXP.
+Use `S-TAB', [next], and [prior], to match regexp input - this lets
+you see what items will be available in the customize buffer."
+  (interactive
+   (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (get (intern s) 'custom-group))))
+     (list (completing-read "Customize groups (regexp): " obarray nil nil nil 'regexp-history))))
+  (customize-apropos regexp 'groups))
+
+
+;; REPLACE ORIGINAL `customize-apropos-options' defined in `cus-edit.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the regexp.
+;;
+(unless (fboundp 'old-customize-apropos-options)
+  (defalias 'old-customize-apropos-options (symbol-function 'customize-apropos-options)))
+
+;;;###autoload
+(defun icicle-customize-apropos-options (regexp &optional arg)
+  "Customize all user options matching REGEXP.
+With prefix argument, include options which are not user-settable.
+
+Use `S-TAB', [next], and [prior], to match regexp input - this lets
+you see what items will be available in the customize buffer."
+  (interactive
+   (let* ((pref-arg  current-prefix-arg)
+          (icicle-must-pass-after-match-predicate
+           #'(lambda (s)
+               (setq s  (intern s))
+               (and (boundp s) (or (get s 'saved-value)
+                                   (custom-variable-p s)
+                                   (if (null pref-arg)
+                                       (user-variable-p s)
+                                     (get s 'variable-documentation)))))))
+     (list (completing-read "Customize options (regexp): " obarray nil nil nil 'regexp-history)
+           pref-arg)))
+  (customize-apropos regexp (or arg 'options)))
+
+
+;; REPLACE ORIGINAL `customize-apropos-options-of-type' defined in `cus-edit+.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the regexp.
+;;
+(when (and (fboundp 'customize-apropos-options-of-type)
+           (not (fboundp 'old-customize-apropos-options-of-type)))
+  (defalias 'old-customize-apropos-options-of-type
+      (symbol-function 'customize-apropos-options-of-type)))
+
+;;;###autoload
+(defun icicle-customize-apropos-options-of-type (type regexp)
+  "Customize all loaded customizable options of type TYPE that match REGEXP.
+With no prefix arg, each option is defined with `defcustom' type TYPE.
+With a prefix arg, either each option is defined with `defcustom' type
+ TYPE or its current value is compatible with TYPE.
+
+If TYPE is nil (the default value) then all `defcustom' variables are
+potential candidates.
+
+Use `S-TAB', `next', and `prior', to match regexp input - this lets
+you see which options will be available in the customize buffer."
+  (interactive
+   (let ((typ       (car (condition-case err
+                             (read-from-string
+                              (let ((types ()))
+                                (mapatoms
+                                 #'(lambda (cand)
+                                     (when (custom-variable-p cand)
+                                       (push (list (format "%s"
+                                                           (format "%S" (get cand 'custom-type))))
+                                             types))))
+                                (completing-read "Customize all options of type: "
+                                                 (icicle-remove-duplicates types)
+                                                 nil nil nil nil "nil")))
+                           (end-of-file (error "No such custom type")))))
+         (pref-arg  current-prefix-arg))
+     (list typ  (let ((icicle-must-pass-after-match-predicate
+                       #'(lambda (s)
+                           (setq s  (intern s))
+                           (and (boundp s)
+                                (or (not (fboundp 'indirect-variable)) (eq (indirect-variable s) s))
+                                (or (get s 'saved-value) (custom-variable-p s))
+                                (or (not typ) ; `typ' = nil means use all types.
+                                    (if pref-arg
+                                        (condition-case nil
+                                            (icicle-var-is-of-type-p s (list typ))
+                                          (error nil))
+                                      (equal (get s 'custom-type) typ)))))))
+                  (completing-read "Customize options matching (regexp): "
+                                   obarray nil nil nil 'regexp-history)))))
+  (custom-buffer-create (custom-sort-items
+                         (mapcar #'(lambda (s) (list (intern s) 'custom-variable))
+                                 icicle-completion-candidates)
+                         t "*Customize Apropos*")))
+
+
+;; REPLACE ORIGINAL `repeat-complex-command' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Uses `completing-read' to read the command to repeat, letting you use `S-TAB' and
+;; `TAB' to see the history list and `C-,' to toggle sorting that display.
+;;
+(unless (fboundp 'old-repeat-complex-command)
+  (defalias 'old-repeat-complex-command (symbol-function 'repeat-complex-command)))
+
+;;;###autoload
+(defun icicle-repeat-complex-command (arg) ; Bound to `C-x ESC ESC', `C-x M-:' in Icicle mode.
+  "Edit and re-evaluate the last complex command, or ARGth from last.
+A complex command is one that used the minibuffer.
+ARG is the prefix argument numeric value.
+
+You can edit the past command you choose before executing it.  The
+Lisp form of the command is used.  If the command you enter differs
+from the previous complex command, then it is added to the front of
+the command history.
+
+Icicles completion is available for choosing a past command.  You can
+still use the vanilla Emacs bindings `\\\\[next-history-element]' and \
+`\\[previous-history-element]' to cycle inputs,
+and `\\[repeat-matching-complex-command]' to match regexp input, but Icicles input cycling (`up',
+`down', `next', `prior', `home', `end') and apropos completion
+\(`S-TAB') are superior and more convenient."
+  (interactive "p")
+  (let ((elt  (nth (1- arg) command-history))
+        newcmd)
+    (if elt
+        (progn
+          (setq newcmd
+                (let ((print-level                   nil)
+                      (minibuffer-history-position   arg)
+                      (minibuffer-history-sexp-flag  (1+ (minibuffer-depth))))
+                  (unwind-protect
+                       (let ((icicle-transform-function  'icicle-remove-duplicates))
+                         (read (completing-read
+                                "Redo: " (mapcar #'(lambda (entry) (list (prin1-to-string entry)))
+                                                 command-history)
+                                nil nil (prin1-to-string elt) (cons 'command-history arg)
+                                (prin1-to-string elt))))
+                    ;; If command was added to command-history as a string, get rid of that.
+                    ;; We want only evaluable expressions there.
+                    (if (stringp (car command-history))
+                        (setq command-history  (cdr command-history))))))
+          ;; If command to be redone does not match front of history, add it to the history.
+          (or (equal newcmd (car command-history))
+              (setq command-history  (cons newcmd command-history)))
+          (eval newcmd))
+      (if command-history
+          (error "Argument %d is beyond length of command history" arg)
+        (error "There are no previous complex commands to repeat")))))
+
+;;;###autoload
+(defun icicle-add-entry-to-saved-completion-set (set-name entry type)
+  "Add ENTRY to saved completion-candidates set SET-NAME.
+ENTRY is normally a single candidate (a string).
+ With a prefix arg, however, and if option
+ `icicle-filesets-as-saved-completion-sets-flag' is non-nil, then
+ ENTRY is the name of an Emacs fileset (Emacs 22 or later).
+TYPE is the type of entry to add: `Fileset' or `Candidate'."
+  (interactive
+   (let ((typ (if (and current-prefix-arg icicle-filesets-as-saved-completion-sets-flag
+                       (prog1 (or (require 'filesets nil t)
+                                  (error "Feature `filesets' not provided"))
+                         (filesets-init))
+                       filesets-data)
+                  'Fileset
+                'Candidate)))
+     (list
+      (save-selected-window
+        (completing-read "Saved completion set: " icicle-saved-completion-sets nil t nil
+                         'icicle-completion-set-history))
+      (if (eq typ 'Fileset)
+          (list ':fileset               ; Just save the fileset name, not the data.
+                (car (assoc (completing-read "Fileset to add: " filesets-data nil t)
+                            filesets-data)))
+        (completing-read "Candidate to add: " (mapcar #'list icicle-saved-completion-candidates)))
+      typ)))
+  (let ((file-name  (cdr (assoc set-name icicle-saved-completion-sets))))
+    (unless (icicle-file-readable-p file-name) (error "Cannot read cache file `%s'" file-name))
+    (let ((list-buf  (find-file-noselect file-name 'nowarn 'raw))
+          candidates newcands entry-type)
+      (unwind-protect
+           (condition-case icicle-add-entry-to-saved-completion-set
+               (when (listp (setq newcands  (setq candidates  (read list-buf))))
+                 (message "Set `%s' read from file `%s'" set-name file-name))
+             (error (error "Bad cache file.  %s"
+                           (error-message-string icicle-add-entry-to-saved-completion-set))))
+        (kill-buffer list-buf))
+      (unless (consp newcands) (error "Bad data in cache file `%s'" file-name))
+      (pushnew entry newcands :test #'equal)
+      (setq entry  (if (eq type 'Fileset) (caar entry) entry))
+      (if (= (length candidates) (length newcands))
+          (message "%s `%s' is already in saved set `%s', file `%s'" type entry set-name file-name)
+        (with-temp-message (format "Writing entry to cache file `%s'..." file-name)
+          (with-temp-file file-name (prin1 newcands (current-buffer))))
+        (message "%s `%s' added to saved set `%s', file `%s'" type entry set-name file-name)))))
+
+;;;###autoload
+(defun icicle-remove-entry-from-saved-completion-set (set-name)
+  "Remove an entry from saved completion-candidates set SET-NAME.
+SET-NAME can be an Icicles saved completions set (cache file) or the
+name of an Emacs fileset.
+
+The entry to remove can be a single completion candidate (a string) or
+an Emacs fileset.  You can thus remove a file name from a fileset or
+remove a fileset from an Icicles saved completion set.  (You can also
+remove a file name from a saved completion set.)  If a saved set has
+both a file and a fileset of the same name, then both are removed.
+
+To use filesets here, use Emacs 22 or later, load library `filesets',
+use `(filesets-init)', and ensure that option
+`icicle-filesets-as-saved-completion-sets-flag' is non-nil."
+  (interactive
+   (list (completing-read "Saved completion set: "
+                          (if (and icicle-filesets-as-saved-completion-sets-flag
+                                   (featurep 'filesets) filesets-data)
+                              (append filesets-data icicle-saved-completion-sets)
+                            icicle-saved-completion-sets)
+                          nil t nil 'icicle-completion-set-history)))
+  (let* ((file-name                              (cdr (assoc set-name icicle-saved-completion-sets)))
+         (candidates                             (icicle-get-candidates-from-saved-set
+                                                  set-name 'dont-expand))
+         (icicle-whole-candidate-as-text-prop-p  t)
+         (entry
+          (funcall icicle-get-alist-candidate-function
+                   (completing-read
+                    "Candidate to remove: "
+                    (mapcar #'(lambda (e)
+                                (cond ((icicle-saved-fileset-p e) ; Swap `:fileset' with fileset name
+                                       `(,(cadr e) ,(car e) ,@(cddr e)))
+                                      ((consp e) e)
+                                      (t (list e)))) ; Listify naked string.
+                            candidates)
+                    nil t))))
+    (when (and (consp entry) (eq (cadr entry) ':fileset)) ; Swap back again: `:fileset' and name.
+      (setq entry  `(,(cadr entry) ,(car entry) ,@(cddr entry))))
+    (when (and (consp entry) (null (cdr entry))) (setq entry  (car entry))) ; Use just the string.
+    ;; Delete any such candidate, then remove text properties used for completion.
+    (setq candidates  (mapcar #'icicle-unpropertize (delete entry candidates)))
+    (cond (file-name
+           (with-temp-message           ; Remove from cache file.
+               (format "Writing remaining candidates to cache file `%s'..." file-name)
+             (with-temp-file file-name (prin1 candidates (current-buffer)))))
+          ((icicle-saved-fileset-p (list ':fileset set-name)) ; Remove from fileset.
+           (unless (require 'filesets nil t) (error "Feature `filesets' not provided"))
+           (filesets-init)
+           (let ((fst  (and filesets-data (assoc set-name filesets-data)))) ; The fileset itself.
+             (unless fst (error "No such fileset: `%s'" set-name))
+             (let ((fst-files  (filesets-entry-get-files fst)))
+               (if (car (filesets-member entry fst-files :test 'filesets-files-equalp))
+                   (if fst-files        ; Similar to code in `filesets-remove-buffer'.
+                       (let ((new-fst  (list (cons ':files (delete entry fst-files)))))
+                         (setcdr fst new-fst)
+                         (filesets-set-config set-name 'filesets-data filesets-data))
+                     (message "Cannot remove `%s' from fileset `%s'" entry set-name))
+                 (message "`%s' not in fileset `%s'" entry set-name))))))
+    (icicle-msg-maybe-in-minibuffer
+     (concat (format "`%s' removed from %s `%s'"
+                     (if (icicle-saved-fileset-p entry) (cadr entry) entry)
+                     (if (icicle-saved-fileset-p entry) "fileset" "saved set")
+                     set-name)
+             (and file-name (format ", file `%s'" file-name))))))
+
+;;;###autoload (autoload 'icicle-remove-saved-completion-set "icicles-cmd1.el")
+(icicle-define-command icicle-remove-saved-completion-set ; Command name
+  "Remove an entry from `icicle-saved-completion-sets'.
+Save the updated option.
+You are prompted to also delete the associated cache file.
+You can add entries to `icicle-saved-completion-sets' using command
+`icicle-add/update-saved-completion-set'." ; Doc string
+  icicle-remove-saved-set-action
+  "Remove set of completion candidates named: " ; `completing-read' args
+  icicle-saved-completion-sets nil t nil 'icicle-completion-set-history nil nil
+  ((icicle-whole-candidate-as-text-prop-p  t) ; Additional bindings
+   (icicle-use-candidates-only-once-flag   t))
+  nil nil (icicle-remove-Completions-window)) ; First code, undo code, last code
+
+(defun icicle-remove-saved-set-action (set-name)
+  "Remove saved set SET-NAME from `icicle-saved-completion-sets'."
+  (let ((enable-recursive-minibuffers  t)
+        (sets                          icicle-saved-completion-sets)
+        set cache)
+    (save-selected-window
+      (select-window (minibuffer-window))
+      (while (setq set    (assoc set-name sets)
+                   cache  (cdr set))
+        (when (file-exists-p cache)
+          (if (y-or-n-p (format "Delete cache file `%s'? " cache))
+              (when (condition-case err
+                        (progn (delete-file cache) t)
+                      (error (progn (message "%s" (error-message-string err)) nil)))
+                (message "DELETED `%s'" cache) (sit-for 1))
+            (message "OK, file NOT deleted") (sit-for 1)))
+        (setq sets  (delete set sets)))))
+  (setq icicle-saved-completion-sets
+        (icicle-assoc-delete-all set-name icicle-saved-completion-sets))
+  (funcall icicle-customize-save-variable-function
+           'icicle-saved-completion-sets
+           icicle-saved-completion-sets)
+  (message "Candidate set `%s' removed" set-name))
+
+;;;###autoload
+(defun icicle-bookmark-save-marked-files (&optional arg) ; Bound to `C-M->' in *Bookmark List*.
+  "Save file names of marked bookmarks as a set of completion candidates.
+Saves file names in variable `icicle-saved-completion-candidates', by
+default.  Marked bookmarks that have no associated file are ignored.
+With a plain prefix arg (`C-u'), save candidates in a cache file.
+With a non-zero numeric prefix arg (`C-u N'), save candidates in a
+ variable for which you are prompted.
+With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
+ or later).  Use this only for file-name candidates, obviously.
+ To subsequently use a fileset for candidate retrieval, option
+ `icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
+
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a bookmark-list display buffer
+\(`*Bookmark List*')."
+  (interactive "P")
+  (unless (fboundp 'bmkp-bmenu-get-marked-files)
+    (error "Command `icicle-bookmark-save-marked-files' requires library `Bookmark+'"))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg))
+
+;;;###autoload
+(defun icicle-bookmark-save-marked-files-more (&optional arg) ; Bound to `C->' in *Bookmark List*.
+  "Add the file names of the marked bookmarks to the saved candidates set.
+Marked bookmarks that have no associated file are ignored.
+Add candidates to `icicle-saved-completion-candidates', by default.
+A prefix argument acts the same as for `icicle-candidate-set-save'.
+
+The existing saved candidates remain saved.  The current candidates
+are added to those already saved.
+
+You can retrieve the saved set of candidates with `C-M-<'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a bookmark-list display buffer
+\(`*Bookmark List*')."
+  (interactive "P")
+  (unless (fboundp 'bmkp-bmenu-get-marked-files)
+    (error "Command `icicle-bookmark-save-marked-files-more' requires library `Bookmark+'"))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg t))
+
+;;;###autoload
+(defun icicle-bookmark-save-marked-files-to-variable () ; Bound to `C-M-}' in *Bookmark List*.
+  "Save the file names of the marked bookmarks to a variable.
+Marked bookmarks that have no associated file are ignored.
+
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a bookmark-list display buffer
+\(`*Bookmark List*')."
+  (interactive)
+  (unless (fboundp 'bmkp-bmenu-get-marked-files)
+    (error "Command `icicle-bookmark-save-marked-files-to-variable' requires library `Bookmark+'"))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) 99))
+
+;;;###autoload
+(defalias 'icicle-bookmark-save-marked-files-as-project ; Bound to `C-}' in *Bookmark List*.
+    'icicle-bookmark-save-marked-files-persistently)
+;;;###autoload
+(defun icicle-bookmark-save-marked-files-persistently (filesetp)
+  "Save the file names of the marked bookmarks as a persistent set.
+Marked bookmarks that have no associated file are ignored.
+With no prefix arg, save in a cache file.
+With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
+
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a bookmark-list display buffer
+\(`*Bookmark List*')."
+  (interactive "P")
+  (unless (fboundp 'bmkp-bmenu-get-marked-files)
+    (error "This command requires library `Bookmark+'"))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) (if filesetp 0 '(1))))
+
+;;;###autoload
+(defun icicle-dired-save-marked (&optional arg) ; Bound to `C-M->' in Dired.
+  "Save the marked file names in Dired as a set of completion candidates.
+Saves file names in variable `icicle-saved-completion-candidates', by
+default.
+With a plain prefix arg (`C-u'), save candidates in a cache file.
+With a non-zero numeric prefix arg (`C-u N'), save candidates in a
+ variable for which you are prompted.
+With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
+ or later).  Use this only for file-name candidates, obviously.
+ To subsequently use a fileset for candidate retrieval, option
+ `icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
+
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a Dired buffer."
+  (interactive "P")
+  (unless (eq major-mode 'dired-mode)
+    (error "Command `icicle-dired-save-marked' must be called from a Dired buffer"))
+  (icicle-candidate-set-save-1 (dired-get-marked-files) arg))
+
+;;;###autoload
+(defun icicle-dired-save-marked-more (&optional arg) ; Bound to `C->' in Dired.
+  "Add the marked file names in Dired to the saved candidates set.
+Add candidates to `icicle-saved-completion-candidates', by default.
+A prefix argument acts the same as for `icicle-candidate-set-save'.
+
+The existing saved candidates are still saved.  The current candidates
+are added to those already saved.
+
+You can retrieve the saved set of candidates with `C-M-<'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a Dired buffer."
+  (interactive "P")
+  (unless (eq major-mode 'dired-mode)
+    (error "`icicle-dired-save-marked-more' must be called from a Dired buffer"))
+  (icicle-candidate-set-save-1 (dired-get-marked-files) arg t))
+
+;;;###autoload
+(defun icicle-dired-save-marked-to-variable () ; Bound to `C-M-}' in Dired.
+  "Save the marked file names in Dired to a variable as a candidate set.
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a Dired buffer."
+  (interactive)
+  (icicle-candidate-set-save-1 (dired-get-marked-files) 99))
+
+;;;###autoload
+(defalias 'icicle-dired-save-marked-as-project ; Bound to `C-}' in Dired.
+    'icicle-dired-save-marked-persistently)
+;;;###autoload
+(defun icicle-dired-save-marked-persistently (filesetp)
+  "Save the marked file names in Dired as a persistent set.
+With no prefix arg, save in a cache file.
+With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
+
+You can retrieve the saved set of file-name candidates during
+completion using `\\\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from a Dired buffer."
+  (interactive "P")
+  (icicle-candidate-set-save-1 (dired-get-marked-files) (if filesetp 0 '(1))))
+
+
+(put 'icicle-dired-saved-file-candidates 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defalias 'icicle-dired-chosen-files 'icicle-dired-saved-file-candidates)
+;;;###autoload
+(defun icicle-dired-saved-file-candidates (prompt-for-dir-p)
+  "Open Dired on a set of files and directories of your choice.
+If you have saved a set of file names using \\\
+`\\[icicle-candidate-set-save]', then it is used.
+If not, you are prompted to choose the files.
+With a prefix argument, you are prompted for the default directory to use.
+Otherwise, the current value of `default-directory' is used.
+Names that do not correspond to existing files are ignored.
+Existence of files with relative names is checked in the Dired
+directory (default directory)."
+  (interactive "P")
+  ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
+  (unless icicle-saved-completion-candidates
+    (error "%s" (substitute-command-keys "No saved completion candidates.  \
+Use \\`\\[icicle-candidate-set-save]' to save candidates")))
+  (let* ((default-directory           (if prompt-for-dir-p
+                                          (read-file-name "Directory: " nil default-directory nil)
+                                        default-directory))
+         (icicle-list-use-nth-parts   '(1))
+         (file-names                  (icicle-remove-if
+                                       #'(lambda (fil) (or (null fil) (not (file-exists-p fil))))
+                                       (or (and icicle-saved-completion-candidates
+                                                (mapcar #'icicle-transform-multi-completion
+                                                        icicle-saved-completion-candidates))
+                                           (icicle-file-list)))))
+    (dired (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
+
+;;;###autoload
+(defalias 'icicle-dired-chosen-files-other-window 'icicle-dired-saved-file-candidates-other-window)
+;;;###autoload
+(defun icicle-dired-saved-file-candidates-other-window (prompt-for-dir-p) ; Bound `C-M-<' in Dired.
+  "Open Dired in other window on set of files & directories of your choice.
+If you have saved a set of file names using \\\
+`\\[icicle-candidate-set-save]', then it is used.
+If not, you are prompted to choose the files.
+With a prefix arg, you are prompted for the default directory to use.
+Otherwise, the current value of `default-directory' is used.
+Names that do not correspond to existing files are ignored.
+Existence of files with relative names is checked in the Dired
+directory (default directory)."
+  (interactive "P")
+  ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
+  (let* ((default-directory           (if prompt-for-dir-p
+                                          (read-file-name "Directory: " nil default-directory nil)
+                                        default-directory))
+         (icicle-list-use-nth-parts   '(1))
+         (file-names                  (icicle-remove-if
+                                       #'(lambda (fil) (or (null fil) (not (file-exists-p fil))))
+                                       (or (and icicle-saved-completion-candidates
+                                                (mapcar #'icicle-transform-multi-completion
+                                                        icicle-saved-completion-candidates))
+                                           (icicle-file-list)))))
+    (dired-other-window (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
+
+(put 'icicle-dired-project 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-dired-project (prompt-for-dir-p)
+  "Open Dired on a saved project.
+A project is either a persistent completion set or an Emacs fileset.
+With a prefix argument, you are prompted for the directory.
+Otherwise, the default directory is assumed.
+
+Project file names that do not correspond to existing files are
+ignored.  Existence of files with relative names is checked in the
+directory.
+
+You can use `C-x m' during completion to access Dired bookmarks, if
+you use library `Bookmark+'."
+  (interactive "P")
+  (when (require 'bookmark+ nil t)
+    (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-dired-other-window))
+  (unwind-protect
+       ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
+       (let ((set-name  (completing-read "Project (saved file names): "
+                                         (if (and icicle-filesets-as-saved-completion-sets-flag
+                                                  (featurep 'filesets) filesets-data)
+                                             (append filesets-data icicle-saved-completion-sets)
+                                           icicle-saved-completion-sets)
+                                         nil nil nil 'icicle-completion-set-history)))
+         (icicle-retrieve-candidates-from-set set-name)
+         (let* ((default-directory  (if prompt-for-dir-p
+                                        (read-file-name "Dired directory: " nil
+                                                        default-directory nil)
+                                      default-directory))
+                (file-names         ()))
+           (dolist (f  icicle-saved-completion-candidates)
+             (when (file-exists-p f) (push f file-names)))
+           (unless file-names (error "No files in project `%s' actually exist" set-name))
+           (dired (cons (generate-new-buffer-name set-name)
+                        (nreverse (mapcar #'(lambda (file)
+                                              (if (file-name-absolute-p file)
+                                                  (expand-file-name file)
+                                                file))
+                                          file-names))))))
+    (define-key minibuffer-local-completion-map "\C-xm" nil)))
+
+;;;###autoload
+(defun icicle-dired-project-other-window (prompt-for-dir-p) ; Bound to `C-{' in Dired.
+  "Open Dired on a saved project in another window.
+A project is either a persistent completion set or an Emacs fileset.
+With a prefix argument, you are prompted for the directory.
+Otherwise, the default directory is assumed.
+
+Project file names that do not correspond to existing files are
+ignored.  Existence of files with relative names is checked in the
+directory.
+
+You can use `C-x m' during completion to access Dired bookmarks, if
+you use library `Bookmark+'."
+  (interactive "P")
+  (when (require 'bookmark+ nil t)
+    (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-dired-other-window))
+  (unwind-protect
+       ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
+       (let ((set-name  (completing-read "Project (saved file names): "
+                                         (if (and icicle-filesets-as-saved-completion-sets-flag
+                                                  (featurep 'filesets) filesets-data)
+                                             (append filesets-data icicle-saved-completion-sets)
+                                           icicle-saved-completion-sets)
+                                         nil nil nil 'icicle-completion-set-history)))
+         (icicle-retrieve-candidates-from-set set-name)
+         (let* ((default-directory  (if prompt-for-dir-p
+                                        (read-file-name "Dired directory: " nil
+                                                        default-directory nil)
+                                      default-directory))
+                (file-names         ()))
+           (dolist (f  icicle-saved-completion-candidates)
+             (when (file-exists-p f) (push f file-names)))
+           (unless file-names (error "No files in project `%s' actually exist" set-name))
+           (dired-other-window (cons (generate-new-buffer-name set-name)
+                                     (nreverse (mapcar #'(lambda (file)
+                                                           (if (file-name-absolute-p file)
+                                                               (expand-file-name file)
+                                                             file))
+                                                       file-names))))))
+    (define-key minibuffer-local-completion-map "\C-xm" nil)))
+
+;;;###autoload
+(defun icicle-grep-saved-file-candidates (command-args)
+  "Run `grep' on the set of completion candidates saved with \\\
+`\\[icicle-candidate-set-save]'.
+Saved names that do not correspond to existing files are ignored.
+Existence of files with relative names is checked in the default
+directory."
+  (interactive
+   (list
+    (let ((file-names  ()))
+      (unless icicle-saved-completion-candidates
+        (error "%s" (substitute-command-keys "No saved completion candidates.  \
+Use \\`\\[icicle-candidate-set-save]' to save candidates")))
+      (unless grep-command (grep-compute-defaults))
+      (dolist (f  icicle-saved-completion-candidates) (when (file-exists-p f) (push f file-names)))
+      (let ((default  (and (fboundp 'grep-default-command) (grep-default-command))))
+        (read-from-minibuffer
+         "grep   :  "
+         (let ((up-to-files  (concat grep-command "   ")))
+           (cons (concat up-to-files (mapconcat #'identity icicle-saved-completion-candidates " "))
+                 (- (length up-to-files) 2)))
+         nil nil 'grep-history default)))))
+  (grep command-args))
+
+;; Utility function.  Use it to define multi-commands that navigate.
+(defun icicle-explore (define-candidates-fn final-action-fn quit-fn error-fn cleanup-fn prompt
+                                            &rest compl-read-args)
+  "Icicle explorer: explore complex completion candidates.
+Navigate among locations or other entities represented by a set of
+completion candidates.  See `icicle-search' for a typical example.
+
+Arguments:
+ DEFINE-CANDIDATES-FN:
+   Function of no args called to fill `icicle-candidates-alist' with
+   the candidates.
+ FINAL-ACTION-FN:
+   Function of no args called after the final choice of candidate
+   (after both `icicle-explore-final-choice' and
+   `icicle-explore-final-choice-full' have been set).  Typically uses
+   `icicle-explore-final-choice-full', the full candidate.
+ QUIT-FN: Function of no args called if user uses `C-g'.
+ ERROR-FN: Function of no args called if an error is raised.
+ CLEANUP-FN: Function of no args called after exploring.
+ PROMPT: Prompt string for `completing-read'.
+ COMPL-READ-ARGS: `completing-read' args other than PROMPT and
+   COLLECTION.
+
+If there is only one candidate, then FINAL-ACTION-FN is called
+immediately.  The candidate is not available to act on (e.g. using
+``C-S-RET').
+
+Returns:
+ The result of executing FINAL-ACTION-FN, if that arg is non-nil.
+ Otherwise, `icicle-explore-final-choice-full'.
+
+To use `icicle-explore' to define a multi-command, you must also bind
+`icicle-candidate-action-fn'.
+
+Though `icicle-explore' is typically used to define navigation
+commands, it need not be.  It can be useful anytime you need to use
+`completing-read' and also provide specific behavior for quitting
+\(`C-g'), completion errors, and final actions."
+  (let ((icicle-incremental-completion-flag     'always)
+        (icicle-whole-candidate-as-text-prop-p  t)
+        (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
+        (icicle-act-before-cycle-flag           icicle-act-before-cycle-flag)
+        (icicle-orig-pt-explore                 (point-marker))
+        (icicle-orig-win-explore                (selected-window))
+        result)
+    (setq icicle-act-before-cycle-flag      nil
+          icicle-candidates-alist           nil
+          icicle-explore-final-choice       nil
+          icicle-explore-final-choice-full  nil)
+    (icicle-highlight-lighter)
+    (message "Finding candidates...")
+    (when define-candidates-fn (funcall define-candidates-fn))
+    (unless icicle-candidates-alist (error "No candidates defined"))
+    (when (= (length icicle-candidates-alist) 1)
+      (setq icicle-explore-final-choice  (icicle-display-cand-from-full-cand
+                                          (car icicle-candidates-alist))))
+    (unwind-protect
+         (icicle-condition-case-no-debug failure
+             (progn
+               (unless icicle-explore-final-choice
+                 (setq icicle-explore-final-choice
+                       (let ((icicle-remove-icicles-props-p  nil)) ; Keep Icicles text properties.
+                         (apply #'completing-read prompt icicle-candidates-alist compl-read-args))))
+               (setq icicle-explore-final-choice-full
+                     (funcall icicle-get-alist-candidate-function
+                              icicle-explore-final-choice 'no-error-p))
+               (unless icicle-explore-final-choice-full (error "No such occurrence"))
+               (setq result  (if final-action-fn
+                                 (funcall final-action-fn)
+                               icicle-explore-final-choice-full)))
+           (quit (if quit-fn (funcall quit-fn) (keyboard-quit)))
+           (error (when error-fn (funcall error-fn))
+                  (error "%s" (error-message-string failure))))
+      (setq result  (icicle-unpropertize result)) ; Finally remove any Icicles text properties.
+      (when cleanup-fn (funcall cleanup-fn)))
+    result))
+
+;;;###autoload (autoload 'icicle-execute-extended-command "icicles-cmd1.el")
+(icicle-define-command icicle-execute-extended-command ; Bound to `M-x' in Icicle mode.
+  "Read command name, then read its arguments and call it.
+This is `execute-extended-command', turned into a multi-command.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `execute-extended-command' to
+`icicle-execute-extended-command'.  If you do not want this remapping,
+then customize option `icicle-top-level-key-bindings'." ; Doc string
+  icicle-execute-extended-command-1     ; Function to perform the action
+  (format "Execute command%s: "         ; `completing-read' args
+          (if current-prefix-arg
+              (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
+            ""))
+  obarray nil t nil 'extended-command-history nil nil
+  (;; Bindings
+   (last-command                            last-command) ; Save and restore the last command.
+   (use-file-dialog                         nil) ; `mouse-2' in `*Completions*' won't use dialog box.
+   (alt-fn                                  nil)
+   (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
+   (icicle-must-pass-after-match-predicate  #'(lambda (c) (commandp (intern c))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
+   icicle-new-last-cmd)                 ; Set in `icicle-execute-extended-command-1'.
+  nil  nil                              ; First code, undo code
+  (setq this-command  icicle-new-last-cmd)) ; Last code: this will update `last-command'
+
+;; Free vars here: `icicle-orig-buff' and `icicle-orig-window' are bound by `icicle-define-command'.
+;;                 `icicle-new-last-cmd' and `icicle-orig-must-pass-after-match-pred' are bound in
+;;                 `icicle-execute-extended-command'.
+(defun icicle-execute-extended-command-1 (cmd-name)
+  "Action function to execute command or named keyboard macro CMD-NAME."
+  (when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
+  (when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
+  (when (string= "" cmd-name) (error "No command name"))
+
+  (let* ((cmd                                       (intern cmd-name))
+         ;; Rebind `icicle-candidate-action-fn' to a function that calls the
+         ;; candidate CMD-NAME on a single argument that it reads.  This is
+         ;; used only if CMD-NAME is a command that, itself, reads an input
+         ;; argument with completion.  When that is the case, you can use
+         ;; completion on that input, and if you do that, you can use `C-RET'
+         ;; to use command CMD-NAME as a multi-command.  In other words, this
+         ;; binding allows for two levels of multi-commands.
+         (icicle-candidate-action-fn
+          (and icicle-candidate-action-fn ; This is nil after the command name is read.
+               #'(lambda (arg)
+                   (setq arg  (icicle-transform-multi-completion arg))
+                   (condition-case nil
+                       (funcall cmd arg) ; Try to use string candidate `arg'.
+                     ;; If that didn't work, use a symbol or number candidate.
+                     (wrong-type-argument (funcall cmd (car (read-from-string arg))))
+                     (wrong-number-of-arguments ; Punt - show help.
+                      (funcall #'icicle-help-on-candidate)))
+                   (select-window (minibuffer-window))
+                   (select-frame-set-input-focus (selected-frame)))))
+         (fn                                        (symbol-function cmd))
+         (count                                     (prefix-numeric-value current-prefix-arg))
+         ;; Rebind alternative action functions to nil, so we don't override the command we call.
+         (icicle-candidate-alt-action-fn            nil)
+         (icicle-all-candidates-list-alt-action-fn  nil))
+    ;; Message showing what `cmd' is bound to.  This is pretty much a transcription of C code in
+    ;; `keyboard.c'.  Not sure it DTRT when there is already a msg in the echo area.
+    (when (and suggest-key-bindings (not executing-kbd-macro))
+      (let* ((bindings   (where-is-internal cmd overriding-local-map t))
+             (curr-msg   (current-message))
+             (wait-time  (if curr-msg
+                             (or (and (numberp suggest-key-bindings) suggest-key-bindings) 2)
+                           0)))
+        (when (and bindings (not (and (vectorp bindings) (eq (aref bindings 0) 'mouse-movement))))
+          (when (and (sit-for wait-time) (atom unread-command-events))
+            (let ((message-log-max  nil)) ; Don't log this message.
+              (message "You can run the command `%s' with `%s'"
+                       (symbol-name cmd)
+                       (key-description bindings)))
+            (when (and (sit-for wait-time) curr-msg) (message curr-msg))))))
+    (cond ((arrayp fn)
+           (let ((this-command  cmd)) (execute-kbd-macro fn count))
+           (when (> count 1) (message "(%d times)" count)))
+          (t
+           (run-hooks 'post-command-hook)
+           (run-hooks 'pre-command-hook)
+           (let ((enable-recursive-minibuffers            t)
+                 ;; Restore this before we invoke command, since it might use completion.
+                 (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred)
+                 ;; Bind, don't set `this-command'.  When you use `C-next', `this-command' needs
+                 ;; to be `cmd' during the `C-RET' part, but `last-command' must not be `cmd'
+                 ;; during the `next' part.
+                 (this-command                            cmd))
+             (call-interactively cmd 'record-it))))
+    ;; After `M-x' `last-command' must be the command finally entered with `RET' or, if you end
+    ;; with `C-g', the last command entered with `C-RET'.
+    (setq icicle-new-last-cmd  cmd)))
+
+;; Inspired by Emacs partial completion and by library `exec-abbrev-cmd.el' (Tassilo Horn
+;; ).  The idea of command abbreviation is combined here with normal
+;; command invocation, in an Icicles multi-command.
+
+;;;###autoload (autoload 'icicle-command-abbrev "icicles-cmd1.el")
+(icicle-define-command icicle-command-abbrev ; Bound to `C-x SPC' in Icicle mode.
+  "Read command name or its abbreviation, read command args, call command.
+Read input, then call `icicle-command-abbrev-action' to act on it.
+
+If `icicle-add-proxy-candidates-flag' is non-nil, then command
+abbreviations, as well as commands, are available as completion
+candidates.  Otherwise, only commands are available.  You can toggle
+this user option using `\\\\[icicle-toggle-proxy-candidates]'\
+in the minibuffer.
+
+When an abbreviation is available, you can treat it just like a
+command.  The rest of this description covers the behavior of choosing
+an abbreviation.
+
+If an abbreviation matches a single command name, then that command is
+invoked.  If it matches more than one, then you can use completion to
+choose one.
+
+Hyphens (`-') in command names divide them into parts.  For example,
+`find-file' has two parts: `find' and `file'.  Each character of a
+command abbreviation corresponds to one part of each of the commands
+that match the abbreviation.  For example, abbreviation `ff' matches
+commands `find-file' and `focus-frame', and abbreviation `fg' matches
+`find-grep'.
+
+User option `icicle-command-abbrev-match-all-parts-flag' = nil means
+that an abbreviation need not match all parts of a command name; it
+need match only a prefix.  For example, nil means that abbreviation
+`ff' also matches `find-file-other-window' and `fg' also matches
+`find-grep-dired'."                     ; Doc string
+  icicle-command-abbrev-action          ; Function to perform the action
+  prompt obarray nil nil nil 'icicle-command-abbrev-history nil nil ; `completing-read' args
+  ((prompt                                  "Command or abbrev: ")
+   (last-command                            last-command) ; Save and restore the last command.
+   (icicle-sort-comparer                    'icicle-command-abbrev-used-more-p) ; Bindings.
+   (icicle-proxy-candidates                 (let ((ipc  ())
+                                                  abv)
+                                              (dolist (entry  icicle-command-abbrev-alist  ipc)
+                                                (setq abv  (symbol-name (cadr entry)))
+                                                (unless (member abv ipc) (push abv ipc)))))
+   (use-file-dialog                         nil) ; `mouse-2' in `*Completions*' won't use dialog box.
+   (alt-fn                                  nil)
+   (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
+   (icicle-must-pass-after-match-predicate  #'(lambda (c) (commandp (intern c))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command"))))
+  (when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt)) ; First code
+  nil (setq icicle-proxy-candidates  nil)) ; Undo code, last code
+
+(defun icicle-command-abbrev-action (abbrev-or-cmd)
+  "Action function for `icicle-command-abbrev'.
+If ABBREV-OR-CMD is a command, call it.
+If ABBREV-OR-CMD is an abbreviation for a single command, invoke it.
+If ABBREV-OR-CMD is an abbreviation for multiple commands, call
+`icicle-command-abbrev-command', to let user choose commands.
+If ABBREV-OR-CMD is not an abbreviation or a command, raise an error."
+  (setq abbrev-or-cmd  (intern abbrev-or-cmd))
+  (let* ((not-cmdp                                  (not (commandp abbrev-or-cmd)))
+         (regexp                                    (and (or not-cmdp
+                                                             icicle-command-abbrev-priority-flag)
+                                                         (icicle-command-abbrev-regexp
+                                                          abbrev-or-cmd)))
+         (icicle-commands-for-abbrev                (and (or not-cmdp
+                                                             icicle-command-abbrev-priority-flag)
+                                                         (icicle-command-abbrev-matching-commands
+                                                          regexp)))
+         (icicle-add-proxy-candidates-flag          icicle-add-proxy-candidates-flag)
+         (icicle-proxy-candidates                   icicle-proxy-candidates)
+         ;; Restore this before we invoke command, since it might use completion.
+         ;; Free var `orig-must-pass...' is bound in `icicle-command-abbrev'.
+         (icicle-must-pass-after-match-predicate    icicle-orig-must-pass-after-match-pred)
+         ;; Rebind alternative action functions to nil, so we don't override command we call.
+         (icicle-candidate-alt-action-fn            nil)
+         (icicle-all-candidates-list-alt-action-fn  nil))
+    (cond ((and not-cmdp (null icicle-commands-for-abbrev))
+           (error "No such command or abbreviation `%s'" abbrev-or-cmd))
+          (icicle-commands-for-abbrev
+           (let* ((icicle-sort-comparer  'icicle-command-abbrev-used-more-p)
+                  (cmd
+                   (if (null (cdr icicle-commands-for-abbrev))
+                       (prog1 (intern (caar icicle-commands-for-abbrev))
+                         (push (caar icicle-commands-for-abbrev) extended-command-history)
+                         (call-interactively (intern (caar icicle-commands-for-abbrev)) t))
+                     (let ((enable-recursive-minibuffers  t))
+                       (icicle-remove-Completions-window)
+                       (icicle-command-abbrev-command)))))
+             (icicle-command-abbrev-record abbrev-or-cmd cmd)))
+          ((not not-cmdp) (call-interactively abbrev-or-cmd)))))
+
+(defun icicle-command-abbrev-regexp (abbrev)
+  "Return the command-matching regexp for ABBREV."
+  (let ((char-list  (append (symbol-name abbrev) ()))
+        (str        "^"))
+    (dolist (c  char-list) (setq str  (concat str (list c) "[^-]*-")))
+    (concat (substring str 0 (1- (length str)))
+            (if icicle-command-abbrev-match-all-parts-flag "$" ".*$"))))
+
+(defun icicle-command-abbrev-matching-commands (regexp)
+  "Return a completion alist of commands that match REGEXP."
+  (mapcar #'list (icicle-remove-if-not
+                  #'(lambda (strg) (string-match regexp strg))
+                  (let ((cmds  ()))
+                    (mapatoms #'(lambda (symb)
+                                  (when (commandp symb) (push (symbol-name symb) cmds))))
+                    cmds))))
+
+;;;###autoload (autoload 'icicle-command-abbrev-command "icicles-cmd1.el")
+(icicle-define-command icicle-command-abbrev-command
+  "Read command name, then read its arguments and call command." ; Doc string
+  icicle-execute-extended-command-1     ; Function to perform the action
+  (format "Command abbreviated%s%s: "   ; `completing-read' arguments
+          (cond ((and icicle-current-input (not (string= "" icicle-current-input)))
+                 (format " `%s'" icicle-current-input))
+                (icicle-candidate-nb
+                 (format " `%s'" (elt icicle-completion-candidates icicle-candidate-nb)))
+                (t ""))
+          (if current-prefix-arg
+              (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
+            ""))
+  icicle-commands-for-abbrev nil t nil 'extended-command-history nil nil
+  (;; Bindings
+   (use-file-dialog                   nil) ; `mouse-2' in `*Completions*' shouldn't use file dialog.
+   (alt-fn                            nil)
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
+   (icicle-add-proxy-candidates-flag  nil) ; No abbrevs - just commands here.
+   (last-command                      last-command) ; Save and restore the last command.
+   icicle-new-last-cmd)                 ; Set in `icicle-execute-extended-command-1'.
+  nil nil                               ; First code, undo code
+  (setq this-command  icicle-new-last-cmd) ; Last code: this will update `last-command'.
+  'NON-INTERACTIVE)                     ; This is not a real command.
+
+(defun icicle-command-abbrev-record (abbrev command)
+  "Record ABBREV and COMMAND in `icicle-command-abbrev-alist'."
+  (let ((entry  (assq command icicle-command-abbrev-alist)))
+    (when (and abbrev command)
+      (if entry
+          (setq icicle-command-abbrev-alist  (cons (list command abbrev (1+ (car (cddr entry))))
+                                                   (delete entry icicle-command-abbrev-alist)))
+        (push (list command abbrev 1) icicle-command-abbrev-alist)))))
+
+;;;###autoload (autoload 'icicle-execute-named-keyboard-macro "icicles-cmd1.el")
+(icicle-define-command icicle-execute-named-keyboard-macro ; Bound to `C-x M-e' in Icicle mode.
+  "Read the name of a keyboard macro, then execute it."
+  icicle-execute-extended-command-1     ; Function to perform the action
+  (format "Execute keyboard macro%s: "  ; `completing-read' args
+          (if current-prefix-arg
+              (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
+            ""))
+  obarray nil t nil 'icicle-kmacro-history nil nil
+  ((last-command                            last-command) ; Save and restore the last command.
+   (alt-fn                                  nil)
+   (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
+   (icicle-must-pass-after-match-predicate
+    #'(lambda (fn) (setq fn  (intern fn)) (and (commandp fn) (arrayp (symbol-function fn)))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))))
+
+;;;###autoload (autoload 'icicle-kmacro "icicles-cmd1.el")
+(when (require 'kmacro nil t)
+  (icicle-define-command icicle-kmacro  ; Bound to `S-f4' in Icicle mode (Emacs 22+).
+    "Execute a keyboard macro according to its position in `kmacro-ring'.
+Macros in the keyboard macro ring are given names `1', `2', and so on,
+for use as completion candidates.
+
+With prefix argument, repeat macro that many times (but see below).
+If a macro is still being defined, end it first, then execute it.
+
+Since this is a multi-command, you can execute any number of macros
+any number of times in a single invocation.  In particular, you can
+execute a given macro repeatedly using `C-RET' (be sure you use `TAB'
+first, to make it the current candidate).
+
+If you use a prefix arg for `icicle-kmacro', then each multi-command
+action (e.g. `C-RET') repeats the macro that number of times.  However
+if you use a prefix arg for an individual action, then the action
+repeats the macro that number of times.  Without its own prefix arg,
+an action uses the base prefix arg you used for `icicle-kmacro'."
+    icicle-kmacro-action                ; Function to perform the action
+    (format "Execute keyboard macro%s: " ; `completing-read' args
+            (if current-prefix-arg
+                (format " (prefix %s)" (prefix-numeric-value current-prefix-arg))
+              ""))
+    (let ((count  0))
+      (setq icicle-kmacro-alist
+            (mapcar #'(lambda (x) (cons (format "%d" (setq count  (1+ count))) x))
+                    (reverse (if nil kmacro-ring (cons (kmacro-ring-head) kmacro-ring))))))
+    nil 'NO-EXIT-WO-MATCH nil 'icicle-kmacro-history
+    (and (kmacro-ring-head) (null kmacro-ring) "1") nil
+    ((icicle-pref-arg  current-prefix-arg))    ; Additional bindings
+    (progn                              ; First code
+      (when defining-kbd-macro (kmacro-end-or-call-macro current-prefix-arg) (error "Done"))
+      (unless (or (kmacro-ring-head) kmacro-ring) (error "No keyboard macro defined"))))
+
+  ;; Free vars here: `icicle-orig-buff' & `icicle-orig-window' are bound by `icicle-define-command'.
+  ;;                 `icicle-pref-arg' is bound in `icicle-kmacro'.
+  (defun icicle-kmacro-action (cand)
+    "Action function for `icicle-kmacro'."
+    (when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
+    (when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
+    (let* ((count  (if current-prefix-arg (prefix-numeric-value current-prefix-arg) icicle-pref-arg))
+           (macro  (cadr (assoc cand icicle-kmacro-alist))))
+      (unless macro (error "No such macro: `%s'" cand))
+      (execute-kbd-macro macro count #'kmacro-loop-setup-function)
+      (when (> count 1) (message "(%d times)" count)))))
+
+;;;###autoload (autoload 'icicle-set-option-to-t "icicles-cmd1.el")
+(icicle-define-command icicle-set-option-to-t ; Command name
+  "Set option to t.  This makes sense for binary (toggle) options.
+By default, completion candidates are limited to user options that
+have `boolean' custom types.  However, there are many \"binary\" options
+that allow other non-nil values than t.
+
+You can use a prefix argument to change the set of completion
+candidates, as follows:
+
+ - With a non-negative prefix arg, all user options are candidates.
+ - With a negative prefix arg, all variables are candidates." ; Doc string
+  (lambda (opt) (set (intern opt) t) (message "`%s' is now t" opt)) ; Action function
+  "Set option to t: " obarray nil 'must-confirm nil ; `completing-read' args
+  (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
+  ((enable-recursive-minibuffers          t) ; Bindings
+   (icicle-use-candidates-only-once-flag  t)
+   (alt-fn                                nil)
+   (icicle-must-pass-after-match-predicate
+    (cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
+           #'(lambda (x)
+               (setq x  (intern x)) (and (boundp x) (user-variable-p x) (eq nil (symbol-value x)))))
+          (current-prefix-arg
+           #'(lambda (x)
+               (setq x  (intern x)) (and (boundp x) (eq nil (symbol-value x)))))
+          (t
+           #'(lambda (x)
+               (setq x  (intern x))
+               (and (boundp x) (icicle-binary-option-p x) (eq nil (symbol-value x)))))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
+
+;;;###autoload (autoload 'icicle-clear-history "icicles-cmd1.el")
+(icicle-define-command icicle-clear-history
+  "Clear a minibuffer history of selected entries.
+You are prompted for the history to clear, then you are prompted for
+the entries to delete from it.  You can use multi-command completion
+for both inputs.  That is, you can act on multiple histories and
+delete multiple entries from each.
+
+For convenience, you can use `S-delete' the same way as `C-RET': Each
+of them deletes the current entry candidate from the history.
+
+With a prefix argument, empty the chosen history completely
+\(you are not prompted to choose history entries to delete).
+
+`icicle-act-before-cycle-flag' is bound to t here during completion of
+history entries, so `C-next' and so on act on the current candidate."
+  icicle-clear-history-1                ; Function to perform the action
+  "History to clear: " icicle-clear-history-hist-vars ; `completing-read' args
+  nil t nil nil (symbol-name minibuffer-history-variable) nil
+  ((icicle-pref-arg                 current-prefix-arg) ; Bindings
+   (enable-recursive-minibuffers    t)
+   (icicle-transform-function       'icicle-remove-duplicates)
+   (icicle-clear-history-hist-vars  `((,(symbol-name minibuffer-history-variable))
+                                      (,(symbol-name 'icicle-previous-raw-file-name-inputs))
+                                      (,(symbol-name 'icicle-previous-raw-non-file-name-inputs))))
+   (icicle-delete-candidate-object  'icicle-clear-history-entry))
+  (mapatoms #'(lambda (x) (when (and (boundp x) (consp (symbol-value x)) ; First code
+                                     (stringp (car (symbol-value x)))
+                                     (string-match "-\\(history\\|ring\\)\\'" (symbol-name x)))
+                            (push (list (symbol-name x)) icicle-clear-history-hist-vars)))))
+
+;; Free vars here: `icicle-pref-arg' is bound in `icicle-clear-history'.
+(defun icicle-clear-history-1 (hist)
+  "Action function for `icicle-clear-history' history-variable candidates."
+  (setq hist  (intern hist))
+  (if (not icicle-pref-arg)
+      (let* ((icicle-candidate-action-fn              'icicle-clear-history-entry)
+             (icicle-transform-function               'icicle-remove-duplicates)
+             (icicle-clear-history-hist               hist)
+             (icicle-use-candidates-only-once-flag    t)
+             (icicle-show-Completions-initially-flag  t)
+             (icicle-act-before-cycle-flag            t))
+        (when hist                      ; Maybe there are no more, due to deletion actions.
+          (funcall icicle-candidate-action-fn
+                   (completing-read "Clear input: " (mapcar #'list (symbol-value hist)) nil t))))
+    (set hist nil))
+  (unless hist (message "History `%s' is now empty" hist))
+  nil)
+
+;; Free vars here: `icicle-clear-history-hist' is bound in `icicle-clear-history-1'
+;; and in `icicle-clear-current-history'.
+(defun icicle-clear-history-entry (cand)
+  "Action function for history entry candidates in `icicle-clear-history'."
+  (unless (string= "" cand)
+    (set icicle-clear-history-hist
+         (icicle-remove-if
+          #'(lambda (x)
+              (string= (icicle-substring-no-properties cand) (icicle-substring-no-properties x)))
+          (symbol-value icicle-clear-history-hist)))
+    ;; We assume here that CAND was in fact present in the history originally.
+    (message "`%s' deleted from history `%s'" cand icicle-clear-history-hist))
+  nil)
+
+;;;###autoload (autoload 'icicle-clear-current-history "icicles-cmd1.el")
+(icicle-define-command icicle-clear-current-history ; Bound to `M-i' in minibuffer.
+  "Clear current minibuffer history of selected entries.
+You are prompted for the history entries to delete.
+
+With a prefix argument, however, empty the history completely
+\(you are not prompted to choose history entries to delete).
+
+`icicle-act-before-cycle-flag' is bound to t here during completion of
+history entries, so `C-next' and so on act on the current candidate."
+  icicle-clear-history-entry            ; Action function
+  "Clear input: " (mapcar #'list (symbol-value icicle-clear-history-hist)) ; `completing-read' args
+  nil t nil nil nil nil
+  ((icicle-pref-arg                         current-prefix-arg) ; Bindings
+   (enable-recursive-minibuffers            t)
+   (icicle-transform-function               'icicle-remove-duplicates)
+   (icicle-use-candidates-only-once-flag    t)
+   (icicle-show-Completions-initially-flag  t)
+   (icicle-clear-history-hist               minibuffer-history-variable))
+  (when icicle-pref-arg                 ; First code
+    (icicle-ding)                       ; Use `error' just to exit and make sure message is seen.
+    (if (not (yes-or-no-p (format "Are you sure you want to empty `%s' completely? "
+                                  minibuffer-history-variable)))
+        (error "")
+      (set minibuffer-history-variable nil)
+      (error "History `%s' is now empty" minibuffer-history-variable))))
+
+(when (and icicle-define-alias-commands-flag (not (fboundp 'clear-option)))
+  (defalias 'clear-option 'icicle-reset-option-to-nil))
+
+;;;###autoload (autoload 'icicle-reset-option-to-nil "icicles-cmd1.el")
+(icicle-define-command icicle-reset-option-to-nil ; Command name
+  "Set option to nil.  This makes sense for binary and list options.
+By default, the set of completion candidates is limited to user
+options.  Note: it is *not* limited to binary and list options.
+With a prefix arg, all variables are candidates." ; Doc string
+  (lambda (opt) (set (intern opt) nil) (message "`%s' is now nil" opt)) ; Action function
+  "Clear option (set it to nil): " obarray nil t nil ; `completing-read' args
+  (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history)
+  nil nil
+  ((enable-recursive-minibuffers          t) ; Bindings
+   (icicle-use-candidates-only-once-flag  t)
+   (alt-fn                                nil)
+   (icicle-must-pass-after-match-predicate
+    (if current-prefix-arg
+        #'(lambda (x) (setq x  (intern x)) (and (boundp x) (symbol-value x)))
+      #'(lambda (x) (setq x  (intern x)) (and (boundp x) (user-variable-p x) (symbol-value x)))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
+
+(when (and icicle-define-alias-commands-flag (not (fboundp 'toggle)))
+  (defalias 'toggle 'icicle-toggle-option))
+
+;;;###autoload (autoload 'icicle-toggle-option "icicles-cmd1.el")
+(icicle-define-command icicle-toggle-option ; Command name
+  "Toggle option's value.  This makes sense for binary (toggle) options.
+By default, completion candidates are limited to user options that
+have `boolean' custom types.  However, there are many \"binary\" options
+that allow other non-nil values than t.
+
+You can use a prefix argument to change the set of completion
+candidates, as follows:
+
+ - With a non-negative prefix arg, all user options are candidates.
+ - With a negative prefix arg, all variables are candidates." ; Doc string
+  (lambda (opt)                         ; Action function
+    (let ((sym  (intern opt)))
+      (set sym (not (eval sym))) (message "`%s' is now %s" opt (eval sym))))
+  "Toggle value of option: " obarray nil 'must-confirm nil ; `completing-read' args
+  (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
+  ((enable-recursive-minibuffers  t)    ; Bindings
+   (alt-fn                        nil)
+   (icicle-must-pass-after-match-predicate
+    (cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
+           #'(lambda (c) (user-variable-p (intern c))))
+          (current-prefix-arg #'(lambda (c) (boundp (intern c))))
+          (t                  #'(lambda (c) (icicle-binary-option-p (intern c))))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
+
+(defun icicle-binary-option-p (symbol)
+  "Non-nil if SYMBOL is a user option that has custom-type `boolean'."
+  (eq (get symbol 'custom-type) 'boolean))
+
+;;;###autoload (autoload 'icicle-increment-option "icicles-cmd1.el")
+(icicle-define-command icicle-increment-option ; Command name
+  "Increment option's value using the arrow keys (`up', `down').
+Completion candidates are limited to options that have `integer',
+`float', and `number' custom types.
+This command needs library `doremi.el'." ; Doc string
+  (lambda (opt)                         ; Action function
+    (let ((sym                                     (intern opt))
+          ;; Restore this before we read number, since that might use completion.
+          (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
+      (icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") t)
+      (message "`%s' is now %s" opt (eval sym))))
+  "Increment value of option: " obarray nil 'must-confirm nil ; `completing-read' args
+  (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
+  ((enable-recursive-minibuffers            t) ; Bindings
+   (alt-fn                                  nil)
+   (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
+   (icicle-must-pass-after-match-predicate
+    #'(lambda (s) (memq (get (intern s) 'custom-type) '(number integer float))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option"))))
+  (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))) ; First code
+
+;;;###autoload (autoload 'icicle-increment-variable "icicles-cmd1.el")
+(icicle-define-command icicle-increment-variable ; Command name
+  "Increment variable's value using the arrow keys (`up', `down').
+With a prefix arg, only numeric user options are candidates.
+With no prefix arg, all variables are candidates, even those that are
+ not numeric. 
+This command needs library `doremi.el'." ; Doc string
+  (lambda (var)                         ; Action function
+    (let ((sym                                     (intern var))
+          ;; Restore this before we read number, since that might use completion.
+          (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
+      (icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") prefix-arg)
+      (message "`%s' is now %s" var (eval sym))))
+  "Increment value of variable: " obarray nil 'must-confirm nil ; `completing-read' args
+  (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
+  ((enable-recursive-minibuffers            t) ; Bindings
+   (prefix-arg                              current-prefix-arg)
+   (alt-fn                                  nil)
+   (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
+   (icicle-must-pass-after-match-predicate
+    (if prefix-arg
+        #'(lambda (s) (memq (get (intern s) 'custom-type) '(number integer float)))
+      #'(lambda (s) (boundp (intern s)))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn
+        (setq alt-fn  (icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn
+        (icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
+  (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))) ; First code
+
+;;;###autoload
+(defun icicle-doremi-increment-variable+ (variable &optional increment optionp)
+  "Increment VARIABLE by INCREMENT (default 1).
+Use arrow key `up' or `down' or mouse wheel to increase or decrease.
+You can use the `Meta' key (e.g. `M-up') to increment in larger steps.
+
+Interactively, you can choose VARIABLE using completion.
+With a prefix arg, only user options are available to choose from.
+Raises an error if VARIABLE's value is not a number."
+  (interactive
+   (let ((symb                                      (or (and (fboundp 'symbol-nearest-point)
+                                                             (symbol-nearest-point))
+                                                        (and (symbolp (variable-at-point))
+                                                             (variable-at-point))))
+         (enable-recursive-minibuffers              t)
+         (icicle-orig-must-pass-after-match-pred    icicle-must-pass-after-match-predicate)
+         (icicle-must-pass-after-match-predicate    (if current-prefix-arg
+                                                        #'(lambda (s) (user-variable-p (intern s)))
+                                                      #'(lambda (s) (boundp (intern s))))))
+     (list (intern (completing-read "Increment variable: " obarray nil t nil nil
+                                    (and symb (symbol-name symb)) t))
+           ;; Restore this before we read number, since that might use completion.
+           (let ((icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
+             (icicle-read-number "Increment (amount): "))
+           current-prefix-arg)))
+  (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))
+  (unless increment (setq increment 1))
+  (unless (numberp (symbol-value variable))
+    (error "Variable's value is not a number: %S" (symbol-value variable)))
+  (doremi (lambda (new-val)
+            (set variable  new-val)
+            new-val)
+          (symbol-value variable)
+          increment))
+
+;;;###autoload (autoload 'icicle-bookmark-list "icicles-cmd1.el")
+(icicle-define-command icicle-bookmark-list ; Command name
+  "Choose a list of bookmark names.
+If `icicle-bookmark-types' is non-nil, then it is a list of bookmark
+types and only bookmarks of those types are candidates.
+
+You can use `S-delete' during completion to delete a candidate bookmark.
+The list of bookmark names (strings) is returned." ; Doc string
+  (lambda (name) (push (icicle-substring-no-properties (icicle-transform-multi-completion name))
+                       bmk-names))      ; Action function
+  "Choose bookmark (`RET' when done): " icicle-candidates-alist nil ; `completing-read' args
+  (not icicle-show-multi-completion-flag)
+  nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+  (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
+  ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
+   (completion-ignore-case                 bookmark-completion-ignore-case)
+   (icicle-list-use-nth-parts              '(1))
+   (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
+                                               nil
+                                             (if (facep 'file-name-shadow)
+                                                 '((2 (face file-name-shadow))
+                                                   (3 (face bookmark-menu-heading)))
+                                               '((3 (face bookmark-menu-heading))))))
+   (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
+   (icicle-whole-candidate-as-text-prop-p  t)
+   (icicle-transform-before-sort-p         t)
+   (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
+   (types                                  icicle-bookmark-types)
+   (icicle-candidates-alist                ())
+   (bmk-names                              ())
+   (icicle-sort-orders-alist
+    (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
+              ("by bookmark name" . icicle-alpha-p))
+            (and (featurep 'bookmark+)
+                 (append
+                  '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+                    ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
+                  (and (icicle-set-intersection types '("info" "region"))
+                       '(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
+                  (and (icicle-set-intersection types '("gnus" "region"))
+                       '(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
+                  (and (icicle-set-intersection types '("url" "region"))
+                       '(("by URL" (bmkp-url-cp) icicle-alpha-p)))
+                  (and (icicle-set-difference types
+                                              '("bookmark-list" "desktop" "gnus" "info" "man" "url"))
+                       '(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                                              bmkp-local-file-type-cp bmkp-handler-cp)
+                          icicle-alpha-p)))
+                  (and (icicle-set-difference
+                        types '("bookmark-list" "desktop" "dired" "non-file"))
+                       '(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
+                  (and (icicle-set-intersection types
+                                                '("local-file" "file" "dired" "region"))
+                       '(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+                         ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+                         ("by last local file access"
+                          (bmkp-local-file-accessed-more-recently-cp)
+                          icicle-alpha-p)
+                         ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+                          icicle-alpha-p)))
+                  (and (not (equal types '("desktop")))
+                       '(("by last buffer or file access"
+                          (bmkp-buffer-last-access-cp
+                           bmkp-local-file-accessed-more-recently-cp)
+                          icicle-alpha-p)))
+                  (and (get-buffer "*Bookmark List*")
+                       '(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+                          icicle-alpha-p)))))
+            '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+              ("case insensitive" . icicle-case-insensitive-string-less-p))))         
+   (icicle-candidate-help-fn
+    #'(lambda (cand)
+        (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
+          (setq cand  (funcall icicle-get-alist-candidate-function cand))
+          (setq cand  (cons (caar cand) (cdr cand))))
+        (if (featurep 'bookmark+)
+            (if current-prefix-arg
+                (bmkp-describe-bookmark-internals cand)
+              (bmkp-describe-bookmark cand))
+          (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand))))))
+  (progn                                ; First code
+    (message "Gathering bookmarks...")
+    (unless types  (setq types '(all)))
+    (dolist (type  types)
+      (setq icicle-candidates-alist
+            (nconc icicle-candidates-alist
+                   (if (not (featurep 'bookmark+))
+                       (mapcar #'(lambda (cand) (list (icicle-candidate-short-help
+                                                       (icicle-bookmark-help-string cand)
+                                                       (icicle-bookmark-propertize-candidate cand))))
+                               (if (eq type 'all)
+                                   bookmark-alist
+                                 (funcall (intern (format "bmkp-%s-alist-only" type)))))
+                     (bookmark-maybe-load-default-file) ; Load bookmarks, define `bookmark-alist'.
+                     (mapcar (if icicle-show-multi-completion-flag
+                                 #'(lambda (bmk)
+                                     ;; Ignore errors, e.g. from bad bookmark.
+                                     (icicle-condition-case-no-debug nil
+                                         (let* ((bname     (bookmark-name-from-full-record bmk))
+                                                (guts      (bookmark-get-bookmark-record bmk))
+                                                (file      (bookmark-get-filename bmk))
+                                                (buf       (bmkp-get-buffer-name bmk))
+                                                (file/buf
+                                                 (if (and buf
+                                                          (equal file bmkp-non-file-filename))
+                                                     buf
+                                                   file))
+                                                (tags      (bmkp-get-tags bmk)))
+                                           (cons `(,(icicle-candidate-short-help
+                                                     (icicle-bookmark-help-string bname)
+                                                     (icicle-bookmark-propertize-candidate bname))
+                                                   ,file/buf
+                                                   ,@(and tags (list (format "%S" tags))))
+                                                 guts))
+                                       (error nil)))
+                               #'(lambda (bmk)
+                                   ;; Ignore errors, e.g. from bad bookmark.
+                                   (icicle-condition-case-no-debug nil
+                                       (let ((bname  (bookmark-name-from-full-record bmk))
+                                             (guts   (bookmark-get-bookmark-record bmk)))
+                                         (cons (icicle-candidate-short-help
+                                                (icicle-bookmark-help-string bname)
+                                                (icicle-bookmark-propertize-candidate bname))
+                                               guts))
+                                     (error nil))))
+                             (bmkp-sort-omit
+                              (if (eq type 'all)
+                                  bookmark-alist
+                                (funcall (intern (format "bmkp-%s-alist-only" type)))))))))))
+  (icicle-bookmark-cleanup-on-quit)     ; Undo code
+  (prog1 (setq bmk-names  (nreverse (delete "" bmk-names))) ; Last code - return the list.
+    (icicle-bookmark-cleanup)
+    (when (interactive-p) (message "Bookmarks: %S" bmk-names))))
+
+;;;###autoload
+(defun icicle-bookmark-cmd (&optional parg) ; Bound to what `bookmark-set' is bound to (`C-x r m').
+  "Set bookmark or visit bookmark(s).
+With a negative prefix arg, visit bookmark(s), using
+  `icicle-bookmark-other-window' (see that command for more info).
+
+Otherwise, set a bookmark, as follows:
+
+* No prefix arg: Prompt for the bookmark name.
+
+  If feature `bookmark+' is present:
+
+  . You can use (lax) completion for the bookmark name.
+    The candidates are bookmarks in the current buffer (or all
+    bookmarks if there are none in this buffer).
+
+  . If the region is active and nonempty, then use the buffer name
+    followed by the region prefix as the default name.
+
+  If feature `bookmark+' is not present, then completion is not
+  available, and the default bookmark name is the last one used in
+  this buffer.
+
+  Note: You can use command `icicle-bookmark-set' with a numeric
+  prefix arg if you want to complete against all bookmark names,
+  instead of those for the current buffer.
+
+* Plain prefix arg (`C-u'): Same as no prefix arg, but do not
+  overwrite any existing bookmark that has the same name.
+
+* Non-negative numeric prefix arg: Do not prompt for bookmark name.
+  If feature `bookmark+' is present and the region is active and
+    nonempty, then use the buffer name followed by a prefix of the
+    region text as the bookmark name.
+  Otherwise, use the buffer name followed by the text of the current
+    line, starting at point.
+  Use at most `icicle-bookmark-name-length-max' chars, in either case.
+  If the prefix arg is 0, then do not overwrite any existing bookmark
+    that has the same name.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `bookmark-set' to `icicle-bookmark-cmd'.  If you do not want
+this remapping, then customize option `icicle-top-level-key-bindings'.
+In particular, you might prefer to remap `bookmark-set' to
+`icicle-bookmark-set' (see Note, above)."
+  (interactive "P")
+  (if (and parg (< (prefix-numeric-value parg) 0))
+      (icicle-bookmark-other-window)
+    (if (or (not parg) (consp parg))
+        (icicle-bookmark-set nil parg 'PSEUDO-INTERACTIVEP)
+      (let* ((regionp    (and (featurep 'bookmark+)  transient-mark-mode  mark-active
+                              (not (eq (region-beginning) (region-end)))))
+             (name-beg   (if regionp (region-beginning) (point)))
+             (name-end   (if regionp (region-end) (save-excursion (end-of-line) (point))))
+             (def-name   (concat (buffer-name) ": " (buffer-substring name-beg name-end)))
+             (trim-name  (replace-regexp-in-string
+                          "\n" " " (substring def-name 0 (min icicle-bookmark-name-length-max
+                                                              (length def-name))))))
+        (message "Setting bookmark `%s'" trim-name) (sit-for 2)
+        (bookmark-set trim-name (and parg (or (consp parg)
+                                              (zerop (prefix-numeric-value parg)))))))))
+
+;;;###autoload
+(defun icicle-bookmark-set (&optional name parg interactivep) ; `C-x r m'
+  "With `Bookmark+', this is `bookmark-set' with Icicles multi-completions.
+In particular, you can use (lax) completion for the bookmark name.
+Without library `Bookmark+', this is the same as vanilla Emacs
+`bookmark-set'."
+  (interactive (list nil current-prefix-arg t))
+  (if (not (featurep 'bookmark+))
+      (bookmark-set name parg)
+    (unwind-protect
+         (let ((enable-recursive-minibuffers           t) ; In case read input, e.g. File changed...
+               (completion-ignore-case                 bookmark-completion-ignore-case)
+               (prompt                                 "Bookmark: ")
+               (icicle-list-use-nth-parts              '(1))
+               (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
+                                                           nil
+                                                         (if (facep 'file-name-shadow)
+                                                             '((2 (face file-name-shadow))
+                                                               (3 (face bookmark-menu-heading)))
+                                                           '((3 (face bookmark-menu-heading))))))
+               (icicle-transform-function              (and (not (interactive-p))
+                                                            icicle-transform-function))
+               (icicle-whole-candidate-as-text-prop-p  t)
+               (icicle-transform-before-sort-p         t)
+               (icicle-sort-orders-alist
+                (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
+                          ("by bookmark name" . icicle-alpha-p))
+                        (and (featurep 'bookmark+)
+                             '(("by last bookmark access" (bmkp-bookmark-last-access-cp)
+                                icicle-alpha-p)
+                               ("by bookmark visit frequency" (bmkp-visited-more-cp)
+                                icicle-alpha-p)
+                               ("by last buffer or file access"
+                                (bmkp-buffer-last-access-cp
+                                 bmkp-local-file-accessed-more-recently-cp)
+                                icicle-alpha-p)
+                               ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+                                icicle-alpha-p)
+                               ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+                               ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
+                               ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+                               ("by last local file access"
+                                (bmkp-local-file-accessed-more-recently-cp)
+                                icicle-alpha-p)
+                               ("by last local file update"
+                                (bmkp-local-file-updated-more-recently-cp)
+                                icicle-alpha-p)
+                               ("by Info location" (bmkp-info-cp) icicle-alpha-p)
+                               ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
+                               ("by URL" (bmkp-url-cp) icicle-alpha-p)
+                               ("by bookmark type"
+                                (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                                 bmkp-local-file-type-cp bmkp-handler-cp)
+                                icicle-alpha-p)))
+                        '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+                          ("case insensitive" . icicle-case-insensitive-string-less-p))))
+               (icicle-candidate-help-fn
+                #'(lambda (cand)
+                    (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
+                      (setq cand  (funcall icicle-get-alist-candidate-function cand))
+                      (setq cand  (cons (caar cand) (cdr cand))))
+                    (if (featurep 'bookmark+)
+                        (if current-prefix-arg
+                            (bmkp-describe-bookmark-internals cand)
+                          (bmkp-describe-bookmark cand))
+                      (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
+               (icicle-candidates-alist
+                (if (not (featurep 'bookmark+))
+                    (mapcar #'(lambda (cand)
+                                (list (icicle-candidate-short-help
+                                       (icicle-bookmark-help-string cand)
+                                       (icicle-bookmark-propertize-candidate cand))))
+                            (bookmark-all-names)) ; Loads bookmarks file.
+                  (bookmark-maybe-load-default-file) ; Loads bookmarks file.
+                  (mapcar (if icicle-show-multi-completion-flag
+                              #'(lambda (bmk)
+                                  (let* ((bname     (bookmark-name-from-full-record bmk))
+                                         (guts      (bookmark-get-bookmark-record bmk))
+                                         (tags      (bmkp-get-tags bmk))
+                                         (file      (bookmark-get-filename bmk))
+                                         (buf       (bmkp-get-buffer-name bmk))
+                                         (file/buf
+                                          (if (and buf (equal file bmkp-non-file-filename))
+                                              buf
+                                            file)))
+                                    (cons `(,(icicle-candidate-short-help
+                                              (icicle-bookmark-help-string bname)
+                                              (icicle-bookmark-propertize-candidate bname))
+                                            ,file/buf
+                                            ,@(and tags (list (format "%S" tags))))
+                                          guts)))
+                            #'(lambda (bmk)
+                                (let ((bname  (bookmark-name-from-full-record bmk))
+                                      (guts   (bookmark-get-bookmark-record bmk)))
+                                  (cons (icicle-candidate-short-help
+                                         (icicle-bookmark-help-string bname)
+                                         (icicle-bookmark-propertize-candidate bname))
+                                        guts))))
+                          (bmkp-sort-omit
+                           (and (or (not parg) (consp parg)) ; No numeric PARG: all bookmarks.
+                                (or (bmkp-specific-buffers-alist-only)
+                                    bookmark-alist)))))))
+           (require 'bookmark)
+           (when (featurep 'bookmark+)
+             ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
+             (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
+               (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
+               (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
+               (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
+               (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
+               (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
+               (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
+               (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
+               (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
+               (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; C-M-@
+               (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
+                 'icicle-bookmark-specific-buffers-narrow)
+               (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
+                 'icicle-bookmark-specific-files-narrow)
+               (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
+                 'icicle-bookmark-this-buffer-narrow)
+               (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
+                 'icicle-bookmark-bookmark-list-narrow)
+               (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
+                 'icicle-bookmark-local-file-narrow)
+               (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
+                 'icicle-bookmark-info-narrow)
+               (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
+                 'icicle-bookmark-desktop-narrow)))
+           (setq bookmark-current-point   (point)
+                 bookmark-current-buffer  (current-buffer))
+           (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
+           (let* ((record   (bookmark-make-record))
+                  (regionp  (and transient-mark-mode mark-active (not (eq (mark) (point)))))
+                  (regname  (concat (buffer-name) ": "
+                                    (buffer-substring (if regionp (region-beginning) (point))
+                                                      (if regionp
+                                                          (region-end)
+                                                        (save-excursion (end-of-line) (point))))))
+                  (defname  (bmkp-replace-regexp-in-string
+                             "\n" " "
+                             (cond (regionp
+                                    (save-excursion
+                                      (goto-char (region-beginning))
+                                      (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
+                                    (substring regname 0 (min bmkp-bookmark-name-length-max
+                                                              (length regname))))
+                                   ((eq major-mode 'w3m-mode) w3m-current-title)
+                                   ((eq major-mode 'gnus-summary-mode)
+                                    (elt (gnus-summary-article-header) 1))
+                                   ((memq major-mode '(Man-mode woman-mode))
+                                    (buffer-substring (point-min) (save-excursion
+                                                                    (goto-char (point-min))
+                                                                    (skip-syntax-forward "^ ")
+                                                                    (point))))
+                                   (t (car record)))))
+                  (bname    (or name
+                                (icicle-transform-multi-completion
+                                 (bmkp-completing-read-lax "Set bookmark " defname
+                                                                icicle-candidates-alist
+                                                                nil bookmark-history)))))
+             (when (string-equal bname "") (setq bname  defname))
+             (bookmark-store bname (cdr record) (consp parg))
+             (when (and bmkp-prompt-for-tags-flag interactivep)
+               (bmkp-add-tags bname (bmkp-read-tags-completing)))
+             (case (and (boundp 'bmkp-auto-light-when-set) bmkp-auto-light-when-set)
+               (autonamed-bookmark       (when (bmkp-autonamed-bookmark-p bname)
+                                           (bmkp-light-bookmark bname)))
+               (non-autonamed-bookmark   (unless (bmkp-autonamed-bookmark-p bname)
+                                           (bmkp-light-bookmark bname)))
+               (any-bookmark             (bmkp-light-bookmark bname))
+               (autonamed-in-buffer      (bmkp-light-bookmarks
+                                          (bmkp-remove-if-not
+                                           #'bmkp-autonamed-bookmark-p
+                                           (bmkp-this-buffer-alist-only)) nil 'MSG))
+               (non-autonamed-in-buffer  (bmkp-light-bookmarks
+                                          (bmkp-remove-if
+                                           #'bmkp-autonamed-bookmark-p
+                                           (bmkp-this-buffer-alist-only)) nil 'MSG))
+               (all-in-buffer            (bmkp-light-this-buffer nil 'MSG)))
+             (run-hooks 'bmkp-after-set-hook)
+             (if bookmark-use-annotations
+                 (bookmark-edit-annotation bname)
+               (goto-char bookmark-current-point))))
+      (icicle-bookmark-cleanup))))
+
+;;;###autoload (autoload 'icicle-bookmark "icicles-cmd1.el")
+(icicle-define-command icicle-bookmark  ; Command name
+  "Jump to a bookmark.
+With a plain prefix argument (`C-u'), reverse the effect of option
+`icicle-bookmark-refresh-cache-flag'.
+
+During completion, you can use `S-delete' on a bookmark to delete it.
+
+If you also use library `Bookmark+', then:
+
+ * `C-M-RET' shows detailed info about the current bookmark candidate.
+   `C-u C-M-RET' shows the complete, internal info for the bookmark.
+   Likewise, for the other candidate help keys: `C-M-down' etc.
+   (And the mode line always shows summary info about the bookmark.)
+   
+ * You can use `C-,' to sort bookmarks in many different ways,
+   according to their properties.
+
+ * In `*Completions*', the candidate bookmarks are highlighted
+   according to their type.  You can customize the highlighting faces:
+
+  `bmkp-bad-bookmark'              - possibly bad bookmark
+  `bmkp-bookmark-list'             - bookmark list
+  `bmkp-buffer'                    - buffer
+  `bmkp-desktop'                   - desktop
+  `bmkp-function'                  - function bookmark
+  `bmkp-gnus'                      - Gnus article
+  `bmkp-info'                      - Info node
+  `bmkp-local-directory'           - local directory
+  `bmkp-local-file-with-region'    - local file with a region
+  `bmkp-local-file-without-region' - local file without a region
+  `bmkp-man'                       - `man' page
+  `bmkp-non-file'                  - non-file (no current buffer)
+  `bmkp-remote-file'               - remote-file
+  `bmkp-sequence'                  - sequence bookmark
+  `bmkp-url'                       - URL
+
+ * In `*Completions*', if option `icicle-show-multi-completion-flag'
+   is non-nil, then each completion candidate is a multi-completion:
+
+    a. the bookmark name
+    b. the bookmark file or buffer name
+    c. any tags
+
+   You can match any parts of the multi-completion.  You can toggle
+   the option (for the next command) using `M-m' during completion.
+   For example, you can match all bookmarks that have tags by typing:
+
+     C-M-j . * C-M-j S-TAB
+
+   (Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string'.)
+
+ * You can narrow the current completion candidates to bookmarks of a
+   given type:
+
+   `C-M-b'   - non-file (buffer) bookmarks
+   `C-M-B'   - bookmark-list bookmarks
+   `C-M-d'   - Dired bookmarks
+   `C-M-f'   - file bookmarks
+   `C-M-F'   - local-file bookmarks
+   `C-M-g'   - Gnus bookmarks
+   `C-M-I'   - Info bookmarks
+   `C-M-K'   - desktop bookmarks
+   `C-M-m'   - `man' pages
+   `C-M-r'   - bookmarks with regions
+   `C-M-u'   - URL bookmarks
+   `C-M-w'   - W3M (URL) bookmarks
+   `C-M-@'   - remote-file bookmarks
+   `C-M-.'   - bookmarks for the current buffer
+   `C-M-= b' - bookmarks for specific buffers
+   `C-M-= f' - bookmarks for specific files
+
+   See also the individual multi-commands for different bookmark
+   types: `icicle-bookmark-info-other-window' etc.
+
+If you also use library `crosshairs.el', then the visited bookmark
+position is highlighted."               ; Doc string
+  (lambda (cand) (icicle-bookmark-jump (icicle-transform-multi-completion cand))) ; Action
+  prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag) ; `completing-read' args
+  nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+  (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
+  ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
+   (completion-ignore-case                 bookmark-completion-ignore-case)
+   (prompt                                 "Bookmark: ")
+   (icicle-list-use-nth-parts              '(1))
+   (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
+                                               nil
+                                             (if (facep 'file-name-shadow)
+                                                 '((2 (face file-name-shadow))
+                                                   (3 (face bookmark-menu-heading)))
+                                               '((3 (face bookmark-menu-heading))))))
+   (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
+   (icicle-whole-candidate-as-text-prop-p  t)
+   (icicle-transform-before-sort-p         t)
+   (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
+   (icicle-sort-orders-alist
+    (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
+              ("by bookmark name" . icicle-alpha-p))
+            (and (featurep 'bookmark+)
+                 '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+                   ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
+                   ("by last buffer or file access" (bmkp-buffer-last-access-cp
+                                                     bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+                    icicle-alpha-p)
+                   ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+                   ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
+                   ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+                   ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by Info location" (bmkp-info-cp) icicle-alpha-p)
+                   ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
+                   ("by URL" (bmkp-url-cp) icicle-alpha-p)
+                   ("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                                        bmkp-local-file-type-cp bmkp-handler-cp)
+                    icicle-alpha-p)))
+            '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+              ("case insensitive" . icicle-case-insensitive-string-less-p))))
+   (icicle-candidate-help-fn
+    #'(lambda (cand)
+        (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
+          (setq cand  (funcall icicle-get-alist-candidate-function cand))
+          (setq cand  (cons (caar cand) (cdr cand))))
+        (if (featurep 'bookmark+)
+            (if current-prefix-arg
+                (bmkp-describe-bookmark-internals cand)
+              (bmkp-describe-bookmark cand))
+          (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
+   (icicle-candidates-alist
+    (if (not (featurep 'bookmark+))
+        (mapcar #'(lambda (cand)
+                    (list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
+                                                       (icicle-bookmark-propertize-candidate cand))))
+                (bookmark-all-names))   ; Loads bookmarks file, defining `bookmark-alist'.
+      (bookmark-maybe-load-default-file) ; Loads bookmarks file, defining `bookmark-alist'.
+      (mapcar (if icicle-show-multi-completion-flag
+                  #'(lambda (bmk)
+                      ;; Ignore errors, e.g. from bad or stale bookmark records.
+                      (icicle-condition-case-no-debug nil
+                          (let* ((bname     (bookmark-name-from-full-record bmk))
+                                 (guts      (bookmark-get-bookmark-record bmk))
+                                 (file      (bookmark-get-filename bmk))
+                                 (buf       (bmkp-get-buffer-name bmk))
+                                 (file/buf  (if (and buf (equal file bmkp-non-file-filename))
+                                                buf
+                                              file))
+                                 (tags      (bmkp-get-tags bmk)))
+                            (cons `(,(icicle-candidate-short-help
+                                      (icicle-bookmark-help-string bname)
+                                      (icicle-bookmark-propertize-candidate bname))
+                                    ,file/buf
+                                    ,@(and tags (list (format "%S" tags))))
+                                  guts))
+                        (error nil)))
+                #'(lambda (bmk)
+                    ;; Ignore errors, e.g. from bad or stale bookmark records.
+                    (icicle-condition-case-no-debug nil
+                        (let ((bname  (bookmark-name-from-full-record bmk))
+                              (guts   (bookmark-get-bookmark-record bmk)))
+                          (cons (icicle-candidate-short-help
+                                 (icicle-bookmark-help-string bname)
+                                 (icicle-bookmark-propertize-candidate bname))
+                                guts))
+                      (error nil))))
+              (or (and (or (and (not icicle-bookmark-refresh-cache-flag)
+                                (not (consp current-prefix-arg)))
+                           (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
+                       bmkp-sorted-alist)
+                  (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist)))))))
+  (progn                                ; First code
+    (require 'bookmark)
+    (when (featurep 'bookmark+)
+      ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
+      (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
+        (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
+        (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
+        (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
+        (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
+        (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
+        (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
+        (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
+        (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
+        (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; `C-M-@'
+        (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
+          'icicle-bookmark-specific-buffers-narrow)
+        (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
+          'icicle-bookmark-specific-files-narrow)
+        (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
+          'icicle-bookmark-this-buffer-narrow)
+        (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
+          'icicle-bookmark-bookmark-list-narrow)
+        (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
+          'icicle-bookmark-local-file-narrow)
+        (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
+          'icicle-bookmark-info-narrow)
+        (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
+          'icicle-bookmark-desktop-narrow))))
+  (icicle-bookmark-cleanup-on-quit)     ; Undo code
+  (icicle-bookmark-cleanup))            ; Last code
+
+;;;###autoload (autoload 'icicle-bookmark-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-bookmark-other-window ; Command name
+  "Jump to a bookmark in another window.
+Same as `icicle-bookmark', but uses another window." ; Doc string
+  (lambda (cand) (icicle-bookmark-jump-other-window (icicle-transform-multi-completion cand)))
+  prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag) ; `completing-read' args
+  nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+  (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
+  ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
+   (completion-ignore-case                 bookmark-completion-ignore-case)
+   (prompt                                 "Bookmark: ")
+   (icicle-list-use-nth-parts              '(1))
+   (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
+                                               nil
+                                             (if (facep 'file-name-shadow)
+                                                 '((2 (face file-name-shadow))
+                                                   (3 (face bookmark-menu-heading)))
+                                               '((3 (face bookmark-menu-heading))))))
+   (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
+   (icicle-whole-candidate-as-text-prop-p  t)
+   (icicle-transform-before-sort-p         t)
+   (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
+   (icicle-sort-orders-alist
+    (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
+              ("by bookmark name" . icicle-alpha-p))
+            (and (featurep 'bookmark+)
+                 '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+                   ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
+                   ("by last buffer or file access" (bmkp-buffer-last-access-cp
+                                                     bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+                    icicle-alpha-p)
+                   ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+                   ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
+                   ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+                   ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by Info location" (bmkp-info-cp) icicle-alpha-p)
+                   ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
+                   ("by URL" (bmkp-url-cp) icicle-alpha-p)
+                   ("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                                        bmkp-local-file-type-cp bmkp-handler-cp)
+                    icicle-alpha-p)))
+            '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+              ("case insensitive" . icicle-case-insensitive-string-less-p))))
+   (icicle-candidate-help-fn
+    #'(lambda (cand)
+        (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
+          (setq cand  (funcall icicle-get-alist-candidate-function cand))
+          (setq cand  (cons (caar cand) (cdr cand))))
+        (if (featurep 'bookmark+)
+            (if current-prefix-arg
+                (bmkp-describe-bookmark-internals cand)
+              (bmkp-describe-bookmark cand))
+          (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
+   (icicle-candidates-alist
+    (if (not (featurep 'bookmark+))
+        (mapcar #'(lambda (cand)
+                    (list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
+                                                       (icicle-bookmark-propertize-candidate cand))))
+                (bookmark-all-names))   ; Loads bookmarks file, defining `bookmark-alist'.
+      (bookmark-maybe-load-default-file) ; Loads bookmarks file, defining `bookmark-alist'.
+      (mapcar (if icicle-show-multi-completion-flag
+                  #'(lambda (bmk)
+                      ;; Ignore errors, e.g. from bad or stale bookmark records.
+                      (icicle-condition-case-no-debug nil
+                          (let* ((bname     (bookmark-name-from-full-record bmk))
+                                 (guts      (bookmark-get-bookmark-record bmk))
+                                 (file      (bookmark-get-filename bmk))
+                                 (buf       (bmkp-get-buffer-name bmk))
+                                 (file/buf  (if (and buf (equal file bmkp-non-file-filename))
+                                                buf
+                                              file))
+                                 (tags      (bmkp-get-tags bmk)))
+                            (cons `(,(icicle-candidate-short-help
+                                      (icicle-bookmark-help-string bname)
+                                      (icicle-bookmark-propertize-candidate bname))
+                                    ,file/buf
+                                    ,@(and tags (list (format "%S" tags))))
+                                  guts))
+                        (error nil)))
+                #'(lambda (bmk)
+                    ;; Ignore errors, e.g. from bad or stale bookmark records.
+                    (icicle-condition-case-no-debug nil
+                        (let ((bname  (bookmark-name-from-full-record bmk))
+                              (guts   (bookmark-get-bookmark-record bmk)))
+                          (cons (icicle-candidate-short-help
+                                 (icicle-bookmark-help-string bname)
+                                 (icicle-bookmark-propertize-candidate bname))
+                                guts))
+                      (error nil))))
+              (or (and (or (and (not icicle-bookmark-refresh-cache-flag)
+                                (not (consp current-prefix-arg)))
+                           (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
+                       bmkp-sorted-alist)
+                  (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist)))))))
+  (progn                                ; First code
+    (require 'bookmark)
+    (when (featurep 'bookmark+)
+      ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
+      (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
+        (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
+        (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
+        (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
+        (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
+        (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
+        (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
+        (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
+        (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
+        (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; `C-M-@'
+        (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
+          'icicle-bookmark-specific-buffers-narrow)
+        (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
+          'icicle-bookmark-specific-files-narrow)
+        (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
+          'icicle-bookmark-this-buffer-narrow)
+        (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
+          'icicle-bookmark-bookmark-list-narrow)
+        (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
+          'icicle-bookmark-local-file-narrow)
+        (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
+          'icicle-bookmark-info-narrow)
+        (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
+          'icicle-bookmark-desktop-narrow))))
+  (icicle-bookmark-cleanup-on-quit)     ; Undo code
+  (icicle-bookmark-cleanup))            ; Last code
+
+(defun icicle-bookmark-delete-action (cand)
+  "Delete bookmark candidate CAND, then update `bmkp-sorted-alist'."
+  (bookmark-delete (icicle-transform-multi-completion cand))
+  (when (or (and (not icicle-bookmark-refresh-cache-flag)
+                 (not (consp current-prefix-arg)))
+            (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
+    (setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist))))
+
+(defun icicle-bookmark-propertize-candidate (cand)
+  "Return bookmark name CAND, with a face indicating its type."
+  (when (featurep 'bookmark+)
+    (put-text-property
+     0 (length cand) 'face
+     (cond ((bmkp-sequence-bookmark-p cand)        'bmkp-sequence)
+           ((bmkp-function-bookmark-p cand)        'bmkp-function)
+           ((bmkp-bookmark-list-bookmark-p cand)   'bmkp-bookmark-list)
+           ((bmkp-desktop-bookmark-p cand)         'bmkp-desktop)
+           ((bmkp-info-bookmark-p cand)            'bmkp-info)
+           ((bmkp-man-bookmark-p cand)             'bmkp-man)
+           ((bmkp-gnus-bookmark-p cand)            'bmkp-gnus)
+           ((bmkp-url-bookmark-p cand)             'bmkp-url)
+           ((bmkp-remote-file-bookmark-p cand)     'bmkp-remote-file)
+           ((and (bmkp-file-bookmark-p cand)
+                 (file-directory-p
+                  (bookmark-get-filename cand)))        'bmkp-local-directory)
+           ((and (bmkp-local-file-bookmark-p cand)
+                 (bmkp-region-bookmark-p cand))    'bmkp-local-file-with-region)
+           ((bmkp-local-file-bookmark-p cand)      'bmkp-local-file-without-region)
+           ((and (bmkp-get-buffer-name cand)
+                 (get-buffer (bmkp-get-buffer-name cand))
+                 (equal (bookmark-get-filename cand)
+                        bmkp-non-file-filename))   'bmkp-buffer)
+           ((not (bmkp-file-bookmark-p cand))      'bmkp-non-file)
+           (t                                           'bmkp-bad-bookmark))
+     cand))
+  cand)
+
+;;;###autoload
+(defun icicle-bookmark-jump (bookmark)
+  "Jump to BOOKMARK.
+If `crosshairs.el' is loaded, then highlight the target position.
+You probably don't want to use this.  Use `icicle-bookmark' instead."
+  (interactive (list (bookmark-completing-read "Jump to bookmark" bookmark-current-bookmark)))
+  (icicle-bookmark-jump-1 bookmark))
+
+;;;###autoload
+(defun icicle-bookmark-jump-other-window (bookmark)
+  "Jump to BOOKMARK in another window.
+If `crosshairs.el' is loaded, then highlight the target position.
+You probably don't want to use this.  Use
+`icicle-bookmark-other-window' instead."
+  (interactive (list (bookmark-completing-read "Jump to bookmark (other window)"
+                                               bookmark-current-bookmark)))
+  (icicle-bookmark-jump-1 bookmark 'other-window))
+
+(defun icicle-bookmark-jump-1 (bookmark &optional other-window-p)
+  "Helper function for `icicle-bookmark-jump(-other-window)'."
+  (unless bookmark (error "No bookmark specified"))
+  (bookmark-maybe-historicize-string bookmark)
+  (if (fboundp 'bookmark--jump-via)
+      (bookmark--jump-via bookmark (if other-window-p 'pop-to-buffer 'switch-to-buffer))
+    (let ((cell  (bookmark-jump-noselect bookmark))) ; Emacs < 23 and without `Bookmark+'.
+      (when cell
+        (if other-window-p
+            (pop-to-buffer (car cell) 'other-window)
+          (switch-to-buffer (car cell)))
+        (goto-char (cdr cell))
+        (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+        (progn (run-hooks 'bookmark-after-jump-hook) t)
+        ;; If there is an annotation for this bookmark, show it in a buffer.
+        (when bookmark-automatically-show-annotations (bookmark-show-annotation bookmark)))))
+  ;; Unless `bmkp-use-region' and bookmark has a region, show position using crosshairs.
+  (unless (and (boundp 'bmkp-use-region) bmkp-use-region
+               (fboundp 'bmkp-get-end-position) (bmkp-get-end-position bookmark)
+               (/= (bookmark-get-position bookmark) (bmkp-get-end-position bookmark)))
+    (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))))
+;; $$$$$$   (select-window (minibuffer-window))
+;; $$$$$$   (select-frame-set-input-focus (selected-frame)))
+
+(defun icicle-bookmark-help-string (bookmark-name)
+  "Return a help string for BOOKMARK-NAME." ; `bmkp-*' functions are defined in `Bookmark+'.
+  ;; Use BOOKMARK-NAME, not full bookmark BMK, as arg to vanilla bookmark functions, for Emacs < 23.
+  (let* ((bmk         (bookmark-get-bookmark bookmark-name))
+         (buf         (and (fboundp 'bmkp-get-buffer-name) (bmkp-get-buffer-name bmk)))
+         (file        (bookmark-get-filename bookmark-name))
+         (start       (bookmark-get-position bookmark-name))
+         (end         (and (fboundp 'bmkp-get-end-position) (bmkp-get-end-position bmk)))
+         (annot       (bookmark-get-annotation bookmark-name))
+         (sequence-p  (and (fboundp 'bmkp-sequence-bookmark-p)
+                           (bmkp-sequence-bookmark-p bmk)))
+         (function-p  (and (fboundp 'bmkp-function-bookmark-p)
+                           (bmkp-function-bookmark-p bmk)))
+         (blist-p     (and (fboundp 'bmkp-bookmark-list-bookmark-p)
+                           (bmkp-bookmark-list-bookmark-p bmk)))
+         (desktop-p   (and (fboundp 'bmkp-desktop-bookmark-p)
+                           (bmkp-desktop-bookmark-p bmk)))
+         (dired-p     (and (fboundp 'bmkp-dired-bookmark-p) (bmkp-dired-bookmark-p bmk)))
+         (gnus-p      (and (fboundp 'bmkp-gnus-bookmark-p) (bmkp-gnus-bookmark-p bmk)))
+         (info-p      (and (fboundp 'bmkp-info-bookmark-p) (bmkp-info-bookmark-p bmk)))
+         (man-p       (and (fboundp 'bmkp-man-bookmark-p) (bmkp-man-bookmark-p bmk)))
+         (url-p       (and (fboundp 'bmkp-url-bookmark-p) (bmkp-url-bookmark-p bmk)))
+         type-info-p no-position-p)
+    (when (or sequence-p function-p) (setq no-position-p  t))
+    (concat (setq type-info-p
+                  (cond (sequence-p (format "Sequence: %S" (bookmark-prop-get bmk 'sequence)))
+                        (function-p (let ((fn  (bookmark-prop-get bmk 'function)))
+                                      (if (symbolp fn) (format "Function: `%s'" fn) "Function")))
+                        (desktop-p  "Desktop, ")
+                        (dired-p    (format "Dired %s, " file))
+                        (gnus-p     "Gnus, ")
+                        (info-p     "Info, ")
+                        (man-p      (let ((man-args  (bookmark-prop-get bmk 'man-args)))
+                                      (if man-args
+                                          (format "`man %s', " man-args)
+                                        ;; WoMan has no variable for the cmd name.
+                                        (format "%s, " (bookmark-prop-get bmk 'buffer-name)))))
+                        (url-p      "URL, ")
+                        (t nil)))
+            (and (not dired-p)
+                 (or (and file (or (not (boundp 'bmkp-non-file-filename))
+                                   (not (equal file bmkp-non-file-filename)))
+                          (format (if type-info-p "file `%s', " "File `%s', ") file))
+                     (and buf (format (if type-info-p "buffer `%s', " "Buffer `%s', ") buf))))
+            (and (not no-position-p)
+                 (if (and end (> (- end start) 0))
+                     (format "from %d to %d (%d chars)" start end (- end start))
+                   (format "position %d" start)))
+            (and annot (format ", %s" annot)))))
+
+;;; MUST keep this synchronized with any general Icicle-mode `C-M-' bindings in `icicles-mode.el'.
+;;  That includes things like `icicle-read+insert-file-name-keys'.
+(defun icicle-bookmark-cleanup ()
+  "Cleanup code for `icicle-bookmark'.
+Remove crosshairs highlighting and unbind filtering keys."
+  (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))
+  (when (featurep 'bookmark+)
+    (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
+      (define-key (symbol-value map) "\C-\M-b" nil) ; `C-M-b'
+      (define-key (symbol-value map) [(control meta ?B)] nil) ; `C-M-B'
+      (define-key (symbol-value map) "\C-\M-d" nil) ; `C-M-d'
+      (define-key (symbol-value map) "\C-\M-f" nil) ; `C-M-f'
+      (define-key (symbol-value map) [(control meta ?F)] nil) ; `C-M-F'
+      (dolist (key  icicle-read+insert-file-name-keys) ; `C-M-F' - overrides previous.
+        (define-key (symbol-value map) key 'icicle-read+insert-file-name))
+      (define-key (symbol-value map) "\C-\M-g" nil) ; `C-M-g'
+      (define-key (symbol-value map) [(control meta ?I)] nil) ; `C-M-I' (`C-M-i' is `ESC TAB')
+      (define-key (symbol-value map) [(control meta ?K)] nil) ; `C-M-K'
+      (define-key (symbol-value map) "\C-\M-m" nil) ; `C-M-m'
+      (define-key (symbol-value map) "\C-\M-r" nil) ; `C-M-r'
+      (define-key (symbol-value map) "\C-\M-w" nil) ; `C-M-w'
+      (define-key (symbol-value map) "\C-\M-@" nil) ; `C-M-@'
+      (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-.'
+        'icicle-toggle-dot)             ; `icicles-mode.el'.
+      (define-key (symbol-value map) [(control meta ?=) ?b] nil) ; `C-M-= b'
+      (define-key (symbol-value map) [(control meta ?=) ?f] nil)))) ; `C-M-= f'
+
+(defun icicle-bookmark-cleanup-on-quit ()
+  "Do `icicle-bookmark-cleanup', then return to original window."
+  (icicle-bookmark-cleanup)
+  (when (window-live-p icicle-orig-window)
+    (select-window icicle-orig-window)
+    (select-frame-set-input-focus (selected-frame))))
+
+;;; These are minibuffer commands, but we define them here instead of in `icicles-mcmd.el'.
+
+;;;###autoload
+(defun icicle-bookmark-bookmark-list-narrow () ; Bound to `C-M-B' in minibuffer for completion.
+  "Narrow the bookmark candidates to bookmark-list bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-bookmark-list-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-desktop-narrow ()   ; Bound to `C-M-K' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to desktop bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-desktop-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-dired-narrow ()   ; Bound to `C-M-d' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to Dired bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-dired-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-file-narrow ()   ; Bound to `C-M-f' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to file bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-file-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-gnus-narrow ()   ; Bound to `C-M-g' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to Gnus bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-gnus-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-info-narrow ()   ; Bound to `C-M-I' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to Info bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-info-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-local-file-narrow () ; Bound to `C-M-F' for bookmark completion.
+  "Narrow the bookmark candidates to local-file bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-local-file-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-man-narrow () ; Bound to `C-M-m' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to `man'-page bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-man-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-non-file-narrow () ; Bound to `C-M-b' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to non-file (buffer-only) bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-non-file-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-region-narrow () ; Bound to `C-M-r' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to bookmarks with regions."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-region-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-remote-file-narrow () ; Bound to `C-M-@' in minibuf for bookmark completion.
+  "Narrow the bookmark candidates to remote-file bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-remote-file-bookmark-p
+                  (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-specific-buffers-narrow (buffers) ; `C-M-= b' for bookmark completion.
+  "Narrow the bookmark candidates to bookmarks for specific BUFFERS.
+You are prompted for the BUFFERS."
+  (interactive (let ((icicle-completion-candidates  icicle-completion-candidates))
+                 (list (icicle-bookmarked-buffer-list))))
+  (icicle-narrow-candidates-with-predicate
+   `(lambda (x)
+     (member (bmkp-get-buffer-name (funcall icicle-get-alist-candidate-function (car x)))
+      ',buffers))))
+
+;;;###autoload
+(defun icicle-bookmark-specific-files-narrow (files) ; `C-M-= f' in minibuf for bookmark completion.
+  "Narrow the bookmark candidates to bookmarks for specific FILES.
+You are prompted for the FILES."
+  (interactive (list (icicle-bookmarked-file-list)))
+  (icicle-narrow-candidates-with-predicate
+   `(lambda (x)
+     (member (bookmark-get-filename (funcall icicle-get-alist-candidate-function (car x)))
+      ',files))))
+
+;;;###autoload
+(defun icicle-bookmark-this-buffer-narrow () ; `C-M-.' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to bookmarks for the current buffer."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x)
+       (with-current-buffer icicle-orig-buff
+         (bmkp-this-buffer-p (funcall icicle-get-alist-candidate-function (car x)))))))
+
+;;;###autoload
+(defun icicle-bookmark-url-narrow ()    ; Bound to `C-M-u' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to URL bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-url-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defun icicle-bookmark-w3m-narrow ()    ; Bound to `C-M-w' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to W3M (URL) bookmarks."
+  (interactive)
+  (icicle-narrow-candidates-with-predicate
+   #'(lambda (x) (bmkp-w3m-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
+
+;;;###autoload
+(defmacro icicle-define-bookmark-command-1 (otherp type prompt args)
+  "Helper macro for `icicle-define*-bookmark-command' macros.
+The command defined raises an error unless library `Bookmark+' can be
+loaded."
+  `(icicle-define-command
+    ,(intern (format "icicle-bookmark-%s%s" type (if otherp "-other-window" ""))) ; Command name
+    ,(format "Jump to a %s bookmark%s.
+Like `icicle-bookmark%s',
+ but with %s bookmarks only.
+This is a multi-command version of
+ `bmkp-%s-jump%s'.
+You need library `Bookmark+' for this command."
+             type (if otherp " in other window" "")
+             (if otherp "-other-window" "") type
+             type (if otherp "-other-window" "")) ; Doc string
+    (lambda (cand) (,(if otherp 'icicle-bookmark-jump-other-window 'icicle-bookmark-jump) ; Action fn.
+                     (icicle-transform-multi-completion cand)))
+    prompt1 icicle-candidates-alist nil ; `completing-read' args
+    (not icicle-show-multi-completion-flag)
+    nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+    nil nil
+    ((IGNORED1                               (unless (require 'bookmark+ nil t) ; Additional bindings
+                                               (error "You need library `Bookmark+' for this command")))
+     (IGNORED2                               (bookmark-maybe-load-default-file)) ; `bookmark-alist'.
+     (enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
+     (completion-ignore-case                 bookmark-completion-ignore-case)
+     (prompt1                                ,(or prompt
+                                                  (format "%s%s bookmark: "
+                                                          (capitalize (substring type 0 1))
+                                                          (substring type 1 (length type)))))
+     (icicle-list-use-nth-parts              '(1))
+     (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
+                                                 nil
+                                               (if (facep 'file-name-shadow)
+                                                   '((2 (face file-name-shadow))
+                                                     (3 (face bookmark-menu-heading)))
+                                                 '((3 (face bookmark-menu-heading))))))
+     (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
+     (icicle-whole-candidate-as-text-prop-p  t)
+     (icicle-transform-before-sort-p         t)
+     (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
+     (icicle-sort-orders-alist
+      (append
+       '(("in *Bookmark List* order")   ; Renamed from "turned OFF'.
+         ("by bookmark name" . icicle-alpha-p)
+         ("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+         ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
+       (and (member ,type '("info" "region"))
+        '(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
+       (and (member ,type '("gnus" "region"))
+        '(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
+       (and (member ,type '("url" "region"))
+        '(("by URL" (bmkp-url-cp) icicle-alpha-p)))
+       (and (not (member ,type '("bookmark-list" "desktop" "gnus" "info" "man" "url")))
+        '(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                               bmkp-local-file-type-cp bmkp-handler-cp)
+           icicle-alpha-p)))
+       (and (not (member ,type '("bookmark-list" "desktop" "dired" "non-file")))
+        '(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
+       (and (member ,type '("local-file" "file" "dired" "region"))
+        '(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+          ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+          ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
+           icicle-alpha-p)
+          ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+           icicle-alpha-p)))
+       (and (not (string= ,type "desktop"))
+        '(("by last buffer or file access" (bmkp-buffer-last-access-cp
+                                            bmkp-local-file-accessed-more-recently-cp)
+           icicle-alpha-p)))
+       (and (get-buffer "*Bookmark List*")
+        '(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+           icicle-alpha-p)))
+       '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+         ("case insensitive" . icicle-case-insensitive-string-less-p))))
+     (icicle-candidate-help-fn
+      #'(lambda (cand)
+          (when icicle-show-multi-completion-flag
+            (setq cand  (funcall icicle-get-alist-candidate-function cand))
+            (setq cand  (cons (caar cand) (cdr cand))))
+          (if current-prefix-arg
+              (bmkp-describe-bookmark-internals cand)
+            (bmkp-describe-bookmark cand))))
+     (icicle-candidates-alist
+      (mapcar (if icicle-show-multi-completion-flag
+                  #'(lambda (bmk)
+                      ;; Ignore errors, e.g. from bad or stale bookmark records.
+                      (icicle-condition-case-no-debug nil
+                          (let* ((bname     (bookmark-name-from-full-record bmk))
+                                 (guts      (bookmark-get-bookmark-record bmk))
+                                 (file      (bookmark-get-filename bmk))
+                                 (buf       (bmkp-get-buffer-name bmk))
+                                 (file/buf  (if (and buf (equal file bmkp-non-file-filename))
+                                                buf
+                                              file))
+                                 (tags      (bmkp-get-tags bmk)))
+                            ;; Emacs 20 byte-compiler bug prevents using backslash syntax here.
+                            (cons (append (list (icicle-candidate-short-help
+                                                 (icicle-bookmark-help-string bname)
+                                                 (icicle-bookmark-propertize-candidate bname))
+                                                file/buf)
+                                          (and tags (list (format "%S" tags))))
+                                  guts))
+                        (error nil)))
+                #'(lambda (bmk)
+                    ;; Ignore errors, e.g. from bad or stale bookmark records.
+                    (icicle-condition-case-no-debug nil
+                        (let ((bname  (bookmark-name-from-full-record bmk))
+                              (guts   (bookmark-get-bookmark-record bmk)))
+                          (cons (icicle-candidate-short-help
+                                 (icicle-bookmark-help-string bname)
+                                 (icicle-bookmark-propertize-candidate bname))
+                                guts))
+                      (error nil))))
+       (bmkp-sort-omit (funcall ',(intern (format "bmkp-%s-alist-only" type)) ,@args)))))
+    nil                                 ; First code
+    (icicle-bookmark-cleanup-on-quit)   ; Undo code
+    (icicle-bookmark-cleanup)))         ; Last code
+
+;;;###autoload
+(defmacro icicle-define-bookmark-command (type &optional prompt &rest args)
+  "Define an Icicles multi-command for jumping to bookmarks of type TYPE.
+TYPE is a string to be used for the doc string, default prompt, and in
+ function names.  It should be lowercase and contain no spaces.
+Optional arg PROMPT is the completion prompt.
+ARGS is a list of any additional arguments to be passed to the
+appropriate `bmkp-TYPE-alist-only' function."
+  `(icicle-define-bookmark-command-1 nil ,type ,prompt ,args))
+
+;;;###autoload
+(defmacro icicle-define-bookmark-other-window-command (type &optional prompt &rest args)
+  "Same as `icicle-define-bookmark-command', but command uses other window."
+  `(icicle-define-bookmark-command-1 t ,type ,prompt ,args))
+
+;; The following sexps macro-expand to define these commands:
+;;  `icicle-bookmark-bookmark-list',
+;;  `icicle-bookmark-desktop',
+;;  `icicle-bookmark-dired',                 `icicle-bookmark-dired-other-window',
+;;  `icicle-bookmark-file',                  `icicle-bookmark-file-other-window',
+;;  `icicle-bookmark-file-all-tags',         `icicle-bookmark-file-all-tags-other-window',
+;;  `icicle-bookmark-file-all-tags-regexp',  `icicle-bookmark-file-all-tags-regexp-other-window',
+;;  `icicle-bookmark-file-some-tags',        `icicle-bookmark-file-some-tags-other-window',
+;;  `icicle-bookmark-file-some-tags-regexp', `icicle-bookmark-file-some-tags-regexp-other-window',
+;;  `icicle-bookmark-file-this-dir',         `icicle-bookmark-file-this-dir-other-window',
+;;  `icicle-bookmark-file-this-dir-all-tags',
+;;  `icicle-bookmark-file-this-dir-all-tags-other-window',
+;;  `icicle-bookmark-file-this-dir-all-tags-regexp',
+;;  `icicle-bookmark-file-this-dir-all-tags-regexp-other-window',
+;;  `icicle-bookmark-file-this-dir-some-tags',
+;;  `icicle-bookmark-file-this-dir-some-tags-other-window',
+;;  `icicle-bookmark-file-this-dir-some-tags-regexp',
+;;  `icicle-bookmark-file-this-dir-some-tags-regexp-other-window',
+;;  `icicle-bookmark-gnus',                  `icicle-bookmark-gnus-other-window',
+;;  `icicle-bookmark-info',                  `icicle-bookmark-info-other-window',
+;;  `icicle-bookmark-local-file',            `icicle-bookmark-local-file-other-window',
+;;  `icicle-bookmark-man',                   `icicle-bookmark-man-other-window',
+;;  `icicle-bookmark-non-file',              `icicle-bookmark-non-file-other-window',
+;;  `icicle-bookmark-region',                `icicle-bookmark-region-other-window',
+;;  `icicle-bookmark-remote-file',           `icicle-bookmark-remote-file-other-window',
+;;  `icicle-bookmark-specific-buffers',      `icicle-bookmark-specific-buffers-other-window'
+;;  `icicle-bookmark-specific-files',        `icicle-bookmark-specific-files-other-window'
+;;  `icicle-bookmark-all-tags',              `icicle-bookmark-all-tags-other-window'
+;;  `icicle-bookmark-all-tags-regexp',       `icicle-bookmark-all-tags-regexp-other-window'
+;;  `icicle-bookmark-some-tags',             `icicle-bookmark-some-tags-other-window'
+;;  `icicle-bookmark-some-tags-regexp',      `icicle-bookmark-some-tags-regexp-other-window'
+;;  `icicle-bookmark-this-buffer',           `icicle-bookmark-this-buffer-other-window'
+;;  `icicle-bookmark-url',                   `icicle-bookmark-url-other-window'
+;;  `icicle-bookmark-w3m',                   `icicle-bookmark-w3m-other-window'
+
+;; Other-window means nothing for a bookmark list or a desktop.
+;;;###autoload (autoload 'icicle-bookmark-non-file "icicles-cmd1.el")
+(icicle-define-bookmark-command              "non-file")                      ; `C-x j b'
+;;;###autoload (autoload 'icicle-bookmark-non-file-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "non-file")                      ; `C-x 4 j b'
+;;;###autoload (autoload 'icicle-bookmark-bookmark-list "icicles-cmd1.el")
+(icicle-define-bookmark-command              "bookmark-list")                 ; `C-x j B'
+;;;###autoload (autoload 'icicle-bookmark-dired "icicles-cmd1.el")
+(icicle-define-bookmark-command              "dired")                         ; `C-x j d'
+;;;###autoload (autoload 'icicle-bookmark-dired-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "dired")                         ; `C-x 4 j d'
+;;;###autoload (autoload 'icicle-bookmark-file "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file")                          ; `C-x j f'
+;;;###autoload (autoload 'icicle-bookmark-file-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file")                          ; `C-x 4 j f'
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-this-dir")                 ; `C-x j C-f'
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-this-dir")                 ; `C-x 4 j C-f'
+;;;###autoload (autoload 'icicle-bookmark-gnus "icicles-cmd1.el")
+(icicle-define-bookmark-command              "gnus")                          ; `C-x j g'
+;;;###autoload (autoload 'icicle-bookmark-gnus-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "gnus")                          ; `C-x 4 j g'
+;;;###autoload (autoload 'icicle-bookmark-info "icicles-cmd1.el")
+(icicle-define-bookmark-command              "info")                          ; `C-x j i'
+;;;###autoload (autoload 'icicle-bookmark-info-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "info")                          ; `C-x 4 j i'
+;;;###autoload (autoload 'icicle-bookmark-desktop "icicles-cmd1.el")
+(icicle-define-bookmark-command              "desktop")                       ; `C-x j K'
+;;;###autoload (autoload 'icicle-bookmark-local-file "icicles-cmd1.el")
+(icicle-define-bookmark-command              "local-file")                    ; `C-x j l'
+;;;###autoload (autoload 'icicle-bookmark-local-file-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "local-file")                    ; `C-x 4 j l'
+;;;###autoload (autoload 'icicle-bookmark-man "icicles-cmd1.el")
+(icicle-define-bookmark-command              "man")                           ; `C-x j m'
+;;;###autoload (autoload 'icicle-bookmark-man-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "man")                           ; `C-x 4 j m'
+;;;###autoload (autoload 'icicle-bookmark-remote-file "icicles-cmd1.el")
+(icicle-define-bookmark-command              "remote-file")                   ; `C-x j n'
+;;;###autoload (autoload 'icicle-bookmark-remote-file-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "remote-file")                   ; `C-x 4 j n'
+;;;###autoload (autoload 'icicle-bookmark-region "icicles-cmd1.el")
+(icicle-define-bookmark-command              "region" "Select region: ")      ; `C-x j r'
+;;;###autoload (autoload 'icicle-bookmark-region-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "region" "Select region: ")      ; `C-x 4 j r'
+;;;###autoload (autoload 'icicle-bookmark-all-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "all-tags" nil                   ; `C-x j t *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-all-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "all-tags" nil                   ; `C-x 4 j t *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-some-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "some-tags" nil                  ; `C-x j t +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-some-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "some-tags" nil                  ; `C-x 4 j t +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-all-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "all-tags-regexp" nil            ; `C-x j t % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-all-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "all-tags-regexp" nil            ; `C-x 4 j t % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-some-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "some-tags-regexp" nil           ; `C-x j t % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-some-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "some-tags-regexp" nil           ; `C-x 4 j t % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-all-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-all-tags" nil              ; `C-x j t f *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-all-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-all-tags" nil              ; `C-x 4 j t f *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-some-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-some-tags" nil             ; `C-x j t f +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-some-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-some-tags" nil             ; `C-x 4 j t f +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-all-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-all-tags-regexp" nil       ; `C-x j t f % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-all-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-all-tags-regexp" nil       ; `C-x 4 j t f % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-some-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-some-tags-regexp" nil      ; `C-x j t f % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-some-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-some-tags-regexp" nil      ; `C-x 4 j t f % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-this-dir-file-all-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-this-dir-all-tags" nil ; `C-x j t C-f *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-this-dir-all-tags" nil ; `C-x 4 j t C-f *'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-this-dir-some-tags" nil ; `C-x j t C-f +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-this-dir-some-tags" nil ; `C-x 4 j t C-f +'
+                                             (bmkp-read-tags-completing))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-this-dir-all-tags-regexp" nil ; `C-x j t C-f % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-this-dir-all-tags-regexp" nil ; `C-x 4 j t C-f % *'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-regexp "icicles-cmd1.el")
+(icicle-define-bookmark-command              "file-this-dir-some-tags-regexp" nil ; `C-x j t C-f % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-regexp-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "file-this-dir-some-tags-regexp" nil ; `C-x 4 j t C-f % +'
+                                             (read-string "Regexp for tags: "))
+;;;###autoload (autoload 'icicle-bookmark-url "icicles-cmd1.el")
+(icicle-define-bookmark-command              "url")                           ; `C-x j u'
+;;;###autoload (autoload 'icicle-bookmark-url-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "url")                           ; `C-x 4 j u'
+;;;###autoload (autoload 'icicle-bookmark-w3m "icicles-cmd1.el")
+(icicle-define-bookmark-command              "w3m")                           ; `C-x j w'
+;;;###autoload (autoload 'icicle-bookmark-w3m-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "w3m")                           ; `C-x 4 j w'
+;;;###autoload (autoload 'icicle-bookmark-this-buffer "icicles-cmd1.el")
+(icicle-define-bookmark-command              "this-buffer")                   ; `C-x j .'
+;;;###autoload (autoload 'icicle-bookmark-this-buffer-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "this-buffer")                   ; `C-x 4 j .'
+;;;###autoload (autoload 'icicle-bookmark-specific-buffers "icicles-cmd1.el")
+(icicle-define-bookmark-command              "specific-buffers" nil           ; `C-x j = b'
+                                             (icicle-bookmarked-buffer-list))
+;;;###autoload (autoload 'icicle-bookmark-specific-buffers-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "specific-buffers" nil           ; `C-x 4 j = b'
+                                             (icicle-bookmarked-buffer-list))
+;;;###autoload (autoload 'icicle-bookmark-specific-files "icicles-cmd1.el")
+(icicle-define-bookmark-command              "specific-files" nil             ; `C-x j = f'
+                                             (icicle-bookmarked-file-list))
+;;;###autoload (autoload 'icicle-bookmark-specific-files-other-window "icicles-cmd1.el")
+(icicle-define-bookmark-other-window-command "specific-files" nil             ; `C-x 4 j = f'
+                                             (icicle-bookmarked-file-list))
+;;;###autoload
+(defalias 'icicle-select-bookmarked-region 'icicle-bookmark-region-other-window)
+
+;;;###autoload
+(defun icicle-bookmarked-buffer-list ()
+  "`icicle-buffer-list', but only for bookmarked buffers."
+  (interactive)
+  (let ((icicle-buffer-predicate  (lambda (buf) (member buf (bmkp-buffer-names)))))
+    (icicle-buffer-list)))
+  
+;;;###autoload
+(defun icicle-bookmarked-file-list ()
+  "`icicle-buffer-list', but only for bookmarked buffers."
+  (interactive)
+  (let ((use-file-dialog        nil)
+        (icicle-file-predicate  (lambda (file) (member (expand-file-name file) (bmkp-file-names)))))
+    (icicle-file-list)))
+
+;;;###autoload (autoload 'icicle-find-first-tag "icicles-cmd1.el")
+(icicle-define-command icicle-find-first-tag ; Command name
+  "Find first tag in current tags table whose name matches your input.
+This is similar to standard command `find-tag', with these
+differences:
+
+* This is a multi-command, so you can visit any number of tags.
+
+* Only the first tag of several identical tags is a candidate, so you
+  cannot visit the others.  That is, there is no equivalent to using
+  `M-,' (`tags-loop-continue') after `find-tag' to find additional,
+  identical tags.
+
+* If `crosshairs.el' is loaded, the target position is highlighted.
+
+To browse all tags (including duplicates) in all tags tables, use the
+more powerful Icicles multi-command `icicle-find-tag'.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `find-tag-other-window' to `icicle-find-first-tag'.  If you
+do not want this remapping, then customize option
+`icicle-top-level-key-bindings'."       ; Doc string
+  icicle-find-first-tag-action          ; Action function
+  "Find tag: "                          ; `completing-read' args
+  (if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
+  nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
+                               'find-tag-default))
+  nil
+  ((completion-ignore-case  (progn (require 'etags) ; Bindings
+                                   (if (and (boundp 'tags-case-fold-search)
+                                            (memq tags-case-fold-search '(t nil)))
+                                       tags-case-fold-search
+                                     case-fold-search)))
+   (case-fold-search        completion-ignore-case))
+  nil nil                               ; First code, undo code
+  (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))) ; Last code
+
+(defun icicle-find-first-tag-action (cand)
+  "Action function for `icicle-find-first-tag'."
+  (find-tag cand)
+  (when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
+
+;;;###autoload (autoload 'icicle-find-first-tag-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-find-first-tag-other-window ; Command name
+  "Find first tag in current tags table whose name matches your input.
+Same as `icicle-find-first-tag' except it uses a different window." ; Doc string
+  icicle-find-first-tag-other-window-action ; Action function
+  "Find tag other window: "             ; `completing-read' args
+  (if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
+  nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
+                               'find-tag-default))
+  nil
+  ((completion-ignore-case  (progn (require 'etags)
+                                   (if (and (boundp 'tags-case-fold-search) ; Bindings
+                                            (memq tags-case-fold-search '(t nil)))
+                                       tags-case-fold-search
+                                     case-fold-search)))
+   (case-fold-search        completion-ignore-case))
+  nil nil                               ; First code, undo code
+  (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))) ; Last code
+
+(defun icicle-find-first-tag-other-window-action (cand)
+  "Action function for `icicle-find-first-tag-other-window'."
+  (find-tag-other-window cand)
+  (when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
+
+;;;###autoload
+(defun icicle-find-tag (regexp &optional arg)
+  "Navigate among all tags that match REGEXP.
+You are prompted for the REGEXP to match.  Enter REGEXP with `RET'.
+You can use completion to choose a tag in the current tags table as
+REGEXP.  You can use `\\[icicle-pop-tag-mark]' to return to your starting point.
+
+All matching tags are shown, including duplicate tags from the same or
+different source files.  This means that you do not need `M-,' - you
+see all tags as candidates to visit.
+
+By default:
+
+* Tags from all tags files are candidates.
+* In `*Completions*', the source file name is shown after each tag.
+
+A prefix argument changes this default behavior, as follows:
+
+* ARG = 0 or ARG > 0: only the current tag table is used
+* ARG = 0 or ARG < 0: source file names are not shown
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `find-tag' to `icicle-find-tag'.  If you do not want this
+remapping, then customize option `icicle-top-level-key-bindings'.
+
+If `crosshairs.el' is loaded, then the target position is highlighted."
+  (interactive
+   (let* ((completion-ignore-case  (if (and (boundp 'tags-case-fold-search)
+                                            (memq tags-case-fold-search '(t nil)))
+                                       tags-case-fold-search
+                                     case-fold-search))
+          (case-fold-search        completion-ignore-case))
+     (require 'etags)
+     (list (completing-read "Find tag matching regexp: "
+                            ;; $$$ Or should we just read a regexp against `regexp-history'?
+                            (if (fboundp 'tags-lazy-completion-table)
+                                (tags-lazy-completion-table) ; Emacs 23+
+                              'tags-complete-tag) ; Emacs < 23
+                            nil nil nil 'find-tag-history
+                            (funcall (or find-tag-default-function
+                                         (get major-mode 'find-tag-default-function)
+                                         'find-tag-default)))
+           current-prefix-arg)))
+
+  (unwind-protect
+       (let* ((icicle-whole-candidate-as-text-prop-p  t)
+              (icicle-sort-comparer                   nil)
+              (icicle-inhibit-sort-p                  t)
+              (icicle-candidate-action-fn             'icicle-find-tag-action)
+              (icicle-candidate-help-fn               'icicle-find-tag-help)
+              (completion-ignore-case                 (if (and (boundp 'tags-case-fold-search)
+                                                               (memq tags-case-fold-search
+                                                                     '(t nil)))
+                                                          tags-case-fold-search
+                                                        case-fold-search))
+              (case-fold-search                       completion-ignore-case)
+              (orig-pt-find-tag                       (point-marker)))
+
+         (ring-insert find-tag-marker-ring orig-pt-find-tag) ; Record starting point.
+         (icicle-explore #'(lambda () (icicle-find-tag-define-candidates regexp arg))
+                         #'icicle-find-tag-final-act #'icicle-find-tag-quit-or-error
+                         #'icicle-find-tag-quit-or-error nil
+                         "Choose a tag: " nil nil nil 'find-tag-history))
+    (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))))
+
+;;;###autoload
+(defun icicle-pop-tag-mark ()
+  "Like `pop-tag-mark', but uses `pop-to-buffer', not `switch-to-buffer'.
+By default, Icicle mode remaps all key sequences that are normally
+bound to `pop-tag-mark' to `icicle-pop-tag-mark'.  If you do not want
+this remapping, then customize option
+`icicle-top-level-key-bindings'."
+  (interactive)
+  (require 'etags)
+  (when (ring-empty-p find-tag-marker-ring) (error "No previous locations for find-tag invocation"))
+  (let ((marker  (ring-remove find-tag-marker-ring 0)))
+    (pop-to-buffer (or (marker-buffer marker) (error "The marked buffer has been deleted")))
+    (goto-char (marker-position marker))
+    (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+    (set-marker marker nil nil)))
+
+(defun icicle-find-tag-define-candidates (regexp arg)
+  "Define candidates for `icicle-find-tag'.
+See `icicle-explore', argument DEFINE-CANDIDATES-FN."
+  (save-excursion
+    (let ((first-time  t)
+          (morep       t))
+      (setq icicle-candidates-alist  ())
+      (while (and morep (visit-tags-table-buffer (not first-time)))
+        (when (and arg (wholenump (prefix-numeric-value arg))) (setq morep  nil))
+        (setq first-time               nil
+              icicle-candidates-alist  (append icicle-candidates-alist
+                                               (nreverse
+                                                (icicle-find-tag-define-candidates-1
+                                                 regexp (> (prefix-numeric-value arg)
+                                                           0)))))))))
+
+(defun icicle-find-tag-define-candidates-1 (regexp show-file-p)
+  "Helper function for `icicle-find-tag-define-candidates'.
+Returns completion alist of tag information for tags matching REGEXP.
+Include file name (label) if SHOW-FILE-P is non-nil.
+
+If SHOW-FILE-P is nil, then alist items look like this:
+
+ (TAG TAG-INFO FILE-PATH GOTO-FUNC)
+
+If SHOW-FILE-P is non-nil, then alist items look like this:
+
+ ((TAG FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC) or
+
+ (FILE-LABEL TAG-INFO FILE-PATH GOTO-FUNC) if no matching TAG.
+
+TAG-INFO is what `snarf-tag-function' (e.g. `etags-snarf-tag')
+returns.  It is a cons (TEXT LINE . POSITION).
+
+TEXT is the initial part of a line containing the tag.
+LINE is the line number.
+POSITION is the (one-based) char position of TEXT within the file.
+
+If TEXT is t, it means the tag refers to exactly LINE or POSITION,
+whichever is present, LINE having preference, no searching.
+Either LINE or POSITION can be nil.  POSITION is used if present."
+  (icicle-highlight-lighter)
+  (message "Gathering tags...")
+  (goto-char (point-min))
+  (let ((temp-list  ()))
+    (while (re-search-forward (concat regexp ".*\177*") nil t) ; Look before the DEL character.
+      (beginning-of-line)
+      (let* ((goto-func  goto-tag-location-function) ; e.g. `etags-goto-tag-location'.
+             ;; TAG-INFO: If no specific tag, (t nil (point-min)). Else, (TEXT LINE . STARTPOS).
+             ;; e.g. TEXT = "(defun foo ()" or just "foo" (if explicit),
+             ;;      LINE = "148", STARTPOS = "1723"
+             (tag-info (save-excursion (funcall snarf-tag-function))) ; e.g. `etags-snarf-tag'.
+             (tag (if (eq t (car tag-info)) nil (car tag-info)))
+             ;; FILE-PATH is absolute. FILE-LABEL is relative to `default-directory'.
+             (file-path (save-excursion
+                          (if tag (file-of-tag) (save-excursion (next-line 1) (file-of-tag)))))
+             (file-label (expand-file-name file-path (file-truename default-directory))))
+        (when (and tag (not (string= "" tag)) (= (aref tag 0) ?\( ))
+          (setq tag  (concat tag " ...)")))
+        (when (file-readable-p file-path)
+          ;; Add item to alist.
+          ;;   Item looks like this:         ((TAG FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC)
+          ;;   or like this, if no matching tag: ((FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC)
+          (cond (tag
+                 (push `(,(if show-file-p
+                              (list tag ; Make multi-completion cons: add file name to candidate.
+                                    (progn (put-text-property 0 (length file-label) 'face
+                                                              'icicle-candidate-part file-label)
+                                           file-label))
+                              tag)
+                         ,tag-info ,file-path ,goto-func)
+                       temp-list))
+                (show-file-p            ; No tag.  Use only the FILE-LABEL.
+                 (push `((,(progn (put-text-property 0 (length file-label) 'face
+                                                     'icicle-candidate-part file-label)
+                                  file-label))
+                         ,tag-info ,file-path ,goto-func)
+                       temp-list)))))
+      (forward-line))
+    temp-list))                         ; Return the alist for this TAGS file.
+
+(defun icicle-find-tag-action (ignored-string)
+  "Action function for `icicle-find-tag'."
+  ;; Ignore (TAG FILE-LABEL) part.  Use only (TAG-INFO FILE-PATH GOTO-FUNC) part.
+  (let* ((cand       (cdr (elt (icicle-filter-alist icicle-candidates-alist
+                                                    icicle-completion-candidates)
+                               icicle-candidate-nb)))
+         (tag-info   (nth 0 cand))
+         (goto-func  (nth 2 cand)))
+    (switch-to-buffer-other-window      ; Go to source file at FILE-PATH.
+     (if (fboundp 'tag-find-file-of-tag-noselect)
+         (tag-find-file-of-tag-noselect (nth 1 cand))
+       (find-file-noselect (nth 1 cand))))
+    (widen)
+    (icicle-condition-case-no-debug err
+        (funcall goto-func tag-info)    ; Go to text at TAG-INFO.
+      (error (message "%s" (error-message-string err)) (sit-for 2) nil)))
+  (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
+  (select-window (minibuffer-window))
+  (select-frame-set-input-focus (selected-frame)))
+
+(defun icicle-find-tag-help (cand)
+  "Use as `icicle-candidate-help-fn' for `icicle-find-first-tag'."
+  (let* ((cand      (cdr (elt (icicle-filter-alist icicle-candidates-alist
+                                                   icicle-completion-candidates)
+                              icicle-candidate-nb)))
+         (tag-info  (nth 0 cand)))
+    (message (if (eq t (car tag-info))
+                 "No tag - file name itself matches"
+               (format "Line: %d, Position: %d, File: %s"
+                       (cadr tag-info) (cddr tag-info) (nth 1 cand))))
+    (sit-for 4)))
+
+(defun icicle-find-tag-final-act ()
+  "Go to the final tag choice."
+  (let ((cand  (cdr icicle-explore-final-choice-full)))
+    (unless cand (error "No such occurrence: %s" cand))
+    (switch-to-buffer-other-window ; Go to source file at FILE-PATH.
+     (if (fboundp 'tag-find-file-of-tag-noselect)
+         (tag-find-file-of-tag-noselect (nth 1 cand))
+       (find-file-noselect (nth 1 cand))))
+    (widen)
+    (funcall (nth 2 cand) (nth 0 cand)))) ; Go to text at TAG-INFO.
+
+(defun icicle-find-tag-quit-or-error ()
+  "Pop back to the last tag visited."
+  (icicle-pop-tag-mark)
+  (raise-frame))
+
+;;;###autoload
+(defun icicle-other-window-or-frame (arg) ; Bound to `C-x o' in Icicle mode.
+  "Select a window or frame, by name or by order.
+This command combines Emacs commands `other-window' and `other-frame',
+together with Icicles multi-commands `icicle-select-window', and
+`icicle-select-frame'.  Use the prefix argument to choose, as follows:
+
+ With no prefix arg or a non-zero numeric prefix arg:
+  If the selected frame has multiple windows, then this is
+  `other-window'.  Otherwise, it is `other-frame'.
+
+ With a zero prefix arg (e.g. `C-0'):
+  If the selected frame has multiple windows, then this is
+  `icicle-select-window' with windows in the frame as candidates.
+  Otherwise (single-window frame), this is `icicle-select-frame'.
+
+ With plain `C-u':
+  If the selected frame has multiple windows, then this is
+  `icicle-select-window' with windows from all visible frames as
+  candidates.  Otherwise, this is `icicle-select-frame'.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `other-window' to `icicle-other-window-or-frame'.  If you do
+not want this remapping, then customize option
+`icicle-top-level-key-bindings'."
+  (interactive "P")
+  (let ((numarg  (prefix-numeric-value arg)))
+    (cond ((consp arg)
+           (if (one-window-p) (icicle-select-frame) (icicle-select-window)))
+          ((zerop numarg)
+           (if (one-window-p)
+               (icicle-select-frame)
+             (let ((current-prefix-arg  nil)) (icicle-select-window))))
+          (t
+           (if (one-window-p) (other-frame numarg) (other-window numarg))))))
+
+;;;###autoload (autoload 'icicle-select-frame "icicles-cmd1.el")
+(icicle-define-command icicle-select-frame ; Bound to `C-x 5 o' in Icicle mode.
+  "Select frame by its name and raise it.
+A frame name in this context is suffixed as needed by [NUMBER], to
+make it unique.  For example, in a context where frames are named for
+their buffers and you have two frames showing buffer *Help*, one of
+the frames will be called `*Help*[2]' for use with this command." ; Doc string
+  icicle-select-frame-by-name           ; Action function
+  "Select frame: "                      ; `completing-read' args
+  icicle-frame-alist nil t nil
+  (if (boundp 'frame-name-history) 'frame-name-history 'icicle-frame-name-history)
+  (cdr (assq 'name (frame-parameters (next-frame (selected-frame))))) nil
+  ((icicle-frame-alist  (icicle-make-frame-alist)) ; Bindings
+   (alt-fn              nil)
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "frame"))))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "frame")))))
+
+;;;###autoload
+(defun icicle-select-frame-by-name (name &optional frame-alist)
+  "Select the frame named NAME, and raise it.
+Optional argument FRAME-ALIST is an alist of frames to choose from.
+Each element has the form (FNAME . FRAME), where FNAME names FRAME.
+See `icicle-make-frame-alist' for more about FNAME."
+  (interactive (let* ((alist    (icicle-make-frame-alist))
+                      (default  (car (rassoc (selected-frame) alist)))
+                      (input    (completing-read "Select Frame: " alist nil t nil
+                                                 'frame-name-history default)))
+                 (list (if (= (length input) 0) default input)
+                       alist)))
+  (unless frame-alist (setq frame-alist  (or (and (boundp 'icicle-frame-alist) icicle-frame-alist)
+                                             (icicle-make-frame-alist))))
+  (let ((frame  (cdr (assoc name frame-alist))))
+    (unless frame (error "No such frame: `%s'" name))
+    (make-frame-visible frame)
+    (select-frame-set-input-focus frame)))
+
+(defun icicle-make-frame-alist ()
+  "Return an alist of entries (FNAME . FRAME), where FNAME names FRAME.
+Frame parameter `name' is used as FNAME, unless there is more than one
+frame with the same name.  In that case, FNAME includes a suffix
+\[NUMBER], to make it a unique name.  The NUMBER order among frame
+names that differ only by their [NUMBER] is arbitrary."
+  (let ((fr-alist  ())
+        (count     2)
+        fname new-name)
+    (dolist (fr  (frame-list))
+      (setq fname  (frame-parameter fr 'name))
+      (if (not (assoc fname fr-alist))
+          (push (cons fname fr) fr-alist)
+        (setq new-name  fname)
+        (while (assoc new-name fr-alist)
+          (setq new-name  (format "%s[%d]" fname count)
+                count     (1+ count)))
+        (push (cons new-name fr) fr-alist))
+      (setq count  2))
+    fr-alist))
+
+;;;###autoload (autoload 'icicle-select-window "icicles-cmd1.el")
+(icicle-define-command icicle-select-window ; Command name
+;; Free vars here: `icicle-window-alist' is bound in Bindings form.
+  "Select window by its name.
+With no prefix arg, candidate windows are those of the selected frame.
+With a prefix arg, windows of all visible frames are candidates.
+
+A window name is the name of its displayed buffer, but suffixed as
+needed by [NUMBER], to make the name unique.  For example, if you have
+two windows showing buffer *Help*, one of the windows will be called
+`*Help*[2]' for use with this command." ; Doc string
+  icicle-select-window-by-name          ; Action function
+  "Select window: " icicle-window-alist nil t nil nil ; `completing-read' args
+  (buffer-name (window-buffer (other-window 1))) nil
+  ((icicle-window-alist  (icicle-make-window-alist current-prefix-arg)))) ; Bindings
+
+;; Free vars here: `icicle-window-alist' is bound in `icicle-select-window'.
+;;;###autoload
+(defun icicle-select-window-by-name (name &optional window-alist)
+  "Select the window named NAME.
+Optional argument WINDOW-ALIST is an alist of windows to choose from.
+
+Interactively:
+ A prefix arg means windows from all visible frames are candidates.
+ No prefix arg means windows from the selected frame are candidates.
+
+Each alist element has the form (WNAME . WINDOW), where WNAME names
+WINDOW.  See `icicle-make-window-alist' for more about WNAME.
+
+If `crosshairs.el' is loaded, then the target position is highlighted."
+  (interactive (let* ((alist    (icicle-make-window-alist current-prefix-arg))
+                      (default  (car (rassoc (selected-window) alist)))
+                      (input    (completing-read "Select Window: " alist nil t nil nil default)))
+                 (list (if (= (length input) 0) default input) alist)))
+  (unless window-alist
+    (setq window-alist  (or (and (boundp 'icicle-window-alist) icicle-window-alist)
+                            (icicle-make-window-alist))))
+  (let ((window  (cdr (assoc name window-alist))))
+    (unless window (error "No such window: `%s'" name))
+    (select-window window)
+    (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
+    (select-frame-set-input-focus (selected-frame))))
+
+(defun icicle-make-window-alist (&optional all-p)
+  "Return an alist of entries (WNAME . WINDOW), where WNAME names WINDOW.
+The name of the buffer in a window is used as its name, unless there
+is more than one window displaying the same buffer.  In that case,
+WNAME includes a suffix [NUMBER], to make it a unique name.  The
+NUMBER order among window names that differ only by their [NUMBER] is
+arbitrary.
+
+Non-nil argument ALL-P means use windows from all visible frames.
+Otherwise, use only windows from the selected frame."
+  (let ((win-alist  ())
+        (count      2)
+        wname new-name)
+    (walk-windows #'(lambda (w)
+                      (setq wname  (buffer-name (window-buffer w)))
+                      (if (not (assoc wname win-alist))
+                          (push (cons wname w) win-alist)
+                        (setq new-name  wname)
+                        (while (assoc new-name win-alist)
+                          (setq new-name  (format "%s[%d]" wname count)
+                                count     (1+ count)))
+                        (push (cons new-name w) win-alist))
+                      (setq count  2))
+                  'no-mini
+                  (if all-p 'visible 'this-frame))
+    win-alist))
+
+;;;###autoload (autoload 'icicle-delete-windows "icicles-cmd1.el")
+(icicle-define-command icicle-delete-windows ; Command name
+  "Delete windows showing a buffer, anywhere." ; Doc string
+  delete-windows-on                     ; Action function
+  "Delete windows on buffer: "          ; `completing-read' args
+  (let ((cand-bufs  nil))
+    (dolist (buf  (buffer-list))
+      (when (get-buffer-window buf 0) (push (list (buffer-name buf)) cand-bufs)))
+    cand-bufs)
+  nil t nil 'buffer-name-history (buffer-name (current-buffer)) nil
+  ((icicle-use-candidates-only-once-flag  t) ; Bindings
+   (icicle-inhibit-try-switch-buffer      t)
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))))
+
+;;;###autoload
+(defun icicle-delete-window (bufferp)   ; Bound to `C-x 0' in Icicle mode.
+  "`delete-window' or prompt for buffer and delete all its windows.
+When called from the minibuffer, remove the `*Completions*' window.
+
+Otherwise:
+ With no prefix argument, delete the selected window.
+ With a prefix argument, prompt for a buffer and delete all windows,
+   on any frame, that show that buffer.
+
+ With a prefix argument, this is an Icicles multi-command - see
+ command `icicle-mode'.  Input-candidate completion and cycling are
+ available.  While cycling, these keys with prefix `C-' are active:
+
+ `C-RET'   - Act on current completion candidate only
+ `C-down'  - Move to next completion candidate and act
+ `C-up'    - Move to previous completion candidate and act
+ `C-next'  - Move to next apropos-completion candidate and act
+ `C-prior' - Move to previous apropos-completion candidate and act
+ `C-end'   - Move to next prefix-completion candidate and act
+ `C-home'  - Move to previous prefix-completion candidate and act
+ `C-!'     - Act on *all* candidates (or all that are saved),
+             successively (careful!)
+
+ With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+ `C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+ Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
+ or `C-g' to quit.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `delete-window' to `icicle-delete-window'.  If you do not
+want this remapping, then customize option
+`icicle-top-level-key-bindings'."
+  (interactive "P")
+  (if (window-minibuffer-p (selected-window))
+      (icicle-remove-Completions-window)
+    (if bufferp (icicle-delete-windows) (delete-window))))
+
+;;;###autoload (autoload 'icicle-kill-buffer "icicles-cmd1.el")
+(icicle-define-command icicle-kill-buffer ; Bound to `C-x k' in Icicle mode.
+  "Kill a buffer.
+With a positive prefix arg, only buffers visiting files are candidates.
+With a negative prefix arg, only buffers associated with the selected
+ frame are candidates.
+With a zero prefix arg, only buffers that have the same mode as the
+ current buffer are candidates.
+
+You can use `C-x M' during completion to allow only buffers of a
+certain major mode as candidates.  You are prompted for the mode.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
+ `icicle-buffer-extras'             - Extra buffers to display
+ `icicle-buffer-match-regexp'       - Regexp that buffers must match
+ `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
+ `icicle-buffer-predicate'          - Predicate buffer must satisfy
+ `icicle-buffer-sort'               - Sort function for candidates
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `kill-buffer' to `icicle-kill-buffer'.  If you do not want
+this remapping, then customize option
+`icicle-top-level-key-bindings'.
+
+Note: The prefix arg is tested, even when this is called
+noninteractively.  Lisp code can bind `current-prefix-arg' to control
+the behavior."                          ; Doc string
+  icicle-kill-a-buffer-and-update-completions ; Action function
+  "Kill buffer: "                       ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
+  nil 'buffer-name-history (buffer-name (current-buffer)) nil
+  (icicle-buffer-bindings)              ; Bindings
+  (progn                                ; First code
+    (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
+    (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
+  nil                                   ; Undo code
+  (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
+         (define-key minibuffer-local-must-match-map "\C-xM" nil)))
+
+(defun icicle-kill-a-buffer-and-update-completions (buf)
+  "Kill buffer BUF and update the set of completions."
+  (setq buf  (get-buffer buf))
+  (if buf
+      (icicle-condition-case-no-debug err
+          (if (not (buffer-live-p buf))
+              (message "Buffer already deleted: `%s'" buf)
+            (if (fboundp 'kill-buffer-and-its-windows)
+                (kill-buffer-and-its-windows buf) ; Defined in `misc-cmds.el'.
+              (kill-buffer buf))
+            ;; Update the set of completions, then update `*Completions*'.
+            (setq minibuffer-completion-table  (mapcar #'(lambda (buf) (list (buffer-name buf)))
+                                                       (buffer-list)))
+            (icicle-complete-again-update))
+        (error nil))
+    (message "No such live buffer: `%s'" buf)))
+
+(put 'icicle-buffer 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-buffer "icicles-cmd1.el")
+(icicle-define-command icicle-buffer    ; Bound to `C-x b' in Icicle mode.
+  "Switch to a different buffer.
+With a positive prefix arg, only buffers visiting files are candidates.
+With a negative prefix arg, only buffers associated with the selected
+ frame are candidates.
+With a zero prefix arg, only buffers that have the same mode as the
+ current buffer are candidates.
+
+You can use `C-x m' during completion to access buffer (non-file)
+ bookmarks, if you use library `Bookmark+'.
+You can use `S-delete' during completion to kill a candidate buffer.
+
+You can use `C-x M' during completion to allow only buffers of a
+certain major mode as candidates.  You are prompted for the mode.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
+ `icicle-buffer-extras'             - Extra buffers to display
+ `icicle-buffer-match-regexp'       - Regexp that buffers must match
+ `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
+ `icicle-buffer-predicate'          - Predicate buffer must satisfy
+ `icicle-buffer-sort'               - Sort function for candidates
+
+For example, to show only buffers that are associated with files, set
+`icicle-buffer-predicate' to (lambda (buf) (buffer-file-name buf)).
+
+Option `icicle-buffer-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-buffers-ido-like' non-nil gives this command a more
+Ido-like behavior.
+
+See also command `icicle-buffer-config'.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `switch-to-buffer' to `icicle-buffer'.  If you do not want
+this remapping, then customize option
+`icicle-top-level-key-bindings'.
+
+Note: The prefix arg is tested, even when this is called
+noninteractively.  Lisp code can bind `current-prefix-arg' to control
+the behavior."                          ; Doc string
+  switch-to-buffer                      ; Action function
+  "Switch to buffer: "                  ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
+  nil 'buffer-name-history (icicle-default-buffer-names) nil
+  (icicle-buffer-bindings)              ; Bindings
+  (progn                                ; First code
+    (when (require 'bookmark+ nil t)
+      (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-non-file-other-window)
+      (define-key minibuffer-local-must-match-map "\C-xm" 'icicle-bookmark-non-file-other-window))
+    (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
+    (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
+  nil                                   ; Undo code
+  (progn (define-key minibuffer-local-completion-map "\C-xm" nil) ; Last code
+         (define-key minibuffer-local-must-match-map "\C-xm" nil)
+         (define-key minibuffer-local-completion-map "\C-xM" nil)
+         (define-key minibuffer-local-must-match-map "\C-xM" nil)))
+
+;; Free var here: `icicle-bufflist' is bound by `icicle-buffer-bindings'.
+(defun icicle-default-buffer-names ()
+  "Default buffer names (Emacs 23+) or name (< Emacs 23)."
+  (let ((bname  (buffer-name (if (fboundp 'another-buffer) ; In `misc-fns.el'.
+                                 (another-buffer nil t)
+                               (other-buffer (current-buffer))))))
+    (if (> emacs-major-version 22)      ; Emacs 23 accepts a list of default values.
+        (cons bname
+              (mapcar #'buffer-name
+                      (delete (current-buffer) ; Just keep the first 4.  (This could be an option.)
+                              (icicle-first-N 4 (or icicle-bufflist (buffer-list))))))
+      bname)))
+
+;; Free var here: `icicle-bufflist' is bound by `icicle-buffer-bindings'.
+(defun icicle-filter-buffer-cands-for-mode ()
+  "Prompt for a major mode, then remove buffer candidates not in that mode."
+  (interactive)
+  (save-selected-window (icicle-remove-Completions-window))
+  (let* ((enable-recursive-minibuffers  t)
+         (mode
+          (intern (completing-read
+                   "Major mode: "
+                   (icicle-remove-duplicates
+                    (mapcar (lambda (buf) (with-current-buffer buf (list (symbol-name major-mode))))
+                            icicle-bufflist))
+                   nil t))))
+    (setq icicle-must-pass-after-match-predicate
+          `(lambda (buf)
+            (with-current-buffer buf (eq major-mode ',mode)))))
+  (icicle-complete-again-update))
+
+;;;###autoload (autoload 'icicle-buffer-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-buffer-other-window ; Bound to `C-x 4 b' in Icicle mode.
+  "Switch to a different buffer in another window.
+Same as `icicle-buffer' except it uses a different window." ; Doc string
+  switch-to-buffer-other-window         ; Action function
+  "Switch to buffer in other window: "  ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
+  nil 'buffer-name-history (icicle-default-buffer-names) nil
+  (icicle-buffer-bindings)              ; Bindings
+  (progn                                ; First code
+    (when (require 'bookmark+ nil t)
+      (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-non-file-other-window)
+      (define-key minibuffer-local-must-match-map "\C-xm" 'icicle-bookmark-non-file-other-window))
+    (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
+    (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
+  nil                                   ; Undo code
+  (progn (define-key minibuffer-local-completion-map "\C-xm" nil) ; Last code
+         (define-key minibuffer-local-must-match-map "\C-xm" nil)
+         (define-key minibuffer-local-completion-map "\C-xM" nil)
+         (define-key minibuffer-local-must-match-map "\C-xM" nil)))
+
+;;;###autoload (autoload 'icicle-insert-buffer "icicles-cmd1.el")
+(icicle-define-command icicle-insert-buffer
+  "Multi-command version of `insert-buffer'.
+With a positive prefix arg, only buffers visiting files are candidates.
+With a negative prefix arg, only buffers associated with the selected
+ frame are candidates.
+With a zero prefix arg, only buffers that have the same mode as the
+ current buffer are candidates.
+
+You can use `C-x M' during completion to allow only buffers of a
+certain major mode as candidates.  You are prompted for the mode.
+
+You can use `S-delete' during completion to kill a candidate buffer.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
+ `icicle-buffer-extras'             - Extra buffers to display
+ `icicle-buffer-match-regexp'       - Regexp that buffers must match
+ `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
+ `icicle-buffer-predicate'          - Predicate buffer must satisfy
+ `icicle-buffer-sort'               - Sort function for candidates
+
+For example, to show only buffers that are associated with files, set
+`icicle-buffer-predicate' to (lambda (buf) (buffer-file-name buf)).
+
+Option `icicle-buffer-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+See also command `icicle-buffer-config'.
+
+Note: The prefix arg is tested, even when this is called
+noninteractively.  Lisp code can bind `current-prefix-arg' to control
+the behavior."                          ; Doc string
+  insert-buffer                         ; Action function
+  "Buffer: "                            ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
+  nil 'buffer-name-history (icicle-default-buffer-names) nil
+  (icicle-buffer-bindings)              ; Bindings
+  (progn                                ; First code
+    (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
+    (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
+  nil                                   ; Undo code
+  (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
+         (define-key minibuffer-local-must-match-map "\C-xM" nil)))
+
+;;;###autoload (autoload 'icicle-add-buffer-candidate "icicles-cmd1.el")
+(icicle-define-command icicle-add-buffer-candidate ; Command name
+  "Add buffer as an always-show completion candidate.
+Add the buffer to `icicle-buffer-extras'.  Save the updated option.
+With a positive prefix arg, only buffers visiting files are candidates.
+With a negative prefix arg, only buffers associated with the selected
+ frame are candidates.
+With a zero prefix arg, only buffers that have the same mode as the
+ current buffer are candidates.
+
+You can use `S-delete' on any completion candidate to remove it from
+`icicle-buffer-extras'.
+
+You can use `C-x M' during completion to allow only buffers of a
+certain major mode as candidates.  You are prompted for the mode.
+
+Note: The prefix arg is tested, even when this is called
+noninteractively.  Lisp code can bind `current-prefix-arg' to control
+the behavior."                          ; Doc string
+  (lambda (buf)
+    (add-to-list 'icicle-buffer-extras buf) ; Action function
+    (funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
+    (message "Buffer `%s' added to always-show buffers" buf))
+  "Buffer candidate to show always: "   ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
+  nil 'buffer-name-history (icicle-default-buffer-names) nil
+  (icicle-buffer-bindings ((icicle-use-candidates-only-once-flag  t))) ; Bindings
+  (progn                                ; First code
+    (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
+    (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
+  nil                                   ; Undo code
+  (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
+         (define-key minibuffer-local-must-match-map "\C-xM" nil)))
+
+;;;###autoload (autoload 'icicle-remove-buffer-candidate "icicles-cmd1.el")
+(icicle-define-command icicle-remove-buffer-candidate ; Command name
+  "Remove buffer as an always-show completion candidate.
+Remove the buffer from `icicle-buffer-extras'.
+Save the updated option."               ; Doc string
+  icicle-remove-buffer-candidate-action ; Action function
+  "Remove buffer from always-show list: " ; `completing-read' args
+  (mapcar #'list icicle-buffer-extras) nil t nil 'buffer-name-history (car icicle-buffer-extras) nil
+  ((icicle-use-candidates-only-once-flag  t) ; Bindings
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer"))))
+  (unless icicle-buffer-extras (error "`icicle-extra-buffers' is empty"))) ; First code
+
+(defun icicle-remove-buffer-candidate-action (buf)
+  "Action function for command `icicle-remove-buffer-candidate'."
+  (setq icicle-buffer-extras  (delete buf icicle-buffer-extras))
+  (funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
+  (message "Buffer `%s' removed from always-show buffers" buf))
+
+;;;###autoload (autoload 'icicle-buffer-config "icicles-cmd1.el")
+(icicle-define-command icicle-buffer-config ; Command name
+  "Choose a configuration of user options for `icicle-buffer'.
+You can use `S-delete' on any configuration during completion to
+remove it.  See user option `icicle-buffer-configs'.
+See also commands `icicle-add-buffer-config' and
+`icicle-remove-buffer-config'."         ; Doc string
+  (lambda (config-name)                 ; Action function
+    (let ((config  (assoc config-name icicle-buffer-configs)))
+      (setq icicle-buffer-match-regexp     (elt config 1)
+            icicle-buffer-no-match-regexp  (elt config 2)
+            icicle-buffer-predicate        (elt config 3)
+            icicle-buffer-extras           (elt config 4)
+            icicle-buffer-sort             (elt config 5))))
+  "Configuration: " icicle-buffer-configs nil t nil ; `completing-read' args
+  'icicle-buffer-config-history nil nil
+  ((icicle-delete-candidate-object  'icicle-remove-buffer-config-action))) ; Bindings
+
+;;;###autoload (autoload 'icicle-add-buffer-config "icicles-cmd1.el")
+(icicle-define-add-to-alist-command icicle-add-buffer-config ; Command name
+  "Add buffer configuration to `icicle-buffer-configs'.
+You are prompted for the buffer configuration components.
+For the list of extra buffers to always display, you can choose them
+using `C-mouse-2', `C-RET', and so on, just as you would make any
+Icicles multiple choice."
+  #'(lambda ()
+      (let ((name            (read-from-minibuffer "Add buffer configuration.  Name: "))
+            (match-regexp    (icicle-read-from-minibuf-nil-default
+                              "Regexp to match: " nil nil nil 'regexp-history
+                              icicle-buffer-match-regexp))
+            (nomatch-regexp  (icicle-read-from-minibuf-nil-default
+                              "Regexp not to match: " nil nil nil 'regexp-history
+                              icicle-buffer-no-match-regexp))
+            (pred            (icicle-read-from-minibuf-nil-default
+                              "Predicate to satify: " nil nil nil
+                              (if (boundp 'function-name-history)
+                                  'function-name-history
+                                'icicle-function-name-history)
+                              icicle-buffer-predicate))
+            (sort-fn         (icicle-read-from-minibuf-nil-default
+                              "Sort function: " nil nil t
+                              (if (boundp 'function-name-history)
+                                  'function-name-history
+                                'icicle-function-name-history)
+                              (and icicle-buffer-sort (symbol-name icicle-buffer-sort))))
+            (extras          (progn (message "Choose extra buffers to show...") (sit-for 1)
+                                    (icicle-buffer-list)))) ; Do last, for convenience.
+        (list name match-regexp nomatch-regexp pred extras sort-fn)))
+  icicle-buffer-configs)
+
+;;;###autoload (autoload 'icicle-buffer-list "icicles-cmd1.el")
+(icicle-define-command icicle-buffer-list ; Command name
+  "Choose a list of buffer names.
+With a positive prefix arg, only buffers visiting files are candidates.
+With a negative prefix arg, only buffers associated with the selected
+frame are candidates.
+
+You can use `S-delete' during completion to kill a candidate buffer.
+The list of names (strings) is returned.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
+ `icicle-buffer-extras'             - Extra buffers to display
+ `icicle-buffer-match-regexp'       - Regexp that buffers must match
+ `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
+ `icicle-buffer-predicate'          - Predicate buffer must satisfy
+ `icicle-buffer-sort'               - Sort function for candidates
+
+Note: The prefix arg is tested, even when this is called
+noninteractively.  Lisp code can bind `current-prefix-arg' to control
+the behavior."                          ; Doc string
+  (lambda (name) (push name buf-names)) ; Action function
+  "Choose buffer (`RET' when done): "   ; `completing-read' args
+  (mapcar #'(lambda (buf) (list (buffer-name buf)))
+          (if current-prefix-arg
+              (if (wholenump (prefix-numeric-value current-prefix-arg))
+                  (icicle-remove-if-not #'(lambda (bf) (buffer-file-name bf)) (buffer-list))
+                (cdr (assq 'buffer-list (frame-parameters))))
+            (buffer-list)))
+  nil
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'buffer-name-history nil nil
+  ((buf-names                               ()) ; Bindings
+   (completion-ignore-case                  (or (and (boundp 'read-buffer-completion-ignore-case)
+                                                     read-buffer-completion-ignore-case)
+                                                completion-ignore-case))
+   (icicle-must-match-regexp                icicle-buffer-match-regexp)
+   (icicle-must-not-match-regexp            icicle-buffer-no-match-regexp)
+   (icicle-must-pass-after-match-predicate  icicle-buffer-predicate)
+   (icicle-require-match-flag               icicle-buffer-require-match-flag)
+   (icicle-extra-candidates                 icicle-buffer-extras)
+   (icicle-ignore-space-prefix-flag         icicle-buffer-ignore-space-prefix-flag)
+   (icicle-delete-candidate-object          'icicle-kill-a-buffer) ; `S-delete' kills current buf
+   (icicle-transform-function               'icicle-remove-dups-if-extras)
+   (icicle-sort-comparer                    (or icicle-buffer-sort icicle-sort-comparer))
+   (icicle-sort-orders-alist
+    (append (list '("by last access")   ; Renamed from "turned OFF'.
+                  '("*...* last" . icicle-buffer-sort-*...*-last)
+                  '("by buffer size" . icicle-buffer-smaller-p)
+                  '("by major mode name" . icicle-major-mode-name-less-p)
+                  (and (fboundp 'icicle-mode-line-name-less-p)
+                       '("by mode-line mode name" . icicle-mode-line-name-less-p))
+                  '("by file/process name" . icicle-buffer-file/process-name-less-p))
+            (delete '("turned OFF") icicle-sort-orders-alist)))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+   (icicle-use-candidates-only-once-flag  t))
+  nil nil                               ; First code, undo code
+  (prog1 (setq buf-names  (nreverse (delete "" buf-names))) ; Last code - return the list of buffers
+    (when (interactive-p) (message "Buffers: %S" buf-names))))
+
+;;;###autoload (autoload 'icicle-remove-buffer-config "icicles-cmd1.el")
+(icicle-define-command icicle-remove-buffer-config ; Command name
+  "Remove buffer configuration from `icicle-buffer-configs'.
+Save the updated option."               ; Doc string
+  icicle-remove-buffer-config-action    ; Action function
+  "Remove buffer configuration: "       ; `completing-read' args
+  (mapcar #'(lambda (config) (list (car config))) icicle-buffer-configs)
+  nil t nil 'icicle-buffer-config-history (caar icicle-buffer-configs) nil
+  ((icicle-use-candidates-only-once-flag  t))) ; Bindings
+
+(defun icicle-remove-buffer-config-action (config-name)
+  "Action function for command `icicle-remove-buffer-config'."
+  (setq icicle-buffer-configs  (icicle-assoc-delete-all config-name icicle-buffer-configs))
+  (funcall icicle-customize-save-variable-function 'icicle-buffer-configs icicle-buffer-configs)
+  (message "Buffer configuration `%s' removed" config-name))
+
+;;;###autoload (autoload 'icicle-face-list "icicles-cmd1.el")
+(icicle-define-command icicle-face-list ; Command name
+  "Choose a list of face names.  The list of names (strings) is returned." ; Doc string
+  (lambda (name) (push (icicle-transform-multi-completion name) face-names)) ; Action function
+  prompt (mapcar #'icicle-make-face-candidate (face-list)) nil ; `completing-read' args
+  (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+  (if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history)
+  nil nil
+  ((prompt                                "Choose face (`RET' when done): ") ; Bindings
+   (icicle-list-nth-parts-join-string     ": ")
+   (icicle-list-join-string               ": ")
+   ;; $$$$$$ (icicle-list-end-string                "")
+   (icicle-list-use-nth-parts             '(1))
+   (icicle-use-candidates-only-once-flag  t)
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "face")))
+   (icicle-all-candidates-list-alt-action-fn ; M-|'
+    (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "face")))
+   (face-names                            ()))
+  (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+  nil                                   ; Undo code
+  (prog1 (setq face-names  (nreverse (delete "" face-names))) ; Last code - return list of faces
+    (when (interactive-p) (message "Faces: %S" face-names))))
+
+;;;###autoload (autoload 'icicle-color-theme "icicles-cmd1.el")
+(icicle-define-command icicle-color-theme ; Command name
+  "Change color theme.
+You can use `S-delete' during completion to remove the current
+candidate from the list of color themes.
+
+If you use `C-g' during this command, the previous color-theme
+snapshot is used to restore that color theme.
+
+Remember too that you can use the pseudo-theme [Reset] to restore the
+last theme: `M-x color-theme-select [Reset]'.
+
+By default, each time you invoke this command, a snapshot is first
+made of the current color theme (or current colors, if no theme is
+used).  Thus, by default, if you use `C-g', the colors restored are
+those used before you changed themes using this command.
+
+However, if you use a prefix arg, then this command takes no new
+snapshot, unless no snapshot has ever been taken during this Emacs
+session.  This can be useful when experimenting, to restore not to the
+state just before this command invocation, but to some previous
+snapshot.
+
+To use this command, you must have loaded library `color-theme.el',
+available from http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme." ; Doc string
+  (lambda (theme)
+    (when (string= "" theme) (error "No theme name entered (empty input)"))
+    (funcall  (intern theme)))          ; Action function: just call the theme.
+  "Theme: " icicle-color-themes nil t nil ; `completing-read' args
+  (if (boundp 'color-theme-history) 'color-theme-history 'icicle-color-theme-history)
+  nil nil
+  ((icicle-delete-candidate-object  'icicle-color-themes) ; Bindings
+   (prefix-arg                      current-prefix-arg))
+  (progn (unless (prog1 (require 'color-theme nil t) ; First code
+                   (when (and (fboundp 'color-theme-initialize) (not color-theme-initialized))
+                     ;; NOTE: We need the `icicle-condition-case-no-debug' because of a BUG in
+                     ;; `directory-files' for Emacs 20.  Bug reported to `color-theme.el'
+                     ;; maintainer 2009-11-22.  The problem is that the default value of
+                     ;; `color-theme-libraries' concats `file-name-directory', which ends in `/',
+                     ;; with `/themes', not with `themes'.  So the result is `...//themes'.
+                     ;; That is tolerated by Emacs 21+ `directory-files', but not for Emacs 20.
+                     ;; Until this `color-theme.el' bug is fixed, Emacs 20 users will need to
+                     ;; manually load `color-theme-libraries.el'.
+                     (icicle-condition-case-no-debug nil
+                         (let ((color-theme-load-all-themes  t))
+                           (color-theme-initialize)
+                           (setq color-theme-initialized  t))
+                       (error nil))))
+           (error "This command requires library `color-theme.el'"))
+         (unless icicle-color-themes
+           (setq icicle-color-themes
+                 (delete '("bury-buffer")
+                         (mapcar (lambda (entry) (list (symbol-name (car entry))))
+                                 color-themes)))) ; Free here, defined in `color-theme.el'.
+         ;; Create the snapshot, if not available.  Do this so users can also undo using
+         ;; pseudo-theme `[Reset]'.
+         (when (or (not prefix-arg)
+                   (not (assq 'color-theme-snapshot color-themes))
+                   (not (commandp 'color-theme-snapshot)))
+           (fset 'color-theme-snapshot (color-theme-make-snapshot))
+           (setq color-themes  (delq (assq 'color-theme-snapshot color-themes) color-themes)
+                 color-themes  (delq (assq 'bury-buffer color-themes) color-themes)
+                 color-themes  (append '((color-theme-snapshot
+                                          "[Reset]" "Undo changes, if possible.")
+                                         (bury-buffer "[Quit]" "Bury this buffer."))
+                                       color-themes))))
+  (color-theme-snapshot))               ; Undo code
+
+
+;; Make delete-selection mode recognize yanking, so it replaces region text.
+(put 'icicle-completing-yank 'delete-selection 'yank)
+;; Bound to `C-- C-y' via `icicle-yank-maybe-completing'.
+;;;###autoload (autoload 'icicle-completing-yank "icicles-cmd1.el")
+(icicle-define-command icicle-completing-yank
+  "Yank an entry from the `kill-ring', choosing it using completion.
+This is like `yank', but it does not rotate the `kill-ring'.
+The mark is pushed first, so the yanked text becomes the region.
+You can sort the candidates to yank - use `C-,'.
+You can use `S-delete' during completion to remove a candidate entry
+from the `kill-ring'."                  ; Doc string
+  icicle-insert-for-yank                ; Action function
+  "Insert: " (mapcar #'list kills-in-order) nil t nil 'icicle-kill-history ; `completing-read' args
+  (car kills-in-order) nil
+  ((icicle-transform-function       'icicle-remove-duplicates) ; Bindings
+   (icicle-sort-comparer            nil)
+   (icicle-delete-candidate-object  'kill-ring)
+   (kills-in-order                  (icicle-delete-dups
+                                     (append kill-ring-yank-pointer kill-ring nil)))))
+
+(defun icicle-insert-for-yank (string)
+  "`insert-for-yank', if defined; else, `insert' with `read-only' removed.
+Pushes the mark first, so the inserted text becomes the region."
+  (setq this-command  'yank)
+  (push-mark)
+  (if (fboundp 'insert-for-yank)        ; Defined in `subr.el' (not required).
+      (insert-for-yank string)
+    (let ((opoint  (point)))
+      (insert string)
+      (let ((inhibit-read-only  t)) (remove-text-properties opoint (point) '(read-only nil))))))
+
+
+;; Make delete-selection mode recognize yanking, so it replaces region text.
+(put 'icicle-yank-maybe-completing 'delete-selection 'yank)
+;;;###autoload
+(defun icicle-yank-maybe-completing (&optional arg) ;  Bound to `C-y' (or what `yank' was bound to).
+  "`icicle-completing-yank', `icicle-yank', or `icicle-yank-function'.
+If called from the minibuffer, call `icicle-yank'.
+Otherwise:
+ With a negative prefix argument, call `icicle-completing-yank'.
+ Otherwise, call the value of user option `icicle-yank-function' (by
+ default, `yank')."
+  (interactive "*P")
+  (if (window-minibuffer-p (selected-window))
+      (icicle-yank arg)
+    (if (wholenump (prefix-numeric-value arg))
+        (funcall icicle-yank-function arg)
+      (icicle-completing-yank))))
+
+;;;###autoload (autoload 'icicle-delete-file "icicles-cmd1.el")
+(icicle-define-file-command icicle-delete-file ; Command name
+  "Delete a file or directory.
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
+  icicle-delete-file-or-directory       ; Function to perform the action
+  "Delete file or directory: " default-directory nil t nil nil ; `read-file-name' args
+  (icicle-file-bindings)                ; Bindings
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+(defun icicle-delete-file-or-directory (file)
+  "Delete file or (empty) directory FILE."
+  (icicle-condition-case-no-debug i-delete-file
+      (if (eq t (car (file-attributes file)))
+          (delete-directory file)
+        (delete-file file))
+    (error (message "%s" (error-message-string i-delete-file))
+           (error "%s" (error-message-string i-delete-file)))))
+
+;; $$$$$ (icicle-define-command icicle-file-list ; Command name
+;;   "Choose a list of file names.
+;; You can use `S-delete' during completion to delete a candidate file.
+;; The list of names (strings) is returned." ; Doc string
+;;   (lambda (name) (push name file-names)) ; Function to perform the action
+;;   "Choose file (`RET' when done): "     ; `completing-read' args
+;;   (mapcar #'list (directory-files default-directory nil icicle-re-no-dot))
+;;   nil nil nil 'file-name-history nil nil
+;;   ((file-names nil)                     ; Additional bindings
+;;    (icicle-delete-candidate-object  'icicle-delete-file-or-directory) ; `S-delete' deletes file.
+;;    (icicle-use-candidates-only-once-flag  t))
+;;   nil nil                               ; First code, undo code
+;;   (prog1 (setq file-names  (nreverse (delete "" file-names))) ; Last code - return files list
+;;     (when (interactive-p) (message "Files: %S" file-names))))
+
+;;;###autoload (autoload 'icicle-file-list "icicles-cmd1.el")
+(icicle-define-file-command icicle-file-list ; Command name
+  "Choose a list of file and directory names (strings), and return it.
+Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
+and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
+You can navigate the directory tree, picking files and directories
+anywhere in the tree.
+
+Remember too that you can use `C-!' to gather all of the file names
+matching your current input.  For example, apropos-completing with
+input `foo.*bar' and hitting `C-!' adds all file names matching that
+regexp.
+
+You can use either `RET' or `C-g' to finish adding file names to the
+list.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (name) (push name file-names)) ; Function to perform the action
+  "Choose file (`RET' when done): " nil nil t nil nil ; `read-file-name' args
+  (icicle-file-bindings                 ; Bindings
+   ((file-names                         nil)
+    (icicle-comp-base-is-default-dir-p  t)
+    ;; $$$$$ (icicle-dir-candidate-can-exit-p (not current-prefix-arg))
+    ))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (prog1 (setq file-names  (nreverse (delete "" file-names))) ; Last code - return list of files
+    (icicle-unbind-file-candidate-keys)
+    (when (interactive-p) (message "Files: %S" file-names))))
+
+;;;###autoload (autoload 'icicle-directory-list "icicles-cmd1.el")
+(icicle-define-file-command icicle-directory-list ; Command name
+  "Choose a list of directory names (strings), and return it.
+Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
+and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
+You can navigate the directory tree, picking directories anywhere in
+the tree.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra directory names to display
+ `icicle-file-match-regexp'     - Regexp directory names must match
+ `icicle-file-no-match-regexp'  - Regexp dir names must not match
+ `icicle-file-predicate'        - Predicate the dir names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (name) (push name dir-names)) ; Function to perform the action
+  "Choose directory (`RET' when done): " ; `read-file-name' args
+  nil nil t nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((dir-names                          ())
+    (user-file-pred                     icicle-file-predicate)
+    (icicle-file-predicate              (if user-file-pred
+                                            #'(lambda (f) (and (file-directory-p f)
+                                                               (funcall user-file-pred f)))
+                                          #'file-directory-p))
+    (icicle-comp-base-is-default-dir-p  t)
+    ;; $$$$$ (icicle-dir-candidate-can-exit-p (not current-prefix-arg))
+    ))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (prog1 (setq dir-names  (nreverse (delete "" dir-names))) ; Last code - return the list of dirs
+    (icicle-unbind-file-candidate-keys)
+    (when (interactive-p) (message "Directories: %S" dir-names))))
+
+;;;###autoload (autoload 'icicle-dired "icicles-cmd1.el")
+(icicle-define-file-command icicle-dired
+  "Multi-command version of `dired'.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
+  (lambda (dir) (dired dir switches))   ; Function to perform the action
+  "Dired (directory): " nil default-directory nil nil nil ; `read-file-name' args
+  (icicle-file-bindings                 ; Bindings
+   ((switches               (and current-prefix-arg
+                                 (read-string "Dired listing switches: " dired-listing-switches)))
+    (icicle-file-sort       (or icicle-file-sort 'icicle-dirs-first-p))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+;;;###autoload (autoload 'icicle-dired-other-window "icicles-cmd1.el")
+(icicle-define-file-command icicle-dired-other-window
+  "Same as `icicle-dired', except uses another window."                           ; Doc string
+  (lambda (dir) (dired-other-window dir switches)) ; Function to perform the action
+  "Dired in other window (directory): " nil default-directory nil nil nil ; `read-file-name' args
+  (icicle-file-bindings                 ; Bindings
+   ((switches               (and current-prefix-arg
+                                 (read-string "Dired listing switches: " dired-listing-switches)))
+    (icicle-file-sort       (or icicle-file-sort 'icicle-dirs-first-p))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+
+(put 'icicle-file 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-file (arg)                ; Bound to `C-x C-f' in Icicle mode.
+  "Visit a file or directory.
+With no prefix argument, use relative file names
+ (`icicle-find-file').
+With a prefix argument, use absolute file names
+ (`icicle-find-file-absolute').
+With a negative prefix argument, you can choose also by date:
+ Completion candidates include the last modification date.
+
+Note that when you use a prefix argument completion matches candidates
+as ordinary strings.  It knows nothing of file names per se.  In
+particular, you cannot use remote file-name syntax if you use a prefix
+argument.
+
+During completion:
+ You can use `C-x m' to access file bookmarks, if you use library
+  `Bookmark+'.
+ You can use `C-c +' to create a new directory.
+ You can use `M-|' to open Dired on the currently matching file names.
+ You can use `S-delete' to delete a candidate file or (empty)
+  directory.
+
+By default, Icicle mode remaps all key sequences that are normally bound
+to `find-file' to `icicle-file'.  If you do not want this remapping,
+then customize option `icicle-top-level-key-bindings'."
+  (interactive "P")
+  (if arg
+      (if (wholenump (prefix-numeric-value arg))
+          (let ((current-prefix-arg  nil)) (icicle-find-file-absolute))
+        (icicle-find-file-absolute))
+    (icicle-find-file)))
+
+
+(put 'icicle-file-other-window 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-file-other-window (arg)   ; Bound to `C-x 4 f' in Icicle mode.
+  "Same as `icicle-file', except uses another window."
+  (interactive "P")
+  (if arg
+      (if (wholenump (prefix-numeric-value arg))
+          (let ((current-prefix-arg  nil)) (icicle-find-file-absolute-other-window))
+        (icicle-find-file-absolute-other-window))
+    (icicle-find-file-other-window)))
+
+
+(put 'icicle-find-file-absolute 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-find-file-absolute "icicles-cmd1.el")
+(icicle-define-command icicle-find-file-absolute ; Command name
+  "Visit a file or directory, given its absolute name.
+Unlike `icicle-find-file', the completion candidates are absolute, not
+relative, file names.  By default, the completion candidates are files
+in the current directory, but you can substitute other candidates by
+retrieving a saved candidate set.
+
+Note that completion here matches candidates as ordinary strings.  It
+knows nothing of file names per se.  In particular, you cannot use
+remote file-name syntax.
+
+Remember that you can use `\\\
+\\[icicle-toggle-hiding-common-match]' to hide the common match portion of
+each candidate.  That can be particularly helpful for files that are
+in a common directory.
+
+With a prefix argument, you can choose also by date: Completion
+candidates include the last modification date.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
+  prompt icicle-abs-file-candidates nil ; `completing-read' args
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  default-directory 'file-name-history default-directory nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                             "File or dir (absolute): ")
+    (icicle-full-cand-fn                `(lambda (file)
+                                          (setq file  (if (file-directory-p file)
+                                                          (concat file "/")
+                                                        file))
+                                          ,(if current-prefix-arg
+                                               '(icicle-make-file+date-candidate file)
+                                               '(list file))))
+    (icicle-abs-file-candidates         (mapcar icicle-full-cand-fn
+                                                (directory-files default-directory 'FULL nil 'NOSORT)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
+    (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
+    (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (icicle-highlight-lighter)
+    (message "Gathering files...")
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+
+(put 'icicle-find-file-absolute-other-window 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-find-file-absolute-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-find-file-absolute-other-window ; Command name
+  "Same as `icicle-find-file-absolute' except uses another window." ; Doc string
+  (lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
+  prompt icicle-abs-file-candidates nil ; `completing-read' args
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  default-directory 'file-name-history default-directory nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                             "File or dir (absolute): ")
+    (icicle-full-cand-fn                `(lambda (file)
+                                          (setq file  (if (file-directory-p file)
+                                                          (concat file "/")
+                                                        file))
+                                          ,(if current-prefix-arg
+                                               '(icicle-make-file+date-candidate file)
+                                               '(list file))))
+    (icicle-abs-file-candidates         (mapcar icicle-full-cand-fn
+                                                (directory-files default-directory 'FULL nil 'NOSORT)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
+    (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
+    (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (icicle-highlight-lighter)
+    (message "Gathering files...")
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+;; This is a minibuffer command.  It is in this file because it is used only here.
+;;;###autoload
+(defun icicle-cd-for-abs-files (dir)    ; Bound to `C-c C-d' in minibuffer for abs file completion.
+  "Change `default-directory' during `icicle-find-file-absolute'."
+  (interactive
+   ;; Should not need to bind `minibuffer-completion-predicate'.  Emacs 23.2 bug, per Stefan.
+   (let ((enable-recursive-minibuffers     t)
+         (minibuffer-completion-predicate  minibuffer-completion-predicate))
+     (list (funcall (if (fboundp 'read-directory-name)
+                        #'read-directory-name
+                      #'read-file-name)
+                    "Change default directory: " nil nil
+                    (and (member cd-path '(nil ("./"))) (null (getenv "CDPATH")))))))
+  (cd dir)
+  (let ((icicle-abs-file-candidates
+         (mapcar #'(lambda (file)
+                     (setq file  (if (file-directory-p file) (concat file "/") file))
+                     (if icicle-list-use-nth-parts (icicle-make-file+date-candidate file) (list file)))
+                 (directory-files default-directory 'full nil 'nosort))))
+    (setq minibuffer-completion-table
+          (car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
+
+
+(put 'icicle-find-file 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-find-file "icicles-cmd1.el")
+(icicle-define-file-command icicle-find-file
+  "Visit a file or directory.
+If you use a prefix argument when you act on a candidate file name,
+then you visit the file in read-only mode.
+
+If you use a prefix arg for the command itself, this reverses the
+effect of using a prefix arg on individual candidates.  That is, with
+a prefix arg for the command, files are visited in read-only mode by
+default and a prefix arg for an individual file visits it without
+read-only mode.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra absolute file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (file)                        ; Function to perform the action
+    (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                     (or (and init-pref-arg        (not current-prefix-arg))
+                         (and (not init-pref-arg)  current-prefix-arg))
+                   init-pref-arg))
+           (fn   (if r-o 'find-file-read-only 'find-file)))
+      (funcall fn file 'WILDCARDS)))
+  (concat "File or directory" (and init-pref-arg " (read-only)") ": ") ; `read-file-name' args
+  nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
+          (condition-case nil           ; E.g. error because not on file line (ignore)
+              (abbreviate-file-name (dired-get-file-for-visit))
+            (error nil))
+        default-directory)
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((init-pref-arg  current-prefix-arg)
+    (icicle-all-candidates-list-alt-action-fn ; `M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+;;;###autoload (autoload 'icicle-find-file-other-window "icicles-cmd1.el")
+(icicle-define-file-command icicle-find-file-other-window
+  "Same as `icicle-find-file', except uses another window." ; Doc string
+  (lambda (file)                        ; Function to perform the action
+    (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                     (or (and init-pref-arg        (not current-prefix-arg))
+                         (and (not init-pref-arg)  current-prefix-arg))
+                   init-pref-arg))
+           (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
+      (funcall fn file 'WILDCARDS)))
+  (concat "File or directory" (and init-pref-arg " (read-only)") ": ") ; `read-file-name' args
+  nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
+          (condition-case nil           ; E.g. error because not on file line (ignore)
+              (abbreviate-file-name (dired-get-file-for-visit))
+            (error nil))
+        default-directory)
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((init-pref-arg  current-prefix-arg)
+    (icicle-all-candidates-list-alt-action-fn ; `M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (icicle-bind-file-candidate-keys)     ; First code
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+
+(put 'icicle-find-file-read-only 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-find-file-read-only ()    ; Bound to `C-x C-r' in Icicle mode.
+  "Visit a file or directory in read-only mode.
+If you use a prefix argument when you act on a candidate file name,
+then visit the file without read-only mode.
+
+If you use a prefix arg for the command itself, this reverses the
+effect of using a prefix arg on individual candidates.  That is, with
+a prefix arg for the command, files are not visited in read-only mode
+by default and a prefix arg for an individual file visits it in
+read-only mode.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir."
+  (interactive)
+  (let ((current-prefix-arg  (not current-prefix-arg)))
+    (icicle-find-file)))
+
+;;;###autoload
+(defun icicle-find-file-read-only-other-window () ; Bound to `C-x 4 r' in Icicle mode.
+  "Same as `icicle-find-file-read-only' except uses another window."
+  (interactive)
+  (let ((current-prefix-arg  (not current-prefix-arg)))
+    (icicle-find-file-other-window)))
+
+
+(put 'icicle-recent-file 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-recent-file "icicles-cmd1.el")
+(icicle-define-command icicle-recent-file ; Command name
+  "Open a recently used file.
+With a prefix argument, you can choose also by date: Completion
+candidates include the last modification date.
+
+Note that completion here matches candidates as ordinary strings.  It
+knows nothing of file names per se.  In particular, you cannot use
+remote file-name syntax.
+
+Remember that you can use `\\\
+\\[icicle-toggle-hiding-common-match]' to hide the common match portion of
+each candidate.  That can be particularly helpful for files that are
+in a common directory.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+You can use any of the alternative-action keys, such as `C-S-RET', to
+remove a candidate file from the recent files list, `recentf-list'.
+\(The file itself is not deleted.)
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra absolute file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
+  prompt icicle-abs-file-candidates nil ; `completing-read' args
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'file-name-history (car recentf-list) nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                                 "Recent file (absolute): ")
+    (icicle-full-cand-fn                `(lambda (file)
+                                              (setq file  (if (file-directory-p file)
+                                                              (concat file "/")
+                                                            file))
+                                              ,(if current-prefix-arg
+                                                   '(icicle-make-file+date-candidate file)
+                                                   '(list file))))
+    (icicle-abs-file-candidates
+     (progn (unless (boundp 'recentf-list) (require 'recentf))
+            (when (fboundp 'recentf-mode) (recentf-mode 99))
+            (unless (consp recentf-list)
+              (error "No recently accessed files"))
+            (mapcar #'(lambda (file)
+                        (if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
+                    recentf-list)))
+    (icicle-candidate-alt-action-fn         'icicle-remove-from-recentf-candidate-action)
+    (icicle-use-candidates-only-once-alt-p  t)
+    (icicle-candidate-properties-alist      (and current-prefix-arg
+                                                 '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts              (and current-prefix-arg '(1)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ")
+                                                 (mapcar #'icicle-transform-multi-completion
+                                                         files))))))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (icicle-highlight-lighter)
+    (message "Gathering files...")
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+;;;###autoload (autoload 'icicle-recent-file-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-recent-file-other-window ; Command name
+  "Same as `icicle-recent-file' except uses another window." ; Doc string
+  (lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
+  prompt icicle-abs-file-candidates nil ; `completing-read' args
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'file-name-history (car recentf-list) nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                                 "Recent file (absolute): ")
+    (icicle-full-cand-fn                    `(lambda (file)
+                                              (setq file  (if (file-directory-p file)
+                                                              (concat file "/")
+                                                            file))
+                                              ,(if current-prefix-arg
+                                                   '(icicle-make-file+date-candidate file)
+                                                   '(list file))))
+    (icicle-abs-file-candidates
+     (progn (unless (boundp 'recentf-list) (require 'recentf))
+            (when (fboundp 'recentf-mode) (recentf-mode 99))
+            (unless (consp recentf-list)
+              (error "No recently accessed files"))
+            (mapcar #'(lambda (file)
+                        (if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
+                    recentf-list)))
+    (icicle-candidate-alt-action-fn         'icicle-remove-from-recentf-candidate-action)
+    (icicle-use-candidates-only-once-alt-p  t)
+    (icicle-candidate-properties-alist      (and current-prefix-arg
+                                                 '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts              (and current-prefix-arg '(1)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ")
+                                                 (mapcar #'icicle-transform-multi-completion
+                                                         files))))))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (icicle-highlight-lighter)
+    (message "Gathering files...")
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+;;;###autoload (autoload 'icicle-remove-file-from-recentf-list "icicles-cmd1.el")
+(icicle-define-command icicle-remove-file-from-recentf-list
+  "Remove file from `recentf-list' - the list of recently used files."
+  icicle-remove-from-recentf-candidate-action
+  "Remove from recent files list, `recentf-list': "
+  (mapcar #'list (progn (unless (boundp 'recentf-list) (require 'recentf))
+                        (when (fboundp 'recentf-mode) (recentf-mode 99))
+                        (unless (consp recentf-list) (error "No recently accessed files"))
+                        recentf-list))
+  nil (and (fboundp 'confirm-nonexistent-file-or-buffer) ; Emacs23.
+           (confirm-nonexistent-file-or-buffer))
+  nil 'file-name-history (car recentf-list) nil
+  ((icicle-use-candidates-only-once-flag  t)))
+
+(defun icicle-remove-from-recentf-candidate-action (file)
+  "Action function for command `icicle-remove-file-from-recentf-list'."
+  (setq recentf-list  (delete file recentf-list))
+  (message "`%s' removed from `recentf-list'" file))
+
+
+(defvar icicle-locate-file-action-fn nil
+  "Action function used in `icicle-locate-file-1'.")
+
+(defvar icicle-locate-file-no-symlinks-p nil
+  "Flag bound in `icicle-locate-file* for use by `icicle-files-within'.")
+
+
+(put 'icicle-locate-file 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-locate-file ()
+  "Visit a file within a directory or its subdirectories.
+With a non-negative (>= 0) prefix argument, you are prompted for the
+directory.  Otherwise, the current directory is used.
+
+With a non-positive (<= 0) prefix argument, you can choose also by
+date: Completion candidates include the last modification date.
+
+The absolute names of all files within the directory and all of its
+subdirectories are targets for completion.  Regexp input is matched
+against all parts of the absolute name, not just the file-name part.
+
+Remember that you can use `\\\
+\\[icicle-toggle-hiding-common-match]' to hide the common match portion of
+each candidate.  That can be particularly helpful for files that are
+in a common directory.
+
+You can use this command to find all files within your file system
+that match a regexp, but be aware that gathering and matching the file
+names will take some time.
+
+See also command `icicle-locate-file-no-symlinks', which does the same
+thing but without following symbolic links.
+
+Remember that you can save the set of files matching your input using
+`\\[icicle-candidate-set-save]' or \
+`\\[icicle-candidate-set-save-persistently]'.  You can then retrieve quickly them later using
+`\\[icicle-candidate-set-retrieve]' or \
+`\\[icicle-candidate-set-retrieve-persistent]'.
+
+Note that completion here matches candidates as ordinary strings.  It
+knows nothing of file names per se.  In particular, you cannot use
+remote file-name syntax.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+Directories in `icicle-ignored-directories' are ignored (skipped).  In
+addition, these options control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-require-match-flag' - See `icicle-require-match-flag'
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))"
+  (interactive)
+  (let ((icicle-locate-file-action-fn      'icicle-locate-file-action)
+        (icicle-locate-file-no-symlinks-p  nil))
+    (icicle-locate-file-1)))
+
+;;;###autoload
+(defun icicle-locate-file-other-window ()
+  "Same as `icicle-locate-file' except uses another window.
+See also command `icicle-locate-file-no-symlinks-other-window', which
+does not follow symbolic links."
+  (interactive)
+  (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
+        (icicle-locate-file-no-symlinks-p  nil))
+    (icicle-locate-file-1)))
+
+(put 'icicle-locate-file-no-symlinks 'icicle-Completions-window-max-height 200)
+;;;###autoload
+(defun icicle-locate-file-no-symlinks ()
+  "Same as `icicle-locate-file', except do not follow symlinks."
+  (interactive)
+  (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
+        (icicle-locate-file-no-symlinks-p  t))
+    (icicle-locate-file-1)))
+
+;;;###autoload
+(defun icicle-locate-file-no-symlinks-other-window ()
+  "Same as `icicle-locate-file-no-symlinks', except uses another window."
+  (interactive)
+  (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
+        (icicle-locate-file-no-symlinks-p  t))
+    (icicle-locate-file-1)))
+
+(defun icicle-locate-file-action (file)
+  "Action function for `icicle-locate-file'."
+  (find-file (icicle-transform-multi-completion file) 'WILDCARDS))
+
+(defun icicle-locate-file-other-window-action (file)
+  "Action function for `icicle-locate-file-other-window'."
+  (find-file-other-window (icicle-transform-multi-completion file) 'WILDCARDS))
+
+;;;###autoload (autoload 'icicle-locate-file-1 "icicles-cmd1.el")
+(icicle-define-command icicle-locate-file-1
+  "Helper function for `icicle-locate-file(-other-window)'." ; Doc string
+  ;; `icicle-locate-file-action-fn' is free here.
+  (lambda (f) (funcall icicle-locate-file-action-fn f)) ; Action function
+  prompt icicle-abs-file-candidates nil ; `completing-read' args
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'file-name-history nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                             "File (absolute): ")
+    (dir                                (if (and current-prefix-arg
+                                                 (wholenump (prefix-numeric-value
+                                                             current-prefix-arg)))
+                                            (read-file-name "Locate under which directory: " nil
+                                                            default-directory nil)
+                                          default-directory))
+    (IGNORED--FOR-SIDE-EFFECT           (progn
+                                          (icicle-highlight-lighter)
+                                          (message "Gathering files within `%s' (this could take \
+a while)..." dir)))
+    (icicle-full-cand-fn                `(lambda (file)
+                                          (setq file  (if (file-directory-p file)
+                                                          (concat file "/")
+                                                        file))
+                                          ,(if (<= (prefix-numeric-value current-prefix-arg) 0)
+                                               '(icicle-make-file+date-candidate file)
+                                               '(list file))))
+    (icicle-abs-file-candidates         ; `icicle-locate-file-no-symlinks-p' is free here.
+     (mapcar #'(lambda (file)
+                 (if (<= (prefix-numeric-value current-prefix-arg) 0)
+                     (icicle-make-file+date-candidate file)
+                   (list file)))
+             (icicle-files-within (directory-files dir 'full icicle-re-no-dot)
+                                  nil icicle-locate-file-no-symlinks-p)))
+    (use-dialog-box                     nil)
+    (icicle-candidate-properties-alist  (and (<= (prefix-numeric-value current-prefix-arg) 0)
+                                             '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts          (and (<= (prefix-numeric-value current-prefix-arg) 0)
+                                             '(1)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ")
+                                                 (mapcar #'icicle-transform-multi-completion
+                                                         files))))))))
+  (progn                                ; First code
+    (when (<= (prefix-numeric-value current-prefix-arg) 0)
+      (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (icicle-highlight-lighter)
+    (message "Gathering files...")
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys)   ; Last code
+  'NON-INTERACTIVE)                     ; This is not a real command.
+
+;; This is a minibuffer command.  It is in this file because it is used only here.
+;;;###autoload
+(defun icicle-cd-for-loc-files (dir &optional no-symlinks-p) ; Bound to `C-c C-d' in minibuf locate-*.
+  "Change `default-directory' during `icicle-locate-file'.
+Optional arg NO-SYMLINKS-P non-nil means do not follow symbolic links."
+  (interactive
+   (save-selected-window
+     ;; Should not need to bind `minibuffer-completion-predicate'.  Emacs 23.2 bug, per Stefan.
+     (let ((minibuffer-completion-predicate  minibuffer-completion-predicate))
+       (list (funcall (if (fboundp 'read-directory-name)
+                          #'read-directory-name
+                        #'read-file-name)
+                      "Change default directory: " nil nil
+                      (and (member cd-path '(nil ("./"))) (null (getenv "CDPATH"))))))))
+  (cd dir)
+  (let ((icicle-abs-file-candidates
+         (mapcar #'(lambda (file)
+                     (if icicle-list-use-nth-parts (icicle-make-file+date-candidate file) (list file)))
+                 (icicle-files-within (directory-files dir 'full icicle-re-no-dot) nil no-symlinks-p))))
+    (setq minibuffer-completion-table
+          (car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
+
+
+(put 'icicle-find-file-in-tags-table 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-find-file-in-tags-table "icicles-cmd1.el")
+(icicle-define-command icicle-find-file-in-tags-table ; Command name
+  "Visit a file listed in a tags table.
+By default, the completion candidates are the file names listed in the
+current tags table, but you can substitute other candidates by
+retrieving a saved candidate set.  The default candidates appear as
+they did in the `etags' command that created the tags table, which
+typically means without directory names.
+
+Completion here matches candidates as ordinary strings.  It knows
+nothing of file names per se.  In particular, you cannot use remote
+file-name syntax.  If a candidate is an absolute file name then you
+can complete against any and all parts of the name (including
+directory components).
+
+`find-file' is called for the candidate(s) you choose, with the
+directory of the tags file as `default-directory'.
+
+Remember that you can use `\\\
+\\[icicle-toggle-hiding-common-match]' to hide the common match portion of
+each candidate.  That can be particularly helpful for files that are
+in a common directory.
+
+With a prefix argument, you can choose also by date: Completion
+candidates include the last modification date.
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir.
+
+These options, when non-nil, control candidate matching and filtering:
+
+ `icicle-file-extras'           - Extra file names to display
+ `icicle-file-match-regexp'     - Regexp that file names must match
+ `icicle-file-no-match-regexp'  - Regexp file names must not match
+ `icicle-file-predicate'        - Predicate file names must satisfy
+ `icicle-file-sort'             - Sort function for candidates
+
+For example, to show only names of files larger than 5000 bytes, set
+`icicle-file-predicate' to:
+
+  (lambda (file) (> (nth 5 (file-attributes file)) 5000))
+
+Option `icicle-file-require-match-flag' can be used to override
+option `icicle-require-match-flag'.
+
+Option `icicle-files-ido-like' non-nil gives this command a more
+Ido-like behavior."                     ; Doc string
+  (lambda (ff)
+    (visit-tags-table-buffer 'same)     ; To pick up `default-directory' of TAGS table.
+    (find-file (icicle-transform-multi-completion ff) 'WILDCARDS)) ; Action function
+  prompt                                ; `completing-read' args
+  (mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
+          (save-excursion (let ((enable-recursive-minibuffers  t)) (visit-tags-table-buffer))
+                          (tags-table-files)))
+  nil
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'file-name-history nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                             "File (in tags table): ")
+    (icicle-full-cand-fn                `(lambda (file)
+                                          (setq file  (if (file-directory-p file)
+                                                          (concat file "/")
+                                                        file))
+                                          ,(if current-prefix-arg
+                                               '(icicle-make-file+date-candidate file)
+                                               '(list file))))
+    (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
+    (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (unless (require 'etags nil t) (error "`etags.el' is required"))
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+
+(put 'icicle-find-file-in-tags-table-other-window 'icicle-Completions-window-max-height 200)
+;;;###autoload (autoload 'icicle-find-file-in-tags-table-other-window "icicles-cmd1.el")
+(icicle-define-command icicle-find-file-in-tags-table-other-window ; Command name
+  "Same as `icicle-find-file-in-tags-table', but uses another window." ; Doc string
+  (lambda (ff)
+    (visit-tags-table-buffer 'same)     ; To pick up `default-directory' of TAGS table.
+    (find-file (icicle-transform-multi-completion ff) 'WILDCARDS)) ; Action function
+  prompt                                ; `completing-read' args
+  (mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
+          (save-excursion (let ((enable-recursive-minibuffers  t)) (visit-tags-table-buffer))
+                          (tags-table-files)))
+  nil
+  (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
+  nil 'file-name-history nil nil
+  (icicle-file-bindings                 ; Bindings
+   ((prompt                             "File (in tags table): ")
+    (icicle-full-cand-fn                `(lambda (file)
+                                          (setq file  (if (file-directory-p file)
+                                                          (concat file "/")
+                                                        file))
+                                          ,(if current-prefix-arg
+                                               '(icicle-make-file+date-candidate file)
+                                               '(list file))))
+    (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
+    (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
+    (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))
+    (icicle-all-candidates-list-alt-action-fn ; M-|'
+     (lambda (files) (let ((enable-recursive-minibuffers  t))
+                       (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+  (progn                                ; First code
+    (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (unless (require 'etags nil t) (error "`etags.el' is required"))
+    (icicle-bind-file-candidate-keys))
+  nil                                   ; Undo code
+  (icicle-unbind-file-candidate-keys))  ; Last code
+
+(defun icicle-make-file+date-candidate (file)
+  "Return a multi-completion candidate: FILE + last modification date."
+  (list (list file (format-time-string "%Y %m %d %T " (nth 5 (file-attributes file))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-cmd1)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-cmd1.el ends here
diff --git a/auto-install/icicles-cmd2.el b/auto-install/icicles-cmd2.el
new file mode 100644
index 0000000..62f5e9e
--- /dev/null
+++ b/auto-install/icicles-cmd2.el
@@ -0,0 +1,7753 @@
+;;; icicles-cmd2.el --- Top-level commands for Icicles
+;;
+;; Filename: icicles-cmd2.el
+;; Description: Top-level commands for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Thu May 21 13:31:43 2009 (-0700)
+;; Version: 22.0
+;; Last-Updated: Fri Sep  9 13:53:30 2011 (-0700)
+;;           By: dradams
+;;     Update #: 4206
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-cmd2.el
+;; Keywords: extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos-fn+var', `avoid', `backquote', `bytecomp',
+;;   `cl', `cus-edit', `cus-face', `cus-load', `cus-start', `doremi',
+;;   `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
+;;   `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-cmd1',
+;;   `icicles-face', `icicles-fn', `icicles-mac', `icicles-mcmd',
+;;   `icicles-opt', `icicles-var', `image-dired', `kmacro',
+;;   `levenshtein', `misc-fns', `mouse3', `mwheel', `pp', `pp+',
+;;   `regexp-opt', `ring', `ring+', `strings', `thingatpt',
+;;   `thingatpt+', `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  top-level commands (and a few non-interactive functions used in
+;;  those commands).  This is a continuation of library
+;;  `icicles-cmd1.el' (a single file for all top-level commands would
+;;  be too large to upload to Emacs Wiki).
+;;
+;;  For commands to be used mainly in the minibuffer or buffer
+;;  `*Completions*', see `icicles-mcmd.el'.
+;;
+;;  For Icicles documentation, see `icicles-doc1.el' and
+;;  `icicles-doc2.el'.
+;;
+;;  If you use the byte-compiled version of this library,
+;;  `icicles-cmd2.elc', in Emacs 23, then it must be byte-compiled
+;;  using Emacs 23.  Otherwise, Icicles key completion (and perhaps
+;;  other things?) will not work correctly.
+;;
+;;  Macros defined here:
+;;
+;;    `icicle-define-search-bookmark-command',
+;;    `icicle-with-comments-hidden'.
+;;
+;;  Commands defined here - (+) means a multi-command:
+;;
+;;    (+)`a', (+)`any', (+)`buffer', (+)`file', (+)`icicle-anything',
+;;    (+)`icicle-apply', `icicle-apropos', `icicle-apropos-command',
+;;    `icicle-apropos-function', `icicle-apropos-option',
+;;    `icicle-apropos-variable', `icicle-apropos-zippy',
+;;    (+)`icicle-bookmark-a-file', (+)`icicle-choose-faces',
+;;    (+)`icicle-choose-invisible-faces',
+;;    (+)`icicle-choose-visible-faces', (+)`icicle-comint-command',
+;;    (+)`icicle-comint-search', (+)`icicle-compilation-search',
+;;    (+)`icicle-complete-keys', `icicle-complete-thesaurus-entry',
+;;    (+)`icicle-describe-option-of-type', (+)`icicle-doc',
+;;    (+)`icicle-exchange-point-and-mark',
+;;    (+)`icicle-find-file-all-tags',
+;;    (+)`icicle-find-file-all-tags-other-window',
+;;    (+)`icicle-find-file-all-tags-regexp',
+;;    (+)`icicle-find-file-all-tags-regexp-other-window',
+;;    (+)`icicle-find-file-some-tags',
+;;    (+)`icicle-find-file-some-tags-other-window',
+;;    (+)`icicle-find-file-some-tags-regexp',
+;;    (+)`icicle-find-file-some-tags-regexp-other-window',
+;;    (+)`icicle-find-file-tagged',
+;;    (+)`icicle-find-file-tagged-other-window', (+)`icicle-font',
+;;    (+)`icicle-frame-bg', (+)`icicle-frame-fg', (+)`icicle-fundoc',
+;;    (+)`icicle-goto-global-marker',
+;;    (+)`icicle-goto-global-marker-or-pop-global-mark',
+;;    (+)`icicle-goto-marker',
+;;    (+)`icicle-goto-marker-or-set-mark-command',
+;;    (+)`icicle-hide-faces', (+)`icicle-hide-only-faces',
+;;    `icicle-hide/show-comments', (+)`icicle-imenu',
+;;    (+)`icicle-imenu-command', (+)`icicle-imenu-command-full',
+;;    (+)`icicle-imenu-face-full', (+)`icicle-imenu-face-full',
+;;    (+)`icicle-imenu-full', (+)`icicle-imenu-key-explicit-map',
+;;    (+)`icicle-imenu-key-explicit-map-full',
+;;    (+)`icicle-imenu-key-implicit-map',
+;;    (+)`icicle-imenu-key-implicit-map-full',
+;;    (+)`icicle-imenu-macro', (+)`icicle-imenu-macro-full',
+;;    (+)`icicle-imenu-non-interactive-function',
+;;    (+)`icicle-imenu-non-interactive-function-full',
+;;    (+)`icicle-imenu-user-option',
+;;    (+)`icicle-imenu-user-option-full', (+)`icicle-imenu-variable',
+;;    (+)`icicle-imenu-variable-full', `icicle-ido-like-mode',
+;;    (+)`icicle-Info-goto-node', (+)`icicle-Info-index',
+;;    (+)`icicle-Info-index-20', (+)`icicle-Info-menu',
+;;    `icicle-Info-virtual-book', (+)`icicle-insert-thesaurus-entry',
+;;    (+)`icicle-keyword-list', (+)`icicle-map',
+;;    `icicle-next-visible-thing', `icicle-non-whitespace-string-p',
+;;    (+)`icicle-object-action', (+)`icicle-occur',
+;;    (+)`icicle-pick-color-by-name', (+)`icicle-plist',
+;;    `icicle-previous-visible-thing', `icicle-read-color',
+;;    `icicle-read-kbd-macro', (+)`icicle-regexp-list',
+;;    `icicle-save-string-to-variable', (+)`icicle-search',
+;;    (+)`icicle-search-all-tags-bookmark',
+;;    (+)`icicle-search-all-tags-regexp-bookmark',
+;;    (+)`icicle-search-autofile-bookmark',
+;;    (+)`icicle-search-bookmark',
+;;    (+)`icicle-search-bookmark-list-bookmark',
+;;    `icicle-search-bookmark-list-marked',
+;;    (+)`icicle-search-bookmarks-together',
+;;    (+)`icicle-search-buffer', (+)`icicle-search-buff-menu-marked',
+;;    (+)`icicle-search-char-property', (+)`icicle-search-defs',
+;;    (+)`icicle-search-defs-full',
+;;    (+)`icicle-search-desktop-bookmark',
+;;    (+)`icicle-search-dired-bookmark',
+;;    (+)`icicle-search-dired-marked', (+)`icicle-search-file',
+;;    (+)`icicle-search-file-bookmark', (+)`icicle-search-generic',
+;;    (+)`icicle-search-gnus-bookmark',
+;;    `icicle-search-highlight-cleanup',
+;;    (+)`icicle-search-ibuffer-marked',
+;;    (+)`icicle-search-info-bookmark', (+)`icicle-search-keywords',
+;;    (+)`icicle-search-lines',
+;;    (+)`icicle-search-local-file-bookmark',
+;;    (+)`icicle-search-man-bookmark',
+;;    (+)`icicle-search-non-file-bookmark',
+;;    (+)`icicle-search-overlay-property',
+;;    (+)`icicle-search-paragraphs', (+)`icicle-search-pages',
+;;    (+)`icicle-search-region-bookmark',
+;;    (+)`icicle-search-remote-file-bookmark',
+;;    (+)`icicle-search-sentences',
+;;    (+)`icicle-search-some-tags-bookmark',
+;;    (+)`icicle-search-some-tags-regexp-bookmark',
+;;    (+)`icicle-search-specific-buffers-bookmark',
+;;    (+)`icicle-search-specific-files-bookmark',
+;;    (+)`icicle-search-text-property', (+)`icicle-search-thing',
+;;    (+)`icicle-search-this-buffer-bookmark',
+;;    (+)`icicle-search-url-bookmark',
+;;    `icicle-search-w-isearch-string',
+;;    (+)`icicle-search-w3m-bookmark', (+)`icicle-search-word',
+;;    (+)`icicle-search-xml-element',
+;;    (+)`icicle-search-xml-element-text-node',
+;;    (+)`icicle-select-frame', `icicle-select-frame-by-name',
+;;    `icicle-set-S-TAB-methods-for-command',
+;;    `icicle-set-TAB-methods-for-command', (+)`icicle-show-faces',
+;;    (+)`icicle-show-only-faces', (+)`icicle-synonyms',
+;;    (+)`icicle-tag-a-file', (+)`icicle-tags-search',
+;;    (+)`icicle-untag-a-file', (+)`icicle-vardoc',
+;;    (+)`icicle-where-is', (+)`synonyms', (+)`what-which-how'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `icicle-add-key+cmd', `icicle-anything-candidate-value',
+;;    `icicle-apply-action', `icicle-apply-list-action',
+;;    `icicle-char-properties-in-buffer',
+;;    `icicle-char-properties-in-buffers',
+;;    `icicle-choose-anything-candidate',
+;;    `icicle-choose-candidate-of-type', `icicle-color-blue-lessp',
+;;    `icicle-color-completion-setup',
+;;    `icicle-color-distance-hsv-lessp',
+;;    `icicle-color-distance-rgb-lessp', `icicle-color-green-lessp',
+;;    `icicle-color-help', `icicle-color-hsv-lessp',
+;;    `icicle-color-hue-lessp', `icicle-color-red-lessp',
+;;    `icicle-color-saturation-lessp', `icicle-color-value-lessp',
+;;    `icicle-comint-hook-fn',
+;;    `icicle-comint-search-get-final-choice',
+;;    `icicle-comint-search-get-minibuffer-input',
+;;    `icicle-comint-search-send-input', `icicle-compilation-hook-fn',
+;;    `icicle-compilation-search-in-context-fn',
+;;    `icicle-complete-keys-1', `icicle-complete-keys-action',
+;;    `icicle-defined-thing-p', `icicle-describe-opt-action',
+;;    `icicle-describe-opt-of-type-complete', `icicle-doc-action',
+;;    `icicle-edmacro-parse-keys', `icicle-flat-list',
+;;    `icicle-fn-doc-minus-sig', `icicle-font-w-orig-size',
+;;    `icicle-get-anything-actions-for-type',
+;;    `icicle-get-anything-cached-candidates',
+;;    `icicle-get-anything-candidates',
+;;    `icicle-get-anything-candidates-of-type',
+;;    `icicle-get-anything-default-actions-for-type',
+;;    `icicle-get-anything-input-delay',
+;;    `icicle-get-anything-req-pat-chars',
+;;    `icicle-get-anything-types', `icicle-goto-marker-1',
+;;    `icicle-goto-marker-1-action', `icicle-group-regexp',
+;;    `icicle-imenu-command-p', `icicle-imenu-in-buffer-p',
+;;    `icicle-imenu-non-interactive-function-p',
+;;    `icicle-Info-book-order-p',
+;;    `icicle-Info-build-node-completions',
+;;    `icicle-Info-build-node-completions-1',
+;;    `icicle-Info-goto-node-1', `icicle-Info-goto-node-action',
+;;    `icicle-Info-index-action', `icicle-Info-read-node-name',
+;;    `icicle-insert-thesaurus-entry-cand-fn',
+;;    `icicle-invisible-face-p', `icicle-invisible-p',
+;;    `icicle-keys+cmds-w-prefix', `icicle-make-color-candidate',
+;;    `icicle-marker+text', `icicle-markers',
+;;    `icicle-next-single-char-property-change',
+;;    `icicle-next-visible-thing-1', `icicle-next-visible-thing-2',
+;;    `icicle-next-visible-thing-and-bounds',
+;;    `icicle-pick-color-by-name-action',
+;;    `icicle-previous-single-char-property-change',
+;;    `icicle-read-args-for-set-completion-methods',
+;;    `icicle-read-single-key-description',
+;;    `icicle-read-var-value-satisfying',
+;;    `icicle-region-or-buffer-limits', `icicle-search-action',
+;;    `icicle-search-action-1', `icicle-search-bookmark-action',
+;;    `icicle-search-char-property-scan',
+;;    `icicle-search-choose-buffers', `icicle-search-cleanup',
+;;    `icicle-search-define-candidates',
+;;    `icicle-search-define-candidates-1', `icicle-search-final-act',
+;;    `icicle-search-help',
+;;    `icicle-search-highlight-all-input-matches',
+;;    `icicle-search-highlight-and-maybe-replace',
+;;    `icicle-search-highlight-input-matches-here',
+;;    `icicle-search-in-context-default-fn',
+;;    `icicle-search-property-args', `icicle-search-quit-or-error',
+;;    `icicle-search-read-context-regexp', `icicle-search-read-word',
+;;    `icicle-search-regexp-scan',
+;;    `icicle-search-replace-all-search-hits',
+;;    `icicle-search-replace-cand-in-alist',
+;;    `icicle-search-replace-cand-in-mct',
+;;    `icicle-search-replace-fixed-case-p',
+;;    `icicle-search-replace-match',
+;;    `icicle-search-replace-search-hit', `icicle-search-thing-args',
+;;    `icicle-search-thing-scan', `icicle-search-where-arg',
+;;    `icicle-set-completion-methods-for-command',
+;;    `icicle-things-alist', `icicle-this-command-keys-prefix'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `icicle-active-map', `icicle-info-buff', `icicle-info-window',
+;;    `icicle-key-prefix', `icicle-key-prefix-2',
+;;    `icicle-last-thing-type', `icicle-named-colors',
+;;    `icicle-orig-buff-key-complete', `icicle-orig-extra-cands',
+;;    `icicle-orig-font', `icicle-orig-frame', `icicle-orig-menu-bar',
+;;    `icicle-orig-pixelsize', `icicle-orig-pointsize',
+;;    `icicle-orig-show-initially-flag',
+;;    `icicle-orig-sort-orders-alist', `icicle-orig-win-key-complete',
+;;    `icicle-this-cmd-keys'.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `cus-edit.el' have
+;;              been REDEFINED HERE:
+;;
+;;  `customize-face', `customize-face-other-window' - Multi-commands.
+;;
+;;
+;;  Key bindings made by Icicles: See "Key Bindings" in
+;;  `icicles-doc2.el'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Icicles Top-Level Commands, Part 2")
+;;    (@> "Icicles Commands for Other Packages")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;; case, loop
+                                  ;; plus, for Emacs < 21: dolist, push
+(eval-when-compile (when (>= emacs-major-version 22) (require 'edmacro))) ;; edmacro-subseq
+(eval-when-compile (require 'comint))
+  ;; comint-check-proc, comint-copy-old-input, comint-get-old-input, comint-input-ring,
+  ;; comint-prompt-regexp, comint-send-input
+(eval-when-compile (require 'imenu)) ;; imenu-syntax-alist
+(eval-when-compile (require 'compile)) ;; compilation-find-buffer
+(eval-when-compile (require 'info)) ;; Info-goto-node
+(eval-when-compile (require 'etags)) ;; tags-case-fold-search, tags-table-files,
+                                     ;; visit-tags-table-buffer
+(eval-when-compile (when (> emacs-major-version 21)
+                     (require 'anything nil t))) ;; (no error if not found):
+  ;; anything-candidate-cache, anything-get-sources, anything-idle-delay, anything-pattern,
+  ;; anything-sources, anything-transform-candidates
+(eval-when-compile (require 'yow nil t)) ;; (no error if not found):
+  ;; apropos-zippy, yow-after-load-message, yow-file, yow-load-message
+(eval-when-compile (require 'cookie1 nil t)) ;; (no error if not found): cookie-cache
+(require 'apropos-fn+var nil t) ;; (no error if not found):
+  ;; apropos-command, apropos-function, apropos-option, apropos-variable
+(require 'strings nil t) ;; (no error if not found): read-number (my version)
+(eval-when-compile (require 'bookmark+ nil t)) ;; (no error if not found):
+  ;; bmkp-bmenu-barf-if-not-in-menu-list, bmkp-bmenu-get-marked-files, bmkp-bookmark-last-access-cp,
+  ;; bmkp-buffer-last-access-cp, bmkp-describe-bookmark, bmkp-describe-bookmark-internals,
+  ;; bmkp-file-alpha-cp, bmkp-get-buffer-name, bmkp-get-end-position, bmkp-get-tags, bmkp-gnus-cp,
+  ;; bmkp-handler-cp, bmkp-info-cp, bmkp-local-file-accessed-more-recently-cp,
+  ;; bmkp-local-file-size-cp, bmkp-local-file-type-cp, bmkp-local-file-updated-more-recently-cp,
+  ;; bmkp-marked-cp, bmkp-non-file-filename, bmkp-read-tags-completing, bmkp-region-alist-only,
+  ;; bmkp-region-bookmark-p, bmkp-sorted-alist, bmkp-sort-omit, bmkp-url-cp, bmkp-visited-more-cp
+(eval-when-compile (require 'hexrgb nil t)) ;; (no error if not found):
+  ;; hexrgb-color-name-to-hex, hexrgb-defined-colors, hexrgb-defined-colors-alist, hexrgb-hex-to-hsv,
+  ;; hexrgb-hex-to-rgb, hexrgb-read-color, hexrgb-(red|green|blue|hue|saturation|value),
+  ;; hexrgb-rgb-hex-string-p, hexrgb-rgb-to-hsv, hexrgb-value
+(eval-when-compile (require 'highlight nil t)) ;; (no error if not found):
+  ;; hlt-act-on-any-face-flag, hlt-hide-default-face, hlt-highlight-faces-in-buffer,
+  ;; hlt-region-or-buffer-limits, hlt-show-default-face
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "icicles-mac")   ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'icicles-mac)))           ; Require, so can load separately if not on `load-path'.
+  ;; icicle-bind-file-candidate-keys, icicle-define-command, icicle-define-file-command,
+  ;; icicle-file-bindings, icicle-maybe-byte-compile-after-load, icicle-unbind-file-candidate-keys
+(require 'icicles-mcmd)
+  ;; icicle-search-define-replacement
+(require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
+  ;; icicle-alternative-sort-comparer, icicle-buffer-extras, icicle-buffer-ignore-space-prefix-flag,
+  ;; icicle-buffer-match-regexp, icicle-buffer-no-match-regexp, icicle-buffer-predicate,
+  ;; icicle-buffer-require-match-flag, icicle-buffer-sort, icicle-complete-keys-self-insert-ranges,
+  ;; icicle-ignore-space-prefix-flag, icicle-key-descriptions-use-<>-flag, icicle-recenter,
+  ;; icicle-require-match-flag, icicle-saved-completion-sets,
+  ;; icicle-search-cleanup-flag, icicle-search-highlight-all-current-flag,
+  ;; icicle-search-highlight-threshold, icicle-search-hook, icicle-sort-comparer,
+  ;; icicle-transform-function
+(require 'icicles-var)                  ; (This is required anyway by `icicles-fn.el'.)
+  ;; icicle-candidate-action-fn, icicle-candidate-entry-fn, icicle-candidate-nb,
+  ;; icicle-candidates-alist, icicle-char-property-value-history, icicle-complete-keys-alist,
+  ;; icicle-completion-candidates, icicle-current-input, icicle-extra-candidates,
+  ;; icicle-get-alist-candidate-function, icicle-must-match-regexp, icicle-must-not-match-regexp,
+  ;; icicle-must-pass-predicate, icicle-saved-completion-candidates, icicle-search-command,
+  ;; icicle-search-current-overlay, icicle-search-final-choice, icicle-search-overlays,
+  ;; icicle-search-refined-overlays
+(require 'icicles-fn)                   ; (This is required anyway by `icicles-mcmd.el'.)
+  ;; icicle-candidate-short-help, icicle-completing-read-history,
+  ;; icicle-highlight-lighter, icicle-insert-cand-in-minibuffer, icicle-kill-a-buffer
+(require 'icicles-cmd1)
+  ;; custom-variable-p, icicle-bookmark-cleanup,
+  ;; icicle-bookmark-cleanup-on-quit, icicle-bookmark-cmd, icicle-bookmark-help-string,
+  ;; icicle-bookmark-history, icicle-bookmark-propertize-candidate, icicle-buffer-list,
+  ;; icicle-explore, icicle-face-list, icicle-file-list, icicle-make-frame-alist,
+  ;; icicle-select-bookmarked-region
+
+
+
+;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
+;; These are probably benign - ignore them.  Icicles is designed to work with multiple
+;; versions of Emacs, and that fact provokes compiler warnings.  If you get byte-compiler
+;; errors (not warnings), then please report a bug, using `M-x icicle-send-bug-report'.
+
+;;; Some defvars to quiet byte-compiler a bit:
+
+(defvar anything-sources)               ; In `anything.el'
+(defvar anything-candidate-cache)       ; In `anything.el'
+(defvar anything-idle-delay)            ; In `anything.el'
+(defvar apropos-do-all)                 ; In `apropos.el'
+(defvar bmkp-non-file-filename)         ; In `bookmark+-1.el'
+(defvar bmkp-sorted-alist)              ; In `bookmark+-1.el'
+(defvar hlt-act-on-any-face-flag)       ; In `highlight.el'
+(defvar icicle-complete-keys-self-insert-ranges) ; In `icicles-var.el' (Emacs 22+)
+(defvar icicle-search-ecm)              ; In `icicle-search'
+(defvar icicle-track-pt)                ; In `icicle-insert-thesaurus-entry'
+(defvar replace-count)                  ; In `replace.el'.
+
+;; (< emacs-major-version 21)
+(defvar tooltip-mode)                   ; In `tooltip.el'
+
+;; (< emacs-major-version 22)
+(defvar compilation-current-error)
+(defvar cookie-cache)
+(defvar Info-menu-entry-name-re)        ; In `info.el'
+(defvar Info-read-node-completion-table) ; In `info.el'
+(defvar palette-current-color)          ; In `palette.el'
+(defvar palette-last-color)             ; In `palette.el'
+(defvar palette-mode-map)               ; In `palette.el'
+(defvar palette-popup-map)              ; In `palette.el'
+(defvar read-file-name-completion-ignore-case) ; In `minibuffer.el'
+(defvar synonyms-obarray)               ; In `synonyms.el'
+(defvar tags-case-fold-search)          ; In `etags.el'
+(defvar yow-after-load-message)
+(defvar yow-file)
+(defvar yow-load-message)
+
+;; (> emacs-major-version 21)
+(defvar Info-saved-nodes)               ; In `info+.el'
+
+;; (< emacs-major-version 23)
+(defvar read-buffer-completion-ignore-case)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Icicles Top-Level Commands, Part 2")
+;;; Icicles Top-Level Commands, Part 2 .   .   .   .   .   .   .   .   .
+
+
+(defvar icicle-orig-font nil
+  "Font of selected frame, before command.")
+
+(defvar icicle-orig-frame nil
+  "Selected frame, before command.")
+
+(defvar icicle-orig-menu-bar nil
+  "`menu-bar-lines' of selected frame, before command.")
+
+(defvar icicle-orig-pixelsize nil
+  "Size of font of selected frame in pixels, before command.")
+
+(defvar icicle-orig-pointsize nil
+  "Size of font of selected frame in points, before command.")
+
+;;;###autoload (autoload 'icicle-font "icicles-cmd2.el")
+(icicle-define-command icicle-font      ; Command name
+  "Change font of current frame."       ; Doc string
+  (lambda (font) (modify-frame-parameters icicle-orig-frame (list (cons 'font font)))) ; Action fn
+  "Font: "                              ; `completing-read' args
+  (let ((fonts  ())
+        fws)
+    (dolist (ft  (x-list-fonts "*")  fonts) ; Just avoiding two traversals, one to remove nil elts.
+      (when (setq fws  (icicle-font-w-orig-size ft)) (push fws fonts)))) ; Ignore nil entries.
+  nil t nil (if (boundp 'font-name-history) 'font-name-history 'icicle-font-name-history) nil nil
+  ((icicle-orig-frame      (selected-frame)) ; Bindings
+   (icicle-orig-font       (frame-parameter nil 'font))
+   (icicle-orig-pixelsize  (aref (x-decompose-font-name icicle-orig-font)
+                                 xlfd-regexp-pixelsize-subnum))
+   (icicle-orig-pointsize  (aref (x-decompose-font-name icicle-orig-font)
+                                 xlfd-regexp-pointsize-subnum))
+   (icicle-orig-menu-bar   (assq 'menu-bar-lines (frame-parameters icicle-orig-frame))))
+  ;; First code - remove menu-bar, to avoid Emacs bug that resizes frame.
+  (modify-frame-parameters icicle-orig-frame (list '(menu-bar-lines . 0)))
+  (modify-frame-parameters icicle-orig-frame ; Undo code.
+                           (list (cons 'font icicle-orig-font) icicle-orig-menu-bar))
+  (modify-frame-parameters icicle-orig-frame (list icicle-orig-menu-bar))) ; Last code.
+
+;; Free var here: `icicle-orig-pixelsize' is bound in `icicle-font'.
+(defun icicle-font-w-orig-size (font)
+  "Return a font like FONT, but with pixel size `icicle-orig-pixelsize'.
+Return nil if `x-decompose-font-name' returns nil for FONT.
+`icicle-orig-pixelsize' is the original pixel size for `icicle-font'."
+  (let ((xlfd-fields  (x-decompose-font-name font)))
+    (if (not xlfd-fields)               ; Can't handle such font names - return nil.
+        nil
+      (aset xlfd-fields xlfd-regexp-pixelsize-subnum icicle-orig-pixelsize)
+      (aset xlfd-fields xlfd-regexp-pointsize-subnum icicle-orig-pointsize)
+      (let* ((sized-font   (x-compose-font-name xlfd-fields))
+             (font-info    (and (or (> icicle-help-in-mode-line-delay 0) ; Only if user will see it.
+                                    (and (boundp 'tooltip-mode) tooltip-mode))
+                                (font-info sized-font)))
+             (iii          (if (< emacs-major-version 21) 3 2))
+             (help-string  (if font-info
+                               (format "width: %s, height: %s, offset: %s, compose: %s"
+                                       (aref font-info iii) (aref font-info (+ iii 1))
+                                       (aref font-info (+ iii 2)) (aref font-info (+ iii 3)))
+                             "Font is not yet loaded (used)")))
+        (icicle-candidate-short-help help-string sized-font)
+        (list sized-font)))))
+
+(defvar icicle-named-colors ()
+  "Named colors.")
+
+;;;###autoload (autoload 'icicle-frame-bg "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-frame-fg "icicles-cmd2.el")
+(eval-after-load "hexrgb"
+  '(progn
+
+    (when (and (fboundp 'read-color) (not (fboundp 'old-read-color))) ; Exists starting with Emacs 23.
+      (defalias 'old-read-color (symbol-function 'read-color))) ; Not used, but save it anyway.
+
+    ;; See also `hexrgb-read-color' in `hexrgb.el'.
+    (defun icicle-read-color (&optional arg prompt)
+      "Read a color name or hex RGB color value #RRRRGGGGBBBB.
+A string value is returned.
+Interactively, optional argument ARG is the prefix arg.
+Optional argument PROMPT is the prompt to use (default \"Color: \").
+
+In addition to standard color names and RGB (red, green, blue) hex
+values, the following are also available as proxy color candidates,
+provided `icicle-add-proxy-candidates-flag' is non-nil and library
+`palette.el' or `eyedropper.el' is used.  In each case, the
+corresponding color is used.
+
+* `*copied foreground*'  - last copied foreground, if available
+* `*copied background*'  - last copied background, if available
+* `*mouse-2 foreground*' - foreground where you click `mouse-2'
+* `*mouse-2 background*' - background where you click `mouse-2'
+* `*point foreground*'   - foreground under the text cursor
+* `*point background*'   - background under the text cursor
+
+\(You can copy a color using eyedropper commands such as
+`eyedrop-pick-foreground-at-mouse'.)
+
+In addition, the names of user options (variables) whose custom type
+is `color' are also proxy candidates, but with `'' as a prefix and
+suffix.  So, for example, option `icicle-region-background' appears as
+proxy color candidate `'icicle-region-background''.
+
+As always, you can toggle the use of proxy candidates using `\\\
+\\[icicle-toggle-proxy-candidates]' in
+the minibuffer.
+
+With plain `C-u', use `hexrgb-read-color', which lets you complete a
+color name or input any valid RGB hex value (without completion).
+
+With no prefix arg, return a string with both the color name and the
+RGB value, separated by `icicle-list-nth-parts-join-string'.
+
+With a numeric prefix arg of 0 or 1, return the color name.  With any
+other numeric prefix arg, return the RGB value.
+
+In the plain `C-u' case, your input is checked to ensure that it
+represents a valid color.
+
+In all other cases:
+
+- You can complete your input against the color name, the RGB value,
+  or both.
+
+- If you enter input without completing or cycling, the input is not
+  checked: whatever is entered is returned as the string value.
+
+From Emacs Lisp, ARG controls what is returned.  If ARG is nil,
+`icicle-list-use-nth-parts' can also be used to control the behavior.
+
+Note: Duplicate color names are removed by downcasing and removing
+whitespace.  For example, \"AliceBlue\" and \"alice blue\" are both
+treated as \"aliceblue\".  Otherwise, candidates with different names
+but the same RGB values are not considered duplicates, so, for
+example, input can match either \"darkred\" or \"red4\", which both
+have RGB #8b8b00000000.  You can toggle duplicate removal at any time
+using `C-$'.
+
+During completion, candidate help (e.g. `C-M-RET') shows you the RGB
+and HSV (hue, saturation, value) color components.
+
+This command is intended only for use in Icicle mode (but it can be
+used with `C-u', with Icicle mode turned off)."
+      (interactive "P")
+      (unless (featurep 'hexrgb) (error "`icicle-read-color' requires library `hexrgb.el'"))
+      (let (color)
+        (if (consp arg)                 ; Plain `C-u': complete against color name only,
+            (setq color  (hexrgb-read-color t)) ; and be able to input any valid RGB string.
+
+          ;; Complete against name+RGB pairs, but user can enter invalid value without completing.
+          (let ((icicle-list-use-nth-parts
+                 (or (and arg (if (< arg 2) '(1) '(2))) ; 1 or 2, by program or via `C-1' or `C-2'.
+                     icicle-list-use-nth-parts ; Bound externally by program.
+                     '(1 2)))           ; Both parts, by default.
+                (mouse-pseudo-color-p  nil)
+
+                icicle-candidate-help-fn           completion-ignore-case
+                icicle-transform-function          icicle-sort-orders-alist
+                icicle-list-nth-parts-join-string  icicle-list-join-string
+                ;; $$$$$$ icicle-list-end-string
+                icicle-proxy-candidate-regexp      icicle-named-colors
+                icicle-proxy-candidates)
+            ;; Copy the prompt string because `icicle-color-completion-setup' puts a text prop on it.
+            ;; Use `icicle-prompt' from now on, since that's what `icicle-color-completion-setup'
+            ;; sets up.
+            (setq icicle-prompt  (copy-sequence (or prompt "Color: ")))
+            (icicle-color-completion-setup)
+            (setq icicle-proxy-candidates
+                  (append icicle-proxy-candidates
+                          (mapcar       ; Convert multi-completions to strings.
+                           ;; $$$$$$ #'(lambda (entry)
+                           ;;           (concat (mapconcat #'identity (car entry)
+                           ;;                              icicle-list-join-string)
+                           ;;                   icicle-list-end-string)) ; $$$$$$
+                           #'(lambda (entry) (mapconcat #'identity (car entry)
+                                                        icicle-list-join-string))
+                           '((("*mouse-2 foreground*")) (("*mouse-2 background*")))))
+                  color  (icicle-transform-multi-completion
+                          (let ((icicle-orig-window  (selected-window))
+                                (icicle-candidate-alt-action-fn
+                                 (or icicle-candidate-alt-action-fn
+                                     (icicle-alt-act-fn-for-type "color")))
+                                (icicle-all-candidates-list-alt-action-fn
+                                 (or icicle-all-candidates-list-alt-action-fn
+                                     (icicle-alt-act-fn-for-type "color"))))
+                            (completing-read icicle-prompt icicle-named-colors))))
+            (when (fboundp 'eyedrop-foreground-at-point)
+              (cond ((string-match "^\*mouse-2 foreground\*" color)
+                     (setq color  (prog1 (eyedrop-foreground-at-mouse
+                                          (read-event
+                                           "Click `mouse-2' anywhere to choose foreground color"))
+                                    (read-event)) ; Discard mouse up event.
+                           mouse-pseudo-color-p  t))
+                    ((string-match "^\*mouse-2 background\*" color)
+                     (setq color  (prog1 (eyedrop-background-at-mouse
+                                          (read-event
+                                           "Click `mouse-2' anywhere to choose background color"))
+                                    (read-event)) ; Discard mouse up event.
+                           mouse-pseudo-color-p  t))))
+            (when mouse-pseudo-color-p
+              (let ((icicle-list-nth-parts-join-string  ": ")
+                    (icicle-list-join-string            ": ")
+                    ;; $$$$$$ (icicle-list-end-string             "")
+                    (icicle-list-use-nth-parts
+                     (or (and arg
+                              (if (< arg 2) '(1) '(2))) ; 1 or 2, by program or via `C-1' or `C-2'.
+                         icicle-list-use-nth-parts ; Bound externally by program.
+                         '(1 2))))      ; Both parts, by default.
+                (setq color  (icicle-transform-multi-completion
+                              (concat color ": " (hexrgb-color-name-to-hex color))))))))
+        (when (interactive-p) (message "Color: `%s'" color))
+        color))
+
+    (icicle-maybe-byte-compile-after-load icicle-read-color)
+
+
+    (icicle-define-command icicle-frame-bg ; Command name
+      "Change background of current frame.
+Read color name or hex RGB color value #RRRRGGGGBBBB with completion.
+In addition to standard color names and RGB (red, green, blue) hex
+values, the following are also available as proxy color candidates,
+provided `icicle-add-proxy-candidates-flag' is non-nil and library
+`palette.el' or `eyedropper.el' is used.  In each case, the
+corresponding color is used.
+
+* `*copied foreground*'  - last copied foreground, if available
+* `*copied background*'  - last copied background, if available
+* `*point foreground*'   - foreground under the text cursor
+* `*point background*'   - background under the text cursor
+
+\(You can copy a color using eyedropper commands such as
+`eyedrop-pick-foreground-at-mouse'.)
+
+In addition, the names of user options (variables) whose custom type
+is `color' are also proxy candidates, but with `'' as a prefix and
+suffix.  So, for example, option `icicle-region-background' appears as
+proxy color candidate `'icicle-region-background''.
+
+As always, you can toggle the use of proxy candidates using `\\\
+\\[icicle-toggle-proxy-candidates]' in
+the minibuffer.
+
+You can complete your input against the color name, the RGB value, or
+both.
+
+Note: Duplicate color names are removed by downcasing and removing
+whitespace.  For example, \"AliceBlue\" and \"alice blue\" are both
+treated as \"aliceblue\".  Otherwise, candidates with different names
+but the same RGB values are not considered duplicates, so, for
+example, input can match either \"darkred\" or \"red4\", which both
+have RGB #8b8b00000000.  You can toggle duplicate removal at any time
+using `C-$'.
+
+During completion, candidate help (e.g. `C-M-RET') shows you the RGB
+and HSV (hue, saturation, value) color components.
+
+This command is intended only for use in Icicle mode." ; Doc string
+      (lambda (color)                   ; Action function
+        (modify-frame-parameters
+         icicle-orig-frame (list (cons 'background-color (icicle-transform-multi-completion color)))))
+      icicle-prompt icicle-named-colors nil t nil ; `completing-read' args
+      (if (boundp 'color-history) 'color-history 'icicle-color-history) nil nil
+      ((icicle-orig-frame                  (selected-frame)) ; Bindings
+       (orig-bg                            (frame-parameter nil 'background-color))
+       (icicle-prompt                      "Background color: ")
+       (icicle-list-use-nth-parts          '(2)) ; Use RGB part.
+       (icicle-candidate-alt-action-fn
+        (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "color")))
+       (icicle-all-candidates-list-alt-action-fn
+        (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "color")))
+
+       icicle-candidate-help-fn     completion-ignore-case             icicle-transform-function
+       icicle-sort-orders-alist     icicle-list-nth-parts-join-string  icicle-list-join-string
+       ;; $$$$$$ icicle-list-end-string
+       icicle-proxy-candidate-regexp      icicle-named-colors          icicle-proxy-candidates)
+      (icicle-color-completion-setup)   ; First code - needs `hexrgb.el'
+      (modify-frame-parameters icicle-orig-frame (list (cons 'background-color orig-bg))) ; Undo code
+      nil)                              ; Last code
+
+    (icicle-maybe-byte-compile-after-load icicle-frame-bg)
+
+
+    (icicle-define-command icicle-frame-fg ; Command name
+      "Change foreground of current frame.
+See `icicle-frame-bg' - but this is for foreground, not background." ; Doc string
+      (lambda (color)                   ; Action function
+        (modify-frame-parameters
+         icicle-orig-frame (list (cons 'foreground-color (icicle-transform-multi-completion color)))))
+      icicle-prompt icicle-named-colors nil t nil ; `completing-read' args
+      (if (boundp 'color-history) 'color-history 'icicle-color-history) nil nil
+      ((icicle-orig-frame                  (selected-frame)) ; Bindings
+       (orig-bg                            (frame-parameter nil 'foreground-color))
+       (icicle-prompt                      "Foreground color: ")
+       (icicle-list-use-nth-parts          '(2)) ; Use RGB part.
+       (icicle-candidate-alt-action-fn
+        (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "color")))
+       (icicle-all-candidates-list-alt-action-fn
+        (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "color")))
+
+       icicle-candidate-help-fn     completion-ignore-case             icicle-transform-function
+       icicle-sort-orders-alist     icicle-list-nth-parts-join-string  icicle-list-join-string
+       ;; $$$$$$ icicle-list-end-string
+       icicle-proxy-candidate-regexp      icicle-named-colors          icicle-proxy-candidates)
+      (icicle-color-completion-setup)   ; First code - needs `hexrgb.el'
+      (modify-frame-parameters icicle-orig-frame (list (cons 'foreground-color orig-bg))) ; Undo code
+      nil)                              ; Last code
+
+    (icicle-maybe-byte-compile-after-load icicle-frame-fg)
+
+
+    ;; Free vars here:
+    ;; `icicle-prompt', `icicle-candidate-help-fn', `completion-ignore-case',
+    ;; `icicle-transform-function', `icicle-sort-orders-alist', `icicle-list-nth-parts-join-string',
+    ;; `icicle-list-join-string', `icicle-proxy-candidate-regexp', `icicle-named-colors',
+    ;; `icicle-proxy-candidates'.
+    (defun icicle-color-completion-setup ()
+      "Set up for color-name/RGB-value completion (helper function).
+Sets these variables, which are assumed to be already `let'-bound:
+  `icicle-prompt'
+  `icicle-candidate-help-fn'
+  `completion-ignore-case'
+  `icicle-transform-function'
+  `icicle-sort-orders-alist'
+  `icicle-list-nth-parts-join-string'
+  `icicle-list-join-string'
+  `icicle-proxy-candidate-regexp'
+  `icicle-named-colors'
+  `icicle-proxy-candidates'
+Puts property `icicle-fancy-candidates' on string `icicle-prompt'."
+      (if (< emacs-major-version 22)
+          (require 'eyedropper nil t)
+        (or (require 'palette nil t) (require 'eyedropper nil t)))
+      (put-text-property 0 1 'icicle-fancy-candidates t icicle-prompt)
+      (icicle-highlight-lighter)
+      (setq icicle-candidate-help-fn           'icicle-color-help
+            completion-ignore-case             t
+            icicle-sort-orders-alist
+            '(("by color name" . icicle-part-1-lessp)
+              ("by color hue"  . (lambda (s1 s2) (not (icicle-color-hue-lessp s1 s2))))
+              ("by color purity (saturation)"
+               . (lambda (s1 s2) (not (icicle-color-saturation-lessp s1 s2))))
+              ("by color brightness (value)"
+               . (lambda (s1 s2) (not (icicle-color-value-lessp s1 s2))))
+              ("by color hsv"       . (lambda (s1 s2) (not (icicle-color-hsv-lessp s1 s2))))
+              ("by hsv distance"    . (lambda (s1 s2) (icicle-color-distance-hsv-lessp s1 s2)))
+              ("by amount of red"   . (lambda (s1 s2) (not (icicle-color-red-lessp s1 s2))))
+              ("by amount of green" . (lambda (s1 s2) (not (icicle-color-green-lessp s1 s2))))
+              ("by amount of blue"  . (lambda (s1 s2) (not (icicle-color-blue-lessp s1 s2))))
+              ("by color rgb"       . (lambda (s1 s2) (not (icicle-color-rgb-lessp s1 s2))))
+              ("by rgb distance"    . (lambda (s1 s2) (icicle-color-distance-rgb-lessp s1 s2)))
+              ("turned OFF"))
+            ;; Make the two `*-join-string' variables the same, so past inputs are recognized.
+            ;; Do not use " " as the value, because color names such as "white smoke" would be
+            ;; split, and "smoke" would not be recognized as a color name when trying to list
+            ;; candidates in `*Completions*'.
+            icicle-list-nth-parts-join-string  ": "
+            icicle-list-join-string            ": "
+            ;; $$$$$$ icicle-list-end-string             ""
+            icicle-proxy-candidate-regexp      "^[*'].+[*']"
+
+            icicle-named-colors                (mapcar #'icicle-make-color-candidate
+                                                       (hexrgb-defined-colors))
+            icicle-proxy-candidates
+            (mapcar                     ; Convert multi-completions to strings.
+             (lambda (entry)
+               ;; $$$$$$ (concat (mapconcat #'identity (car entry) icicle-list-join-string)
+               ;;                icicle-list-end-string) ; $$$$$$
+               (mapconcat #'identity (car entry) icicle-list-join-string))
+             (append
+              (and (fboundp 'eyedrop-foreground-at-point)
+                   (append
+                    (and eyedrop-picked-foreground ; Multi-completions.
+                         `(,(icicle-make-color-candidate
+                             "*copied foreground*" (downcase (hexrgb-color-name-to-hex
+                                                              eyedrop-picked-foreground)))))
+                    (and eyedrop-picked-background
+                         `(,(icicle-make-color-candidate
+                             "*copied background*" (downcase (hexrgb-color-name-to-hex
+                                                              eyedrop-picked-background)))))
+                    `(,(icicle-make-color-candidate
+                        "*point foreground*" (downcase (hexrgb-color-name-to-hex
+                                                        (eyedrop-foreground-at-point))))
+                      ,(icicle-make-color-candidate
+                        "*point background*" (downcase (hexrgb-color-name-to-hex
+                                                        (eyedrop-background-at-point)))))))
+              (let ((ipc  ()))
+                (mapatoms
+                 (lambda (cand)
+                   (when (and (user-variable-p cand)
+                              (condition-case nil (icicle-var-is-of-type-p cand '(color)) (error nil))
+                              ;; This should not be necessary, but type `color' isn't
+                              ;; enforced - it just means `string' (so far).
+                              (x-color-defined-p (symbol-value cand)))
+                     (push `,(icicle-make-color-candidate
+                              (concat "'" (symbol-name cand) "'")
+                              (downcase (hexrgb-color-name-to-hex (symbol-value cand))))
+                           ipc))))
+                ipc)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-completion-setup)
+
+
+    (defun icicle-color-help (color)
+      "Display help on COLOR."
+      (let ((icicle-list-use-nth-parts  '(1 2)))
+        (with-output-to-temp-buffer "*Help*"
+          (setq icicle-list-use-nth-parts  '(2)
+                color                      (icicle-transform-multi-completion color))
+          (princ (format "Color: %s" color)) (terpri) (terpri)
+          (let* ((rgb  (hexrgb-hex-to-rgb color))
+                 (hsv  (apply #'hexrgb-rgb-to-hsv rgb)))
+            (princ "RGB:") (mapcar (lambda (component) (princ (format "  %.18f" component))) rgb)
+            (terpri) (terpri)
+            (princ "HSV:") (mapcar (lambda (component) (princ (format "  %.18f" component))) hsv)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-help)
+
+
+    (defun icicle-make-color-candidate (color-name &optional hex-rgb)
+      "Return multi-completion candidate of COLOR-NAME and its hex RGB string.
+If `icicle-WYSIWYG-Completions-flag' is non-nil, then the hex RGB
+string has the color as its background text property.
+Optional arg HEX-RGB is the hex RGB string.
+If nil, then COLOR-NAME is used to determine the hex RGB string."
+      (let* ((rgb-string  (or hex-rgb (hexrgb-color-name-to-hex color-name)))
+             (value       (hexrgb-value rgb-string)))
+        (when icicle-WYSIWYG-Completions-flag
+          (put-text-property 0 (length rgb-string) 'face
+                             (list (cons 'foreground-color (if (< value 0.6) "White" "Black"))
+                                   (cons 'background-color rgb-string))
+                             rgb-string))
+        (when (or (> icicle-help-in-mode-line-delay 0) ; Construct help only if user will see it.
+                  (and (boundp 'tooltip-mode) tooltip-mode))
+          (let* ((rgb   (hexrgb-hex-to-rgb rgb-string))
+                 (hsv   (apply #'hexrgb-rgb-to-hsv rgb))
+                 (help  (format "RGB: %.6f, %.6f, %.6f;  HSV: %.6f, %.6f, %.6f"
+                                (nth 0 rgb) (nth 1 rgb) (nth 2 rgb)
+                                (nth 0 hsv) (nth 1 hsv) (nth 2 hsv))))
+            (icicle-candidate-short-help help color-name)
+            (icicle-candidate-short-help help rgb-string)))
+        (list (list color-name rgb-string))))
+
+    (icicle-maybe-byte-compile-after-load icicle-make-color-candidate)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-red-lessp (s1 s2)
+      "Non-nil means the RGB in S1 has less red than in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-red rgb1) (hexrgb-red rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-red-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-green-lessp (s1 s2)
+      "Non-nil means the RGB in S1 has less green than in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-green rgb1) (hexrgb-green rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-green-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-blue-lessp (s1 s2)
+      "Non-nil means the RGB in S1 has less blue than in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-blue rgb1) (hexrgb-blue rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-blue-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-distance-rgb-lessp (s1 s2)
+      "Return non-nil if color S1 is RGB-closer than S2 to the base color.
+S1 and S2 are color names (strings).
+
+The base color name is the cdr of option `list-colors-sort', whose car
+must be `rgb-dist'.  If the option value is not already a cons with
+car `rgb-dist' then it is made so: you are prompted for the base color
+name to use."
+      (let* ((base-color  (if (and (boundp 'list-colors-sort) ; Emacs 23+
+                                   (consp list-colors-sort) (eq 'rgb-dist (car list-colors-sort)))
+                              (cdr list-colors-sort) ; `list-colors-sort' is free here.
+                            (cdr (setq list-colors-sort
+                                       (cons 'rgb-dist
+                                             (let ((enable-recursive-minibuffers  t)
+                                                   (icicle-sort-comparer          nil))
+                                               (icicle-read-color 0 "With RGB close to color: ")))))))
+             (base-rgb    (hexrgb-hex-to-rgb (hexrgb-color-name-to-hex base-color)))
+             (base-red    (nth 0 base-rgb))
+             (base-green  (nth 1 base-rgb))
+             (base-blue   (nth 2 base-rgb))
+             (s1-rgb      (hexrgb-hex-to-rgb (elt (split-string s1 icicle-list-join-string) 1)))
+             (s2-rgb      (hexrgb-hex-to-rgb (elt (split-string s2 icicle-list-join-string) 1))))
+        (< (+ (expt (- (nth 0 s1-rgb) base-red) 2)
+              (expt (- (nth 1 s1-rgb) base-green) 2)
+              (expt (- (nth 2 s1-rgb) base-blue) 2))
+           (+ (expt (- (nth 0 s2-rgb) base-red) 2)
+              (expt (- (nth 1 s2-rgb) base-green) 2)
+              (expt (- (nth 2 s2-rgb) base-blue) 2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-distance-rgb-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-hue-lessp (s1 s2)
+      "Non-nil means the RGB hue in S1 is less than that in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-hue rgb1) (hexrgb-hue rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-hue-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-saturation-lessp (s1 s2)
+      "Non-nil means the RGB in S1 is less saturated than in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-saturation rgb1) (hexrgb-saturation rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-saturation-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-value-lessp (s1 s2)
+      "Non-nil means the RGB value in S1 is darker than that in S2.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The RGB values are assumed to
+be the second parts of the strings, and they are assumed to start with
+`#'."
+      (let ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+            (rgb2  (elt (split-string s2 icicle-list-join-string) 1)))
+        (and rgb1 rgb2                  ; Just in case strings were not multipart.
+             (< (hexrgb-value rgb1) (hexrgb-value rgb2)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-value-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-hsv-lessp (s1 s2)
+      "Non-nil means the HSV components of S1 are less than those of S2.
+Specifically, the hues are compared first, then if hues are equal then
+saturations are compared, then if those are also equal values are
+compared.
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The second parts of the strings
+are RGB triplets that start with `#'."
+      (let* ((rgb1  (elt (split-string s1 icicle-list-join-string) 1))
+             (hsv1  (and rgb1 (hexrgb-hex-to-hsv rgb1)))
+             (rgb2  (elt (split-string s2 icicle-list-join-string) 1))
+             (hsv2  (and rgb2 (hexrgb-hex-to-hsv rgb2))))
+        (and hsv1 hsv2                  ; Just in case strings were not multipart.
+             (or (< (nth 0 hsv1) (nth 0 hsv2))
+                 (and (= (nth 0 hsv1) (nth 0 hsv2))
+                      (< (nth 1 hsv1) (nth 1 hsv2)))
+                 (and (= (nth 0 hsv1) (nth 0 hsv2))
+                      (= (nth 1 hsv1) (nth 1 hsv2))
+                      (< (nth 2 hsv1) (nth 2 hsv2)))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-color-hsv-lessp)
+
+
+    ;; This predicate is used for color completion.
+    (defun icicle-color-distance-hsv-lessp (s1 s2)
+      "Return non-nil if color S1 is HSV-closer than S2 to the base color.
+S1 and S2 are color names (strings).
+
+The base color name is the cdr of option `list-colors-sort', whose car
+must be `hsv-dist'.  If the option value is not already a cons with
+car `hsv-dist' then it is made so: you are prompted for the base color
+name to use."
+      (let* ((base-color  (if (and (boundp 'list-colors-sort) ; Emacs 23+
+                                   (consp list-colors-sort) (eq 'hsv-dist (car list-colors-sort)))
+                              (cdr list-colors-sort) ; `list-colors-sort' is free here.
+                            (cdr (setq list-colors-sort
+                                       (cons 'hsv-dist
+                                             (let ((enable-recursive-minibuffers  t)
+                                                   (icicle-sort-comparer          nil))
+                                               (icicle-read-color 0 "With HSV close to color: ")))))))
+             (base-hsv    (hexrgb-hex-to-hsv (hexrgb-color-name-to-hex base-color)))
+             (base-hue    (nth 0 base-hsv))
+             (base-sat    (nth 1 base-hsv))
+             (base-val    (nth 2 base-hsv))
+             (s1-hsv      (apply #'hexrgb-rgb-to-hsv
+                                 (hexrgb-hex-to-rgb
+                                  (elt (split-string s1 icicle-list-join-string) 1))))
+             (s2-hsv      (apply #'hexrgb-rgb-to-hsv
+                                 (hexrgb-hex-to-rgb
+                                  (elt (split-string s2 icicle-list-join-string) 1)))))
+        (< (+ (expt (- (nth 0 s1-hsv) base-hue) 2)
+              (expt (- (nth 1 s1-hsv) base-sat) 2)
+              (expt (- (nth 2 s1-hsv) base-val) 2))
+           (+ (expt (- (nth 0 s2-hsv) base-hue) 2)
+              (expt (- (nth 1 s2-hsv) base-sat) 2)
+              (expt (- (nth 2 s2-hsv) base-val) 2)))))
+    ))
+
+(defvar icicle-info-buff nil
+  "Info buffer before command was invoked.")
+
+(defvar icicle-info-window nil
+  "Info window before command was invoked.")
+
+;;;###autoload
+(defun icicle-Info-index ()
+  "Like vanilla `Info-index', but you can use multi-command keys `C-RET', `C-up' etc."
+  (interactive)
+  (when (and (boundp 'Info-current-file) (equal Info-current-file "dir"))
+    (error "The Info directory node has no index; use `m' to select a manual"))
+  (let ((icicle-info-buff            (current-buffer))
+        (icicle-info-window          (selected-window))
+        (icicle-candidate-action-fn  'icicle-Info-index-action)
+        (C-x-m                       (lookup-key minibuffer-local-completion-map "\C-xm")))
+    (when (and (require 'bookmark+ nil t) (fboundp 'icicle-bookmark-info-other-window))
+      (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-info-other-window))
+    (unwind-protect
+         (call-interactively (if (> emacs-major-version 21) 'old-Info-index 'icicle-Info-index-20))
+      (define-key minibuffer-local-completion-map "\C-xm" C-x-m))))
+
+;; Thx to Tamas Patrovics for this Emacs 20 version.
+;;;###autoload
+(defun icicle-Info-index-20 ()
+  "Like `Info-index', but you can use completion for the index topic."
+  (interactive)
+  (let* ((symb (or (and (fboundp 'symbol-nearest-point) ; Defined in `thingatpt+.el'.
+                        (symbol-nearest-point))
+                   (symbol-at-point)))
+         (topic (and symb (symbol-name symb))))
+    (old-Info-index "")
+    (let ((pattern     "\\* +\\([^:]*\\):.")
+          (candidates  ()))
+      (goto-char (point-min))
+      (while (re-search-forward pattern nil t) (push (list (match-string 1)) candidates))
+      (old-Info-index (completing-read "Index topic: " candidates nil t nil nil topic)))))
+
+;; Free vars here: `icicle-info-buff' and `icicle-info-window' are bound in `icicle-Info-index'.
+(defun icicle-Info-index-action (topic)
+  "Completion action function for `icicle-Info-index'."
+  (let ((minibuf-win  (selected-window)))
+    (set-buffer icicle-info-buff)
+    (select-window icicle-info-window)
+    (old-Info-index topic)
+    (select-window minibuf-win)))
+
+;; Free vars here: `Info-menu-entry-name-re' is bound in `info.el'.
+(icicle-define-command icicle-Info-menu
+  "Go to a menu node."                  ; Doc string
+  (lambda (m) (icicle-Info-goto-node (cdr (funcall icicle-get-alist-candidate-function m)))) ; Action
+  "Menu item: " icicle-candidates-alist ; `completing-read' args
+  nil t nil nil (save-excursion
+                  (goto-char (point-min))
+                  (unless (search-forward "\n* menu:" nil t) (error "No menu in this node"))
+                  (setq menu-eol  (point))
+                  (and (< menu-eol opoint)
+                       (save-excursion
+                         (goto-char opoint) (end-of-line)
+                         (and (re-search-backward (concat "\n\\* +\\("
+                                                          (if (boundp 'Info-menu-entry-name-re)
+                                                              Info-menu-entry-name-re
+                                                            "[^:\t\n]*")
+                                                          "\\):")
+                                                  menu-eol t)
+                              (match-string-no-properties 1)))))
+  nil
+  ((opoint                                 (point)) ; Bindings
+   (completion-ignore-case                 t)
+   (case-fold-search                       t)
+   (icicle-sort-comparer                   nil)
+   (icicle-whole-candidate-as-text-prop-p  t)
+   (Info-complete-menu-buffer              (current-buffer))
+   (icicle-candidates-alist                (mapcar #'(lambda (m) (cons m (Info-extract-menu-item m)))
+                                                   (reverse
+                                                    (all-completions "" 'Info-complete-menu-item))))
+   menu-eol))
+
+;;;###autoload
+(defun icicle-Info-goto-node (nodename &optional arg)
+  "Go to Info node named NODENAME.
+NODENAME has the form NODE or (FILE)NODE-IN-FILE, where:
+ NODE names a node in the current Info file or one of its subfiles.
+ FILE names an Info file containing node NODE-IN-FILE.
+Completion is available for node names in the current Info file.
+
+With a prefix argument:
+
+ * Plain `C-u' means prepend the current Info file name (manual name)
+   to each node name.  For example: `(emacs)Paragraphs' instead of
+   just `Paragraphs'.
+
+ * A negative numeric prefix arg (e.g. `C--') means present completion
+   candidates in book order, and limit the candidates to the current
+   node and the rest of the book following it.  In this case, the
+   first candidate is `..', which means go up.
+
+ * A negative numeric prefix arg (e.g. `C-1') means show the target
+   node in a new Info buffer (not available prior to Emacs 21).
+   (This applies only to the final completion choice, not to
+   intermediate candidate actions using, e.g., `C-RET'.)
+
+In Lisp code, if optional argument ARG is a string, then show the node
+in a new Info buffer named `*info-ARG*'.
+
+With no prefix argument, or with a non-negative prefix arg, you can
+use `C-,' to choose how to sort completion candidates.  By default,
+they are sorted alphabetically.
+
+Input-candidate completion and cycling are available.  While cycling,
+these keys with prefix `C-' are active:
+
+`C-mouse-2', `C-RET' - Go to current completion candidate (node)
+`C-down'  - Go to next completion candidate
+`C-up'    - Go to previous completion candidate
+`C-next'  - Go to next apropos-completion candidate
+`C-prior' - Go to previous apropos-completion candidate
+`C-end'   - Go to next prefix-completion candidate
+`C-home'  - Go to previous prefix-completion candidate
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
+`C-g' to quit.
+
+This is an Icicles command - see command `icicle-mode'."
+  (interactive
+   (let* ((icicle-info-buff                 (current-buffer))
+          (icicle-info-window               (selected-window))
+          (icicle-candidate-action-fn       'icicle-Info-goto-node-action)
+          (icicle-Info-only-rest-of-book-p  (< (prefix-numeric-value current-prefix-arg) 0))
+          (icicle-sort-orders-alist         (cons '("in book order" .  icicle-Info-book-order-p)
+                                                  icicle-sort-orders-alist))
+          (icicle-sort-comparer             (if icicle-Info-only-rest-of-book-p
+                                                #'icicle-Info-book-order-p
+                                              icicle-sort-comparer)))
+     (list (icicle-Info-read-node-name "Go to node: " (consp current-prefix-arg))
+           current-prefix-arg)))
+  (icicle-Info-goto-node-1 nodename arg))
+
+(defun icicle-Info-goto-node-1 (nodename &optional arg)
+  "Same as vanilla `Info-goto-node', but go up for `..' pseudo-node."
+  (if (and (string= nodename "..") (Info-check-pointer "up"))
+      (Info-up)
+    (if (> emacs-major-version 20)
+        (old-Info-goto-node nodename (and (not icicle-Info-only-rest-of-book-p) arg))
+      (old-Info-goto-node nodename))))
+
+(defun icicle-Info-read-node-name (prompt &optional include-file-p)
+  "Read a node name, prompting with PROMPT.
+Non-nil INCLUDE-FILE-P means include current Info file in the name.
+You can use `C-x m' during completion to access Info bookmarks, if you
+ use library `Bookmark+'."
+  (let ((C-x-m  (lookup-key minibuffer-local-completion-map "\C-xm")))
+    (when (and (require 'bookmark+ nil t) (fboundp 'icicle-bookmark-info-other-window))
+      (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-info-other-window))
+    (unwind-protect
+         (let* ((completion-ignore-case           t)
+                (Info-read-node-completion-table  (icicle-Info-build-node-completions include-file-p))
+                (nodename                         (completing-read prompt 'Info-read-node-name-1
+                                                                   nil nil)))
+           (if (equal nodename "") (icicle-Info-read-node-name prompt) nodename))
+      (define-key minibuffer-local-completion-map "\C-xm" C-x-m))))
+
+(defun icicle-Info-build-node-completions (&optional include-file-p)
+  "Build completions list for Info nodes.
+This takes `icicle-Info-only-rest-of-book-p' into account.
+Non-nil INCLUDE-FILE-P means include current Info file in the name."
+  (icicle-highlight-lighter)
+  (if (or (not icicle-Info-only-rest-of-book-p) (string= Info-current-node "Top"))
+      (icicle-Info-build-node-completions-1 include-file-p)
+    (reverse (cons '("..")
+                   (member (list Info-current-node)
+                           (reverse (icicle-Info-build-node-completions-1 include-file-p)))))))
+
+(defun icicle-Info-build-node-completions-1 (&optional include-file-p)
+  "Helper function for `icicle-Info-build-node-completions'.
+Use `Info-build-node-completions' to build node list for completion.
+Non-nil INCLUDE-FILE-P means include current Info file in the name.
+Remove pseudo-node `*'.  (This just fixes a bug in Emacs 21 and 22.1.)"
+  (let ((comps  (Info-build-node-completions)))
+    (when (equal (car comps) '("*")) (setq comps  (cdr comps)))
+    (if include-file-p
+        (let ((file  (concat "(" (cond ((stringp Info-current-file)
+                                        (replace-regexp-in-string
+                                         "%" "%%" (file-name-nondirectory Info-current-file)))
+                                       (Info-current-file (format "*%S*" Info-current-file))
+                                       (t ""))
+                             ")")))
+          (mapcar #'(lambda (node) (cons (concat file (car node)) (cdr node))) comps))
+      comps)))
+
+;; Free vars here:
+;; `icicle-info-buff' and `icicle-info-window' are bound in `icicle-Info-goto-node'.
+;; `Info-read-node-completion-table' is bound in `info.el'.
+(defun icicle-Info-goto-node-action (node)
+  "Completion action function for `icicle-Info-goto-node'."
+  (set-buffer icicle-info-buff)
+  (select-window icicle-info-window)
+  (icicle-Info-goto-node-1 node)
+  (when icicle-Info-only-rest-of-book-p
+    (setq Info-read-node-completion-table  (icicle-Info-build-node-completions)
+          icicle-current-input             "")
+    (icicle-complete-again-update)
+    (if (and (string= Info-current-node "Top") Info-history)
+        (let* ((hist  Info-history)
+               (last  (car (cdr (car hist)))))
+          (while (string= "Top" (car (cdr (car hist)))) (pop hist))
+          (setq icicle-candidate-nb
+                (1- (length (reverse (member (list (car (cdr (car hist))))
+                                             (icicle-Info-build-node-completions-1)))))))
+      (setq icicle-candidate-nb  1))     ; Skip `..'.
+
+    ;; $$$$$$ Maybe factor this out. Same thing in several places.  However, here we don't do
+    ;; `icicle-maybe-sort-and-strip-candidates' at beginning of first clause.
+    (cond ((and icicle-completion-candidates (cdr icicle-completion-candidates)) ; > 1 left.
+           (message "Displaying completion candidates...")
+           (save-selected-window (icicle-display-candidates-in-Completions))
+           (with-current-buffer "*Completions*"
+             (goto-char (icicle-start-of-candidates-in-Completions))
+             (icicle-move-to-next-completion
+              (mod icicle-candidate-nb (length icicle-completion-candidates)))
+             (set-window-point (get-buffer-window "*Completions*" 0) (point))
+             (setq icicle-last-completion-candidate  (icicle-current-completion-in-Completions))
+             (set-buffer-modified-p nil)))
+          (icicle-completion-candidates ; Single candidate left
+           (save-selected-window (icicle-remove-Completions-window))
+           (let ((completion  (icicle-transform-multi-completion
+                               (car icicle-completion-candidates))))
+             (select-window (active-minibuffer-window))
+             (with-current-buffer (window-buffer) ; Need if `*Completions*' redirected to minibuffer.
+               (goto-char (icicle-minibuffer-prompt-end))
+               (icicle-clear-minibuffer)
+               (insert (if (and (icicle-file-name-input-p) insert-default-directory
+                                (or (not (member completion icicle-extra-candidates))
+                                    icicle-extra-candidates-dir-insert-p))
+                           (icicle-file-name-directory-w-default icicle-current-input)
+                         "")
+                       completion))))
+          (t                            ; No candidates left
+           (select-window (active-minibuffer-window))
+           (with-current-buffer (window-buffer) ; Needed if `*Completions*' redirected to minibuffer.
+             (goto-char (icicle-minibuffer-prompt-end))
+             (icicle-clear-minibuffer)))))
+  (select-window (active-minibuffer-window)))
+
+(defun icicle-Info-book-order-p (s1 s2)
+  "Non-nil if Info node S1 comes before node S2 in the book."
+  t)        ; This just reverses the default order, which is reversed.
+
+(when (> emacs-major-version 21)
+  (defun icicle-Info-virtual-book (nodeset)
+    "Open Info on a virtual book of saved Info nodes.
+You need library `info+.el' to use this command.
+With a prefix arg, you are prompted to choose a persistent saved
+ completion set from `icicle-saved-completion-sets'.  The set you
+ choose should be a set of saved Info node names.
+With no prefix arg, use `icicle-saved-completion-candidates', which
+ should be a set of Info node names.  If that is empty, then use
+ `Info-saved-nodes'.
+Non-interactively, argument NODESET is a list of Info node names."
+    (interactive
+     (progn (unless (and (require 'info+ nil t) (fboundp 'Info-virtual-book))
+              (error "You need library `info+.el' for this command"))
+            (list (if (not current-prefix-arg)
+                      "Virtual Book"
+                    (save-selected-window
+                      (completing-read "Saved Info node set: " icicle-saved-completion-sets nil t nil
+                                       'icicle-completion-set-history))))))
+    (let ((nodes  (and (consp nodeset) nodeset))) ; (), if interactive - NODESET is a string then.
+      (when (interactive-p)
+        (if (not current-prefix-arg)
+            (setq nodes  icicle-saved-completion-candidates)
+          (let ((file-name  (cdr (assoc nodeset icicle-saved-completion-sets))))
+            (unless (icicle-file-readable-p file-name)
+              (error "Cannot read cache file `%s'" file-name))
+            (let ((list-buf  (find-file-noselect file-name 'nowarn 'raw)))
+              (unwind-protect
+                   (condition-case icicle-Info-virtual-book
+                       (when (listp (setq nodes  (read list-buf)))
+                         (message "Set `%s' read from file `%s'" nodeset file-name))
+                     (error (error "Bad cache file.  %s"
+                                   (error-message-string icicle-Info-virtual-book))))
+                (kill-buffer list-buf))
+              (unless (consp nodes) (error "Bad data in cache file `%s'" file-name))))))
+      (unless nodes (setq nodes  Info-saved-nodes)) ; In `info+.el'.
+      (unless (and nodes (stringp (car nodes))) (error "No saved Info nodes")) ; Minimal check.
+      (unless (stringp nodeset) (setq nodeset "Virtual Book")) ; Non-interactive - NODESET is a list.
+      (Info-virtual-book nodeset nodes))))
+
+;;;###autoload (autoload 'icicle-where-is "icicles-cmd2.el")
+(icicle-define-command icicle-where-is  ; Command name
+  "Show keyboard/menu/mouse sequences that invoke specified command.
+This is a multi-command version of `where-is'.
+
+With no prefix argument, only commands actually bound to keys are
+completion candidates.  With a prefix argument, all commands are
+candidates.  NOTE: This is a significant difference from vanilla
+`where-is', which shows all commands as candidates, even those that
+are not bound.
+
+With a plain (non-numeric) prefix argument, `C-u', insert the message
+in the current buffer.  (This is the same for vanilla `where-is'.)
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `where-is' to `icicle-where-is'.  If you do not want this
+remapping, then customize option `icicle-top-level-key-bindings'." ; Doc string
+  (lambda (x) (let ((symb  (intern-soft x))) ; Action function
+                (where-is symb (and pref-arg (consp pref-arg)))))
+  (if pref-arg "Where is command: " "Where is bound command: ")
+  obarray nil t nil nil ; `completing-read' args
+  (let ((fn  (or (and (fboundp 'symbol-nearest-point) (symbol-nearest-point))
+                 (function-called-at-point))))
+    (and fn (symbol-name fn)))
+  t
+  ((pref-arg  current-prefix-arg)       ; Bindings
+   (icicle-must-pass-after-match-predicate
+    (if pref-arg
+        #'(lambda (c) (commandp (intern c)))
+      #'(lambda (c)
+          (setq c  (intern c))
+          (with-current-buffer icicle-orig-buff
+            (and (commandp c) (where-is-internal c overriding-local-map 'non-ascii))))))
+   (icicle-candidate-help-fn
+    #'(lambda (c)
+        (with-current-buffer icicle-orig-buff
+          (let* ((keys   (where-is-internal (intern-soft c) overriding-local-map))
+                 (keys1  (mapconcat 'key-description keys ", ")))
+            (message (if (string= "" keys1)
+                         (format "`%s' is not on any key" c)
+                       (format "`%s' is on `%s'" c keys1)))
+            (sit-for 3)))))
+   (icicle-candidate-alt-action-fn
+    (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "command")))
+   (icicle-all-candidates-list-alt-action-fn
+    (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "command")))))
+
+;;;###autoload (autoload 'icicle-describe-option-of-type "icicles-cmd2.el")
+(icicle-define-command icicle-describe-option-of-type ; Bound to `C-h C-o'.  Command name
+  "Describe a user option that was defined with a given `defcustom' type.
+Enter patterns for the OPTION name and TYPE definition in the
+minibuffer, separated by `icicle-list-join-string', which is \"^G^J\",
+by default.  (`^G' here means the Control-g character, input using
+`C-h C-g'.  Likewise, for `^J'.)
+
+OPTION is a regexp that is matched against option names.
+
+Depending on the prefix arg, TYPE is interpreted as either of these:
+
+ - a regexp to match against the option type
+
+ - a definition acceptable for `defcustom' :type, or its first symbol,
+   for example, (choice (integer) (regexp)) or `choice'
+
+In the second case, depending on the prefix arg, TYPE can be matched
+against the option type, or it can be matched against either the
+option type or one of its subtypes.
+
+In the second case also, depending on the prefix arg, if TYPE does not
+match some option's type, that option might still be a candidate, if
+its current value satisfies TYPE.
+
+In sum, the prefix arg determines the type-matching behavior, as
+follows:
+
+ - None:      OPTION is defined with TYPE or a subtype of TYPE.
+              TYPE is a regexp.
+
+ - `C-u':     OPTION is defined with TYPE or a subtype of TYPE,
+                or its current value is compatible with TYPE.
+              TYPE is a type definition or its first symbol.
+
+ - Negative:  OPTION is defined with TYPE (exact match).
+              TYPE is a regexp.
+
+ - Positive:  OPTION is defined with TYPE,
+                or its current value is compatible with TYPE.
+              TYPE is a type definition or its first symbol.
+
+ - Zero:      OPTION is defined with TYPE or a subtype of TYPE.
+              TYPE is a type definition or its first symbol.
+
+ - `C-u C-u': OPTION is defined with TYPE (exact match).
+              TYPE is a type definition or its first symbol.
+
+You can change these prefix-arg key sequences by customizing option
+`icicle-option-type-prefix-arg-list'.  For example, if you tend to use
+the matching defined here for `C-u', you might want to make that the
+default behavior (no prefix arg).  You can assign any of the six
+behaviors to any of the prefix-arg keys.
+
+If TYPE is nil, then *all* options that match OPTION are candidates.
+
+Note that options defined in libraries that have not been loaded can
+be candidates, but their type will appear as nil, since it is not
+known before loading the option definition.
+
+You can match your input against the option name or the type
+definition or both.  Use `C-M-j' (equivalent here to `C-q C-g C-j') to
+input the default separator.
+
+For example, to match all Icicles options whose type matches `string'
+\(according to the prefix arg), use `S-TAB' with this input:
+
+icicle.*^G
+string$
+
+If you instead want all Icicles options whose type definition contains
+`string', as in (repeat string), then use this:
+
+icicle.*^G
+\[^^G]*string
+
+Here, `[^^G]' matches any character except ^G, which includes newline.
+If you use `.'  here instead of `[^^G]', then only the first lines of
+type definitions are searched for `string', because `.' matches any
+character except a newline.  (The first `^' in `[^^G]' is a circumflex
+character.  The second `^' is part of `^G', the printed representation
+of a Control-g character.)
+
+Remember that you can use `\\\
+\\[icicle-toggle-incremental-completion] to toggle incremental completion." ; Doc string
+  icicle-describe-opt-action            ; Action function
+  prompt                                ; `completing-read' args
+  'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
+  ((prompt                             "OPTION `C-M-j' TYPE: ") ; Bindings
+   (icicle-candidate-properties-alist  '((1 (face icicle-candidate-part))))
+   ;; Bind `icicle-apropos-complete-match-fn' to nil to prevent automatic input matching
+   ;; in `icicle-unsorted-apropos-candidates' etc., because `icicle-describe-opt-of-type-complete'
+   ;; does everything.
+   (icicle-apropos-complete-match-fn   nil)
+   (icicle-candidate-help-fn           'icicle-describe-opt-action)
+   ;; $$$ (icicle-highlight-input-completion-failure nil)
+   (icicle-pref-arg                    current-prefix-arg))
+  (progn (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+         (icicle-highlight-lighter)
+         (message "Gathering user options and their types...")))
+
+(defun icicle-describe-opt-action (opt+type)
+  "Action function for `icicle-describe-option-of-type'."
+  (let ((icicle-list-use-nth-parts  '(1)))
+    (describe-variable (intern (icicle-transform-multi-completion opt+type)))))
+
+;; Free var here: `icicle-pref-arg' - it is bound in `icicle-describe-option-of-type'.
+(defun icicle-describe-opt-of-type-complete (strg pred completion-mode)
+  "Completion function for `icicle-describe-option-of-type'.
+This is used as the value of `minibuffer-completion-table'."
+  (setq strg  icicle-current-input)
+  ;; Parse strg into its option part and its type part: OPS  and TPS.
+  ;; Make raw alist of all options and their types: ((a . ta) (b . tb)...).
+  (let* ((num-prefix  (prefix-numeric-value icicle-pref-arg))
+         (mode        (cond ((not icicle-pref-arg) ; No prefix arg
+                             (nth 4 icicle-option-type-prefix-arg-list))
+                            ((and (consp icicle-pref-arg) (= 16 num-prefix)) ; C-u C-u
+                             (nth 0 icicle-option-type-prefix-arg-list))
+                            ((consp icicle-pref-arg) (nth 2 icicle-option-type-prefix-arg-list)) ; C-u
+                            ((zerop num-prefix) (nth 1 icicle-option-type-prefix-arg-list)) ; C-0
+                            ((wholenump num-prefix) ; C-9
+                             (nth 3 icicle-option-type-prefix-arg-list))
+                            (t (nth 5 icicle-option-type-prefix-arg-list)))) ; C--
+         (ops         (let ((icicle-list-use-nth-parts  '(1)))
+                        (icicle-transform-multi-completion strg)))
+         (tps         (let ((icicle-list-use-nth-parts  '(2)))
+                        (icicle-transform-multi-completion strg)))
+         (tp          (and (not (string= "" tps))
+                           ;; Use regexp if no prefix arg or negative; else use sexp.
+                           (if (memq mode '(inherit-or-regexp direct-or-regexp)) tps (read tps))))
+         (result      nil))
+    (mapatoms
+     #'(lambda (symb)
+         (when (if (fboundp 'custom-variable-p) (custom-variable-p symb) (user-variable-p symb))
+           (condition-case nil
+               (push (list symb (get symb 'custom-type)) result)
+             (error nil)))))
+    ;; Keep only candidates that correspond to input.
+    (setq result
+          (let ((ops-re  (if (memq icicle-current-completion-mode '(nil apropos))
+                             ops
+                           (concat "^" ops))))
+            (icicle-remove-if-not
+             #'(lambda (opt+typ)
+                 (and (string-match ops-re (symbol-name (car opt+typ)))
+                      (or (null tp)
+                          (condition-case nil
+                              (icicle-var-is-of-type-p (car opt+typ) (list tp)
+                                                       (case mode
+                                                         ((inherit inherit-or-regexp) 'inherit)
+                                                         ((direct  direct-or-regexp)  'direct)
+                                                         (inherit-or-value     'inherit-or-value)
+                                                         (direct-or-value      'direct-or-value)))
+                            (error nil)))))
+             result)))
+    ;; Change alist entries to multi-completions: "op^G^Jtp".  Add short help for mode-line, tooltip.
+    (setq result
+          (mapcar #'(lambda (entry)
+                      (let* ((opt+typ-string
+                              ;; $$$$$$ (concat (mapconcat #'(lambda (e) (pp-to-string e))
+                              ;;                           entry icicle-list-join-string)
+                              ;;                icicle-list-end-string)) ; $$$$$$
+                              (mapconcat #'(lambda (e) (pp-to-string e)) entry
+                                         icicle-list-join-string))
+                             (doc       ; Don't bother to look up doc, if user won't see it.
+                              (and (or (> icicle-help-in-mode-line-delay 0)
+                                       (and (boundp 'tooltip-mode) tooltip-mode))
+                                   (documentation-property (car entry) 'variable-documentation t)))
+                             (doc1  (and (stringp doc)
+                                         (string-match ".+$" doc) (match-string 0 doc))))
+                        (when doc1 (icicle-candidate-short-help doc1 opt+typ-string))
+                        opt+typ-string))
+                  result))
+    (if completion-mode
+        result                          ; `all-completions', `test-completion'
+      (try-completion strg (mapcar #'list result) pred)))) ; `try-completion'
+
+;;;###autoload (autoload 'icicle-vardoc "icicles-cmd2.el")
+(icicle-define-command icicle-vardoc    ; Command name
+  "Choose a variable description.
+Each candidate for completion is a variable name plus its
+documentation.  They are separated by `icicle-list-join-string'
+\(\"^G^J\", by default).  You can match an input regexp against the
+variable name or the documentation or both.  Use `C-M-j' (equivalent
+here to `C-q C-g C-j') to input the default separator.
+
+For example, use input
+
+\"dired.*^G
+\[^^G]*list\"
+
+with `S-TAB' to match all variables whose names contain \"dired\" and
+whose documentation contains \"list\".  Here, `[^^G]' matches any
+character except ^G, which includes newline.  If you use `.*' here,
+instead, then only the first lines of doc strings are searched.
+
+With a non-negative prefix argument, use the same documentation that
+was gathered the last time `icicle-vardoc' was called.  Use a
+non-negative prefix arg to save the time that would be needed to
+gather the documentation.
+
+With a non-positive prefix arg, use only user variables (options) as
+candidates.
+
+Remember that you can use `\\\
+\\[icicle-toggle-incremental-completion] to toggle incremental completion." ; Doc string
+  icicle-doc-action                     ; Action function
+  prompt                                ; `completing-read' args
+  (let* ((num-arg         (prefix-numeric-value pref-arg))
+         (options-only-p  (<= num-arg 0))
+         (result          (and pref-arg (>= num-arg 0)
+                               (if options-only-p
+                                   icicle-vardoc-last-initial-option-cand-set
+                                 icicle-vardoc-last-initial-cand-set))))
+    (unless result                      ; COLLECTION arg is an alist whose items are ((SYMB DOC)).
+      (mapatoms #'(lambda (symb)        ; Each completion candidate is a list of strings.
+                    (when (and (boundp symb)
+                               (or (wholenump (prefix-numeric-value pref-arg))
+                                   (user-variable-p symb)))
+                      (let ((doc  (documentation-property symb 'variable-documentation)))
+                        (when (icicle-non-whitespace-string-p doc)
+                          (push (list (list (symbol-name symb) doc)) result))))))
+      (if options-only-p
+          (setq icicle-vardoc-last-initial-option-cand-set  result)
+        (setq icicle-vardoc-last-initial-cand-set  result)))
+    result)
+  nil nil nil 'icicle-doc-history nil nil
+  ((prompt                             "VAR `C-M-j' DOC: ") ; Bindings
+   (icicle-candidate-properties-alist  '((1 (face icicle-candidate-part))))
+   (icicle-list-use-nth-parts          '(1))
+   (pref-arg                           current-prefix-arg))
+  (progn
+    (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+    (icicle-highlight-lighter)
+    (message "Gathering variable descriptions...")))
+
+;;; $$$$$$ (defun icicle-funvardoc-action (entry)
+;;;   "Action function for `icicle-vardoc', `icicle-fundoc', `icicle-plist'."
+;;;   (with-output-to-temp-buffer "*Help*" (princ entry)))
+
+;;;###autoload (autoload 'icicle-fundoc "icicles-cmd2.el")
+(icicle-define-command icicle-fundoc    ; Command name
+  "Choose a function description.
+Each candidate for completion is a function name plus its
+documentation.  They are separated by `icicle-list-join-string'
+\(\"^G^J\", by default).  You can match an input regexp against the
+function name or the documentation or both.  Use `C-M-j' (equivalent
+here to `C-q C-g C-j') to input the default separator.
+
+For example, use input
+
+\"dired.*^G
+\[^^G]*file\"
+
+with `S-TAB' to match all functions whose names contain \"dired\" and
+whose documentation contains \"file\".  Here, `[^^G]' matches any
+character except ^G, which includes newline.  If you use `.*' here,
+instead, then only the first lines of doc strings are searched.
+
+With a prefix argument, use the same documentation that was gathered
+the last time `icicle-fundoc' was called.  Use a prefix arg to save
+the time that would be needed to gather the documentation.
+
+Remember that you can use `\\\
+\\[icicle-toggle-incremental-completion] to toggle incremental completion." ; Doc string
+  icicle-doc-action                     ; Action function
+  prompt                                ; `completing-read' args
+  (let ((result  (and pref-arg icicle-fundoc-last-initial-cand-set)))
+    (unless result                      ; COLLECTION arg is an alist whose items are ((symb doc)).
+      (mapatoms
+       #'(lambda (symb)                 ; Each completion candidate is a list of strings.
+           (when (fboundp symb)
+             ;; Ignore symbols that produce errors.  Example: In Emacs 20, `any', which is defalias'd
+             ;; to `icicle-anything', raises this error: "Symbol's function definition is void: any".
+             ;; This is caused by the `after' advice `ad-advised-docstring' that is defined by Emacs
+             ;; itself for function `documentation'.  It is not a problem for Emacs 22+.
+             (let ((doc  (condition-case nil (documentation symb) (error nil))))
+               (when (and doc (icicle-non-whitespace-string-p (icicle-fn-doc-minus-sig doc)))
+                 (push (list (list (symbol-name symb) doc)) result))))))
+      (setq icicle-fundoc-last-initial-cand-set  result))
+    result)
+  nil nil nil 'icicle-doc-history nil nil
+  ((prompt                             "FUNC `C-M-j' DOC: ") ; Bindings
+   (icicle-candidate-properties-alist  '((1 (face icicle-candidate-part))))
+   (icicle-list-use-nth-parts          '(1))
+   (pref-arg                           current-prefix-arg))
+  (progn
+    (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+    (icicle-highlight-lighter)
+    (message "Gathering function descriptions...")))
+
+(defun icicle-fn-doc-minus-sig (docstring)
+  "Return DOCSTRING minus the function signature (usage info)."
+  (let ((sig-p  (string-match "\n\n(fn\\(\\( .*\\)?)\\)\\'" docstring)))
+    (if sig-p (substring docstring 0 (match-beginning 0)) docstring)))
+
+;;;###autoload (autoload 'icicle-plist "icicles-cmd2.el")
+(icicle-define-command icicle-plist     ; Command name
+  "Choose a symbol and its property list.
+Each candidate for completion is a symbol name plus its property list
+\(as a string).  They are separated by `icicle-list-join-string'
+\(^G^J, by default).  You can match an input regexp against the symbol
+name or the property list or both.  Use `C-M-j' (equivalent here to
+`C-q C-g C-j') to input the default separator.
+
+With a positive prefix argument, use the same initial set of
+candidates that were gathered the last time `icicle-plist' was called.
+Use a positive prefix arg to save the time that would be needed to
+gather the plists.
+
+With a negative prefix arg, do not pretty-print each property list, in
+buffers `*Help* and `*Completions*'.  Generation of the complete set
+of candidates is about twice as fast when not pretty-printed, but the
+time to match your input and display candidates is the same, and the
+match-and-display time for empty input,is much longer than the
+generation time.
+
+The time to repeat (positive prefix arg) is the same, whether or not
+candidates were pretty-printed the first time.
+
+Note: Plists are never pretty-printed for Emacs 20, because that seems
+to cause an Emacs crash.
+
+Remember that you can use `\\\
+\\[icicle-toggle-incremental-completion] to toggle incremental completion." ; Doc string
+  icicle-doc-action                     ; Action function
+  prompt                                ; `completing-read' args
+  (let ((result  (and pref-arg (wholenump (prefix-numeric-value pref-arg))
+                      icicle-plist-last-initial-cand-set)))
+    (unless result                      ; COLLECTION arg: an alist with items ((symb plist-string))
+      (mapatoms
+       #'(lambda (symb)                 ; Each completion candidate is a list of strings.
+           (condition-case nil          ; Ignore symbols that produce errors.
+               (let ((plist  (symbol-plist symb)))
+                 (when plist
+                   (push (list (list (symbol-name symb)
+                                     (if (or (< (prefix-numeric-value pref-arg) 0)
+                                             (< emacs-major-version 21)) ; Emacs 20 crash if pprint.
+                                         (format "%s" plist)
+                                       (pp-to-string plist))))
+                         result)))
+             (error nil))))
+      (setq icicle-plist-last-initial-cand-set  result))
+    result)
+  nil nil nil nil nil nil
+  ((prompt                             "SYMB `C-M-j' PLIST: ") ; Bindings
+   (icicle-candidate-properties-alist  '((1 (face icicle-candidate-part))))
+   (icicle-list-use-nth-parts          '(1))
+   (pref-arg                           current-prefix-arg))
+  (progn
+    (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+    (icicle-highlight-lighter)
+    (message "Gathering property lists...")))
+
+;;;###autoload (autoload 'icicle-doc "icicles-cmd2.el")
+(icicle-define-command icicle-doc       ; Command name
+  "Choose documentation for a symbol.
+Each candidate for completion is the description of a function,
+variable, or face.  Displays the documentation and returns the symbol.
+
+Each candidate for completion is a symbol name plus its type
+\(FUNCTION, VARIABLE, or FACE) and its documentation.  These candidate
+components are separated by `icicle-list-join-string' (\"^G^J\", by
+default).  You can match an input regexp against the symbol name,
+type, or the documentation or any combination of the three.  Use
+`C-M-j' (equivalent here to `C-q C-g C-j') to input the default
+separator.
+
+With a prefix argument, use the same documentation that was gathered
+the last time `icicle-doc' was called.  Use a prefix arg to save the
+time that would be needed to gather the documentation.
+
+Remember that you can use \\\
+`\\[icicle-toggle-incremental-completion]' to toggle incremental completion." ; Doc string
+  icicle-doc-action                     ; Action function: display the doc.
+  prompt                                ; `completing-read' args
+  (let ((result  (and pref-arg icicle-doc-last-initial-cand-set))
+        doc)                            ; Each completion candidate is a list of strings.
+    (unless result                      ; COLLECTION arg is an alist with items (doc . symb).
+      (mapatoms
+       #'(lambda (symb)
+           (progn
+             (when (and (functionp symb) ; Function's doc.
+                        ;; Ignore symbols that produce errors.  See comment for `icicle-fundoc'.
+                        (setq doc  (condition-case nil (documentation symb) (error nil)))
+                        (setq doc  (icicle-fn-doc-minus-sig doc))
+                        (icicle-non-whitespace-string-p doc)
+                        (setq doc  (concat doc "\n\n")))
+               (push (cons (list (concat (symbol-name symb) icicle-list-join-string "FUNCTION") doc)
+                           symb)
+                     result))
+             (when (and (boundp symb)   ; Variable's doc (and keymap var's bindings if remove nil)
+                        (setq doc  (documentation-property symb 'variable-documentation))
+                        (icicle-non-whitespace-string-p doc))
+               (when (and nil           ; $$$ Remove nil to get keymaps, but it slows things down.
+                          (fboundp 'describe-keymap)
+                          (keymapp (symbol-value symb)))
+                 (setq doc  (concat (symbol-name symb) ":\n" doc "\n\n" ; Keymap variable's doc.
+                                    (substitute-command-keys
+                                     (concat "\\{" (symbol-name symb) "}"))
+                                    "\n\n")))
+               (setq doc  (concat doc "\n\n"))
+               (push (cons (list (concat (symbol-name symb) icicle-list-join-string "VARIABLE") doc)
+                           symb)
+                     result))
+             (when (and (facep symb)
+                        (setq doc  (documentation-property symb 'face-documentation)))
+               (push (cons (list (concat (symbol-name symb) icicle-list-join-string "FACE") doc)
+                           symb)
+                     result)))))
+      (setq icicle-doc-last-initial-cand-set  result))
+    result)
+  nil nil nil 'icicle-doc-history nil nil
+  ((prompt                             "Find doc using regexp: ") ; Bindings
+   (icicle-candidate-properties-alist  '((1 (face icicle-candidate-part))))
+   (icicle-list-use-nth-parts          '(1))
+   (icicle-transform-function          'icicle-remove-duplicates) ; Duplicates are due to `fset's.
+   (icicle-candidate-help-fn           'icicle-doc-action)
+   (pref-arg                           current-prefix-arg))
+  (progn
+    (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+    (icicle-highlight-lighter)
+    (message "Gathering documentation...")))
+
+(defun icicle-doc-action (entry)
+  "Completion action function for `icicle-doc': Display the doc."
+  (let ((symb  (intern (icicle-transform-multi-completion entry))))
+    (cond ((fboundp symb) (describe-function symb))
+          ;; $$$ This works fine, but it slows things down:
+          ;; ((and (fboundp 'describe-keymap) (boundp symb) (keymapp (symbol-value symb)))
+          ;;  (describe-keymap symb))
+          ((and symb (boundp symb)) (describe-variable symb))
+          ((facep symb) (describe-face symb)))
+    symb))
+
+;;;###autoload
+(defun icicle-non-whitespace-string-p (string)
+  "Return non-nil if STRING is a string and contains a non-whitespace char.
+The `standard-syntax-table' definition of whitespace is used."
+  (interactive "s")
+  (let ((orig-syntable  (syntax-table)))
+    (unwind-protect
+       (progn
+         (set-syntax-table (standard-syntax-table))
+         (and (stringp string) (> (length string) 0) (string-match "\\S-" string)))
+      (set-syntax-table orig-syntable))))
+
+;;;###autoload
+(defun icicle-apropos (apropos-regexp &optional do-all)
+  "Like `apropos', but lets you see the list of matches (with `S-TAB').
+Function names are highlighted using face `icicle-special-candidate'."
+  (interactive
+   (list
+    (unwind-protect
+         (progn
+           (mapatoms #'(lambda (symb) (when (fboundp symb) (put symb 'icicle-special-candidate t))))
+           (let ((icicle-fancy-candidates-p  t)
+                 (icicle-candidate-alt-action-fn
+                  (or icicle-candidate-alt-action-fn
+                      (icicle-alt-act-fn-for-type "symbol")))
+                 (icicle-all-candidates-list-alt-action-fn
+                  (or icicle-all-candidates-list-alt-action-fn
+                      (icicle-alt-act-fn-for-type "symbol"))))
+             (completing-read "Apropos symbol (regexp or words): " obarray
+                              nil nil nil 'regexp-history)))
+      (mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))
+    current-prefix-arg))
+  (apropos apropos-regexp do-all))
+
+(cond
+  ;; Use my versions of the `apropos*' commands, defined in `apropos-fn+var.el'.
+  ;; Note that unlike my versions of `apropos-option' and `apropos-command', the `icicle-'
+  ;; versions here do not respect `apropos-do-all': they always work with options and commands.
+  ((fboundp 'apropos-option)
+   (defun icicle-apropos-variable (pattern)
+     "Show variables that match PATTERN.
+This includes variables that are not user options.
+User options are highlighted using face `icicle-special-candidate'.
+You can see the list of matches with `S-TAB'.
+See `apropos-variable' for a description of PATTERN."
+     (interactive
+      (list
+       (unwind-protect
+            (progn
+              (mapatoms #'(lambda (symb)
+                            (when (user-variable-p symb) (put symb 'icicle-special-candidate t))))
+              (let ((icicle-fancy-candidates-p  t)
+                    (icicle-must-pass-after-match-predicate
+                     #'(lambda (s)
+                         (setq s  (intern s))
+                         (and (boundp s) (get s 'variable-documentation))))
+                    (icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "variable")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "variable"))))
+                (completing-read
+                 (concat "Apropos variable (regexp" (and (>= emacs-major-version 22) " or words")
+                         "): ")
+                 obarray nil nil nil 'regexp-history)))
+         (mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))))
+     (apropos-variable pattern))
+
+   (defun icicle-apropos-option (pattern)
+     "Show user options (variables) that match PATTERN.
+You can see the list of matches with `S-TAB'.
+See `apropos-option' for a description of PATTERN."
+     (interactive
+      (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (user-variable-p (intern s)))))
+        (list (completing-read
+               (concat "Apropos user option (regexp" (and (>= emacs-major-version 22) " or words")
+                       "): ") obarray nil nil nil 'regexp-history))))
+     (let ((apropos-do-all  nil)
+           (icicle-candidate-alt-action-fn
+            (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "option")))
+           (icicle-all-candidates-list-alt-action-fn
+            (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "option"))))
+       (apropos-option pattern)))
+
+   (defun icicle-apropos-function (pattern)
+     "Show functions that match PATTERN.
+This includes functions that are not commands.
+Command names are highlighted using face `icicle-special-candidate'.
+You can see the list of matches with `S-TAB'.
+See `apropos-function' for a description of PATTERN."
+     (interactive
+      (list
+       (unwind-protect
+            (progn
+              (mapatoms #'(lambda (symb)
+                            (when (commandp symb) (put symb 'icicle-special-candidate t))))
+              (let ((icicle-fancy-candidates-p               t)
+                    (icicle-must-pass-after-match-predicate  #'(lambda (s) (fboundp (intern s))))
+                    (icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "function")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "function"))))
+                (completing-read
+                 (concat "Apropos function (regexp" (and (>= emacs-major-version 22) " or words")
+                         "): ") obarray nil nil nil 'regexp-history)))
+         (mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil))))))
+     (apropos-function pattern))
+
+   (defun icicle-apropos-command (pattern)
+     "Show commands (interactively callable functions) that match PATTERN.
+You can see the list of matches with `S-TAB'.
+See `apropos-command' for a description of PATTERN."
+     (interactive
+      (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (commandp (intern s))))
+            (icicle-candidate-alt-action-fn
+             (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "command")))
+            (icicle-all-candidates-list-alt-action-fn
+             (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "command"))))
+        (list (completing-read
+               (concat "Apropos command (regexp" (and (>= emacs-major-version 22) " or words")
+                       "): ") obarray nil nil nil 'regexp-history))))
+     (let ((apropos-do-all  nil))  (apropos-command pattern))))
+
+  ;; My versions are not available.  Use the vanilla Emacs versions of the `apropos...' commands.
+  (t
+   (defun icicle-apropos-variable (pattern &optional do-all)
+     "Show variables that match PATTERN.
+You can see the list of matches with `S-TAB'.
+See `apropos-variable' for a description of PATTERN.
+
+By default, only user options are candidates.  With optional prefix
+DO-ALL, or if `apropos-do-all' is non-nil, all variables are
+candidates.  In that case, the user-option candidates are highlighted
+using face `icicle-special-candidate'."
+     (interactive
+      (list
+       (unwind-protect
+            (progn
+              (unless (or (boundp 'apropos-do-all) (require 'apropos nil t))
+                (error "Library `apropos' not found"))
+              (when (or current-prefix-arg apropos-do-all)
+                (mapatoms #'(lambda (symb)
+                              (when (user-variable-p symb) (put symb 'icicle-special-candidate t)))))
+              (let ((icicle-fancy-candidates-p  (or current-prefix-arg apropos-do-all))
+                    (icicle-must-pass-after-match-predicate
+                     (if (or current-prefix-arg apropos-do-all)
+                         #'(lambda (s)
+                             (setq s  (intern s))
+                             (and (boundp s) (get s 'variable-documentation)))
+                       #'(lambda (s) (user-variable-p (intern s)))))
+                    (icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
+                                                         "variable"
+                                                       "option"))))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
+                                                         "variable"
+                                                       "option")))))
+                (completing-read
+                 (concat "Apropos " (if (or current-prefix-arg apropos-do-all)
+                                        "variable" "user option")
+                         " (regexp" (and (>= emacs-major-version 22) " or words") "): ")
+                 obarray nil nil nil 'regexp-history)))
+         (when (or current-prefix-arg apropos-do-all)
+           (mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil)))))
+       current-prefix-arg))
+     (apropos-variable pattern do-all))
+
+   (defun icicle-apropos-command (pattern &optional do-all var-predicate)
+     "Show commands (interactively callable functions) that match PATTERN.
+You can see the list of matches with `S-TAB'.
+
+See `apropos-command' for a description of PATTERN.
+
+With \\[universal-argument] prefix, or if `apropos-do-all' is non-nil,
+also show noninteractive functions.  In that case, the command
+candidates are highlighted using face `icicle-special-candidate'.
+
+If VAR-PREDICATE is non-nil, show only variables, and only those that
+satisfy the predicate VAR-PREDICATE."
+     (interactive
+      (list
+       (unwind-protect
+            (progn
+              (unless (boundp 'apropos-do-all)
+                (unless (require 'apropos nil t) (error "Library `apropos' not found")))
+              (when (or current-prefix-arg apropos-do-all)
+                (mapatoms #'(lambda (symb)
+                              (when (commandp symb) (put symb 'icicle-special-candidate t)))))
+              (let ((icicle-fancy-candidates-p  (or current-prefix-arg apropos-do-all))
+                    (icicle-must-pass-after-match-predicate
+                     (if current-prefix-arg
+                         #'(lambda (s) (fboundp (intern s)))
+                       #'(lambda (s) (commandp (intern s)))))
+                    (icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
+                                                         "function"
+                                                       "command"))))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
+                                                         "function"
+                                                       "command")))))
+                (completing-read
+                 (concat "Apropos " (if (or current-prefix-arg apropos-do-all)
+                                        "command or function" "command")
+                         "(regexp" (and (>= emacs-major-version 22) " or words") "): ")
+                 obarray nil nil nil 'regexp-history)))
+         (when (or current-prefix-arg apropos-do-all)
+           (mapatoms #'(lambda (symb) (put symb 'icicle-special-candidate nil)))))
+       current-prefix-arg))
+     (apropos-command pattern do-all var-predicate))))
+
+;;;###autoload
+(defun icicle-apropos-zippy (regexp)
+  "Show all Zippy quotes matching the regular-expression input REGEXP.
+Return the list of matches."
+  (interactive (progn (unless (boundp 'yow-file)
+                        (unless (require 'yow nil t) (error "Library `yow' not found")))
+                      (cookie yow-file yow-load-message yow-after-load-message)
+                      (let* ((case-fold-search     t)
+                             (cookie-table-symbol  (intern yow-file cookie-cache))
+                             (string-table         (symbol-value cookie-table-symbol))
+                             (table                (nreverse (mapcar #'list string-table))))
+                        (list (completing-read "Apropos Zippy (regexp): " table
+                                               nil nil nil 'regexp-history)))))
+  (let ((matches  (apropos-zippy icicle-current-input)))
+    (when (interactive-p)
+      (with-output-to-temp-buffer "*Zippy Apropos*"
+        (while matches
+          (princ (car matches))
+          (setq matches  (cdr matches))
+          (and matches (princ "\n\n")))))
+    matches))                           ; Return matching Zippyisms.
+
+;;;###autoload
+(defalias 'icicle-map 'icicle-apply)
+;;;###autoload
+(defun icicle-apply (alist fn &optional nomsg predicate initial-input hist def inherit-input-method)
+  "Selectively apply a function to elements in an alist.
+Argument ALIST is an alist such as can be used as the COLLECTION
+argument for Icicles `completing-read'.  Its elements can represent
+multi-completions, for example.  Interactively, COLLECTION is a
+variable (a symbol) whose value is an alist.
+
+Argument FN is a function.
+
+Optional argument NOMSG non-nil means do not display an informative
+message each time FN is applied.  If nil, then a message shows the key
+of the alist element that FN is applied to and the result of the
+application.
+
+The remaining arguments are optional.  They are the arguments
+PREDICATE, INITIAL-INPUT, HIST, DEF, and INHERIT-INPUT-METHOD for
+`completing-read' (that is, all of the `completing-read' args other
+than PROMPT, COLLECTION, and REQUIRE-MATCH).  During `icicle-apply'
+completion, a match is required (REQUIRE-MATCH is t).
+
+Interactively, you are prompted for both arguments.  Completion is
+available for each.  The completion list for ALIST candidates is the
+set of variables whose value is a cons.  With no prefix argument, the
+names of these variables must end with \"alist\".  With a prefix
+argument, the first car of each variable value must itself be a cons.
+
+After choosing the ALIST and FN, you are prompted to choose one or
+more keys of the alist elements, and FN is applied to each element
+that has a key that you choose.  Multi-command completion is available
+for choosing these candidates: you can apply FN to any number of
+elements, any number of times.
+
+Examples: If ALIST is `auto-mode-alist' and FN is `cdr', then the
+completion candidates are the keys of the alist, and the result of
+applying FN to an alist element is simply the value of that key.  If
+you choose, for example, candidate \"\\.el\\'\", then the result is
+`cdr' applied to the alist element (\"\\.el\\'\" . emacs-lisp-mode),
+which is the symbol `emacs-lisp-mode'.  In this case, the function
+performs simple lookup.
+
+If FN were instead (lambda (x) (describe-function (cdr x))), then the
+result of choosing candidate \"\\.el\\'\" would be to display the help
+for function `emacs-lisp-mode'.
+
+NOTE: `icicle-apply' does not, by itself, impose any particular sort
+order.  Neither does it inhibit sorting.  If you call this function
+from Lisp code and you want it to use a certain sort order or you want
+no sorting, then bind `icicle-sort-comparer' accordingly.
+
+During completion you can use multi-command keys.  Each displays the
+value of applying FN to an alist element whose key is a completion
+candidate.
+
+`C-RET'   - Act on current completion candidate only
+`C-down'  - Move to next completion candidate and act
+`C-up'    - Move to previous completion candidate and act
+`C-next'  - Move to next apropos-completion candidate and act
+`C-prior' - Move to previous apropos-completion candidate and act
+`C-end'   - Move to next prefix-completion candidate and act
+`C-home'  - Move to previous prefix-completion candidate and act
+`C-!'     - Act on *each* candidate (or each that is saved), in turn.
+`M-!'     - Act on the list of *all* candidates (or all saved).
+
+Note that `M-!' applies FN to the *list* of chosen alist elements,
+whereas `C-!' applies FN to each chosen element, in turn.  For
+example, if FN is `length' and your input is `\.el', then `M-!' displays
+the result of applying `length' to the list of chosen elements:
+
+ ((\"\\.el\\'\" . emacs-lisp-mode) (\"\\.elc'\" . emacs-lisp-mode))
+
+which is 2.
+
+When candidate action and cycling are combined (e.g. `C-next'), option
+`icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
+`C-g' to quit.  This is an Icicles command - see command
+`icicle-mode'.
+
+`icicle-apply' overrides `icicle-ignore-space-prefix-flag', binding it
+to nil so that candidates with initial spaces can be matched."
+  (interactive
+   (list (symbol-value
+          (intern
+           (let ((icicle-must-pass-after-match-predicate
+                  `(lambda (s)
+                      (setq s  (intern s))
+                      (and (boundp s) (consp (symbol-value s))
+                           ,(if current-prefix-arg
+                                '(consp (car (symbol-value s)))
+                                '(string-match "alist$" (symbol-name s))))))
+                 (icicle-candidate-alt-action-fn
+                  (or icicle-candidate-alt-action-fn
+                      (icicle-alt-act-fn-for-type "variable")))
+                 (icicle-all-candidates-list-alt-action-fn
+                  (or icicle-all-candidates-list-alt-action-fn
+                      (icicle-alt-act-fn-for-type "variable"))))
+             (completing-read "Alist (variable): " obarray nil t nil
+                              (if (boundp 'variable-name-history)
+                                  'variable-name-history
+                                'icicle-variable-name-history)))))
+         (read
+          (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (functionp (intern s))))
+                (icicle-candidate-alt-action-fn
+                 (or icicle-candidate-alt-action-fn
+                     (icicle-alt-act-fn-for-type "function")))
+                (icicle-all-candidates-list-alt-action-fn
+                 (or icicle-all-candidates-list-alt-action-fn
+                     (icicle-alt-act-fn-for-type "function"))))
+            (completing-read "Function: " obarray nil nil nil (if (boundp 'function-name-history)
+                                                                  'function-name-history
+                                                                'icicle-function-name-history))))))
+
+  (setq icicle-candidate-entry-fn  fn)  ; Save in global variable - used by `icicle-apply-action'.
+  (let ((icicle-candidate-action-fn            'icicle-apply-action)
+        (icicle-all-candidates-list-action-fn  'icicle-apply-list-action)
+        (icicle-ignore-space-prefix-flag       nil)
+        (icicle-apply-nomsg                    nomsg)
+        (enable-recursive-minibuffers          t))
+    (icicle-explore
+     #'(lambda ()
+         (setq icicle-candidates-alist  ; Ensure that keys of ALIST are strings or conses.
+               (mapcar #'(lambda (key+val)
+                           (if (consp (car key+val))
+                               key+val  ; Multi-completion candidate: (("aaa" "bbb") . ccc)
+                             (cons (format "%s" (car key+val)) (cdr key+val))))
+                       alist)))
+     #'(lambda ()
+         (let ((result  (funcall icicle-candidate-entry-fn icicle-explore-final-choice-full)))
+           (unless nomsg
+             (message "Key: %s,  Result: %s" (car icicle-explore-final-choice-full) result))
+           result))                     ; Return result.
+     nil nil nil "Choose an occurrence: " predicate t initial-input hist def inherit-input-method)))
+
+(defun icicle-apply-action (string)
+  "Completion action function for `icicle-apply'."
+  (unwind-protect
+      (icicle-condition-case-no-debug icicle-apply-action
+	  (progn
+	    (icicle-highlight-candidate-in-Completions)
+	    ;; Apply function to candidate element and display it.
+	    (let* ((key+value  (funcall icicle-get-alist-candidate-function string))
+		   (result     (funcall icicle-candidate-entry-fn key+value)))
+	      (unless icicle-apply-nomsg
+		(message "Key: %s,  Result: %s" (car key+value) result)))
+	    nil)			; Return nil for success.
+	(error "%s" (error-message-string icicle-apply-action))) ; Return error msg.
+    (select-window (minibuffer-window))
+    (select-frame-set-input-focus (selected-frame))))
+
+(defun icicle-apply-list-action (strings)
+  "Completion action list function for `icicle-apply'."
+  (unwind-protect
+       (icicle-condition-case-no-debug icicle-apply-list-action
+           (progn                       ; Apply function to candidate element and display it.
+             (message "Result: %s" (funcall icicle-candidate-entry-fn
+                                            (mapcar icicle-get-alist-candidate-function strings)))
+             nil)                       ; Return nil for success.
+         (error "%s" (error-message-string icicle-apply-list-action))) ; Return error msg.
+    (select-window (minibuffer-window))
+    (select-frame-set-input-focus (selected-frame))))
+
+;;;###autoload
+(defun icicle-goto-marker-or-set-mark-command (arg) ; Bound to `C-@', `C-SPC'.
+  "With prefix arg < 0, `icicle-goto-marker'; else `set-mark-command'.
+By default, Icicle mode remaps all key sequences that are normally
+bound to `set-mark-command' to
+`icicle-goto-marker-or-set-mark-command'.  If you do not want this
+remapping, then customize option `icicle-top-level-key-bindings'."
+  (interactive "P")
+  (if (not (wholenump (prefix-numeric-value arg)))
+      (icicle-goto-marker)
+    (setq this-command 'set-mark-command) ; Let `C-SPC C-SPC' activate if not `transient-mark-mode'.
+    (set-mark-command arg)))
+
+;;;###autoload
+(defun icicle-goto-global-marker-or-pop-global-mark (arg) ; Bound to `C-x C-@', `C-x C-SPC'.
+  "With prefix arg < 0, `icicle-goto-global-marker'; else `pop-global-mark'.
+By default, Icicle mode remaps all key sequences that are normally
+bound to `pop-global-mark' to
+`icicle-goto-global-marker-or-pop-global-mark'.  If you do not want
+this remapping, then customize option
+`icicle-top-level-key-bindings'."
+  (interactive "P")
+  (if (wholenump (prefix-numeric-value arg))
+      (pop-global-mark)
+    (icicle-goto-global-marker)))
+
+;;;###autoload
+(defun icicle-goto-marker ()            ; Bound to `C-- C-@', `C-- C-SPC'.
+  "Go to a marker in this buffer, choosing it by the line that includes it.
+If `crosshairs.el' is loaded, then the target position is highlighted.
+
+By default, candidates are sorted in marker order, that is, with
+respect to their buffer positions.  Use `C-M-,' or `C-,' to change the
+sort order.
+
+During completion you can use these keys:
+
+`C-RET'   - Goto marker named by current completion candidate
+`C-down'  - Goto marker named by next completion candidate
+`C-up'    - Goto marker named by previous completion candidate
+`C-next'  - Goto marker named by next apropos-completion candidate
+`C-prior' - Goto marker named by previous apropos-completion candidate
+`C-end'   - Goto marker named by next prefix-completion candidate
+`C-home'  - Goto marker named by previous prefix-completion candidate
+`S-delete' - Delete marker named by current completion candidate
+
+When candidate action and cycling are combined (e.g. `C-next'), option
+`icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to choose a candidate as the final
+destination, or `C-g' to quit.  This is an Icicles command - see
+command `icicle-mode'."
+  (interactive)
+  (let ((icicle-sort-orders-alist  (cons '("by position" .  icicle-cdr-lessp)
+                                         icicle-sort-orders-alist))
+        (icicle-sort-comparer      'icicle-cdr-lessp))
+    (icicle-goto-marker-1 mark-ring)))
+
+;;;###autoload
+(defun icicle-goto-global-marker ()     ; Bound to `C-- C-x C-@', `C-- C-x C-SPC'.
+  "Like `icicle-goto-marker', but visits global, not local, markers.
+If user option `icicle-show-multi-completion-flag' is non-nil, then
+each completion candidate is annotated (prefixed) with the name of the
+marker's buffer, to facilitate orientation."
+  (interactive)
+  (let ((icicle-list-nth-parts-join-string  "\t")
+        (icicle-list-join-string            "\t")
+        ;; $$$$$$ (icicle-list-end-string             "")
+        (icicle-sort-orders-alist
+         (cons '("by buffer, then by position" . icicle-part-1-cdr-lessp)
+               icicle-sort-orders-alist))
+        (icicle-sort-comparer               'icicle-part-1-cdr-lessp)
+        (icicle-candidate-properties-alist  (and icicle-show-multi-completion-flag
+                                                 '((1 (face icicle-candidate-part))))))
+    (icicle-goto-marker-1 global-mark-ring)))
+
+(defun icicle-goto-marker-1 (ring)
+  "Helper function for `icicle-goto-marker', `icicle-goto-global-marker'.
+RING is the marker ring to use."
+  (unwind-protect
+       (let* ((global-ring-p
+               (memq this-command '(icicle-goto-global-marker
+                                    icicle-goto-global-marker-or-pop-global-mark)))
+              (markers
+               (if (and (not global-ring-p) (marker-buffer (mark-marker)))
+                   (cons (mark-marker) (icicle-markers ring))
+                 (icicle-markers ring)))
+              (icicle-delete-candidate-object
+               #'(lambda (cand)
+                   (let ((mrkr+txt  (funcall icicle-get-alist-candidate-function cand)))
+                     (move-marker (cdr mrkr+txt) nil))))
+              (icicle-alternative-sort-comparer  nil)
+              (icicle-last-sort-comparer         nil)
+              (icicle-orig-buff                  (current-buffer)))
+         (unless (consp markers)
+           (error (if global-ring-p "No global markers" "No markers in this buffer")))
+         (cond ((cdr markers)
+                (icicle-apply (mapcar #'(lambda (mrkr) (icicle-marker+text mrkr global-ring-p))
+                                      markers)
+                              #'icicle-goto-marker-1-action
+                              'nomsg
+                              (lambda (cand)
+                                (marker-buffer (cdr cand)))))
+               ((= (point) (car markers)) (message "Already at marker: %d" (point)))
+               (t
+                (icicle-goto-marker-1-action (icicle-marker+text (car markers) global-ring-p)))))
+    (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))))
+
+(defun icicle-goto-marker-1-action (cand)
+  "Action function for `icicle-goto-marker-1'."
+  (pop-to-buffer (marker-buffer (cdr cand)))
+  (select-frame-set-input-focus (selected-frame))
+  (goto-char (cdr cand))
+  (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+  (when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
+
+(defun icicle-marker+text (marker &optional globalp)
+  "Cons of text line that includes MARKER with MARKER itself.
+If the marker is on an empty line, then text \"\" is used.
+If both optional argument GLOBALP and option
+`icicle-show-multi-completion-flag' are non-nil, then the text is
+prefixed by MARKER's buffer name."
+  (with-current-buffer (marker-buffer marker)
+    (save-excursion
+      (goto-char marker)
+      (let ((line  (let ((inhibit-field-text-motion  t)) ; Just to be sure, for `end-of-line'.
+                     (buffer-substring-no-properties (save-excursion (beginning-of-line) (point))
+                                                     (save-excursion (end-of-line) (point)))))
+            (buff  (and globalp icicle-show-multi-completion-flag (buffer-name)))
+            (help  (and (or (> icicle-help-in-mode-line-delay 0) ; Get it only if user will see it.
+                            (and (boundp 'tooltip-mode) tooltip-mode))
+                        (format "Line: %d, Char: %d" (line-number-at-pos) (point)))))
+        (when (string= "" line) (setq line  ""))
+        (when help
+          (icicle-candidate-short-help help line)
+          (when (and globalp icicle-show-multi-completion-flag)
+            (icicle-candidate-short-help help buff)))
+        (if (and globalp icicle-show-multi-completion-flag)
+            (cons (list buff line) marker)
+          (cons line marker))))))
+
+(defun icicle-markers (ring)
+  "Marks in mark RING that are in live buffers other than a minibuffer."
+  (let ((markers  ()))
+    (dolist (mkr  ring)
+      (when (and (buffer-live-p (marker-buffer mkr))
+                 (not (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
+                                    (buffer-name (marker-buffer mkr)))))
+        (push mkr markers)))
+    markers))
+
+;;;###autoload
+(defun icicle-exchange-point-and-mark (&optional arg) ; Bound to `C-x C-x'.
+  "`exchange-point-and-mark' or save a region or select a saved region.
+With no prefix arg, invoke `exchange-point-and-mark'.
+If you use library `Bookmark+', then you can use a prefix arg.
+
+ * Plain `C-u': select (activate) one or more bookmarked regions.
+
+ * Numeric prefix arg: bookmark (save) the active region using
+   `icicle-bookmark-cmd'.
+
+   Arg < 0: Prompt for the bookmark name.
+   Arg > 0: Do not prompt for the bookmark name.  Use the buffer name
+            plus a prefix of the region text as the bookmark name.
+   Arg = 0: Same as > 0, except do not overwrite any existing bookmark
+            with the same name.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `exchange-point-and-mark' to
+`icicle-exchange-point-and-mark'.  If you do not want this remapping,
+then customize option `icicle-top-level-key-bindings'."
+  (interactive "P")
+  (let ((bplus  (featurep 'bookmark+)))
+    (if (not arg)
+        (call-interactively #'exchange-point-and-mark)
+      (unless bplus (error "You must load library `Bookmark+' to use a prefix arg"))
+      (cond ((atom arg)
+             (unless (and transient-mark-mode mark-active (not (eq (mark) (point))))
+               (error "Cannot bookmark inactive region: you must activate it first"))
+             (icicle-bookmark-cmd (and (natnump (prefix-numeric-value arg)) 9)))
+            (t
+             (bookmark-maybe-load-default-file)
+             (unless (consp (bmkp-region-alist-only)) (error "No bookmarked regions"))
+             (call-interactively #'icicle-select-bookmarked-region))))))
+
+;;;###autoload
+(defun icicle-search-generic ()         ; Bound to `C-x `'.
+  "Run `icicle-search-command'.  By default, this is `icicle-search'.
+In Compilation and Grep modes, this is `icicle-compilation-search'.
+In Comint, Shell, GUD, and Inferior Lisp modes, this is
+   `icicle-comint-search'."
+  (interactive)
+  (call-interactively icicle-search-command))
+
+;;;###autoload
+(defun icicle-search (beg end scan-fn-or-regexp require-match ; Bound to `C-c `'.
+                      &optional where &rest args)
+  "Search for matches, with completion, cycling, and hit replacement.
+Search a set of contexts, which are defined interactively by
+specifying a regexp (followed by `RET').
+
+After specifying the regexp that defines the search contexts, type
+input (e.g. regexp or other pattern) to match within the contexts.
+The contexts that match your input are available as completion
+candidates.  You can use `M-*' to further narrow the candidates,
+typing additional patterns to match.
+
+By default, candidates are in order of buffer occurrence, but you can
+sort them in various ways using `C-,'.
+
+You can replace individual matches with another string, as in
+`query-replace' or `query-replace-regexp'.  See the Icicles Search doc
+for more info.
+
+Non-interactively, search can be for regexp matches or any other kind
+of matches.  Argument SCAN-FN-OR-REGEXP is the regexp to match, or it
+is a function that defines an alist of buffer zones to search.  You
+can navigate among the matching buffer zones (defined either as regexp
+matches or via function), called search \"contexts\", and you can
+match another regexp against the text in a search context.  See the
+end of this description for information about the other arguments.
+
+If the search-context regexp contains regexp subgroups, that is,
+subexpressions of the form `\(...\)', then you are prompted for the
+subgroup to use to define the search contexts.  Subgroup 0 means the
+context is whatever matches the whole regexp.  Subgroup 1 means the
+context is whatever matches the first subgroup, and so on.  The
+subgroup number is the number of occurrences of `\(', starting at the
+beginning of the regexp.
+
+Search respects `icicle-regexp-quote-flag' and
+`icicle-search-whole-word-flag'.  You can toggle these during search,
+by using `C-`' and `M-q', respectively.  If `icicle-regexp-quote-flag'
+is non-nil, then regexp special characters are quoted, so that they
+become non-special.  If `icicle-search-whole-word-flag' is non-nil,
+then whole-word searching is done.  (You can also use
+`\\[icicle-search-word]' to perform word search.)
+
+For each of the predefined Icicles search commands, including for
+`icicle-search' itself, you can alternatively choose to search, not
+the search contexts as you define them, but the non-contexts, that is,
+the buffer text that is outside (in between) the search contexts as
+defined.  For example, if you use `icicle-search-thing' and you define
+sexps as the search contexts, then this feature lets you search the
+zones of text that are not within a sexp.
+
+To do this, use `C-M-~' (`icicle-toggle-search-complementing-domain')
+during completion to turn on `icicle-search-complement-domain-p'.
+\(This is a toggle, and it affects only future search commands, not
+the current one.)
+
+
+Optional Behaviors: Prefix Argument
+-----------------------------------
+
+By default, search only the current buffer.  Search the active region,
+or, if there is none, then search the entire buffer.
+
+With a prefix argument, you can search multiple buffers, files, or
+bookmarks, as follows:
+
+- With a plain prefix arg (`C-u'), search bookmarks.  This is the
+same as command `icicle-search-bookmarks-together'.  (To search
+bookmarks one at a time instead of together, use multi-command
+`icicle-search-bookmark'.)
+
+- With a non-negative numeric prefix arg, search multiple buffers
+completely.  You are prompted for the buffers to search - all of each
+buffer is searched.  Any existing buffers can be chosen.  If the
+prefix arg is 99, then only buffers visiting files are candidates.
+This is the same as command `icicle-search-buffer'.
+
+- With a negative numeric prefix arg, search multiple files
+completely.  You are prompted for the files to search - all of each
+file is searched.  Any existing files in the current directory can be
+chosen.  This is the same as command `icicle-search-file'.
+
+
+Navigation and Help
+-------------------
+
+The use of completion for this command is special.  It is not unusual
+in this context to have multiple completion candidates that are
+identical - only the positions of their occurrences in the search
+buffer(s) differ.  In that case, you cannot choose one simply by
+completing it in the minibuffer, because the destination would be
+ambiguous.  That is, simply completing your input and entering the
+completion with `RET' will not take you to its occurrence in the
+search buffer, unless it is unique.
+
+Instead, choose search hits to visit using any of the candidate-action
+keys: `C-RET', `C-mouse-2', `C-down', `C-up', `C-next', `C-prior',
+`C-end', and `C-home'.  All but the first two of these cycle among the
+search hits.  The current candidate in `*Completions*' corresponds to
+the current location visited (it is not off by one, as is usually the
+case in Icicles).
+
+As always, the `C-M-' keys provide help on individual candidates:
+`C-M-RET', `C-M-mouse-2', `C-M-down', `C-M-up', `C-M-next',
+`C-M-prior', `C-M-end', and `C-M-home'.  For `icicle-search', they
+indicate the buffer and position of the search hit.
+
+You can cycle among candidates without moving to their occurrences in
+the search buffer, using `down', `up', `next', `prior', `end', or
+`home' (no `C-' modifier).
+
+
+Highlighting
+------------
+
+In the search buffer (that is, where the hits are), `icicle-search'
+does the following:
+
+- Highlights the current match (buffer zone) for the initial (context)
+  regexp, using face `icicle-search-main-regexp-current'.
+
+- Highlights the first `icicle-search-highlight-threshold' context
+  matches, using face `icicle-search-main-regexp-others'.
+
+- Highlights 1-8 context levels, within each search context.  This
+  happens only if your initial (context) regexp has \\(...\\) groups
+  and option `icicle-search-highlight-context-levels-flag' is non-nil.
+
+- Highlights the match for your current input, using face
+  `icicle-search-current-input'.  Highlights all such matches if
+  option `icicle-search-highlight-all-current-flag' is non-nil;
+  otherwise, highlights just the currently visited match.
+  You can toggle this option using `C-^'.
+
+If user option `icicle-search-cleanup-flag' is non-nil (the default),
+then all search highlighting is removed from the search buffer when
+you are finished searching.  If it is nil, then you can remove this
+highlighting later using command `icicle-search-highlight-cleanup'.
+You can toggle `icicle-search-cleanup-flag' during Icicles search
+using `C-.' in the minibuffer.
+
+
+`*Completions*' Display
+-----------------------
+
+In buffer `*Completions*', in addition to eliding the common match
+\(option `icicle-hide-common-match-in-Completions-flag', toggled
+anytime using `C-x .' - no prefix arg), you can elide all lines of a
+multi-line candidate that do not match your current minibuffer input.
+This hiding is governed by option
+`icicle-hide-non-matching-lines-flag', which you can toggle anytime
+during completion using `C-u C-x .' (this is not specfic to Icicles
+search).  This can be useful when candidates are very long, as can be
+the case for instance for the `icicle-imenu-*-full' commands.
+
+
+Search and Replace
+------------------
+
+You can replace the current search match by using any of the
+alternative action keys: `C-S-RET', `C-S-mouse-2' (in
+`*Completions*'), `C-S-down', `C-S-up', `C-S-next', `C-S-prior',
+`C-S-end', and `C-S-home'.  You can use `M-|' to replace all matches
+at once.  (And remember that you can activate the region to limit the
+search-and-replace space.)
+
+
+At the first use of any of these, you are prompted for the replacement
+string; it is used thereafter, or until you use `M-,'
+\(`icicle-search-define-replacement') to change it (anytime).
+
+Unlike `query-replace', you need not visit search matches successively
+or exhaustively.  You can visit and replace selected matches in any
+order.
+
+What is meant here by a \"search match\"?  It can be either an entire
+search context or just a part of the context that your current
+minibuffer input matches.
+
+`C-,' toggles option `icicle-search-replace-whole-candidate-flag'.  By
+default, the entire current search context is replaced, that is,
+whatever matches the context regexp that you entered initially using
+`RET'.  However, you can use `C-,' anytime during searching to toggle
+between this default behavior and replacement of whatever your current
+minibuffer input matches.
+
+Remember this:
+
+ - If `icicle-search-replace-whole-candidate-flag' is non-nil, then
+   the granularity of replacement is a complete search context.  In
+   this case, replacement behaves similarly to `query-replace-regexp'.
+   You can still use minibuffer input to filter the set of search
+   contexts, but replacement is on a whole-context basis.
+
+ - If `icicle-search-replace-whole-candidate-flag' is nil, then you
+   can replace multiple input matches separately within a search
+   context (using `C-S-RET').  This behavior is unique to Icicles.
+   You cannot, however skip over one input match and replace the next
+   one in the same context - `C-S-RET' always replaces the first
+   available match.
+
+If `icicle-search-replace-whole-candidate-flag' is non-nil, then you
+can use the navigational alternative action keys, `C-S-down',
+`C-S-up', `C-S-next', `C-S-prior', `C-S-end', and `C-S-home',
+repeatedly to replace successive search contexts.  At the buffer
+limits, these commands wraps around to the other buffer limit (last
+search context to first, and vice versa).
+
+Search traversal using these go-to-next-context-and-replace keys is
+always by search context, not by individual input match.  This means
+that you cannot use these keys to replace input matches within a
+search context (except for the first such match, if
+`icicle-search-replace-whole-candidate-flag' is nil).
+
+If your input matches multiple parts of a search context, and you want
+to replace these in order, then use `C-S-RET' repeatedly.  You can
+traverse all matches of your input in the order they appear in the
+buffer by repeating `C-S-RET' (provided the replacement text does not
+also match your input - see below).  At the buffer limits, repeating
+`C-S-RET' wraps around too.
+
+`C-S-RET' always replaces the first input match in the current search
+context or, if there are no matches, then the first input match in the
+next context.  This behavior has these important consequences:
+
+* If you repeat `C-S-RET' and the previous replacement no longer
+  matches your input, then `C-S-RET' moves on to the next input match
+  (which is now the first one) and replaces that.  This is why you can
+  usually just repeat `C-S-RET' to successively replaces matches of
+  your input, including from one context to the next.
+
+* If, on the other hand, after replacement the text still matches your
+  input, then repeating `C-S-RET' will just replace that match.
+  For example, if you replace the input match `ab' by `abcd', then
+  repeating `C-S-RET' produces `abcd', then `abcdcd', then `abcdcd'...
+
+* You cannot replace an input match, skip the next match, and then
+  replace the following one, all in the same context.  You can,
+  however, replace some matches and then skip (e.g. `C-next') to the
+  next context.
+
+What your input matches, hence what gets replaced if
+`icicle-search-replace-whole-candidate-flag' is nil, depends on a few
+Icicles options:
+
+ - `icicle-regexp-quote-flag' determines whether to use regexp
+   matching or literal matching.
+
+ - `icicle-search-highlight-all-current-flag',
+   `icicle-expand-input-to-common-match-flag' and
+   `icicle-search-replace-common-match-flag' together determine
+   whether to replace exactly what your input matches in the current
+   search hit or the expanded common match (ECM) of your input among
+   all search hits.  If any of these options is nil, then your exact
+   input match is replaced; if they are all non-nil, then the ECM is
+   replaced.
+
+Finally, the replacement string can be nearly anything that is allowed
+as a replacement by `query-replace-regexp'.  In Emacs 22 or later,
+this includes Lisp sexp evaluation via `\,' and constructs such as
+`\#' and `\N' (back references).  You can also use `\?', but it is not
+very useful - you might as well use `M-,' instead, to change the
+replacement text.
+
+
+Using Regexps
+-------------
+
+At any time, you can use `\\\
+\\[icicle-insert-string-from-variable]' (command
+`icicle-insert-string-from-variable') to insert text (e.g. a regexp)
+from a variable into the minibuffer.  For example, you can search for
+ends of sentences by using `C-u \\[icicle-insert-string-from-variable]' and choosing variable
+`sentence-end' as the variable.  And you can use
+`\\[icicle-save-string-to-variable]' to save a string to a variable
+for later use by `\\[icicle-insert-string-from-variable]'.
+
+When employed with useful regexps, `C-=' can turn `icicle-search' into
+a general navigator or browser of code, mail messages, and many other
+types of buffer.  Imenu regexps work fine, for example - command
+`icicle-imenu' simply uses `icicle-search' this way.  See
+`icicle-insert-string-from-variable' for more tips on inserting
+regexps from variables.
+
+
+Additional Information
+----------------------
+
+If user option `icicle-show-multi-completion-flag' is non-nil, then
+each candidate is annotated with the name of the buffer where the
+search hit occurs, to facilitate orientation.  Note that even when the
+value is nil, you can use `C-M-mouse-2' and so on to see the buffer
+name, as well as the position of the hit in the buffer.
+
+Completion is lax if `icicle-show-multi-completion-flag' is non-nil;
+otherwise, it is strict.
+
+After you visit a completion candidate, the hooks in variable
+`icicle-search-hook' are run.
+
+`icicle-search' overrides `icicle-ignore-space-prefix-flag', binding
+it to nil, so that candidates with initial spaces can be matched.
+
+`icicle-search' sets `icicle-search-final-choice' to the final user
+choice, which might not be one of the search candidates if
+REQUIRE-MATCH is nil.
+
+
+Non-Interactive Use
+-------------------
+
+Function `icicle-search' is not only a powerful command, it is also a
+building block for creating your own Icicles search-and-replace
+commands.  When called non-interactively, these are the
+`icicle-search' arguments:
+
+BEG is the beginning of the region to search; END is the end.
+SCAN-FN-OR-REGEXP: Regexp or function that determines the set of
+  initial candidates (match zones).  If a function, it is passed, as
+  arguments, the buffer to search, the beginning and end of the search
+  region in that buffer, and ARGS.
+REQUIRE-MATCH is passed to `completing-read'.
+Optional arg WHERE is a list of bookmarks, buffers, or files to be
+  searched.  If nil, then search only the current buffer or region.
+  (To search bookmarks you must also use library `Bookmark+').
+ARGS are arguments that are passed to function SCAN-FN-OR-REGEXP.
+
+Note that if SCAN-FN-OR-REGEXP is a regexp string, then function
+`icicle-search-regexp-scan' is used to determine the set of match
+zones.  You can limit hits to regexp matches that also satisfy a
+predicate, by using `(PREDICATE)' as ARGS: PREDICATE is then passed to
+`icicle-search-regexp-scan' as its PREDICATE argument.
+
+This command is intended for use only in Icicle mode."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (setq icicle-search-context-regexp  (and (stringp scan-fn-or-regexp) scan-fn-or-regexp))
+  (let ((icicle-candidate-action-fn                  (or icicle-candidate-action-fn
+                                                         'icicle-search-action))
+        (icicle-candidate-help-fn                    'icicle-search-help)
+        (icicle-all-candidates-list-alt-action-fn
+         (or icicle-all-candidates-list-alt-action-fn 'icicle-search-replace-all-search-hits))
+        (icicle-candidate-alt-action-fn
+         (or icicle-candidate-alt-action-fn 'icicle-search-replace-search-hit))
+        (icicle-scan-fn-or-regexp           scan-fn-or-regexp) ; Used free in `M-,'.
+        (icicle-update-input-hook           (list 'icicle-search-highlight-all-input-matches))
+        (icicle-search-ecm                  nil)
+        (icicle-searching-p                 t)
+        (icicle-search-replacement          nil)
+        (icicle-current-input               "")
+        (icicle-list-nth-parts-join-string  "\t")
+        (icicle-list-join-string            "\t")
+        ;; $$$$$$ (icicle-list-end-string             "")
+        (icicle-list-use-nth-parts          '(1))
+        (icicle-sort-comparer               nil)
+
+        ;; Alternative: If we used `icicle-search-replace-cand-in-alist', then we would inhibit
+        ;; sorting, because we would be depending on the alist order.
+        ;;    (icicle-inhibit-sort-p          t)
+
+        (icicle-no-match-hook               icicle-no-match-hook)
+        (completion-ignore-case             case-fold-search)
+        (replace-count                      0)) ; Defined in `replace.el'.  Used for replacement.
+    (add-hook 'icicle-no-match-hook (lambda () (when (overlayp icicle-search-current-overlay)
+                                                 (delete-overlay icicle-search-current-overlay))))
+    (setq icicle-search-final-choice
+          (icicle-explore #'(lambda () (icicle-search-define-candidates beg end scan-fn-or-regexp
+                                                                        require-match where args))
+                          #'icicle-search-final-act #'icicle-search-quit-or-error
+                          #'icicle-search-quit-or-error #'icicle-search-cleanup
+                          "Choose an occurrence: " nil require-match nil 'icicle-search-history))))
+
+;; This is the same as `region-or-buffer-limits' in `misc-fns.el'.
+(defun icicle-region-or-buffer-limits ()
+  "Return the start and end of the region as a list, smallest first.
+If the region is not active or is empty, then use bob and eob."
+  (if (or (not mark-active) (null (mark)) (= (point) (mark)))
+      (list (point-min) (point-max))
+    (if (< (point) (mark)) (list (point) (mark)) (list (mark) (point)))))
+
+(defun icicle-search-read-context-regexp (&optional prompt pred init hist def i-i-m)
+  "Read context regexp and determine `icicle-search-context-level'.
+Read the regexp using completion against previous regexp input.
+The arguments are for use by `completing-read' to read the regexp.
+ HIST (or `regexp-history' if HIST is nil) is used for the
+ `completing-read' COLLECTION argument.
+ The REQUIRE-MATCH arg to `completing-read' is nil.
+ A default prompt is used if PROMPT is nil."
+  (setq hist    (or hist 'regexp-history)
+        prompt  (or prompt (format "Search %swithin contexts (regexp): "
+                                   (if icicle-search-complement-domain-p "*NOT* " ""))))
+  (let* ((icicle-candidate-action-fn  nil)
+         (icicle-candidate-help-fn    nil)
+         (regexp                      (icicle-completing-read-history
+                                       prompt 'regexp-history pred init def i-i-m)))
+    (while (string= "" regexp)
+      (message "Regexp cannot be empty.  Try again...") (sit-for 2)
+      (setq regexp  (icicle-completing-read-history prompt 'regexp-history pred init def i-i-m)))
+    (setq prompt                       "Subgroup to use as search context [0, 1, 2,...]: "
+          icicle-search-context-level  (if (string-match "\\\\(" regexp)
+                                           (truncate (if (fboundp 'read-number)
+                                                         (read-number prompt 0)
+                                                       (read-from-minibuffer ; Hope for a number.
+                                                        prompt nil nil nil nil 0)))
+                                         0))
+    regexp))
+
+(defun icicle-search-where-arg ()
+  "Return WHERE arg for `icicle-search*' commands, based on prefix arg."
+  (cond ((consp current-prefix-arg)
+         (unless (require 'bookmark+ nil t) (error "This requires library `Bookmark+'"))
+         (message "Searching multiple bookmarks...") (sit-for 1)
+         (let ((icicle-show-Completions-initially-flag  t)
+               (icicle-bookmark-types                   '(all)))
+           (save-selected-window (icicle-bookmark-list))))
+        ((wholenump current-prefix-arg)
+         (message "Searching multiple buffers...") (sit-for 1)
+         (icicle-search-choose-buffers (= 99 (prefix-numeric-value current-prefix-arg))))
+        (current-prefix-arg
+         (message "Searching multiple files...") (sit-for 1)
+         (let ((icicle-show-Completions-initially-flag  t))
+           (save-selected-window (icicle-file-list))))
+        (t nil)))
+
+(defun icicle-search-choose-buffers (files-only-p)
+  "Choose multiple buffers to search.
+FILES-ONLY-P non-nil means that only buffers visiting files are
+candidates."
+  (let ((icicle-show-Completions-initially-flag  t))
+    (mapcar #'get-buffer (let ((icicle-buffer-require-match-flag  'partial-match-ok)
+                               (current-prefix-arg                files-only-p))
+                           (save-selected-window (icicle-buffer-list))))))
+
+;;; $$$$$$ (defun icicle-search-read-word ()
+;;;   "Read a word to search for (whole-word search).
+;;; Regexp special characters within the word are escaped (quoted)."
+;;;   (setq icicle-search-context-level  0)
+;;;   (concat "\\b"
+;;;           (regexp-quote (icicle-completing-read-history "Search for whole word: "
+;;;                                                         'icicle-search-history))
+;;;           "\\b"))
+
+(defun icicle-search-read-word ()
+  "Read a word to search for (whole-word search).
+The search string is regarded as a whole word, but a \"word\" here can
+contain embedded strings of non word-constituent chars (they are
+skipped over, when matching, included in the match), and any leading
+or trailing word-constituent chars in the search string are dropped
+\(ignored for matching, not included in the match): matches begin and
+end on a word boundary."
+  (setq icicle-search-context-level  0)
+  (concat "\\b" (replace-regexp-in-string
+                 "\\W+" "\\W+" (replace-regexp-in-string
+                                "^\\W+\\|\\W+$" ""
+                                (icicle-completing-read-history "Search for whole word: "
+                                                                'icicle-search-history))
+                 nil t)
+          "\\b"))
+
+(defun icicle-search-final-act ()
+  "Go to the final search hit choice, then run `icicle-search-hook'.
+The hit's frame is raised and selected."
+  (let* ((marker  (cdr icicle-explore-final-choice-full))
+         (buf     (marker-buffer marker)))
+    (unless (bufferp buf) (error "No such buffer: %s" buf))
+    (pop-to-buffer buf)
+    (raise-frame)
+    (goto-char (marker-position marker))
+    (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+    (select-frame-set-input-focus (selected-frame))
+    (run-hooks 'icicle-search-hook)))
+
+;; Free vars here: `icicle-orig-pt-explore', `icicle-orig-win-explore' are bound in `icicle-explore'.
+(defun icicle-search-quit-or-error ()
+  "Return to the starting point."
+  (when (window-live-p icicle-orig-win-explore)
+    (select-window icicle-orig-win-explore)
+    (goto-char icicle-orig-pt-explore)))
+
+;; Free vars here: `icicle-orig-win-explore' is bound in `icicle-explore'.
+(defun icicle-search-cleanup ()
+  "Clean up search highlighting, if `icicle-search-cleanup-flag'.
+Select original window."
+  (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+  (when (window-live-p icicle-orig-win-explore)
+    (select-window icicle-orig-win-explore)
+    (select-frame-set-input-focus (selected-frame))))
+
+(defun icicle-search-define-candidates (beg end scan-fn-or-regexp require-match where args)
+  "Define completion candidates for `icicle-search'.
+The arguments are the same as for `icicle-search'."
+  (when (and icicle-regexp-quote-flag
+             (not icicle-search-whole-word-flag)
+             (stringp scan-fn-or-regexp))
+    (setq scan-fn-or-regexp  (regexp-quote scan-fn-or-regexp)))
+  (cond ((and (consp where) (bufferp (car where))) ; List of buffers - search buffers.
+         (dolist (buf  where)
+           (icicle-search-define-candidates-1 buf nil nil scan-fn-or-regexp args)))
+        ((and (consp where) (stringp (car where)) ; List of files - search files.
+              (file-exists-p (car where)))
+         (dolist (file  where)
+           (icicle-search-define-candidates-1 (find-file-noselect file 'nowarn) nil nil
+                                              scan-fn-or-regexp args)))
+        ((consp where)                  ; Search all bookmarked regions.
+         (unless (require 'bookmark+ nil t) (error "This requires library `Bookmark+'"))
+         (let ((non-existent-buffers  ())
+               buf+beg buf beg end)
+           (dolist (bmk  where)
+             (setq buf+beg  (bookmark-jump-noselect bmk)
+                   buf      (car buf+beg)
+                   beg      (cdr buf+beg)
+                   end      (bmkp-get-end-position bmk))
+             (if (bufferp buf)
+                 (icicle-search-define-candidates-1 buf beg end scan-fn-or-regexp args)
+               (push buf non-existent-buffers)))
+           (when non-existent-buffers
+             (message "Skipping regions in non-existent buffers: `%s'"
+                      (mapconcat #'identity (icicle-remove-duplicates non-existent-buffers)
+                                 "', `"))
+             (sit-for 3))))
+        (t                              ; Search this buffer only.
+         (icicle-search-define-candidates-1 nil beg end scan-fn-or-regexp args)))
+  (when (and icicle-candidates-alist  (null (cdr icicle-candidates-alist)))
+    (message "Moving to sole candidate") (sit-for 1.5))
+  (unless icicle-candidates-alist  (if (functionp scan-fn-or-regexp)
+                                       (error "No search hits")
+                                     (error "No search hits for `%s'" scan-fn-or-regexp)))
+  (setq mark-active  nil))              ; Remove any region highlighting, so we can see search hits.
+
+(defun icicle-search-define-candidates-1 (buffer beg end scan-fn-or-regexp args)
+  "Helper function for `icicle-search-define-candidates'.
+BUFFER is a buffer to scan for candidates.
+The other arguments are the same as for `icicle-search'."
+  (if (functionp scan-fn-or-regexp)
+      (apply scan-fn-or-regexp buffer beg end args)
+    (apply 'icicle-search-regexp-scan buffer beg end scan-fn-or-regexp args)))
+
+(defun icicle-search-regexp-scan (buffer beg end regexp &optional predicate action)
+  "Scan BUFFER for REGEXP, pushing hits onto `icicle-candidates-alist'.
+If BUFFER is nil, scan the current buffer.
+If BEG and END are non-nil, scan only between positions BEG and END.
+If REGEXP has subgroups, then use what the Nth subgroup matches as the
+ search context (hit), where N = `icicle-search-context-level'.
+ If N=0, then use the overall match of REGEXP as the search context.
+PREDICATE is nil or a boolean function that takes these arguments:
+  - the search-context string
+  - a marker at the end of the search-context
+If PREDICATE is non-nil, then push only the hits for which it holds.
+
+Highlight the matches in face `icicle-search-main-regexp-others'."
+  (setq regexp  (or regexp (icicle-search-read-context-regexp)))
+  (let ((add-bufname-p  (and buffer icicle-show-multi-completion-flag))
+        (temp-list      ())
+        (last-beg       nil))
+    (unless buffer (setq buffer  (current-buffer)))
+    (when (bufferp buffer)     ; Do nothing if BUFFER is not a buffer.
+      (with-current-buffer buffer
+        (unless (and beg end) (setq beg  (point-min)
+                                    end  (point-max)))
+        (icicle-condition-case-no-debug icicle-search-regexp-scan
+            (save-excursion
+              (goto-char (setq last-beg  beg))
+              (while (and beg (< beg end) (not (eobp))
+                          (progn
+                            (while (and (setq beg  (re-search-forward regexp end t))
+                                        (eq last-beg beg)
+                                        (not (eobp)))
+                              ;; Matched again, same place.  Advance 1 char.
+                              (forward-char) (setq beg  (1+ beg)))
+                            ;; Stop if no more match.  But if complementing then continue until eobp.
+                            (or beg  icicle-search-complement-domain-p)))
+                (unless (or (not beg) (match-beginning icicle-search-context-level))
+                  (error "Search context has no subgroup of level %d - try a lower number"
+                         icicle-search-context-level))
+                (let* ((hit-beg     (if icicle-search-complement-domain-p
+                                        last-beg
+                                      (match-beginning icicle-search-context-level)))
+                       (hit-end     (if icicle-search-complement-domain-p
+                                        (if beg
+                                            (match-beginning icicle-search-context-level)
+                                          (point-max))
+                                      (match-end icicle-search-context-level)))
+                       (IGNORE      (when action
+                                      (save-excursion
+                                        (funcall action)
+                                        (setq hit-end  (point)))))
+                       (hit-string  (buffer-substring-no-properties hit-beg hit-end))
+                       end-marker)
+                  (when (and (not (string= "" hit-string)) ; Do nothing if empty hit.
+                             (setq end-marker  (copy-marker hit-end))
+                             (or (not predicate)
+                                 (save-match-data (funcall predicate hit-string end-marker))))
+                    (icicle-candidate-short-help
+                     (concat (and add-bufname-p
+                                  (format "Buffer: `%s', "
+                                          (buffer-name (marker-buffer end-marker))))
+                             (format "Position: %d, Length: %d"
+                                     (marker-position end-marker) (length hit-string)))
+                     hit-string)
+                    ;; Add whole candidate to `temp-list'.  Whole candidate is
+                    ;; (`hit-string' . `end-marker') or ((`hit-string' BUFNAME) . `end-marker').
+                    (push (cons (if add-bufname-p
+                                    (list hit-string
+                                          (let ((string  (copy-sequence (buffer-name))))
+                                            (put-text-property 0 (length string) 'face
+                                                               'icicle-candidate-part string)
+                                            string))
+                                  hit-string)
+                                end-marker)
+                          temp-list)
+                    ;; Highlight search context in buffer.
+                    (when (<= (+ (length temp-list) (length icicle-candidates-alist))
+                              icicle-search-highlight-threshold)
+                      (let ((ov  (make-overlay hit-beg hit-end)))
+                        (push ov icicle-search-overlays)
+                        (overlay-put ov 'priority 200) ; > ediff's 100+, < isearch-overlay's 1001.
+                        (overlay-put ov 'face 'icicle-search-main-regexp-others)))))
+                (setq last-beg  beg))
+              (setq icicle-candidates-alist  (append icicle-candidates-alist (nreverse temp-list))))
+          (quit (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup)))
+          (error (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+                 (error "%s" (error-message-string icicle-search-regexp-scan))))))))
+
+;; Free var here: `icicle-search-ecm' is bound in `icicle-search'.
+(defun icicle-search-highlight-all-input-matches (&optional input)
+  "Highlight, inside each search context, what INPUT matches."
+  (save-excursion
+    ;; Update by deleting (if it exists) and then creating.
+    ;; If a single overlay exists, it means that the user just changed
+    ;; `icicle-search-highlight-threshold' to non-zero.
+    ;; Otherwise, it's nil or a list of overlays.
+    (when (overlayp icicle-search-refined-overlays)
+      (delete-overlay icicle-search-refined-overlays)
+      (setq icicle-search-refined-overlays  ()))
+    (while icicle-search-refined-overlays
+      (delete-overlay (car icicle-search-refined-overlays))
+      (setq icicle-search-refined-overlays  (cdr icicle-search-refined-overlays))))
+  (when icicle-search-highlight-all-current-flag
+    (setq input  (or input icicle-current-input))
+    (unless (or (string= "" input) (null icicle-search-overlays))
+      (let ((hits  ())
+            pos)
+        (save-excursion
+          (dolist (ov  icicle-search-overlays)
+            (set-buffer (overlay-buffer ov))
+            (unless (equal (overlay-start ov) (overlay-end ov))
+              (save-restriction         ; Search within the current search context.
+                (narrow-to-region (overlay-start ov) (overlay-end ov))
+                (goto-char (point-min))
+                (when (condition-case nil (re-search-forward input nil 'move-to-end) (error nil))
+                  (push (buffer-substring-no-properties (point-min) (point-max)) hits)))))
+          (when (and icicle-expand-input-to-common-match-flag  hits)
+            (setq icicle-search-ecm  (icicle-expanded-common-match input hits))
+            (when (string= "" icicle-search-ecm) (setq icicle-search-ecm  nil)))
+          (when (or icicle-search-ecm (and input (not (string= "" input))))
+            (dolist (ov  icicle-search-overlays)
+              (set-buffer (overlay-buffer ov))
+              (unless (equal (overlay-start ov) (overlay-end ov))
+                (save-restriction       ; Search within the current search context.
+                  (narrow-to-region (overlay-start ov) (overlay-end ov))
+                  (when (member (buffer-substring-no-properties (point-min) (point-max)) hits)
+                    (goto-char (setq pos  (point-min)))
+                    (save-match-data
+                      (while (and (not (eobp))
+                                  (condition-case nil
+                                      (re-search-forward (or icicle-search-ecm input)
+                                                         nil 'move-to-end)
+                                    (error nil)))
+                        (if (or (and (equal (match-beginning 0) (match-end 0)) (not (eobp)))
+                                (equal (point) pos))
+                            (forward-char)
+                          (setq pos  (point))
+                          (unless (equal (match-beginning 0) (match-end 0))
+                            (setq ov  (make-overlay (match-beginning 0) (match-end 0)))
+                            (push ov icicle-search-refined-overlays)
+                            (overlay-put ov 'priority 220)
+                            (overlay-put ov 'face 'icicle-search-current-input)))))))))))))))
+
+(defun icicle-search-replace-search-hit (candidate) ; Bound to `C-S-RET' (`icicle-search').
+  "Replace search hit CANDIDATE with `icicle-search-replacement'."
+  ;; NOTE: We allow side effects during replacement.
+  ;; In particular, `icicle-completion-candidates', `icicle-candidate-nb', and `icicle-last-input'
+  ;; can change.
+
+  (let (;; (icicle-candidate-nb          icicle-candidate-nb)
+        ;; (icicle-completion-candidates icicle-completion-candidates)
+        ;; (icicle-last-input            icicle-last-input)
+        (icicle-last-completion-command  icicle-last-completion-command)
+        (compl-win                       (get-buffer-window "*Completions*" 0)))
+    (unless (or icicle-candidate-nb icicle-all-candidates-action)
+      (error "No current candidate.  Cycle or complete to get to a candidate"))
+    (unless icicle-search-replacement
+      (icicle-search-define-replacement)
+      (when (and compl-win icicle-completion-candidates)
+        (with-output-to-temp-buffer "*Completions*"
+          (display-completion-list icicle-completion-candidates)))))
+  (setq icicle-candidate-nb  (or icicle-candidate-nb 0)) ; Replace-all has nil, so use 0.
+  (funcall icicle-candidate-action-fn candidate icicle-search-replacement)) ; Call with second arg.
+
+(defun icicle-search-replace-all-search-hits (candidates) ; Bound to `M-|' (for `icicle-search').
+  "Default alternative list action function for `icicle-search'.
+CANDIDATES is a list of search-hit strings.  They are all matched by
+the initial regexp (context regexp)."
+  (let ((icicle-last-completion-command  icicle-last-completion-command)
+        (compl-win                       (get-buffer-window "*Completions*" 0)))
+;;; $$$$$$ These are now avoided always for all candidates, in `icicle-all-candidates-action-1'.
+;;;     (icicle-minibuffer-message-ok-p  nil) ; Avoid delays from `icicle-msg-maybe-in-minibuffer'.
+;;;     (icicle-help-in-mode-line-delay  0)) ; Avoid delays for individual candidate help.
+    (unless icicle-search-replacement
+      (icicle-search-define-replacement)
+      (when (and compl-win icicle-completion-candidates)
+        (with-output-to-temp-buffer "*Completions*"
+          (display-completion-list icicle-completion-candidates))))
+    (dolist (cand+mrker  (mapcar icicle-get-alist-candidate-function candidates))
+      (icicle-search-action-1 cand+mrker icicle-search-replacement)))
+  (select-window (minibuffer-window))
+  (select-frame-set-input-focus (selected-frame)))
+
+(defun icicle-search-action (string &optional replace-string) ; Bound to `C-RET' (`icicle-search').
+  "Default completion action function for `icicle-search'.
+STRING is a search-hit string.  It is matched by the initial regexp
+\(context regexp).
+
+1. Move to the STRING occurrence in original buffer.  Highlight it.
+2. If `icicle-search-highlight-threshold' is zero, highlight what the
+   current input matches, inside the STRING occurrence.
+3. If REPLACE-STRING is non-nil, replace the current match with it.
+   If `icicle-search-replace-whole-candidate-flag' is non-nil, replace
+   the entire STRING occurrence.  Otherwise, replace only the part
+   that matches the current input.
+4. Highlight the current candidate in `*Completions*'.
+
+   Note: The replacement can be nearly anything allowed as a
+   replacement by `query-replace-regexp', including Lisp-evaluation
+   constructs (`\,...')."
+  (prog1
+      (let* ((icicle-whole-candidate-as-text-prop-p  t)
+             ;; Alternative: If we used `icicle-search-replace-cand-in-alist', then we would bind that
+             ;; to nil to force using the alist, because we would be performing side effects on it.
+             (cand+mrker  (funcall icicle-get-alist-candidate-function string)))
+        (icicle-search-action-1 cand+mrker replace-string))
+    (select-window (minibuffer-window))
+    (select-frame-set-input-focus (selected-frame))))
+
+;; Free vars here: `icicle-orig-win-explore' is bound in `icicle-explore'.
+(defun icicle-search-action-1 (cand+mrker &optional replace-string)
+  "Same as `icicle-search-action', but using full candidate, not string.
+CAND+MRKER is a full alist completion-candidate entry, not just a
+display string as in `icicle-search-action'."
+  (when icicle-completion-candidates
+    (icicle-condition-case-no-debug icicle-search-action-1
+        (progn
+          ;; Move cursor to the match in the original buffer and highlight it.
+          (let* ((candidate                    (if (consp (car-safe cand+mrker))
+                                                   (car-safe (car-safe cand+mrker))
+                                                 (car-safe cand+mrker)))
+                 (marker                       (cdr-safe cand+mrker))
+                 (icicle-search-in-context-fn  (or icicle-search-in-context-fn
+                                                   'icicle-search-in-context-default-fn)))
+            (when (get-buffer-window (marker-buffer marker) 0)
+              (setq icicle-other-window  (get-buffer-window (marker-buffer marker) 0)))
+            (unless marker (error "No such occurrence"))
+            (icicle-condition-case-no-debug icicle-search-action-1-save-window
+                (save-selected-window
+                  (when (window-live-p icicle-orig-win-explore)
+                    (select-window icicle-orig-win-explore))
+                  (let ((completion-ignore-case  case-fold-search)
+                        (buf                     (marker-buffer marker)))
+                    (unless (bufferp buf) (error "No such buffer: %s" buf))
+                    (pop-to-buffer buf)
+                    (raise-frame)
+                    (goto-char marker)
+                    (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+                    ;; Highlight current search context using `icicle-search-main-regexp-current'.
+                    (icicle-place-overlay (- marker (length candidate)) marker
+                                          'icicle-search-current-overlay
+                                          'icicle-search-main-regexp-current
+                                          202 buf)
+                    (funcall icicle-search-in-context-fn cand+mrker replace-string)
+                    (icicle-highlight-candidate-in-Completions)
+                    (run-hooks 'icicle-search-hook)))
+              (error                    ; Ignore disappearance of `*Completions*'.
+               (unless (string-match "Wrong type argument: window-live-p,"
+                                     (error-message-string icicle-search-action-1-save-window))
+                 (error "%s" (error-message-string icicle-search-action-1-save-window)))))
+            nil))                       ; Return nil for success.
+      (error (message "%s" (error-message-string icicle-search-action-1))
+             (error-message-string icicle-search-action-1))))) ; Return the error string.
+
+(defun icicle-search-in-context-default-fn (cand+mrker replace-string)
+  "Default value of `icicle-search-in-context-fn'."
+  (let ((candidate  (if (consp (car-safe cand+mrker))
+                        (car-safe (car-safe cand+mrker))
+                      (car-safe cand+mrker)))
+        (marker     (cdr-safe cand+mrker)))
+    ;; Highlight match and possibly replace.  If replacement tried, then update the dialog state.
+    (when (save-excursion (save-restriction ; Search within the current search context.
+                            (narrow-to-region (- marker (length candidate)) marker)
+                            (icicle-search-highlight-and-maybe-replace cand+mrker replace-string)))
+      ;; Update, since replacement might have changed the current candidate:
+      ;; Rehighlight current context, update last candidate, update candidate in minibuffer.
+      (if icicle-search-highlight-all-current-flag
+          (let ((icicle-search-highlight-all-current-flag  nil))
+            (icicle-search-highlight-input-matches-here))
+        (let ((ov  icicle-search-current-overlay))
+          (save-restriction (narrow-to-region (overlay-start ov) (overlay-end ov))
+                            (icicle-search-highlight-input-matches-here))))
+      (if (null icicle-completion-candidates) ; If have already replaced all, then no candidates.
+          (when (overlayp icicle-search-current-overlay)
+            (delete-overlay icicle-search-current-overlay))
+        (let* ((cand+mrker  (funcall icicle-get-alist-candidate-function
+                                     (setq icicle-last-completion-candidate
+                                           (elt icicle-completion-candidates icicle-candidate-nb))))
+               (marker      (cdr-safe cand+mrker)))
+          (with-current-buffer (marker-buffer marker)
+            (goto-char marker)
+            ;; Highlight current search context using `icicle-search-main-regexp-current'.
+            (icicle-place-overlay (- marker (if (consp (car cand+mrker))
+                                                (length (caar cand+mrker))
+                                              (length (car cand+mrker))))
+                                  marker 'icicle-search-current-overlay
+                                  'icicle-search-main-regexp-current 202 (current-buffer))
+            (unless icicle-search-highlight-all-current-flag
+              (let ((ov  icicle-search-current-overlay))
+                (save-restriction (narrow-to-region (overlay-start ov) (overlay-end ov))
+                                  (icicle-search-highlight-input-matches-here)))))
+          (save-selected-window
+            (select-window (minibuffer-window))
+            (icicle-clear-minibuffer)
+            (setq icicle-nb-of-other-cycle-candidates  (length icicle-completion-candidates))
+            (icicle-insert-cand-in-minibuffer icicle-last-completion-candidate t)
+            (icicle-show-help-in-mode-line icicle-last-completion-candidate))))))
+  (let ((icicle-candidate-nb               icicle-candidate-nb)
+        (icicle-last-completion-candidate  icicle-last-completion-candidate)
+        (icicle-completion-candidates      icicle-completion-candidates))
+    (icicle-complete-again-update)))
+
+;; Free var here: `icicle-search-ecm' is bound in `icicle-search'.
+(defun icicle-search-highlight-and-maybe-replace (cand+mrker replace-string)
+  "Highlight within search context and replace using REPLACE-STRING.
+If REPLACE-STRING is nil, no replacement occurs.
+Arguments are the same as for `icicle-search-in-context-fn'.
+Return non-nil if replacement occurred, nil otherwise."
+  (icicle-search-highlight-context-levels)
+  (icicle-search-highlight-input-matches-here)
+  (let ((replacement-p  nil))
+    (when replace-string
+      (setq replacement-p  t)
+      (goto-char (point-min))
+      (let ((candidate  (if (consp (car-safe cand+mrker))
+                            (car-safe (car-safe cand+mrker))
+                          (car-safe cand+mrker)))
+            (ecm        (and icicle-search-replace-common-match-flag icicle-search-ecm)))
+        (cond (icicle-search-replace-whole-candidate-flag
+               (cond ((string= candidate replace-string) ; Sanity check only.
+                      (save-restriction (widen) (message "Replacement = candidate, and \
+current input matches candidate") (sit-for 2))
+                      (setq replacement-p  nil))
+                     (t
+                      (set-match-data (list (point-min) (point-max)))
+                      (icicle-search-replace-match replace-string
+                                                   (icicle-search-replace-fixed-case-p
+                                                    icicle-search-context-regexp)))))
+              ((not (save-excursion (re-search-forward (or ecm icicle-current-input) nil t)))
+               (save-restriction (widen)
+                                 (message "Text to be replaced not found in candidate") (sit-for 2))
+               (setq replacement-p  nil))
+              (t
+               (save-match-data
+                 (let ((first-p  t))
+                   ;; The condition order is important.  Don't search unless first time (or all)
+                   (while (and (or first-p icicle-all-candidates-action)
+                               (re-search-forward (or ecm icicle-current-input) nil 'move-to-end))
+                     (setq first-p  nil)
+                     (icicle-search-replace-match replace-string
+                                                  (icicle-search-replace-fixed-case-p
+                                                   icicle-current-input)))))))
+        (when replacement-p
+          ;; Update the alist and `minibuffer-completion-table' with the new text.
+
+          ;; An ALTERNATIVE approach would be to use `icicle-search-replace-cand-in-alist'.
+          ;; In that case we would:
+          ;; 1. Bind `icicle-whole-candidate-as-text-prop-p' to nil (in `icicle-search-action'
+          ;;    and `icicle-search-help').
+          ;; 2. Use these two lines, instead of calling `icicle-search-replace-cand-in-mct'.
+          ;;    (icicle-search-replace-cand-in-alist cand+mrker
+          ;;                                         (buffer-substring (point-min) (point-max)))
+          ;;    (setq minibuffer-completion-table
+          ;;          (car (icicle-mctize-all icicle-candidates-alist nil)))
+          ;;  If we used that method (as we used to), then users could not sort the search hits.
+
+          (icicle-search-replace-cand-in-mct cand+mrker (buffer-substring (point-min) (point-max)))
+
+          ;; If we are replacing input matches within a search context, and there are no more matches
+          ;; in the current context, then this context is removed as a candidate. If the current
+          ;; action command is one that moves to the next or previous candidate, then we might need
+          ;; to adjust the current candidate number, to compensate for the removal.
+          ;;
+          ;; If the current action command is one (e.g. `C-S-next'), that moves to the next candidate
+          ;; to do its action, then move back one.  If the current action acts on the previous
+          ;; candidate (e.g. `C-S-prior'), and that previous candidate is the last one, then move
+          ;; forward one candidate, to the first.
+          (when (and icicle-acting-on-next/prev
+                     (not (save-excursion (goto-char (point-min))
+                                          (re-search-forward icicle-current-input nil t))))
+            (let ((nb-cands  (1- (length icicle-completion-candidates)))) ; -1 for replaced one.
+              (unless (wholenump nb-cands) (setq nb-cands  0))
+              (setq icicle-candidate-nb  (cond ((not icicle-candidate-nb) 0)
+                                               ((eq icicle-acting-on-next/prev 'forward)
+                                                (if (zerop icicle-candidate-nb)
+                                                    (1- nb-cands)
+                                                  (1- icicle-candidate-nb)))
+                                               ((eq icicle-candidate-nb nb-cands)  0)
+                                               (t icicle-candidate-nb)))
+              (when (> icicle-candidate-nb nb-cands) (setq icicle-candidate-nb  0))
+              (when (< icicle-candidate-nb 0) (setq icicle-candidate-nb  nb-cands))))
+
+          (let ((icicle-candidate-nb             icicle-candidate-nb)
+                (icicle-minibuffer-message-ok-p  nil)) ; Inhibit no-candidates message.
+            (icicle-complete-again-update))
+
+          ;; If we are using `C-S-RET' and we are on the last candidate, then wrap to the first one.
+          (when (and (not icicle-acting-on-next/prev)
+                     (or (not icicle-candidate-nb)
+                         (>= icicle-candidate-nb (length icicle-completion-candidates))))
+            (setq icicle-candidate-nb  0))
+          (icicle-highlight-candidate-in-Completions)
+          (icicle-search-highlight-context-levels))))
+    replacement-p))                     ; Return indication of whether we tried to replace something.
+
+(defun icicle-search-replace-match (replace-string fixedcase)
+  "Replace current match with REPLACE-STRING, interpreting escapes.
+Treat REPLACE-STRING as it would be treated by `query-replace-regexp'.
+FIXEDCASE is as for `replace-match'.  Non-nil means do not alter case."
+  (if (fboundp 'query-replace-compile-replacement) ; Emacs 22.
+      (let ((compiled
+             (save-match-data
+               (query-replace-compile-replacement replace-string
+                                                  (not icicle-search-replace-literally-flag)))))
+        (condition-case icicle-search-replace-match1
+            (let ((enable-recursive-minibuffers    t) ; So we can read input from \?.
+                  ;; Save and restore these, because we might read input from \?.
+                  (icicle-last-completion-command  icicle-last-completion-command)
+                  (icicle-last-input               icicle-last-input))
+              (replace-match-maybe-edit
+               (if (consp compiled)
+                   ;; `replace-count' is free here, bound in `icicle-search'.
+                   (funcall (car compiled) (cdr compiled) (setq replace-count  (1+ replace-count)))
+                 compiled)
+               fixedcase icicle-search-replace-literally-flag nil (match-data)))
+          (buffer-read-only (ding) (error "Buffer is read-only"))
+          (error (icicle-remove-Completions-window) (error "No match for `%s'" replace-string))))
+    (condition-case icicle-search-replace-match2 ; Emacs < 22.  Try to interpret `\'.
+        (replace-match replace-string fixedcase icicle-search-replace-literally-flag)
+      (error (replace-match replace-string fixedcase t))))) ;   If error, replace literally.
+
+(defun icicle-search-highlight-context-levels ()
+  "Highlight context levels differently (up to 8 levels).
+No such highlighting is done if any of these conditions holds:
+ * `icicle-search-context-level' is not 0 (search context < regexp).
+ * `icicle-search-highlight-context-levels-flag' is nil.
+ * `icicle-search-context-regexp' is nil (non-regexp searching)."
+  (unless (or (/= icicle-search-context-level 0)
+              (not icicle-search-highlight-context-levels-flag)
+              (not icicle-search-context-regexp)) ; E.g. text-property searching
+    (while icicle-search-level-overlays
+      (delete-overlay (car icicle-search-level-overlays))
+      (setq icicle-search-level-overlays  (cdr icicle-search-level-overlays)))
+    (save-match-data
+      (let ((level       1)
+            (max-levels  (min (regexp-opt-depth icicle-search-context-regexp) 8)))
+        (goto-char (point-min))
+        (re-search-forward icicle-search-context-regexp nil t)
+        (condition-case nil
+            (while (<= level max-levels)
+              (unless (equal (match-beginning level) (match-end level))
+                (let ((ov  (make-overlay (match-beginning level) (match-end level))))
+                  (push ov icicle-search-level-overlays)
+                  (overlay-put ov 'priority (+ 205 level)) ; > ediff's 100+, < isearch-overlay's 1001.
+                  (overlay-put ov 'face (intern (concat "icicle-search-context-level-"
+                                                        (number-to-string level))))))
+              (setq level  (1+ level)))
+          (error nil))))))
+
+;; Free var here: `icicle-search-ecm' is bound in `icicle-search'.
+(defun icicle-search-highlight-input-matches-here ()
+  "Highlight all input matches in the current search context."
+  (unless (or (> 0 icicle-search-highlight-threshold) (string= "" icicle-current-input))
+    (goto-char (point-min))
+    (when (and (not icicle-search-highlight-all-current-flag)
+               (overlayp icicle-search-refined-overlays))
+      (delete-overlay icicle-search-refined-overlays)
+      (setq icicle-search-refined-overlays  nil))
+    (unless icicle-search-highlight-all-current-flag
+      (while icicle-search-refined-overlays
+        (delete-overlay (car icicle-search-refined-overlays))
+        (setq icicle-search-refined-overlays  (cdr icicle-search-refined-overlays))))
+    (let ((ov  nil))
+      (save-match-data
+        (while (and (not (eobp)) (re-search-forward (or icicle-search-ecm icicle-current-input)
+                                                    nil 'move-to-end))
+          (if (equal (match-beginning 0) (match-end 0))
+              (forward-char 1)
+            (setq ov  (make-overlay (match-beginning 0) (match-end 0)))
+            (push ov icicle-search-refined-overlays)
+            (overlay-put ov 'priority 220) ; Greater than any possible context-level priority (213).
+            (overlay-put ov 'face 'icicle-search-current-input)))))))
+
+(defun icicle-search-replace-fixed-case-p (from)
+  "Return non-nil if FROM should be replaced without transferring case.
+FROM is a string or nil.  If FROM is nil, then return nil.
+Retuns non-nil if FROM is a string and one of the following holds:
+ * FROM is not all lowercase
+ * `case-replace' or `case-fold-search' is nil"
+  (and from (not (and case-fold-search case-replace (string= from (downcase from))))))
+
+;; Not used for now - this could replace using mct.  In that case, user must not be able to sort.
+(defun icicle-search-replace-cand-in-alist (cand+mrker new-cand)
+  "In `icicle-candidates-alist', replace car of CAND+MRKER by NEW-CAND.
+Replace only the first occurrence of CAND+MRKER in
+`icicle-candidates-alist'.  (There should be only one.)"
+  (let ((newlist  icicle-candidates-alist))
+    (catch 'icicle-search-replace-cand-in-alist
+      (while newlist
+        (when (equal (car newlist) cand+mrker)
+          (setcar newlist (cons new-cand (cdr-safe cand+mrker)))
+          (throw 'icicle-search-replace-cand-in-alist nil))
+        (setq newlist  (cdr newlist))))
+    icicle-candidates-alist))
+
+(defun icicle-search-replace-cand-in-mct (cand+mrker new-cand)
+  "Replace candidate in `minibuffer-completion-table'.
+Update CAND+MRKER itself to use NEW-CAND (replacement string).
+Any text properties on CAND+MRKER's string are preserved.
+Use this only with a `minibuffer-completion-table' derived from an alist."
+  (let ((newlist  minibuffer-completion-table))
+    (catch 'icicle-search-replace-cand-in-mct
+      ;; CAND+MRKER: ("aa" . c) or (("aa" "bb") . c)
+      ;; `minibuffer-completion-table' entry: ("aa" "aa" . c) or ("aa^G^Jbb" . (("aa" "bb") . c))
+      (while newlist
+        (when (equal (cdr (car newlist)) cand+mrker)
+          (let ((new-compl  (if (consp (car cand+mrker)) ; New completion: "QQ" or ("QQ" "bb")
+                                (cons new-cand (cdar cand+mrker))
+                              new-cand))
+                (old-cand   (if (consp (car cand+mrker)) (caar cand+mrker) (car cand+mrker)))
+                rep-cand)
+            (setcar newlist (icicle-mctized-full-candidate (cons new-compl (cdr-safe cand+mrker))))
+            ;; NEWLIST is done.
+            ;; Now update CAND+MRKER to reflect the replacement but with the text properties it had.
+            ;; (cdar NEWLIST) is the new cand+mrker.  Its car or caar is the replaced candidate.
+            ;; It is the first field of the multi-completion, in the latter case.
+            (setq rep-cand  (if (consp (car cand+mrker)) (caar (cdar newlist)) (car (cdar newlist))))
+            (let ((len-old  (length old-cand))
+                  (len-rep  (length rep-cand))
+                  (ii       0)
+                  props)
+              (while (< ii len-old)
+                (setq props  (text-properties-at ii old-cand))
+                (when (< ii len-rep) (add-text-properties ii (1+ ii) props rep-cand))
+                (setq ii  (1+ ii)))
+              (let ((last-props  (text-properties-at (1- len-old) old-cand)))
+                (when (> len-rep len-old)
+                  (add-text-properties len-old len-rep last-props rep-cand))))
+            (if (consp (car cand+mrker))
+                (setcar (car cand+mrker) rep-cand)
+              (setcar cand+mrker rep-cand)))
+          (throw 'icicle-search-replace-cand-in-mct nil))
+        (setq newlist  (cdr newlist))))
+    minibuffer-completion-table))
+
+(defun icicle-search-help (cand)
+  "Use as `icicle-candidate-help-fn' for `icicle-search' commands."
+  (icicle-msg-maybe-in-minibuffer
+   (let* ((icicle-whole-candidate-as-text-prop-p  t)
+          ;; Alternative: If we used `icicle-search-replace-cand-in-alist', then we would bind that
+          ;; to nil to force using the alist, because we would be performing side effects on it.
+          (marker  (cdr (funcall icicle-get-alist-candidate-function cand))))
+     (concat "Buffer: `" (buffer-name (marker-buffer marker))
+             (format "', Position: %d" (marker-position marker))))))
+
+;;;###autoload
+(defun icicle-search-keywords (beg end keywords require-match ; Bound to `C-c ^'.
+                               &optional where &rest args)
+  "Search with one or more keywords, which can each be a regexp.
+Text that matches *any* of the keywords is found.
+
+You can use completion to choose one or more previously entered
+regexps (using `C-RET', `C-mouse-2', `C-next', and so on), or you can
+enter new keywords (using `C-RET').  Use `RET' or `mouse-2' to choose
+the last keyword.
+
+Keywords are interpreted as regexps.  You can change to substring
+completion instead, matching regexp special characters literally, by
+using `C-`' during completion to toggle `icicle-regexp-quote-flag'.
+
+You can alternatively choose to search, not the search contexts as
+defined by keyword matches, but the non-contexts, that is, the text in
+the buffer that does not match the keyword patterns.  To do this, use
+`C-M-~' during completion.  (This is a toggle, and it affects only
+future search commands, not the current one.)
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the `icicle-search'
+documentation."
+  (interactive
+   `(,@(icicle-region-or-buffer-limits)
+       ,(icicle-group-regexp (mapconcat #'icicle-group-regexp (icicle-keyword-list) "\\|"))
+       ,(not icicle-show-multi-completion-flag)
+       ,(icicle-search-where-arg)))
+  (icicle-search beg end keywords (not icicle-show-multi-completion-flag) where))
+
+;;;###autoload
+(defalias 'icicle-regexp-list 'icicle-keyword-list)
+;;;###autoload (autoload 'icicle-keyword-list "icicles-cmd2.el")
+(icicle-define-command icicle-keyword-list ; Command name
+  "Choose a list of keywords. The list of keywords (strings) is returned.
+You can choose from keywords entered previously or enter new keywords
+using `C-RET'.  Each keyword is a regexp.  The regexps are OR'd, and
+the resulting regexp is usable for `icicle-search'." ; Doc string
+  (lambda (name)                        ; Action function
+    (push name keywords)
+    (message "Added keyword `%s'" name))
+  "Choose keyword (regexp) (`RET' when done): " ; `completing-read' args
+  (mapcar #'list (icicle-remove-duplicates regexp-history)) nil nil nil 'regexp-history nil nil
+  ((keywords                              nil) ; Bindings
+   (icicle-use-candidates-only-once-flag  t))
+  nil nil                               ; First code, undo code
+  (prog1 (setq keywords  (nreverse (delete "" keywords))) ; Last code - return the list of keywords.
+    (when (interactive-p) (message "Keywords (regexps): %S" keywords))))
+
+(defun icicle-group-regexp (regexp)
+  "Wrap REGEXP between regexp parens, as a regexp group."
+  (concat "\\(" regexp "\\)"))
+
+;;;###autoload (autoload 'icicle-search-bookmark "icicles-cmd2.el")
+(icicle-define-command icicle-search-bookmark ; Command name
+  "Search bookmarked text.
+See also `icicle-search-bookmarks-together', which searches bookmarks
+together instead of one at a time.
+
+1. Enter a context regexp (using `RET'), to define the possible
+   search-hit contexts.
+2. Choose a bookmark using completion.  It is opened/visited/handled.
+3. (Optional) Type some text to be matched in the search contexts.
+4. Navigate to matches (search hits) using `C-next' etc.
+5. Finish with that bookmark using `RET' (stay) or `C-g' (skip).
+6. (Optional) Repeat steps 2-5 for other bookmarks.
+
+If you use library `Bookmark+' then:
+
+a. If a bookmark specifies a nonempty region, then search only the text
+  in that region.
+
+b. The candidate bookmarks are those in the current `*Bookmark List*'
+  display (list `bmkp-sorted-alist', to be precise).  This means that
+  you can limit the candidates to bookmarks of a certain type (e.g.,
+  only autofiles, using `A S'), bookmarks with certain tags (e.g.,
+  those with tags matching a regexp using `T m %' followed by `>'),
+  and so on.
+
+\(b) provides you with a great deal of flexibility.  However, for your
+convenience, if you use `Bookmark+' then Icicles also provides some
+special-purpose commands for searching the content of bookmarks of
+various types.  For example, `icicle-search-autofile-bookmark'
+searches autofiles.  And you can define your own such commands using
+macro `icicle-define-search-bookmark-command'.
+
+You can alternatively choose to search, not the search contexts as
+defined by the context regexp, but the non-contexts, that is, the text
+in the bookmarked buffer that does not match the regexp.  To do this,
+use `C-M-~' during completion.  (This is a toggle, and it affects only
+future search commands, not the current one.)" ; Doc string
+  icicle-search-bookmark-action         ; Action function
+  prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag) ; `completing-read' args
+  nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+  (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
+  ((enable-recursive-minibuffers             t) ; In case we read input, e.g. File changed on disk...
+   (completion-ignore-case                   bookmark-completion-ignore-case)
+   (prompt                                   "Search bookmark: ")
+   (regexp                                   (icicle-search-read-context-regexp))
+   (icicle-list-use-nth-parts                '(1))
+   (icicle-candidate-properties-alist        (if (not icicle-show-multi-completion-flag)
+                                                 nil
+                                               (if (facep 'file-name-shadow)
+                                                   '((2 (face file-name-shadow))
+                                                     (3 (face bookmark-menu-heading)))
+                                                 '((3 (face bookmark-menu-heading))))))
+   (icicle-transform-function                (if (interactive-p) nil icicle-transform-function))
+   (icicle-whole-candidate-as-text-prop-p    t)
+   (icicle-transform-before-sort-p           t)
+   (icicle-delete-candidate-object           'icicle-bookmark-delete-action)
+   (bookmark-automatically-show-annotations  nil) ; Do not show annotations
+   (icicle-sort-orders-alist
+    (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
+              ("by bookmark name" . icicle-alpha-p))
+            (and (featurep 'bookmark+)
+                 '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+                   ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
+                   ("by last buffer or file access" (bmkp-buffer-last-access-cp
+                                                     bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+                    icicle-alpha-p)
+                   ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+                   ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
+                   ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+                   ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+                    icicle-alpha-p)
+                   ("by Info location" (bmkp-info-cp) icicle-alpha-p)
+                   ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
+                   ("by URL" (bmkp-url-cp) icicle-alpha-p)
+                   ("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                                        bmkp-local-file-type-cp bmkp-handler-cp)
+                    icicle-alpha-p)))
+            '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+              ("case insensitive" . icicle-case-insensitive-string-less-p))))
+   (icicle-candidate-help-fn
+    #'(lambda (cand)
+        (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
+          (setq cand  (funcall icicle-get-alist-candidate-function cand))
+          (setq cand  (cons (caar cand) (cdr cand))))
+        (if (featurep 'bookmark+)
+            (if current-prefix-arg
+                (bmkp-describe-bookmark-internals cand)
+              (bmkp-describe-bookmark cand))
+          (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
+   (icicle-candidates-alist
+    (if (not (featurep 'bookmark+))
+        (mapcar #'(lambda (cand)
+                    (list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
+                                                       (icicle-bookmark-propertize-candidate cand))))
+                (bookmark-all-names))   ; Loads bookmarks file, defining `bookmark-alist'.
+      (bookmark-maybe-load-default-file) ; Loads bookmarks file, defining `bookmark-alist'.
+      (mapcar (if icicle-show-multi-completion-flag
+                  #'(lambda (bmk)
+                      ;; Ignore errors, e.g. from bad or stale bookmark records.
+                      (icicle-condition-case-no-debug nil
+                          (let* ((bname     (bookmark-name-from-full-record bmk))
+                                 (guts      (bookmark-get-bookmark-record bmk))
+                                 (file      (bookmark-get-filename bmk))
+                                 (buf       (bmkp-get-buffer-name bmk))
+                                 (file/buf  (if (and buf (equal file bmkp-non-file-filename))
+                                                buf
+                                              file))
+                                 (tags      (bmkp-get-tags bmk)))
+                            (cons `(,(icicle-candidate-short-help
+                                      (icicle-bookmark-help-string bname)
+                                      (icicle-bookmark-propertize-candidate bname))
+                                    ,file/buf
+                                    ,@(and tags (list (format "%S" tags))))
+                                  guts))
+                        (error nil)))
+                #'(lambda (bmk)
+                    ;; Ignore errors, e.g. from bad or stale bookmark records.
+                    (icicle-condition-case-no-debug nil
+                        (let ((bname  (bookmark-name-from-full-record bmk))
+                              (guts   (bookmark-get-bookmark-record bmk)))
+                          (cons (icicle-candidate-short-help
+                                 (icicle-bookmark-help-string bname)
+                                 (icicle-bookmark-propertize-candidate bname))
+                                guts))
+                      (error nil))))
+              (or (and (or (and (not icicle-bookmark-refresh-cache-flag)
+                                (not (consp current-prefix-arg)))
+                           (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
+                       bmkp-sorted-alist)
+                  (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist)))))))
+  (progn                                ; First code
+    (require 'bookmark)
+    (when (featurep 'bookmark+)
+      ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
+      (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
+        (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow)
+        (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow)
+        (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow)
+        (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow)
+        (define-key (symbol-value map) "\C-\M-i" 'icicle-bookmark-info-narrow)
+        (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow)
+        (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow)
+        (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow)
+        (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow)
+        (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow)
+        (define-key (symbol-value map) [(control meta ?B)]
+          'icicle-bookmark-bookmark-list-narrow) ; `C-M-B'
+        (define-key (symbol-value map) [(control meta ?F)]
+          'icicle-bookmark-local-file-narrow) ; `C-M-F'
+        (define-key (symbol-value map) [(control meta ?K)]
+          'icicle-bookmark-desktop-narrow)))) ; `C-M-K'
+  (icicle-bookmark-cleanup-on-quit)     ; Undo code
+  (icicle-bookmark-cleanup))            ; Last code
+
+(defun icicle-search-bookmark-action (bookmark-name)
+  "Action function for `icicle-search-bookmark'."
+  (setq bookmark-name  (icicle-transform-multi-completion bookmark-name))
+  (bookmark-jump-other-window bookmark-name)
+  (setq mark-active  nil)               ; Unhighlight region, so you can see search hits etc.
+  (let ((icicle-show-Completions-initially-flag  t)
+        (icicle-candidate-action-fn              'icicle-search-action)
+        (enable-recursive-minibuffers            t)
+        (beg
+         (or (and (featurep 'bookmark+) (bmkp-region-bookmark-p bookmark-name)
+                  (bookmark-get-position bookmark-name))
+             (point-min)))
+        (end
+         (or (and (featurep 'bookmark+) (bmkp-region-bookmark-p bookmark-name)
+                  (bmkp-get-end-position bookmark-name))
+             (point-max))))
+    (when (= beg end) (setq beg  (point-min)    end  (point-max)))
+    (icicle-search beg end regexp t))
+  (with-current-buffer (window-buffer (minibuffer-window)) (icicle-erase-minibuffer)))
+
+;; Similar to `icicle-define-bookmark-command-1' in `icicles-cmd1.el'.  Could combine them.
+(defmacro icicle-define-search-bookmark-command (type &optional prompt &rest args)
+  "Define Icicles multi-command for searching bookmarks of type TYPE.
+TYPE is a string to be used for the doc string, default prompt, and in
+ function names.  It should be lowercase and contain no spaces.
+Optional arg PROMPT is the completion prompt.
+ARGS is a list of any additional arguments to be passed to the
+ appropriate `bmkp-TYPE-alist-only' function.
+
+The command defined raises an error unless library `Bookmark+' can be
+loaded."
+  `(icicle-define-command
+    ,(intern (format "icicle-search-%s-bookmark" type)) ; Command name
+    ,(format "Search %s bookmark text.
+Like `icicle-search-bookmark', but with %s bookmarks only.
+You need library `Bookmark+' for this command." type type) ; Doc string
+    icicle-search-bookmark-action       ; Action function
+    prompt1 icicle-candidates-alist nil ; `completing-read' args
+    (not icicle-show-multi-completion-flag)
+    nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
+    nil nil
+    ((IGNORED1                                 (unless (require 'bookmark+ nil t) ; Bindings
+                                                 (error "You need library `Bookmark+' for this \
+command")))
+     (IGNORED2                                 (bookmark-maybe-load-default-file)) ; `bookmark-alist'.
+     (enable-recursive-minibuffers             t) ; In case we read input, e.g. File changed on...
+     (completion-ignore-case                   bookmark-completion-ignore-case)
+     (prompt1                                  ,(or prompt (format "Search %s bookmark: " type)))
+     (icicle-list-use-nth-parts                '(1))
+     (icicle-candidate-properties-alist        (if (not icicle-show-multi-completion-flag)
+                                                   nil
+                                                 (if (facep 'file-name-shadow)
+                                                     '((2 (face file-name-shadow))
+                                                       (3 (face bookmark-menu-heading)))
+                                                   '((3 (face bookmark-menu-heading))))))
+     (icicle-transform-function                (if (interactive-p) nil icicle-transform-function))
+     (icicle-whole-candidate-as-text-prop-p    t)
+     (icicle-transform-before-sort-p           t)
+     (icicle-delete-candidate-object           'icicle-bookmark-delete-action)
+     (regexp                                   (icicle-search-read-context-regexp))
+     (bookmark-automatically-show-annotations  nil) ; Do not show annotations
+     (icicle-sort-orders-alist
+      (append
+       '(("in *Bookmark List* order")   ; Renamed from "turned OFF'.
+         ("by bookmark name" . icicle-alpha-p)
+         ("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
+         ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
+       (and (member ,type '("info" "region"))
+        '(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
+       (and (member ,type '("gnus" "region"))
+        '(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
+       (and (member ,type '("url" "region"))
+        '(("by URL" (bmkp-url-cp) icicle-alpha-p)))
+       (and (not (member ,type '("bookmark-list" "desktop" "gnus" "info" "man" "url")))
+        '(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
+                               bmkp-local-file-type-cp bmkp-handler-cp)
+           icicle-alpha-p)))
+       (and (not (member ,type '("bookmark-list" "desktop" "dired" "non-file")))
+        '(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
+       (and (member ,type '("local-file" "file" "dired" "region"))
+        '(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
+          ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
+          ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
+           icicle-alpha-p)
+          ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
+           icicle-alpha-p)))
+       (and (not (string= ,type "desktop"))
+        '(("by last buffer or file access" (bmkp-buffer-last-access-cp
+                                            bmkp-local-file-accessed-more-recently-cp)
+           icicle-alpha-p)))
+       (and (get-buffer "*Bookmark List*")
+        '(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
+           icicle-alpha-p)))
+       '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
+         ("case insensitive" . icicle-case-insensitive-string-less-p))))
+     (icicle-candidate-help-fn
+      #'(lambda (cand)
+          (when icicle-show-multi-completion-flag
+            (setq cand  (funcall icicle-get-alist-candidate-function cand))
+            (setq cand  (cons (caar cand) (cdr cand))))
+          (if current-prefix-arg
+              (bmkp-describe-bookmark-internals cand)
+            (bmkp-describe-bookmark cand))))
+     (icicle-candidates-alist
+      (mapcar (if icicle-show-multi-completion-flag
+                  #'(lambda (bmk)
+                      ;; Ignore errors, e.g. from bad or stale bookmark records.
+                      (icicle-condition-case-no-debug nil
+                          (let* ((bname     (bookmark-name-from-full-record bmk))
+                                 (guts      (bookmark-get-bookmark-record bmk))
+                                 (file      (bookmark-get-filename bmk))
+                                 (buf       (bmkp-get-buffer-name bmk))
+                                 (file/buf  (if (and buf (equal file bmkp-non-file-filename))
+                                                buf
+                                              file))
+                                 (tags      (bmkp-get-tags bmk)))
+                            ;; Emacs 20 byte-compiler bug prevents using backslash syntax here.
+                            (cons (append (list (icicle-candidate-short-help
+                                                 (icicle-bookmark-help-string bname)
+                                                 (icicle-bookmark-propertize-candidate bname))
+                                                file/buf)
+                                          (and tags (list (format "%S" tags))))
+                                  guts))
+                        (error nil)))
+                #'(lambda (bmk)
+                    ;; Ignore errors, e.g. from bad or stale bookmark records.
+                    (icicle-condition-case-no-debug nil
+                        (let ((bname  (bookmark-name-from-full-record bmk))
+                              (guts   (bookmark-get-bookmark-record bmk)))
+                          (cons (icicle-candidate-short-help
+                                 (icicle-bookmark-help-string bname)
+                                 (icicle-bookmark-propertize-candidate bname))
+                                guts))
+                      (error nil))))
+       (bmkp-sort-omit (funcall ',(intern (format "bmkp-%s-alist-only" type)) ,@args)))))
+    nil                                 ; First code
+    (icicle-bookmark-cleanup-on-quit)   ; Undo code
+    (icicle-bookmark-cleanup)))         ; Last code
+
+;; The following sexps macro-expand to define these commands:
+;;  `icicle-search-all-tags-bookmark'
+;;  `icicle-search-all-tags-regexp-bookmark'
+;;  `icicle-search-autofile-bookmark'
+;;  `icicle-search-bookmark-list-bookmark'
+;;  `icicle-search-desktop-bookmark'
+;;  `icicle-search-dired-bookmark'
+;;  `icicle-search-file-bookmark'
+;;  `icicle-search-gnus-bookmark'
+;;  `icicle-search-info-bookmark'
+;;  `icicle-search-local-file-bookmark'
+;;  `icicle-search-man-bookmark'
+;;  `icicle-search-non-file-bookmark'
+;;  `icicle-search-region-bookmark'
+;;  `icicle-search-remote-file-bookmark'
+;;  `icicle-search-some-tags-bookmark'
+;;  `icicle-search-some-tags-regexp-bookmark'
+;;  `icicle-search-specific-buffers-bookmark'
+;;  `icicle-search-specific-files-bookmark'
+;;  `icicle-search-this-buffer-bookmark'
+;;  `icicle-search-url-bookmark'
+;;  `icicle-search-w3m-bookmark'
+
+(icicle-define-search-bookmark-command "all-tags" nil (bmkp-read-tags-completing))
+(icicle-define-search-bookmark-command "all-tags-regexp" nil (bmkp-read-tags-completing))
+(icicle-define-search-bookmark-command "autofile")
+(icicle-define-search-bookmark-command "bookmark-list")
+(icicle-define-search-bookmark-command "desktop")
+(icicle-define-search-bookmark-command "dired")
+(icicle-define-search-bookmark-command "file")
+(icicle-define-search-bookmark-command "gnus")
+(icicle-define-search-bookmark-command "info")
+(icicle-define-search-bookmark-command "local-file")
+(icicle-define-search-bookmark-command "man")
+(icicle-define-search-bookmark-command "non-file")
+(icicle-define-search-bookmark-command "region" "Search region: ")
+(icicle-define-search-bookmark-command "remote-file")
+(icicle-define-search-bookmark-command "some-tags" nil (bmkp-read-tags-completing))
+(icicle-define-search-bookmark-command "some-tags-regexp" nil (bmkp-read-tags-completing))
+(icicle-define-search-bookmark-command "specific-buffers" nil (icicle-bookmarked-buffer-list))
+(icicle-define-search-bookmark-command "specific-files" nil (icicle-bookmarked-file-list))
+(icicle-define-search-bookmark-command "this-buffer")
+(icicle-define-search-bookmark-command "url")
+(icicle-define-search-bookmark-command "w3m")
+
+;;; Same as `thgcmd-last-thing-type' in `thing-cmds.el'.
+(defvar icicle-last-thing-type (if (boundp 'thgcmd-last-thing-type) thgcmd-last-thing-type 'sexp)
+  "Type of thing last used by `icicle-next-visible-thing' (or previous).")
+
+;;;###autoload
+(defun icicle-search-xml-element (beg end require-match where element)
+  "`icicle-search' with XML ELEMENTs as search contexts.
+ELEMENT is a regexp that is matched against actual element names.
+
+The search contexts are the top-level matching elements within the
+search limits, BEG and END.  Those elements might or might not contain
+descendent elements that are themselves of type ELEMENT.
+
+You can alternatively choose to search, not the search contexts as
+defined by the element-name regexp, but the non-contexts, that is, the
+buffer text that is outside such elements.  To do this, use `C-M-~'
+during completion.  (This is a toggle, and it affects only future
+search commands, not the current one.)
+
+You probably need nXML for this command.  It is included in vanilla
+Emacs, starting with Emacs 23."
+  (interactive
+   (let* ((where    (icicle-search-where-arg))
+          (beg+end  (icicle-region-or-buffer-limits))
+          (beg1     (car beg+end))
+          (end1     (cadr beg+end))
+          (elt      (read-string "XML element (name regexp, no markup): " nil 'regexp-history)))
+     `(,beg1 ,end1 ,(not icicle-show-multi-completion-flag) ,where ,elt)))
+  (let ((nxml-sexp-element-flag  t))
+    (icicle-search-thing
+     'sexp beg end require-match where
+     `(lambda (thg+bds)
+       (and thg+bds
+        (if (fboundp 'string-match-p)
+            (string-match-p ,(format "\\`\\s-*<\\s-*%s\\s-*>" element) (car thg+bds))
+          (string-match ,(format "\\`\\s-*<\\s-*%s\\s-*>" element) (car thg+bds))))))))
+
+;;;###autoload
+(defun icicle-search-xml-element-text-node (beg end require-match where element)
+  "`icicle-search', with text() nodes of XML ELEMENTs as search contexts.
+ELEMENT is a regexp that is matched against actual XML element names.
+
+The search contexts are the text() nodes of the top-level matching
+elements within the search limits, BEG and END.  (Those elements might
+or might not contain descendent elements that are themselves of type
+ELEMENT.)
+
+You can alternatively choose to search, not the search contexts as
+defined by the element-name regexp, but the non-contexts, that is, the
+buffer text that is outside the text nodes of such elements.  To do
+this, use `C-M-~' during completion.  (This is a toggle, and it
+affects only future search commands, not the current one.)
+
+You probably need nXML for this command.  It is included in vanilla
+Emacs, starting with Emacs 23."
+  (interactive
+   (let* ((where    (icicle-search-where-arg))
+          (beg+end  (icicle-region-or-buffer-limits))
+          (beg1     (car beg+end))
+          (end1     (cadr beg+end))
+          (elt      (read-string "XML element (name regexp, no markup): " nil 'regexp-history)))
+     `(,beg1 ,end1 ,(not icicle-show-multi-completion-flag) ,where ,elt)))
+  (let ((nxml-sexp-element-flag  t))
+    (icicle-search-thing
+     'sexp beg end require-match where
+     `(lambda (thg+bds)
+       (and thg+bds
+        (if (fboundp 'string-match-p)
+            (string-match-p ,(format "\\`\\s-*<\\s-*%s\\s-*>" element) (car thg+bds))
+          (string-match ,(format "\\`\\s-*<\\s-*%s\\s-*>" element) (car thg+bds)))))
+     `(lambda (thg+bds)
+       (save-excursion
+         (let* ((tag-end     (string-match ,(format "\\`\\s-*<\\s-*%s\\s-*>" element)
+                                           (car thg+bds)))
+                (child       (icicle-next-visible-thing
+                              'sexp (+ (match-end 0) (cadr thg+bds)) (cddr thg+bds)))
+                (tag-regexp  (concat "\\`\\s-*<\\s-*"
+                                     (if (> emacs-major-version 20)
+                                         (if (boundp 'xmltok-ncname-regexp)
+                                             xmltok-ncname-regexp
+                                           "\\(?:[_[:alpha:]][-._[:alnum:]]*\\)")
+                                       "\\([_a-zA-Z][-._a-zA-Z0-9]\\)")
+                                     "\\s-*>")))
+           (and child
+                (not (if (fboundp 'string-match-p)
+                         (string-match-p tag-regexp (car child))
+                       (string-match tag-regexp (car child))))
+                child)))))))
+
+;;;###autoload
+(defun icicle-search-thing (thing &optional beg end require-match where predicate transform-fn)
+  "`icicle-search' with THINGs as search contexts.
+Enter the type of THING to search: `sexp', `sentence', `list',
+`string', `comment', etc.
+
+Possible THINGs are those for which `bounds-of-thing-at-point' returns
+non-nil (and for which the bounds are not equal: an empty thing).
+This does not include all THINGs for which `thing-at-point' returns
+non-nil.
+
+You can search the region, buffer, multiple buffers, or multiple
+files.  See `icicle-search' for a full explanation.
+
+If user option `icicle-ignore-comments-flag' is nil then include
+THINGs located within comments.  Non-nil means to ignore comments for
+searching.  You can toggle this option using `C-M-;' in the
+minibuffer, but depending on when you do so you might need to invoke
+this command again.
+
+Non-interactively, if optional arg PREDICATE is non-nil then it is a
+predicate that acceptable things must satisfy.  It is passed the thing
+in the form of the cons returned by
+`icicle-next-visible-thing-and-bounds'.
+
+Non-interactively, if optional arg TRANSFORM-FN is non-nil then it is
+a function to apply to each thing plus its bounds and which returns
+the actual search-target to push to `icicle-candidates-alist' in place
+of THING.  Its argument is the same as PREDICATE's.  It returns the
+replacement for the thing plus its bounds, in the same form: a
+cons (STRING START . END), where STRING is the search hit string and
+START and END are its bounds).
+
+You can alternatively choose to search, not the THINGs as search
+contexts, but the non-THINGs (non-contexts), that is, the buffer text
+that is outside THINGs.  To do this, use `C-M-~' during completion.
+\(This is a toggle, and it affects only future search commands, not
+the current one.)
+
+This command is intended only for use in Icicle mode.
+
+NOTE:
+
+1. For best results, use also library `thingatpt+.el'.
+2. In some cases it can take a while to gather the candidate THINGs.
+   Use the command on an active region when you do not need to search
+   THINGS throughout an entire buffer.
+3. In `nxml-mode', remember that option `nxml-sexp-element-flag'
+   controls what a `sexp' means.  To use whole XML elements as search
+   contexts, set it to t, not nil.  (This is already done for the
+   predefined Icicles XML search commands.)
+4. Remember that if there is only one THING in the buffer or active
+   region then no search is done.  Icicles search does nothing when
+   there is only one possible search hit.
+5. The scan candidate things moves forward a THING at a time.  In
+   particular, if either PREDICATE or TRANSFORM-FN disqualifies the
+   thing being scanned currently, then scanning skips forward to the
+   next thing.  The scan does not dig inside the current thing to look
+   for a qualified THING.
+6. In some Emacs releases, especially prior to Emacs 23, the
+   thing-at-point functions can sometimes behave incorrectly.  Thus,
+   `icicle-search-thing' also behaves incorrectly in such cases.
+7. Prior to Emacs 21 there is no possibility of ignoring comments."
+  (interactive (icicle-search-thing-args))
+  (setq icicle-search-context-level  0)
+  (icicle-search beg end 'icicle-search-thing-scan require-match where thing predicate transform-fn))
+
+(defun icicle-search-thing-args ()
+  "Read and return interactive arguments for `icicle-search-thing'."
+  (let* ((where    (icicle-search-where-arg))
+         (beg+end  (icicle-region-or-buffer-limits))
+         (beg1     (car beg+end))
+         (end1     (cadr beg+end))
+         (thing    (intern
+                    (completing-read
+                     (format "%shing (type): " (if icicle-search-complement-domain-p "*NOT* t" "T"))
+                     (icicle-things-alist) nil nil nil nil (symbol-name icicle-last-thing-type)))))
+    (when (and (eq thing 'comment)  icicle-ignore-comments-flag)
+      (message "Use `C-M-;' if you do not want to ignore comments") (sit-for 2))
+    `(,thing ,beg1 ,end1 ,(not icicle-show-multi-completion-flag) ,where)))
+
+;;; Same as `thgcmd-things-alist' in `thing-cmds.el'.
+(defun icicle-things-alist ()
+  "Alist of most thing types currently defined.
+Each is a cons (STRING), where STRING names a type of text entity for
+which there is a either a corresponding `forward-'thing operation, or
+corresponding `beginning-of-'thing and `end-of-'thing operations.  The
+list includes the names of the symbols that satisfy
+`icicle-defined-thing-p', but with these excluded: `thing', `buffer',
+`point'."
+  (let ((types  ()))
+    (mapatoms
+     (lambda (tt)
+       (when (icicle-defined-thing-p tt) (push (symbol-name tt) types))))
+    (dolist (typ  '("thing" "buffer" "point")) ; Remove types that do not make sense.
+      (setq types (delete typ types)))
+    (setq types  (sort types #'string-lessp))
+    (mapcar #'list types)))
+
+;;; Same as `thgcmd-defined-thing-p' in `thing-cmds.el'.
+(defun icicle-defined-thing-p (thing)
+  "Return non-nil if THING (type) is defined for `thing-at-point'."
+  (let ((forward-op    (or (get thing 'forward-op)  (intern-soft (format "forward-%s" thing))))
+        (beginning-op  (get thing 'beginning-op))
+        (end-op        (get thing 'end-op))
+        (bounds-fn     (get thing 'bounds-of-thing-at-point))
+        (thing-fn      (get thing 'thing-at-point)))
+    (or (functionp forward-op)
+        (and (functionp beginning-op) (functionp end-op))
+        (functionp bounds-fn)
+        (functionp thing-fn))))
+
+;;; Same as `hide/show-comments' in `hide-comnt.el'.
+;;;###autoload
+(defun icicle-hide/show-comments (&optional hide/show start end)
+  "Hide or show comments from START to END.
+Interactively, hide comments, or show them if you use a prefix arg.
+Interactively, START and END default to the region limits, if active.
+Otherwise, including non-interactively, they default to `point-min'
+and `point-max'.
+
+Uses `save-excursion', restoring point.
+
+Be aware that using this command to show invisible text shows *all*
+such text, regardless of how it was hidden.  IOW, it does not just
+show invisible text that you previously hid using this command.
+
+From Lisp, a HIDE/SHOW value of `hide' hides comments.  Other values
+show them.
+
+This function does nothing in Emacs versions prior to Emacs 21,
+because it needs `comment-search-forward'."
+  (interactive `(,(if current-prefix-arg 'show 'hide) ,@(icicle-region-or-buffer-limits)))
+  (when (require 'newcomment nil t)     ; `comment-search-forward'
+    (unless start (setq start  (point-min)))
+    (unless end   (setq end    (point-max)))
+    (unless (<= start end) (setq start  (prog1 end (setq end  start))))
+    (let ((bufmodp           (buffer-modified-p))
+          (buffer-read-only  nil)
+          cbeg cend)
+      (unwind-protect
+           (save-excursion
+             (goto-char start)
+             (while (and (< start end) (setq cbeg  (comment-search-forward end 'NOERROR)))
+               (setq cend  (if (string= "" comment-end)
+                               (min (1+ (line-end-position)) (point-max))
+                             (search-forward comment-end end 'NOERROR)))
+               (when (and cbeg cend)
+                 (if (eq 'hide hide/show)
+                     (put-text-property cbeg cend 'invisible t)
+                   (put-text-property cbeg cend 'invisible nil)))))
+        (set-buffer-modified-p bufmodp)))))
+
+;;; Same as `with-comments-hidden' in `hide-comnt.el', except doc here mentions `C-M-;'.
+(defmacro icicle-with-comments-hidden (start end &rest body)
+  "Evaluate the forms in BODY while comments are hidden from START to END.
+But if `icicle-ignore-comments-flag' is nil, just evaluate BODY,
+without hiding comments.  Show comments again when BODY is finished.
+You can toggle `icicle-ignore-comments-flag' using `C-M-;' in the
+minibuffer, but depending on when you do so you might need to invoke
+the current command again.
+
+See `icicle-hide/show-comments', which is used to hide and show the
+comments.  Note that prior to Emacs 21, this never hides comments."
+  (let ((result  (make-symbol "result"))
+        (ostart  (make-symbol "ostart"))
+        (oend    (make-symbol "oend")))
+    `(let ((,ostart  ,start)
+           (,oend    ,end)
+           ,result)
+      (unwind-protect
+           (setq ,result  (progn (when icicle-ignore-comments-flag
+                                   (icicle-hide/show-comments 'hide ,ostart ,oend))
+                                 ,@body))
+        (when icicle-ignore-comments-flag (icicle-hide/show-comments 'show ,ostart ,oend))
+        ,result))))
+
+(defun icicle-search-thing-scan (buffer beg end thing &optional predicate transform-fn)
+  "Scan BUFFER from BEG to END for things of type THING.
+Push the things found onto `icicle-candidates-alist'.
+If BUFFER is nil, scan the current buffer.
+Highlight the matches using face `icicle-search-main-regexp-others'.
+If BEG and END are nil, scan entire BUFFER.
+
+If PREDICATE is non-nil then it is a predicate that acceptable things
+must satisfy.  It is passed the thing plus its bounds, in the form of
+the cons returned by `icicle-next-visible-thing-and-bounds'.
+
+If TRANSFORM-FN is non-nil then it is a function to apply to each
+thing plus its bounds.  Its argument is the same as PREDICATE's.  It
+returns the actual search-target to push to `icicle-candidates-alist'
+in place of THING.  That is, it returns the replacement for the thing
+plus its bounds, in the same form: a cons (STRING START . END), where
+STRING is the search hit string and START and END are its bounds).  It
+can also return nil, in which case it acts as another predicate: the
+thing is not included as a candidate.
+
+NOTE: The scan moves forward a THING at a time.  In particular, if
+either PREDICATE or TRANSFORM-FN disqualifies the thing being scanned
+currently, then scanning skips forward to the next thing.  The scan
+does not dig inside the current thing to look for a qualified THING.
+
+This function respects both `icicle-search-complement-domain-p' and
+`icicle-ignore-comments-flag'."
+  (let ((add-bufname-p  (and buffer icicle-show-multi-completion-flag))
+        (temp-list      ())
+        (last-beg       nil))
+    (unless buffer (setq buffer  (current-buffer)))
+    (when (bufferp buffer)              ; Do nothing if BUFFER is not a buffer.
+      (with-current-buffer buffer
+        (unless beg (setq beg  (point-min)))
+        (unless end (setq end  (point-max)))
+        (unless (< beg end) (setq beg  (prog1 end (setq end  beg)))) ; Ensure BEG is before END.
+        (icicle-with-comments-hidden
+         beg end
+         (icicle-condition-case-no-debug icicle-search-thing-scan
+             (save-excursion
+               (goto-char (setq last-beg  beg)) ; `icicle-next-visible-thing-and-bounds' uses point.
+               (while (and last-beg  (< last-beg end))
+                 (while (and (< beg end) (icicle-invisible-p beg)) ; Skip invisible, overlay or text.
+                   (when (get-char-property beg 'invisible)
+                     (setq beg  (icicle-next-single-char-property-change beg 'invisible nil end))))
+                 (let ((thg+bnds  (icicle-next-visible-thing-and-bounds thing beg end)))
+                   (if (and (not thg+bnds) (not icicle-search-complement-domain-p))
+                       (setq beg  end)
+                     (let* ((thg-beg       (cadr thg+bnds))
+                            (thg-end       (cddr thg+bnds))
+                            (tr-thg-beg    thg-beg)
+                            (tr-thg-end    thg-end)
+                            (hit-beg       (if icicle-search-complement-domain-p
+                                               last-beg
+                                             tr-thg-beg))
+                            (hit-end       (if icicle-search-complement-domain-p
+                                               (or tr-thg-beg end)
+                                             tr-thg-end))
+                            (hit-string    (buffer-substring hit-beg hit-end))
+                            (end-marker    (copy-marker hit-end))
+                            (filteredp     (or (not predicate)
+                                               (not thg+bnds)
+                                               (funcall predicate thg+bnds)))
+                            (new-thg+bnds  (if icicle-search-complement-domain-p
+                                               thg+bnds
+                                             (and filteredp
+                                                  thg+bnds
+                                                  (if transform-fn
+                                                      (funcall transform-fn thg+bnds)
+                                                    thg+bnds)))))
+                       (when (and (not (string= "" hit-string)) ; No-op if empty hit.
+                                  (or new-thg+bnds  icicle-search-complement-domain-p))
+                         (when (and  transform-fn  (not icicle-search-complement-domain-p))
+                           (setq hit-string  (car  new-thg+bnds)
+                                 tr-thg-beg  (cadr new-thg+bnds)
+                                 tr-thg-end  (cddr new-thg+bnds)
+                                 end-marker  (copy-marker tr-thg-end)))
+
+                         (when (and icicle-ignore-comments-flag  icicle-search-complement-domain-p)
+                           (put-text-property 0 (length hit-string) 'invisible nil hit-string))
+                         
+                         (icicle-candidate-short-help
+                          (concat (and add-bufname-p
+                                       (format "Buffer: `%s', "
+                                               (buffer-name (marker-buffer end-marker))))
+                                  (format "Bounds: (%d, %d), Length: %d"
+                                          hit-beg hit-end (length hit-string)))
+                          hit-string)
+                         (push (cons (if add-bufname-p
+                                         (list hit-string
+                                               (let ((string  (copy-sequence (buffer-name))))
+                                                 (put-text-property
+                                                  0 (length string)
+                                                  'face 'icicle-candidate-part string)
+                                                 string))
+                                       hit-string)
+                                     end-marker)
+                               temp-list)
+                         ;; Highlight search context in buffer.
+                         (when (and (not (equal hit-beg hit-end))
+                                    (<= (+ (length temp-list) (length icicle-candidates-alist))
+                                        icicle-search-highlight-threshold))
+                           (let ((ov  (make-overlay hit-beg hit-end)))
+                             (push ov icicle-search-overlays)
+                             (overlay-put ov 'priority 200) ; > ediff's 100+, but < isearch overlays
+                             (overlay-put ov 'face 'icicle-search-main-regexp-others))))
+                       (if thg-end
+                           ;; $$$$$$
+                           ;; The correct code here is (setq beg end).  However, unless you use my
+                           ;; library `thingatpt+.el' or unless Emacs bug #9300 is fixed (hopefully
+                           ;; in Emacs 24), that will loop forever.  In that case we move forward a
+                           ;; char to prevent looping, but that means that the position just after
+                           ;; a THING is considered to be covered by the THING (which is incorrect).
+                           (setq beg  (if (or (featurep 'thingatpt+) (> emacs-major-version 23))
+                                          thg-end
+                                        (1+ thg-end)))
+                         ;; If visible then no more things - skip to END.
+                         (unless (icicle-invisible-p beg) (setq beg  end)))))
+                   (setq last-beg  beg)))
+               (setq icicle-candidates-alist  (append icicle-candidates-alist (nreverse temp-list))))
+           (quit (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup)))
+           (error (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+                  (error "%s" (error-message-string icicle-search-thing-scan)))))))))
+
+;; Same as `thgcmd-invisible-p' in `thing-cmds.el'.
+(defun icicle-invisible-p (position)
+  "Return non-nil if the character at POSITION is invisible."
+  (if (fboundp 'invisible-p)            ; Emacs 22+
+      (invisible-p position)
+    (let ((prop  (get-char-property position 'invisible))) ; Overlay or text property.
+      (if (eq buffer-invisibility-spec t)
+          prop
+        (or (memq prop buffer-invisibility-spec) (assq prop buffer-invisibility-spec))))))
+
+(defun icicle-invisible-face-p (face)
+  "Return non-nil if FACE is currently invisibile."
+  (and (consp buffer-invisibility-spec)
+       (or (memq face buffer-invisibility-spec) (assq face buffer-invisibility-spec))))
+
+(defun icicle-next-visible-thing-and-bounds (thing start end)
+  "Return the next visible THING and its bounds.
+Start at BEG and end at END, when searching for THING.
+Return (THING THING-START . THING-END), with THING-START and THING-END
+ the bounds of THING.  Return nil if no such THING is found.
+
+The \"visible\" in the name refers to ignoring things that are within
+invisible text, such as hidden comments.
+
+You can toggle hiding of comments using `C-M-;' in the minibuffer, but
+depending on when you do so you might need to invoke the current
+command again."
+  (save-excursion (icicle-next-visible-thing thing start end)))
+
+;;; Simple version of `previous-visible-thing' from `thing-cmds.el'.
+;;;###autoload
+(defun icicle-previous-visible-thing (thing start &optional end)
+  "Same as `icicle-next-visible-thing', except it moves backward."
+  (interactive
+   (list (or (and (memq last-command '(icicle-next-visible-thing icicle-previous-visible-thing))
+                  icicle-last-thing-type)
+             (prog1 (intern (completing-read "Thing (type): " (icicle-things-alist) nil nil nil nil
+                                             (symbol-name icicle-last-thing-type)))))
+         (point)
+         (if mark-active (min (region-beginning) (region-end)) (point-min))))
+  (if (interactive-p)
+      (icicle-with-comments-hidden start end (icicle-next-visible-thing thing start end 'BACKWARD))
+    (icicle-next-visible-thing thing start end 'BACKWARD)))
+
+;;; Simple version of `next-visible-thing' from `thing-cmds.el'.
+;;;###autoload
+(defun icicle-next-visible-thing (thing &optional start end backward)
+  "Go to the next visible THING.
+Start at START.  If END is non-nil then look no farther than END.
+Interactively:
+ - START is point.
+ - If the region is not active, END is the buffer end.  If the region
+   is active, END is the region end: the greater of point and mark.
+
+Ignores (skips) comments if `icicle-ignore-comments-flag' is non-nil.
+You can toggle this ignoring of comments using `C-M-;' in the
+minibuffer, but depending on when you do so you might need to invoke
+the current command again.
+
+If you use this command or `icicle-previous-visible-thing'
+successively, even mixing the two, you are prompted for the type of
+THING only the first time.  You can thus bind these two commands to
+simple, repeatable keys (e.g. `f11', `f12'), to navigate among things
+quickly.
+
+Non-interactively, THING is a symbol, and optional arg BACKWARD means
+go to the previous thing.
+
+Return (THING THING-START . THING-END), with THING-START and THING-END
+the bounds of THING.  Return nil if no such THING is found."
+  (interactive
+   (list (or (and (memq last-command '(icicle-next-visible-thing icicle-previous-visible-thing))
+                  icicle-last-thing-type)
+             (prog1 (intern (completing-read "Thing (type): " (icicle-things-alist) nil nil nil nil
+                                             (symbol-name icicle-last-thing-type)))))
+         (point)
+         (if mark-active (max (region-beginning) (region-end)) (point-max))))
+  (setq icicle-last-thing-type  thing)
+  (unless start (setq start  (point)))
+  (unless end   (setq end    (if backward (point-min) (point-max))))
+  (cond ((< start end) (when backward (setq start  (prog1 end (setq end  start)))))
+        ((> start end) (unless backward (setq start  (prog1 end (setq end  start))))))
+  (if (interactive-p)
+      (icicle-with-comments-hidden start end (icicle-next-visible-thing-1 thing start end backward))
+    (icicle-next-visible-thing-1 thing start end backward)))
+
+;;; Same as `next-visible-thing-1' in `thing-cmds.el'.
+(if (fboundp 'next-visible-thing-1)
+    (defalias 'icicle-next-visible-thing-1 'next-visible-thing-1)
+  (defun icicle-next-visible-thing-1 (thing start end backward)
+    "Helper for `icicle-next-visible-thing'.  Get thing past point."
+    (let ((thg+bds  (icicle-next-visible-thing-2 thing start end backward)))
+      (if (not thg+bds)
+          nil
+        ;; $$$$$$ Which is better, > or >=, < or <=, for the comparisons?
+        ;; $$$$$$ (while (and thg+bds
+        ;;                    (if backward  (> (cddr thg+bds) (point)) (<= (cadr thg+bds) (point))))
+        (while (and thg+bds  (if backward  (> (cddr thg+bds) (point))  (< (cadr thg+bds) (point))))
+          (if backward
+              (setq start  (max end (1- (cadr thg+bds))))
+            (setq start  (min end (1+ (cddr thg+bds)))))
+          (setq thg+bds  (icicle-next-visible-thing-2 thing start end backward)))
+        (when thg+bds (goto-char (cadr thg+bds)))
+        thg+bds))))
+
+;;; Same as `next-visible-thing-2' in `thing-cmds.el'.
+(if (fboundp 'next-visible-thing-2)
+    (defalias 'icicle-next-visible-thing-2 'next-visible-thing-2)
+  (defun icicle-next-visible-thing-2 (thing start end &optional backward)
+    "Helper for `icicle-next-visible-thing-1'.  Thing might not be past START."
+    (and (not (= start end))
+         (save-excursion
+           (let ((bounds  nil))
+             ;; If BACKWARD, swap START and END.
+             (cond ((< start end) (when   backward (setq start  (prog1 end (setq end  start)))))
+                   ((> start end) (unless backward (setq start  (prog1 end (setq end  start))))))
+             (catch 'icicle-next-visible-thing-2
+               (while (if backward (> start end) (< start end))
+                 (goto-char start)
+                 ;; Skip invisible text.
+                 (when (and (if backward (> start end) (< start end)) (icicle-invisible-p start))
+                   (setq start  (if (get-text-property start 'invisible) ; Text prop.
+                                    (if backward
+                                        (previous-single-property-change start 'invisible nil end)
+                                      (next-single-property-change start 'invisible nil end))
+                                  (if backward ; Overlay prop.
+                                      (previous-overlay-change start)
+                                    (next-overlay-change start))))
+                   (goto-char start))
+                 (when (and (setq bounds  (bounds-of-thing-at-point thing))
+                            (not (equal (car bounds) (cdr bounds)))) ; Not an empty thing, "".
+                   (throw 'icicle-next-visible-thing-2
+                     (cons (buffer-substring (car bounds) (cdr bounds)) bounds)))
+                 (setq start  (if backward (1- start) (1+ start))))
+               nil))))))
+
+;;;###autoload
+(defun icicle-search-char-property (beg end require-match
+                                    &optional where prop values predicate)
+  "Search for text that has a character property with a certain value.
+If the property is `face' or `font-lock-face', then you can pick
+multiple faces, using completion.  Text is then searched that has a
+face property that includes any of the selected faces.  If you choose
+no face (empty input), then text with any face is found.
+
+By \"character property\" is meant either an overlay property or a
+text property.  If you want to search for only an overlay property or
+only a text property, then use `icicle-search-overlay-property' or
+`icicle-search-text-property' instead.
+
+Non-interactively, arguments BEG, END, REQUIRE-MATCH, and WHERE are as
+for `icicle-search'.  Arguments PROP, VALUES, and PREDICATE are passed
+to `icicle-search-char-property-scan' to define the search contexts.
+
+You can alternatively choose to search, not the search contexts as
+defined, but the zones of buffer text that do NOT have the given
+character property value.  To do this, use `C-M-~' during completion.
+\(This is a toggle, and it affects only future search commands, not
+the current one.)
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive (icicle-search-property-args))
+  (icicle-search beg end 'icicle-search-char-property-scan require-match where prop values nil
+                 predicate))
+
+;;;###autoload
+(defun icicle-search-overlay-property (beg end require-match &optional where prop values predicate)
+  "Same as `icicle-search-char-property', except only overlay property.
+That is, do not also search a text property."
+  (interactive (icicle-search-property-args))
+  (icicle-search beg end 'icicle-search-char-property-scan require-match where prop values 'overlay
+                 predicate))
+
+;;;###autoload
+(defun icicle-search-text-property (beg end require-match ; Bound to `C-c "'.
+                                    &optional where prop values predicate)
+  "Same as `icicle-search-char-property', except only text property.
+That is, do not also search an overlay property."
+  (interactive (icicle-search-property-args))
+  (icicle-search beg end 'icicle-search-char-property-scan require-match where prop values 'text
+                 predicate))
+
+(defun icicle-search-property-args ()
+  "Read and return interactive arguments for `icicle-search-*-property'."
+  (let* ((where    (icicle-search-where-arg))
+         (beg+end  (icicle-region-or-buffer-limits))
+         (beg1     (car beg+end))
+         (end1     (cadr beg+end))
+         (props    (mapcar #'(lambda (prop) (list (symbol-name prop)))
+                           (icicle-char-properties-in-buffers where beg1 end1)))
+         (prop     (intern (completing-read
+                            (format "Property %sto search: "
+                                    (if icicle-search-complement-domain-p "*NOT* " ""))
+                            props nil nil nil nil "face")))
+         (values   (if (memq prop '(face font-lock-face))
+                       (let ((faces  (icicle-face-list)))
+                         (if faces (mapcar #'intern faces) (face-list))) ; Default: all faces.
+                     (list (intern (icicle-completing-read-history
+                                    "Property value: " 'icicle-char-property-value-history))))))
+    `(,beg1 ,end1 ,(not icicle-show-multi-completion-flag) ,where ,prop ,values)))
+
+(defun icicle-char-properties-in-buffers (where beg end &optional type)
+  "List of all character properties in WHERE.
+The other arguments are passed to `icicle-char-properties-in-buffer'.
+Only the character properties are included, not their values.
+WHERE is a list of buffers, a list of files, or a list of region
+  bookmarks (in which case you must also use library `Bookmark+').
+  If nil, then only the current buffer is used.
+TYPE can be `overlay', `text', or nil, meaning overlay properties,
+text properties, or both, respectively."
+  (cond ((and (consp where) (bufferp (car where))) ; List of buffers - search buffers.
+         (dolist (buf  where) (icicle-char-properties-in-buffer buf nil nil type)))
+        ((and (consp where)             ; List of files - search files.
+              (stringp (car where))
+              (file-exists-p (car where)))
+         (dolist (file  where)
+           (icicle-char-properties-in-buffer (find-file-noselect file) nil nil type)))
+        ((consp where)                  ; Search bookmarked regions.
+         (unless (require 'bookmark+ nil t) (error "This requires library `Bookmark+'"))
+         (let (buf+beg buf beg end)
+           (dolist (bmk  where)
+             (setq buf+beg  (bookmark-jump-noselect bmk)
+                   buf      (car buf+beg)
+                   beg      (cdr buf+beg)
+                   end      (bmkp-get-end-position bmk))
+             (when (bufferp buf) (icicle-char-properties-in-buffer (get-buffer buf) beg end type)))))
+        (t                              ; Search this buffer only.
+         (icicle-char-properties-in-buffer (current-buffer) beg end type))))
+
+(defun icicle-char-properties-in-buffer (&optional buffer beg end type)
+  "List of all character properties in BUFFER between BEG and END.
+Only the character properties are included, not their values.
+TYPE can be `overlay', `text', or nil, meaning overlay properties,
+text properties, or both, respectively."
+  (unless buffer (setq buffer  (current-buffer)))
+  (let ((props  ())
+        ovrlays curr-props)
+    (when (bufferp buffer)              ; Do nothing if BUFFER is not a buffer.
+      (with-current-buffer buffer
+        (unless (and beg end)
+          (setq beg  (point-min)
+                end  (point-max)))
+        (when (or (not type) (eq type 'overlay)) ; Get overlay properties.
+          (setq ovrlays  (overlays-in beg end))
+          (dolist (ovrly  ovrlays)
+            (setq curr-props  (overlay-properties ovrly))
+            (while curr-props
+              (unless (memq (car curr-props) props) (push (car curr-props) props))
+              (setq curr-props  (cddr curr-props)))))
+        (when (or (not type) (eq type 'text)) ; Get text properties.
+          (while (< beg end)
+            (setq beg         (or (next-property-change beg nil end) end)
+                  curr-props  (text-properties-at beg))
+            (while curr-props
+              (unless (memq (car curr-props) props) (push (car curr-props) props))
+              (setq curr-props  (cddr curr-props)))))))
+    props))
+
+(defun icicle-search-char-property-scan (buffer beg end prop values type predicate)
+  "Scan BUFFER from BEG to END for character property PROP with VALUES.
+Push hits onto `icicle-candidates-alist'.
+If BUFFER is nil, scan the current buffer.
+Highlight the matches in face `icicle-search-main-regexp-others'.
+If BEG and END are nil, scan entire BUFFER.
+
+Find text with a PROP value that overlaps with VALUES.  That is, if
+the value of PROP is an atom, then it must be a member of VALUES; if
+it is a list, then at least one list element must be a member of
+VALUES.
+
+TYPE is `overlay', `text', or nil, and specifies the type of character
+property - nil means look for both overlay and text properties.
+
+If PREDICATE is non-nil, then push only the hits for which it holds.
+PREDICATE is nil or a Boolean function that takes these arguments:
+  - the search-context string
+  - a marker at the end of the search-context"
+  (let ((add-bufname-p  (and buffer icicle-show-multi-completion-flag))
+        (temp-list      ())
+        (last-beg       nil)
+        (zone-end       nil))
+    (unless buffer (setq buffer  (current-buffer)))
+    (when (bufferp buffer)              ; Do nothing if BUFFER is not a buffer.
+      (with-current-buffer buffer
+        (unless (and beg end) (setq beg  (point-min)
+                                    end  (point-max)))
+        (icicle-condition-case-no-debug icicle-search-char-property-scan
+            (save-excursion
+              (setq last-beg  beg)
+              (while (and (< beg end)
+                          (let* ((charval  (and (or (not type) (eq type 'overlay))
+                                                (get-char-property beg prop)))
+                                 (textval  (and (or (not type) (eq type 'text))
+                                                (get-text-property beg prop)))
+                                 (currval  (icicle-flat-list charval textval)))
+                            (not (icicle-set-intersection values currval))))
+                (setq beg  (icicle-next-single-char-property-change beg prop nil end)))
+              (while (and beg  (< last-beg end))
+                (setq zone-end  (or (icicle-next-single-char-property-change beg prop nil end) end))
+                (let* ((hit-beg     (if icicle-search-complement-domain-p
+                                        last-beg
+                                      beg))
+                       (hit-end     (if icicle-search-complement-domain-p
+                                          beg
+                                        zone-end))
+                       (hit-string  (buffer-substring-no-properties hit-beg hit-end))
+                       end-marker)
+                  (when (and (not (string= "" hit-string)) ; Do nothing if empty hit.
+                             (setq end-marker  (copy-marker hit-end))
+                             (or (not predicate)
+                                 (save-match-data (funcall predicate hit-string end-marker))))
+                    (icicle-candidate-short-help
+                     (concat (and add-bufname-p
+                                  (format "Buffer: `%s', " (buffer-name (marker-buffer end-marker))))
+                             (format "Position: %d, Length: %d"
+                                     (marker-position end-marker) (length hit-string)))
+                     hit-string)
+                    (push (cons (if add-bufname-p
+                                    (list hit-string
+                                          (let ((string  (copy-sequence (buffer-name))))
+                                            (put-text-property 0 (length string)
+                                                               'face 'icicle-candidate-part string)
+                                            string))
+                                  hit-string)
+                                end-marker)
+                          temp-list)
+                    ;; Highlight search context in buffer.
+                    (when (and (<= (+ (length temp-list) (length icicle-candidates-alist))
+                                   icicle-search-highlight-threshold))
+                      (let ((ov  (make-overlay hit-beg hit-end)))
+                        (push ov icicle-search-overlays)
+                        (overlay-put ov 'priority 200) ; > ediff's 100+, but < isearch overlays
+                        (overlay-put ov 'face 'icicle-search-main-regexp-others)))))
+                (setq beg       zone-end
+                      last-beg  zone-end)
+                (while (and (< beg end)
+                            (let* ((charval  (and (or (not type) (eq type 'overlay))
+                                                  (get-char-property beg prop)))
+                                   (textval  (and (or (not type) (eq type 'text))
+                                                  (get-text-property beg prop)))
+                                   (currval  (icicle-flat-list charval textval)))
+                              (not (icicle-set-intersection values currval))))
+                  (setq beg  (icicle-next-single-char-property-change beg prop nil end))))
+              (setq icicle-candidates-alist  (append icicle-candidates-alist (nreverse temp-list))))
+          (quit (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup)))
+          (error (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+                 (error "%s" (error-message-string icicle-search-char-property-scan))))))))
+
+(defun icicle-flat-list (val1 val2)
+  "Return a flat list with all values in VAL1 and VAL2."
+  (let ((result  nil))
+    (unless (listp val1) (setq val1  (list val1)))
+    (unless (listp val2) (setq val2  (list val2)))
+    (while val1 (add-to-list 'result (pop val1)))
+    (while val2 (add-to-list 'result (pop val2)))
+    result))
+
+;; Same as `thgcmd-next-single-char-property-change' in `thing-cmds.el'.
+(if (fboundp 'next-single-char-property-change)
+    (defalias 'icicle-next-single-char-property-change 'next-single-char-property-change)
+  (defun icicle-next-single-char-property-change (position prop &optional object limit)
+    "Position of next change of PROP for text property or overlay change.
+Scans characters forward from buffer position POSITION until property
+PROP changes.  Returns the position of that change.
+
+POSITION is a buffer position (integer or marker).
+
+Optional third arg OBJECT is ignored.  It is present for compatibility
+ with Emacs 22+.
+
+If optional fourth arg LIMIT is non-nil, search stops at position
+LIMIT.  LIMIT is returned if nothing is found before reaching LIMIT.
+
+The property values are compared with `eq'.  If the property is
+constant all the way to the end of the buffer, then return the last
+valid buffer position."
+    (save-excursion
+      (goto-char position)
+      (let ((propval  (get-char-property (point) prop))
+            (end      (min limit (point-max))))
+        (while (and (< (point) end) (eq (get-char-property (point) prop) propval))
+          (goto-char (min (next-overlay-change (point))
+                          (next-single-property-change (point) prop nil end)))))
+      (point))))
+
+;; Same as `thgcmd-previous-single-char-property-change' in `thing-cmds.el'.
+(if (fboundp 'previous-single-char-property-change)
+    (defalias 'icicle-previous-single-char-property-change 'previous-single-char-property-change)
+  (defun icicle-previous-single-char-property-change (position prop &optional object limit)
+    "Position of previous change of PROP for text property or overlay change.
+Scans characters backward from buffer position POSITION until property
+PROP changes.  Returns the position of that change.
+
+POSITION is a buffer position (integer or marker).
+
+Optional third arg OBJECT is ignored.  It is present for compatibility
+ with Emacs 22+.
+
+If optional fourth arg LIMIT is non-nil, search stops at position
+LIMIT.  LIMIT is returned if nothing is found before reaching LIMIT.
+
+The property values are compared with `eq'.  If the property is
+constant all the way to the start of the buffer, then return the first
+valid buffer position."
+    (save-excursion
+      (goto-char position)
+      (let ((propval  (get-char-property (point) prop))
+            (end      (max limit (point-min))))
+        (while (and (> (point) end) (eq (get-char-property (point) prop) propval))
+          (goto-char (max (next-overlay-change (point))
+                          (next-single-property-change (point) prop nil end)))))
+      (point))))
+
+;;;###autoload
+(defun icicle-search-highlight-cleanup ()
+  "Remove all highlighting from the last use of `icicle-search'."
+  (interactive)
+  (let ((inhibit-quit  t))
+    (message "Removing search highlighting...")
+    (while icicle-search-overlays
+      (delete-overlay (car icicle-search-overlays))
+      (setq icicle-search-overlays  (cdr icicle-search-overlays)))
+    (while icicle-search-level-overlays
+      (delete-overlay (car icicle-search-level-overlays))
+      (setq icicle-search-level-overlays  (cdr icicle-search-level-overlays)))
+    (when (overlayp icicle-search-current-overlay)
+      (delete-overlay icicle-search-current-overlay))
+    (when (overlayp icicle-search-refined-overlays)
+      (delete-overlay icicle-search-refined-overlays)
+      (setq icicle-search-refined-overlays  ()))
+    (while icicle-search-refined-overlays
+      (delete-overlay (car icicle-search-refined-overlays))
+      (setq icicle-search-refined-overlays  (cdr icicle-search-refined-overlays)))
+    (message "Removing search highlighting...done")))
+
+;;;###autoload
+(defun icicle-search-word (beg end word-regexp require-match ; Bound to `C-c $'.
+                           &optional where &rest args)
+  "Search for a whole word.
+The search string is regarded as a whole word, but a \"word\" here can
+contain embedded strings of non word-constituent chars (they are
+skipped over, when matching, included in the match), and any leading
+or trailing word-constituent chars in the search string are dropped
+\(ignored for matching, not included in the match): matches begin and
+end on a word boundary.
+
+At the prompt for a word, you can use completion against previous
+Icicles search inputs to choose the word, or you can enter a new word.
+
+Non-interactively, WORD-REGEXP should be a regexp that matches a word.
+The other arguments are the same as for `icicle-search'.
+
+You can alternatively choose to search, not the word search contexts
+you define, but the buffer text that is outside these contexts: the
+non-word text.  To do this, use `C-M-~' during completion.  \(This is
+a toggle, and it affects only future search commands, not the current
+one.)
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(icicle-search-read-word)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (icicle-search beg end word-regexp (not icicle-show-multi-completion-flag) where))
+
+;;;###autoload
+(defun icicle-search-bookmarks-together (scan-fn-or-regexp require-match &rest args)
+  "Search bookmarked regions (together).
+The arguments are the same as for `icicle-search', but without
+arguments BEG, END, and WHERE.
+
+This is the same as using a plain prefix arg, `C-u', with
+`icicle-search'.
+
+You first choose all of the bookmarked buffers/regions to search.
+Then your input is matched against a multi-completion composed of (a)
+the region text that matches the context regexp and (b) the region's
+buffer name.
+
+You can alternatively choose to search, not the search contexts as
+defined by the context regexp, but the non-contexts, that is, the text
+in the bookmarked buffer that does not match the regexp.  To do this,
+use `C-M-~' during completion.  (This is a toggle, and it affects only
+future search commands, not the current one.)
+
+An alternative is multi-command `icicle-search-bookmark', which
+searches the bookmarked regions/buffers you choose one at a time."
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (apply #'icicle-search nil nil scan-fn-or-regexp require-match
+         (let ((current-prefix-arg  '(4))) (icicle-search-where-arg))
+         args))
+
+;;;###autoload
+(defun icicle-search-buffer (scan-fn-or-regexp require-match &rest args)
+  "Search multiple buffers completely.
+Same as using a non-negative numeric prefix arg, such as `C-9', with
+`icicle-search'.  You are prompted for the buffers to search.  All of
+each buffer is searched.  Any existing buffers can be chosen.
+Arguments are the same as for `icicle-search', but without arguments
+BEG, END, and WHERE.
+
+You can alternatively choose to search, not the search contexts as
+defined by the context regexp you provide, but the non-contexts, that
+is, the text in the buffers that does not match the regexp.  To do
+this, use `C-M-~' during completion.  (This is a toggle, and it
+affects only future search commands, not the current one.)"
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (apply #'icicle-search nil nil scan-fn-or-regexp require-match
+         (let ((icicle-show-Completions-initially-flag  t))
+           (mapcar #'get-buffer (let ((icicle-buffer-require-match-flag  'partial-match-ok))
+                                  (icicle-buffer-list))))
+         args))
+
+;;;###autoload
+(defun icicle-search-file (scan-fn-or-regexp require-match &rest args)
+  "Search multiple files completely.
+Same as using a negative numeric prefix arg, such as `C--', with
+`icicle-search'.  You are prompted for the files to search.  All of
+each file is searched.  Any existing files in the current directory
+can be chosen.  Arguments are the same as for `icicle-search', but
+without arguments BEG, END, and WHERE.
+
+You can alternatively choose to search, not the search contexts as
+defined by the context regexp you provide, but the non-contexts, that
+is, the text in the files that does not match the regexp.  To do this,
+use `C-M-~' during completion.  (This is a toggle, and it affects only
+future search commands, not the current one.)"
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (apply #'icicle-search nil nil scan-fn-or-regexp require-match
+         (let ((icicle-show-Completions-initially-flag  t)) (icicle-file-list))
+         args))
+
+;;;###autoload
+(defun icicle-search-bookmark-list-marked (scan-fn-or-regexp require-match &rest args)
+  "Search the files of the marked bookmarks in `*Bookmark List*'.
+Arguments are the same as for `icicle-search', but without arguments
+BEG, END, and WHERE."
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (unless (fboundp 'bmkp-bmenu-get-marked-files)
+    (error "Command `icicle-bookmark-save-marked-files' requires library Bookmark+"))
+  (bmkp-bmenu-barf-if-not-in-menu-list)
+  (apply #'icicle-search nil nil scan-fn-or-regexp require-match (bmkp-bmenu-get-marked-files) args))
+
+;;;###autoload
+(defun icicle-search-dired-marked (scan-fn-or-regexp require-match &rest args)
+  "Search the marked files in Dired.
+Arguments are the same as for `icicle-search', but without arguments
+BEG, END, and WHERE."
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (unless (eq major-mode 'dired-mode)
+    (error "Command `icicle-search-dired-marked' must be called from a Dired buffer"))
+  (apply #'icicle-search nil nil scan-fn-or-regexp require-match (dired-get-marked-files) args))
+
+;;;###autoload
+(defun icicle-search-ibuffer-marked (scan-fn-or-regexp require-match &rest args)
+  "Search the marked buffers in Ibuffer, in order.
+Arguments are the same as for `icicle-search', but without arguments
+BEG, END, and WHERE."
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (unless (eq major-mode 'ibuffer-mode)
+    (error "Command `icicle-search-ibuffer-marked' must be called from an Ibuffer buffer"))
+  (let ((marked-bufs (nreverse (ibuffer-get-marked-buffers))))
+    (unless marked-bufs (setq marked-bufs  (list (ibuffer-current-buffer t))))
+    (apply #'icicle-search nil nil scan-fn-or-regexp require-match marked-bufs args)))
+
+;;;###autoload
+(defun icicle-search-buff-menu-marked (scan-fn-or-regexp require-match &rest args)
+  "Search the marked buffers in Buffer Menu, in order.
+Arguments are the same as for `icicle-search', but without arguments
+BEG, END, and WHERE."
+  (interactive `(,(if icicle-search-whole-word-flag
+                      (icicle-search-read-word)
+                      (icicle-search-read-context-regexp))
+                 ,(not icicle-show-multi-completion-flag)))
+  (unless (eq major-mode 'Buffer-menu-mode)
+    (error "Command `icicle-search-buff-menu-marked' must be called from a Buffer Menu buffer"))
+  (let ((marked-bufs  ()))
+    (save-excursion
+      (Buffer-menu-beginning)
+      (while (re-search-forward "^>" nil t) (push (Buffer-menu-buffer t) marked-bufs)))
+    (setq marked-bufs  (nreverse marked-bufs))
+    (unless marked-bufs (setq marked-bufs  (list (Buffer-menu-buffer t))))
+    (apply #'icicle-search nil nil scan-fn-or-regexp require-match marked-bufs args)))
+
+;;;###autoload
+(defalias 'icicle-search-lines 'icicle-occur)
+;;;###autoload
+(defun icicle-occur (beg end &optional buffers) ; Bound to `C-c ''.
+  "`icicle-search' with a regexp of \".*\".  An `occur' with icompletion.
+Type a regexp to match within each line of one or more buffers.  Use
+`S-TAB' to show matching lines.  Use `C-RET' or `C-mouse-2' to go to
+the line of the current candidate.  Use `C-down', `C-up', `C-next',
+`C-prior', `C-end', or `C-home', to cycle among the matching lines.
+
+By default, search only the current buffer.  Search the active region,
+or, if none, the entire buffer.  With a prefix argument, you are
+prompted for the buffers to search.  You can choose buffers using
+completion (`C-RET' and so on).  If the prefix argument is 99, then
+only buffers visiting files are candidates.
+
+You can use `M-*' to further narrow the match candidates, typing
+additional regexps to match.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(and current-prefix-arg
+                       (icicle-search-choose-buffers (= 99 (prefix-numeric-value
+                                                            current-prefix-arg))))))
+  (let ((fg (face-foreground        'icicle-search-main-regexp-others))
+        (bg (face-background        'icicle-search-main-regexp-others))
+        (icicle-transform-function  (if (interactive-p) nil icicle-transform-function)))
+    (unwind-protect
+         (progn (set-face-foreground 'icicle-search-main-regexp-others nil)
+                (set-face-background 'icicle-search-main-regexp-others nil)
+                (icicle-search beg end ".*" (not icicle-show-multi-completion-flag) buffers))
+      (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+      (set-face-foreground 'icicle-search-main-regexp-others fg)
+      (set-face-background 'icicle-search-main-regexp-others bg))))
+
+;;;###autoload
+(defun icicle-search-sentences (beg end &optional buffers)
+  "`icicle-search' with sentences as contexts.
+Type a regexp to match within each sentence of one or more buffers.
+Use `S-TAB' to show matching sentences.  Use `C-RET' or `C-mouse-2' to
+go to the line of the current candidate.  Use `C-down', `C-up',
+`C-next', `C-prior', `C-end', or `C-home' to cycle among the matching
+sentences.
+
+By default, search only the current buffer.  Search the active region,
+or, if none, the entire buffer.  With a prefix argument, you are
+prompted for the buffers to search.  You can choose buffers using
+completion (`C-RET' and so on).  If the prefix argument is 99, then
+only buffers visiting files are candidates.
+
+You can use `M-*' to further narrow the match candidates, typing
+additional regexps to match.
+
+You can alternatively choose to search, not the search contexts
+\(sentences), but the non-sentences, that is, the text in the buffer
+that is outside sentences.  To do this, use `C-M-~' during completion.
+\(This is a toggle, and it affects only future search commands, not
+the current one.)
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(and current-prefix-arg
+                       (icicle-search-choose-buffers (= 99 (prefix-numeric-value
+                                                            current-prefix-arg))))))
+  (let ((fg (face-foreground        'icicle-search-main-regexp-others))
+        (bg (face-background        'icicle-search-main-regexp-others))
+        (icicle-transform-function  (if (interactive-p) nil icicle-transform-function)))
+    (unwind-protect
+         (progn (set-face-foreground 'icicle-search-main-regexp-others nil)
+                (set-face-background 'icicle-search-main-regexp-others nil)
+                (icicle-search beg end (concat "[A-Z][^.?!]+[.?!]")
+                               (not icicle-show-multi-completion-flag) buffers))
+      (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+      (set-face-foreground 'icicle-search-main-regexp-others fg)
+      (set-face-background 'icicle-search-main-regexp-others bg))))
+
+;;;###autoload
+(defun icicle-search-paragraphs (beg end &optional buffers)
+  "`icicle-search' with paragraphs as contexts.
+Type a regexp to match within each paragraph of one or more buffers.
+Use `S-TAB' to show matching paragraphs.  Use `C-RET' or `C-mouse-2'
+to go to the line of the current candidate.  Use `C-down', `C-up',
+`C-next', `C-prior', `C-end', or `C-home' to cycle among the matching
+paragraphs.
+
+By default, search only the current buffer.  Search the active region,
+or, if none, the entire buffer.  With a prefix argument, you are
+prompted for the buffers to search.  You can choose buffers using
+completion (`C-RET' and so on).  If the prefix argument is 99, then
+only buffers visiting files are candidates.
+
+You can use `M-*' to further narrow the match candidates, typing
+additional regexps to match.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(and current-prefix-arg
+                       (icicle-search-choose-buffers (= 99 (prefix-numeric-value
+                                                            current-prefix-arg))))))
+  (let ((fg (face-foreground        'icicle-search-main-regexp-others))
+        (bg (face-background        'icicle-search-main-regexp-others))
+        (icicle-transform-function  (if (interactive-p) nil icicle-transform-function)))
+    (unwind-protect
+         (progn (set-face-foreground 'icicle-search-main-regexp-others nil)
+                (set-face-background 'icicle-search-main-regexp-others nil)
+                (icicle-search beg end "\\(.+\n\\)+"
+                               (not icicle-show-multi-completion-flag) buffers))
+      (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+      (set-face-foreground 'icicle-search-main-regexp-others fg)
+      (set-face-background 'icicle-search-main-regexp-others bg))))
+
+;;;###autoload
+(defun icicle-search-pages (beg end &optional buffers)
+  "`icicle-search' with pages as contexts.
+Type a regexp to match within each page of one or more buffers.  Use
+`S-TAB' to show matching page.  Use `C-RET' or `C-mouse-2' to go to
+the line of the current candidate.  Use `C-down', `C-up', `C-next',
+`C-prior', `C-end', or `C-home', to cycle among the matching pages.
+
+By default, search only the current buffer.  Search the active region,
+or, if none, the entire buffer.  With a prefix argument, you are
+prompted for the buffers to search.  You can choose buffers using
+completion (`C-RET' and so on).  If the prefix argument is 99, then
+only buffers visiting files are candidates.
+
+You can use `M-*' to further narrow the match candidates, typing
+additional regexps to match.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(and current-prefix-arg
+                       (icicle-search-choose-buffers (= 99 (prefix-numeric-value
+                                                            current-prefix-arg))))))
+  (let ((fg (face-foreground        'icicle-search-main-regexp-others))
+        (bg (face-background        'icicle-search-main-regexp-others))
+        (icicle-transform-function  (if (interactive-p) nil icicle-transform-function)))
+    (unwind-protect
+         (progn (set-face-foreground 'icicle-search-main-regexp-others nil)
+                (set-face-background 'icicle-search-main-regexp-others nil)
+                (icicle-search beg end "\\([^\f]*[\f]\\|[^\f]+$\\)"
+                               (not icicle-show-multi-completion-flag) buffers))
+      (when icicle-search-cleanup-flag (icicle-search-highlight-cleanup))
+      (set-face-foreground 'icicle-search-main-regexp-others fg)
+      (set-face-background 'icicle-search-main-regexp-others bg))))
+
+;;;###autoload
+(defun icicle-comint-search (beg end)   ; Bound to `C-x `' in `comint-mode'.
+  "Use `icicle-search' to pick up a previous input for reuse.
+Use this in a `comint-mode' buffer, such as *shell* or
+*inferior-lisp*.  This searches your interactive history in the buffer
+for a match to your current input, which you can change dynamically.
+When you choose a previous input, it is copied to the current prompt,
+for reuse.  If the region is active, then only it is searched;
+otherwise, the entire buffer is searched.
+
+Use `C-RET' or `C-mouse-2' to choose a previous input for reuse.  Use
+`down', `up', `next', `prior', `end', or `home' to cycle among your
+previous inputs.  (You probably do NOT want to use `C-next' etc.,
+since such keys will not only cycle to another candidate but also
+reuse it immediately.)
+
+As for other Icicles search commands, your current input narrows the
+set of possible candidates.  See `icicle-search' for more
+information.
+
+You can use `M-*' to further narrow the match candidates, typing
+additional regexps to match.
+
+Note that previous commands are identified by looking through the
+shell buffer for a shell prompt.  This is not foolproof.  If, for
+instance you use command `ls', the output includes an auto-save file
+such as #foo.el#, and `#' in the first column represents a shell
+prompt, then #foo.el# will be misinterpreted as a previous command.
+
+Also, depending on your shell, you might want to customize variables
+such as the following:
+
+`shell-prompt-pattern',`telnet-prompt-pattern'.
+
+Being a search command, `icicle-comint-search' cannot give you access
+to previous shell commands that are not visible in the current buffer.
+See also \\\\[icicle-comint-command] for another way to reuse commands,
+including those from previous sessions.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments, see the doc for command
+`icicle-search'."
+  ;; $$$$$$ It would be good to somehow rebind C-next etc. to just what next etc. does.
+  (interactive (icicle-region-or-buffer-limits))
+  ;; Is there a better test we can use, to make sure the current mode inherits from `comint-mode'?
+  (unless (where-is-internal 'comint-send-input (keymap-parent (current-local-map)))
+    (error "Current mode must be derived from comint mode"))
+  (let ((orig-search-hook           icicle-search-hook)
+        (icicle-transform-function  'icicle-remove-duplicates))
+    (add-hook 'icicle-search-hook 'icicle-comint-search-send-input)
+    (unwind-protect
+         (icicle-search beg end
+                        (concat comint-prompt-regexp "\\S-.*") nil) ; Match not required (edit).
+      (remove-hook 'icicle-search-hook 'icicle-comint-search-send-input)))
+  (goto-char (point-max))
+  (unless (pos-visible-in-window-p) (recenter icicle-recenter)))
+
+(defun icicle-comint-search-send-input ()
+  "Grab current completion input and use that for comint input."
+  (unless (comint-check-proc (current-buffer))
+    (error "No live process associated with this buffer"))
+  (let ((comint-get-old-input
+         (if (minibuffer-window-active-p (minibuffer-window))
+             'icicle-comint-search-get-minibuffer-input ; Use minibuffer input (e.g. for action fn).
+           'icicle-comint-search-get-final-choice))) ; Use final choice.
+    (comint-copy-old-input))
+  (comint-send-input))
+
+(defun icicle-comint-search-get-minibuffer-input ()
+  "Return the minibuffer input, beyond the prompt."
+  (let* ((cand         (icicle-minibuf-input))
+         (input-start  (and (string-match comint-prompt-regexp cand) (match-end 0))))
+    (if input-start (substring cand input-start) cand)))
+
+(defun icicle-comint-search-get-final-choice ()
+  "Return the final choice, beyond the prompt."
+  (let ((input-start  (and (string-match comint-prompt-regexp icicle-explore-final-choice)
+                           (match-end 0))))
+    (if input-start
+        (substring icicle-explore-final-choice input-start)
+      icicle-explore-final-choice)))
+
+;;;###autoload (autoload 'icicle-comint-command "icicles-cmd2.el")
+(icicle-define-command icicle-comint-command ; Bound to `C-c TAB' in `comint-mode'.
+  "Retrieve a previously used command.
+Use this in a `comint-mode' buffer such as `*shell*' or
+`*inferior-lisp*'.
+
+Note, depending on your shell, you might want to customize variables
+such as the following:
+
+`shell-prompt-pattern',`telnet-prompt-pattern'.
+
+See also \\\\[icicle-comint-search] for another way to reuse commands." ; Doc string
+  insert                                ; Action function
+  "Choose a previous command: "         ; `completing-read' args
+  (mapcar #'list (cddr comint-input-ring)) nil nil nil 'shell-command-history
+  (aref (cddr comint-input-ring) 0) nil
+  ((icicle-transform-function  'icicle-remove-duplicates))) ; Bindings
+
+(defun icicle-comint-hook-fn ()
+  "Hook to set up Comint mode for Icicles."
+  (set (make-local-variable 'icicle-search-command) 'icicle-comint-search))
+
+;;;###autoload
+(defun icicle-compilation-search (beg end) ; Bound to `C-c `' in `compilation(-minor)-mode'.
+  "Like `icicle-search', but show the matching compilation-buffer hit.
+Use this in a compilation buffer, such as `*grep*', searching for a
+regexp as with `icicle-search'.  Use `C-RET' or `C-mouse-2' to show
+the target-buffer hit corresponding to the current completion
+candidate.  Use `C-down', `C-up', `C-next', `C-prior', `C-end', or
+`C-home' to cycle among the target-buffer hits.
+
+As for `icicle-search', you can further narrow the match candidates by
+typing a second regexp to search for among the first matches.  See
+`icicle-search' for more information.
+
+Altogether, using this with `grep' gives you two or three levels of
+regexp searching: 1) the `grep' regexp, 2) the major `icicle-search'
+regexp, and optionally 3) the refining `icicle-search' regexp.
+
+In Emacs 22 and later, you can replace search-hit text, as in
+`icicle-search'.  In earlier Emacs versions, you cannot replace text.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments, see the doc for command
+`icicle-search'."
+  (interactive (icicle-region-or-buffer-limits))
+  (unless (condition-case nil (eq (current-buffer) (compilation-find-buffer)) (error nil))
+    (error "Current buffer must be a compilation buffer"))
+  (save-excursion (goto-char (point-min))
+                  (compilation-next-error 1)
+                  (setq beg  (if beg (max beg (point)) (point))))
+  (let ((icicle-transform-function    (if (interactive-p) nil icicle-transform-function))
+        (icicle-candidate-alt-action-fn
+         (if (boundp 'compilation-highlight-overlay) ; Emacs 22 test.
+             icicle-candidate-alt-action-fn
+           #'(lambda (cand)
+               (message "Cannot replace matching text in Emacs before version 22"))))
+        (next-error-highlight
+         ;; Highlight indefinitely.  `until-move' should be part of Emacs (patch sent), but it's not.
+         (if (and (featurep 'compile+) (featurep 'simple+)) 'until-move 1000000))
+        (icicle-search-in-context-fn  'icicle-compilation-search-in-context-fn)
+        (fg (face-foreground          'icicle-search-main-regexp-others))
+        (bg (face-background          'icicle-search-main-regexp-others)))
+    (unwind-protect
+         (progn
+           (set-face-foreground 'icicle-search-main-regexp-others nil)
+           (set-face-background 'icicle-search-main-regexp-others nil)
+           (icicle-search beg end ".*" t))
+      (set-face-foreground 'icicle-search-main-regexp-others fg)
+      (set-face-background 'icicle-search-main-regexp-others bg))))
+
+(defun icicle-compilation-search-in-context-fn (cand+mrker replace-string)
+  "`icicle-search-in-context-fn' used for `icicle-compilation-search'.
+If `crosshairs.el' is loaded, then the target position is highlighted."
+  (if (not (fboundp 'compilation-next-error-function))
+      (compile-goto-error)              ; Emacs 20, 21.
+    (setq compilation-current-error  (point)) ; Emacs 22+.
+    (compilation-next-error-function 0 nil))
+  (save-excursion
+    (save-restriction
+      (let ((inhibit-field-text-motion  t)) ; Just to be sure, for `end-of-line'.
+        (narrow-to-region (progn (beginning-of-line) (point)) (progn (end-of-line) (point))))
+      (icicle-search-highlight-and-maybe-replace cand+mrker replace-string)))
+  (when (fboundp 'crosshairs-highlight) (crosshairs-highlight 'line-only 'nomsg))
+  (let ((icicle-candidate-nb  icicle-candidate-nb)) (icicle-complete-again-update)))
+
+(defun icicle-compilation-hook-fn ()
+  "Hook setting `icicle-search-command' for compilation modes.
+Used on `compilation-mode-hook' and `compilation-minor-mode-hook'."
+  (set (make-local-variable 'icicle-search-command) 'icicle-compilation-search))
+
+;;;###autoload
+(defun icicle-search-w-isearch-string (&optional use-context-p) ; Bound to `S-TAB' in Isearch.
+  "Icicles-search the buffer using an Isearch string chosen by completion.
+The Isearch string you choose is used as the Icicles search context.
+You can navigate among its occurrences or search within those
+occurrences for a subpattern.
+
+For Emacs 22 and later, if option `isearch-allow-scroll' is non-nil
+then a prefix argument changes the behavior, as follows:
+
+1. You are prompted for an Icicles search-context regexp.
+2. You choose an Isearch string using completion.  It is copied to the
+   `kill-ring'.
+3. You can yank that string anytime during Icicles search, to search
+   for it within the search contexts defined by the regexp matches."
+  (interactive "P")
+  (isearch-done)
+  (if (or (not use-context-p) (not (boundp 'isearch-allow-scroll)))
+      (icicle-search (point-min) (point-max) (icicle-isearch-complete-past-string) t)
+    (let ((regexp  (icicle-search-read-context-regexp)))
+      (kill-new (icicle-isearch-complete-past-string))
+      (icicle-search (point-min) (point-max) regexp t))))
+
+;;;###autoload
+(defalias 'icicle-search-defs 'icicle-imenu)
+;;;###autoload
+(defun icicle-imenu (beg end require-match &optional where) ; Bound to `C-c ='.
+  "Search/go to an Imenu entry using `icicle-search'.
+Recommended: Use library `imenu+.el' also.
+In Emacs-Lisp mode, `imenu+.el' classifies definitions using these
+submenus:
+
+ 1. Keys         - keys in the global keymap
+ 2. Keys in Maps - keys in keymaps other than global keymap
+ 3. Functions    - functions, whether interactive or not
+ 4. Macros       - macros defined with `defmacro'
+ 5. User Options - user variables, from `defcustom'
+ 6. Variables    - other variables (non-options), from `defvar'
+ 7. Faces        - faces, from `defface'
+ 8. Other        - other definitions
+
+If you use this command with a prefix argument then multiple buffers,
+files, or bookmarks are used (see `icicle-search' for information
+about prefix arg behavior).  When this is the case, the Imenu mode
+\(and `imenu-generic-expression') of the current buffer at time of
+command invocation determines what kinds of definitions are found.
+So, if you want to search for definitions in a certain language, then
+invoke this command from a buffer in that language.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'.
+
+See also these type-specific Icicles Imenu multi-commands:
+
+* `icicle-imenu-command' - search/go to Emacs command definitions
+* `icicle-imenu-non-interactive-function' - non-command Lisp fn defs
+* `icicle-imenu-macro' - search/go to Lisp macro definitions
+* `icicle-imenu-user-option' - search/go to user option definitions
+* `icicle-imenu-variable' - search/go to Lisp variable definitions
+* `icicle-imenu-face' - search/go to Emacs face definitions
+* `icicle-imenu-key-explicit-map', `icicle-imenu-key-implicit-map'
+  - search/go to Emacs key definitions
+
+In addition, there are commands like each of the Imenu commands
+mentioned above, but with the suffix `-full'.  These commands use
+\"full\" definitions as completion candidates, rather than using only
+whatever the buffer's Imenu regexps matches.
+
+A \"full\" candidate is obtained by first matching the Imenu regexp,
+then moving forward one sexp from the match beginning.  For a Lisp
+function, for instance, the regexp match starts at the `defun' sexp's
+opening parenthesis, and the full candidate is the entire `defun'
+sexp.
+
+Outside of Lisp, \"full\" does not always mean that the candidate is
+larger.  Example: a C-language procedure/function definition.  The
+text between the regexp match beginning and `forward-sexp' is just the
+procedure name."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (icicle-imenu-1 nil beg end require-match where))
+
+;;;###autoload
+(defalias 'icicle-search-defs-full 'icicle-imenu-full)
+;;;###autoload
+(defun icicle-imenu-full (beg end require-match &optional where)
+  "Search/go to an Imenu entry using `icicle-search'.
+Same as `icicle-imenu', except candidates are full definitions.
+This really means that a candidate is the text between the beginning
+of the Imenu regexp match and `forward-sexp' from there.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (icicle-imenu-1 'FULL beg end require-match where))
+
+;;;###autoload
+(defun icicle-imenu-command (beg end require-match &optional where)
+  "Search/go to an Emacs command definition using `icicle-search'.
+This uses `commandp', so it finds only currently defined commands.
+That is, if the buffer has not been evaluated, then its function
+definitions are NOT considered commands by `icicle-imenu-command'.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where 'icicle-imenu-command-p
+                  (lambda (menus)
+                    (or (car (assoc "Functions" menus)) (car (assoc "Other" menus))
+                        (error "No command definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-command-full (beg end require-match &optional where)
+  "Search/go to an Emacs command definition using `icicle-search'.
+Same as `icicle-imenu-command', except candidates are complete command
+definitions.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (eq major-mode 'emacs-lisp-mode) beg end require-match where
+                  'icicle-imenu-command-p
+                  (lambda (menus)
+                    (or (car (assoc "Functions" menus)) (car (assoc "Other" menus))
+                        (error "No command definitions in buffer")))))
+
+(defun icicle-imenu-command-p (ignored-hit-string ignored-marker)
+  "Return non-nil for a command definition.
+Predicate for `icicle-search'.
+Both arguments are ignored here."
+  (let ((indx  (if (< emacs-major-version 21) 6 2)))
+    (commandp (intern-soft
+               (buffer-substring-no-properties (match-beginning indx) (match-end indx))))))
+
+;;;###autoload
+(defun icicle-imenu-non-interactive-function (beg end require-match &optional where)
+  "Search/go to an Emacs non-command function definition with `icicle-search'.
+This uses `commandp' to distinguish currently defined commands from
+other functions.  This means that if the buffer has not yet been
+evaluated, then ALL of its function definitions are considered
+non-interactive by `icicle-imenu-non-interactive-function'.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where 'icicle-imenu-non-interactive-function-p
+                  (lambda (menus)
+                    (or (car (assoc "Functions" menus)) (car (assoc "Other" menus))
+                        (error "No non-command function definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-non-interactive-function-full (beg end require-match &optional where)
+  "Search/go to an Emacs non-command function definition with `icicle-search'.
+Same as `icicle-imenu-non-interactive-function', except candidates are
+complete function definitions.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (memq major-mode '(emacs-lisp-mode lisp-mode)) beg end require-match where
+                  'icicle-imenu-non-interactive-function-p
+                  (lambda (menus)
+                    (or (car (assoc "Functions" menus)) (car (assoc "Other" menus))
+                        (error "No non-command function definitions in buffer")))))
+
+(defun icicle-imenu-non-interactive-function-p (ignored-hit-string ignored-marker)
+  "Return non-nil for a non-interactive function definition.
+Predicate for `icicle-search'.  Both arguments are ignored."
+  (let* ((indx  (if (< emacs-major-version 21) 6 2))
+         (fn    (intern-soft
+                 (buffer-substring-no-properties (match-beginning indx) (match-end indx)))))
+    (and (fboundp fn) (not (commandp fn)))))
+
+;;;###autoload
+(defun icicle-imenu-macro (beg end require-match &optional where)
+  "Search/go to an Emacs macro definition using `icicle-search'.
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode or Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where 'icicle-imenu-macro-p
+                  (lambda (menus)
+                    (or (car (assoc "Macros" menus)) (car (assoc "Other" menus))
+                        (error "No macro definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-macro-full (beg end require-match &optional where)
+  "Search/go to an Emacs macro definition using `icicle-search'.
+Same as `icicle-imenu-non-interactive-function', except candidates are
+complete function definitions.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (memq major-mode '(emacs-lisp-mode lisp-mode)) beg end require-match where
+                  'icicle-imenu-macro-p
+                  (lambda (menus)
+                    (or (car (assoc "Macro" menus)) (car (assoc "Other" menus))
+                        (error "No macro definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-variable (beg end require-match &optional where)
+  "Search/go to an Emacs non-option variable definition using `icicle-search'.
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode or Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Variables" menus)) (car (assoc "Other" menus))
+                        (error "No non-option variable definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-variable-full (beg end require-match &optional where)
+  "Search/go to an Emacs non-option variable definition using `icicle-search'.
+Same as `icicle-imenu-variable', except candidates are complete
+variable definitions.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (memq major-mode '(emacs-lisp-mode lisp-mode)))
+    (error "This command is only for Emacs-Lisp mode or Lisp mode"))
+  (icicle-imenu-1 (memq major-mode '(emacs-lisp-mode lisp-mode)) beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Variables" menus)) (car (assoc "Other" menus))
+                        (error "No non-option variable definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-user-option (beg end require-match &optional where)
+  "Search/go to an Emacs user option definition using `icicle-search'.
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "User Options" menus)) (car (assoc "Other" menus))
+                        (error "No user option definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-user-option-full (beg end require-match &optional where)
+  "Search/go to an Emacs user option definition using `icicle-search'.
+Same as `icicle-imenu-user-option', except candidates are complete
+option definitions.
+
+Remember that non-nil option
+`icicle-hide-common-match-in-Completions-flag' hides, in
+`*Completions*', all lines of multi-line candidates that do not match
+your current minibuffer input.  You can toggle this at anytime during
+completion using `C-u C-x .'"
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (eq major-mode 'emacs-lisp-mode) beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "User Options" menus)) (car (assoc "Other" menus))
+                        (error "No user option definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-key-implicit-map (beg end require-match &optional where)
+  "Search/go to a global/local Emacs key definition using `icicle-search'.
+This means a definition where no key map is specified explicitly -
+e.g., `global-set-key'.
+
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Keys" menus)) (car (assoc "Other" menus))
+                        (error "No implicit-map key definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-key-implicit-map-full (beg end require-match &optional where)
+  "Search/go to a global/local Emacs key definition using `icicle-search'.
+Same as `icicle-imenu-key-implicit-map', except candidates are complete key
+definitions."
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (eq major-mode 'emacs-lisp-mode) beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Keys" menus)) (car (assoc "Other" menus))
+                        (error "No implicit-map key definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-key-explicit-map (beg end require-match &optional where)
+  "Search/go to an Emacs key definition for a named map using `icicle-search'.
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Keys in Maps" menus)) (car (assoc "Other" menus))
+                        (error "No explicit-map key definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-key-explicit-map-full (beg end require-match &optional where)
+  "Search/go to an Emacs key definition for a named map using `icicle-search'.
+Same as `icicle-imenu-key-explicit-map', except candidates are
+complete key definitions."
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (eq major-mode 'emacs-lisp-mode) beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Keys in Maps" menus)) (car (assoc "Other" menus))
+                        (error "No explicit-map key definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-face (beg end require-match &optional where)
+  "Search/go to an Emacs face definition using `icicle-search'.
+This command is intended only for use in Icicle mode.  It is defined
+using `icicle-search'.  For more information, in particular for
+information about the arguments and the use of a prefix argument to
+search multiple regions, buffers, or files, see the doc for command
+`icicle-search'."
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 nil beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Faces" menus)) (car (assoc "Other" menus))
+                        (error "No face definitions in buffer")))))
+
+;;;###autoload
+(defun icicle-imenu-face-full (beg end require-match &optional where)
+  "Search/go to an Emacs face definition using `icicle-search'.
+Same as `icicle-imenu-face', except candidates are complete face
+definitions."
+  ;; Note: For this command, the candidate does not correspond to the regexp match.
+  ;; Instead, it corresponds to that match plus text at the end to complete the definition.
+  (interactive `(,@(icicle-region-or-buffer-limits)
+                 ,(not icicle-show-multi-completion-flag)
+                 ,(icicle-search-where-arg)))
+  (unless (or where (eq major-mode 'emacs-lisp-mode))
+    (error "This command is only for Emacs-Lisp mode"))
+  (icicle-imenu-1 (eq major-mode 'emacs-lisp-mode) beg end require-match where nil
+                  (lambda (menus)
+                    (or (car (assoc "Faces" menus)) (car (assoc "Other" menus))
+                        (error "No face definitions in buffer")))))
+
+(defun icicle-imenu-1 (fullp beg end require-match &optional where predicate submenu-fn)
+  "Helper for `icicle-imenu*' commands.
+Non-nil FULLP means candidate is from the regexp match beginning
+ through `forward-sexp' from there.
+Optional arg SUBMENU-FN is a function to apply to the list of Imenu
+ submenus to choose one.  If nil then the user chooses one using
+ completion.
+The other args are as for `icicle-search'."
+  (unless imenu-generic-expression (error "No Imenu pattern for this buffer"))
+  (let ((case-fold-search  (if (or (local-variable-p 'imenu-case-fold-search)
+                                   (not (local-variable-p 'font-lock-defaults)))
+                               imenu-case-fold-search
+                             (nth 2 font-lock-defaults)))
+        (old-table         (syntax-table))
+        (table             (copy-syntax-table (syntax-table)))
+        (slist             imenu-syntax-alist))
+    (dolist (syn  slist)                ; Modify the syntax table used while matching regexps.
+      (if (numberp (car syn))
+          (modify-syntax-entry (car syn) (cdr syn) table) ; Single character.
+        (dolist (char  (car syn))  (modify-syntax-entry char (cdr syn) table)))) ; String.
+    (unwind-protect
+         (save-match-data
+           (set-syntax-table table)
+           (let* ((others   0)
+                  (menus    (mapcar #'(lambda (menu)
+                                        (when (equal (car menu) "Other")
+                                          (setq others  (1+ others))
+                                          (when (> others 1)
+                                            (setcar menu (format "Other<%d>" others))))
+                                        menu)
+                                    (icicle-remove-if-not
+                                     #'icicle-imenu-in-buffer-p ; Use only menus that match buffer.
+                                     (mapcar #'(lambda (menu) ; Name unlabeled menu(s) `Other[]'.
+                                                 (if (stringp (car menu))
+                                                     menu
+                                                   (cons "Other" (cdr menu))))
+                                             imenu-generic-expression))))
+                  (submenu  (if submenu-fn
+                                (funcall submenu-fn menus)
+                              (if (cadr menus)
+                                  (let ((icicle-show-Completions-initially-flag  t)
+                                        (completion-ignore-case                  t))
+                                    (completing-read "Choose: " menus nil t))
+                                (caar menus)))) ; Only one submenu, so use it.
+                  (regexp   (cadr (assoc submenu menus)))
+                  (icicle-transform-function
+                   (if (interactive-p) nil icicle-transform-function)))
+             (unless (stringp regexp) (error "No match"))
+             (icicle-search
+              beg end regexp require-match where predicate
+              ;; We rely on the match data having been preserved.
+              ;; $$$$$$ An alternative fn for Lisp only: #'(lambda () (up-list -1) (forward-sexp))))))
+              (and fullp #'(lambda ()
+                             (goto-char (match-beginning 0))
+                             (condition-case icicle-imenu-1
+                                 (forward-sexp)
+                               (error (goto-char (match-end 0))))))))) ; Punt: just use regexp match.
+      (set-syntax-table old-table))))
+
+(defun icicle-imenu-in-buffer-p (menu)
+  "Return non-nil if the regexp in MENU has a match in the buffer."
+  (save-excursion (goto-char (point-min)) (re-search-forward (cadr menu) nil t)))
+
+;;;###autoload
+(defun icicle-tags-search (regexp &optional arg)
+  "Search all source files listed in tags tables for matches for REGEXP.
+You are prompted for the REGEXP to match.  Enter REGEXP with `RET'.
+You do not need `M-,' - you see all matches as search hits to visit.
+
+All tags in a tags file are used, including duplicate tags from the
+same or different source files.
+
+By default, all tags files are used, but if you provide a prefix
+argument then only the current tag table is used.
+
+If your TAGS file references source files that no longer exist, those
+files are listed.  In that case, you might want to update your TAGS
+file.
+
+
+You can alternatively choose to search, not the search contexts as
+defined by the context regexp you provide, but the non-contexts, that
+is, the text in the files that does not match the regexp.  To do this,
+use `C-M-~' during completion.  (This is a toggle, and it affects only
+future search commands, not the current one.)"
+  (interactive
+   (let ((completion-ignore-case  (if (and (boundp 'tags-case-fold-search)
+                                           (memq tags-case-fold-search '(t nil)))
+                                      tags-case-fold-search
+                                    case-fold-search)))
+     (require 'etags)
+     (list (icicle-search-read-context-regexp (format
+                                               "Search files with tags %smatching regexp: "
+                                               (if icicle-search-complement-domain-p "*NOT* " "")))
+           current-prefix-arg)))
+  (let ((files  ()))
+    (save-excursion
+      (let ((first-time  t)
+            (morep       t))
+        (while (and morep (visit-tags-table-buffer (not first-time)))
+          (when arg (setq morep  nil))
+          (setq first-time  nil)
+          (let ((tail  (last files)))
+            (if tail
+                (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
+              (setq files  (mapcar 'expand-file-name (tags-table-files))))))))
+    (let ((tail              files)     ; Remove names of non-existent or unreadable files.
+          (unreadable-files  ()))
+      (while tail
+        (if (file-readable-p (car tail))
+            (setq tail  (cdr tail))
+          (push (car tail) unreadable-files)
+          (setcar tail (cadr tail))
+          (setcdr tail (cddr tail))))
+      (when unreadable-files
+        (with-output-to-temp-buffer "*Unreadable Files*"
+          (princ "These missing or unreadable files were ignored:") (terpri) (terpri)
+          (dolist (file  unreadable-files) (princ file) (terpri)))))
+    (select-window (minibuffer-window))
+    (select-frame-set-input-focus (selected-frame))
+    (icicle-search nil nil regexp nil files)))
+
+;;;###autoload
+(defun icicle-save-string-to-variable (askp)
+  "Save a string (text) to a variable.
+You are prompted for the string to save.  Typically, you store a
+regexp or part of a regexp in the variable.
+
+By default, the variable is user option `icicle-input-string'.
+To save to a different variable, use a prefix argument; you are then
+prompted for the variable to use.
+
+You can use `\\\
+\\[icicle-insert-string-from-variable]' to insert a string from a
+variable."
+  (interactive "P")
+  (let* ((enable-recursive-minibuffers  t)
+         (icicle-must-pass-after-match-predicate  #'(lambda (s) (boundp (intern s))))
+         (var
+          (if askp
+              (let ((icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "variable")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "variable"))))
+                (intern (completing-read "Variable: " obarray nil nil nil
+                                         (if (boundp 'variable-name-history)
+                                             'variable-name-history
+                                           'icicle-variable-name-history)
+                                         (symbol-name 'icicle-input-string))))
+            'icicle-input-string))
+         (text                          (icicle-completing-read-history
+                                         (format "Text to save in `%s': " var))))
+    (set var text)))
+
+(when (> emacs-major-version 21)
+
+  (when (and icicle-define-alias-commands-flag (not (fboundp 'any)))
+    (defalias 'any 'icicle-anything))
+
+  (defun icicle-anything (type)
+    "Act on an object of type TYPE.
+You are prompted for the type, then for an object of that type.  The
+type is either the declared `type' of an Anything source, or its
+`name' if it has no `type'.
+
+This command is available only if you use library `anything.el'.
+
+This is an Icicles multi-command: You can act on multiple objects in
+multiple ways during a single command invocation.  When you choose an
+object using `RET' or `mouse-2', the default action is applied to it.
+The default action is also applied to the current completion candidate
+when you use `C-RET', `C-mouse-2', and so on.
+
+You can apply a different action by using an alternative action key:
+`C-S-RET', `C-S-mouse-2', and so on.  This lets you choose the action
+to apply using completion. You can use `C-RET', `C-mouse-2', and so
+on, to perform multiple actions.
+
+This command is intended for use only in Icicle mode."
+    (interactive
+     (let ((icicle-show-Completions-initially-flag  t)
+           (icicle-whole-candidate-as-text-prop-p   icicle-anything-transform-candidates-flag))
+       (unless (require 'anything nil t) (error "You must load library `anything.el' first"))
+       (list (intern (completing-read "What (type): " (icicle-remove-duplicates
+                                                       (mapcar #'list (icicle-get-anything-types)))
+                                      nil t)))))
+    (icicle-object-action type)))
+
+(when (and icicle-define-alias-commands-flag (not (fboundp 'file)))
+  (defun file ()
+    "Act on a file.  You are prompted for the file and the action.
+During file-name completion, you can delete the file named by the
+current candidate, using `S-delete'.
+
+This is just `icicle-object-action' with type `file'."
+    (interactive) (icicle-object-action 'file)))
+
+(when (and icicle-define-alias-commands-flag (not (fboundp 'buffer)))
+  (defun buffer ()
+    "Act on a buffer.  You are prompted for the buffer and the action.
+During buffer-name completion, you can kill the buffer named by the
+current candidate, using `S-delete'.
+
+This is just `icicle-object-action' with type `buffer'."
+    (interactive) (icicle-object-action 'buffer)))
+
+(when (and icicle-define-alias-commands-flag (not (fboundp 'a)))
+  (defalias 'a 'icicle-object-action))
+(when (and icicle-define-alias-commands-flag (not (fboundp 'what-which-how)))
+  (defalias 'what-which-how 'icicle-object-action))
+;;;###autoload
+(defun icicle-object-action (&optional type)
+  "Act on an object of type TYPE (a symbol).
+You are prompted for the type (\"What\"), then for an object of that
+type (\"Which\"), then for the action function to apply to the
+object (\"How\").  For Anything types (see below), you are not
+prompted for the action function.
+
+The \"type\" of an object is one of these:
+
+a. A type defining an entry `icicle-predicate-types-alist'.
+   These are type predicates, such as `bufferp', `keywordp', or `atom'.
+
+b. The `type' of an Anything source, or its `name' if it has no
+   `type'.  This is available only if you use library `anything.el'
+   and option `icicle-use-anything-candidates-flag' is non-nil.
+
+c. A type defining an entry in user option
+   `icicle-type-actions-alist'.
+
+In the case of Anything types (only), this is a multi-command:
+* `C-RET', `C-mouse-2', and so on perform the default action.
+* `C-S-RET', `C-S-mouse-2', and so on let you choose the action using
+  completion.
+
+Though this is not a multi-command for non-Anything types, for types
+`buffer' and `file' you can use `S-delete' during completion to delete
+the object (buffer or file) named by the current completion candidate.
+
+Objects of types (b) and (c) are easily associated with names.  Their
+names are the completion candidates.  So, for instance, if you choose
+type `buffer', then you can act on a buffer by choosing its name.
+
+Objects of predicate type (type a) are not necessarily named.  The
+completion candidates for these objects are variables (symbols) whose
+values are the objects acted upon.  So, for instance, if you choose
+type `bufferp', then you can choose a variable whose value is a
+buffer, in order to act on that buffer.  Whereas a buffer is always
+named, an object of type `stringp' is not.  The value of variable
+`emacs-version' is one such string that you can act on.
+
+Anything types and Anything actions are highlighted when used as
+candidates in `*Completions*', using face `icicle-special-candidate'.
+
+Be aware that the action function you choose must accommodate the
+object you choose as its only an argument.  Also, completion of the
+function candidate itself is not strict, so you can enter a lambda
+form.
+
+With a prefix argument, the result of applying the function to the
+object is pretty-printed using `icicle-pp-eval-expression'.
+Otherwise, the function is called for its effect only, and its value
+is not displayed.
+
+You can use a prefix argument similarly when you act on an individual
+function (\"How\") candidate to apply it to the object, without ending
+completion.  That is, `C-u C-RET', `C-u C-mouse-2', and so on, will
+pretty-print the result of the individual action.
+
+This command is intended for use only in Icicle mode."
+  (interactive)
+  (let* ((anything-loaded-p         (and (> emacs-major-version 21)
+                                         icicle-use-anything-candidates-flag
+                                         (require 'anything nil t)))
+         (anything-types            (and (not type) anything-loaded-p (icicle-get-anything-types)))
+         (typ
+          (or type
+              (let ((icicle-show-Completions-initially-flag  t))
+                (intern
+                 (completing-read "What (type): "
+                                  (icicle-remove-duplicates (append (mapcar #'list anything-types)
+                                                                    icicle-type-actions-alist
+                                                                    icicle-predicate-types-alist))
+                                  nil t)))))
+         (predicate-type-p          (and (assoc (symbol-name typ) icicle-predicate-types-alist)
+                                         (not (memq (symbol-name typ) anything-types))))
+         (anything-candidates       (and anything-loaded-p (not predicate-type-p)
+                                         (icicle-get-anything-candidates-of-type typ)))
+         (anything-default-actions  (and anything-candidates
+                                         (icicle-get-anything-default-actions-for-type typ)))
+         (anything-actions          (and anything-candidates
+                                         (icicle-get-anything-actions-for-type typ)))
+         (icicle-saved-completion-candidate
+          (cond (predicate-type-p (icicle-read-var-value-satisfying typ))
+                (anything-candidates
+                 (icicle-choose-anything-candidate typ anything-candidates
+                                                   anything-default-actions anything-actions))
+                ((member (symbol-name typ) (and anything-loaded-p (icicle-get-anything-types)))
+                 (error "No candidates for type `%s'" (symbol-name typ)))
+                (t (icicle-choose-candidate-of-type typ))))
+         (icicle-candidate-action-fn    ; For "how".
+          #'(lambda (fn) (icicle-apply-to-saved-candidate fn anything-candidates typ)))
+         (icicle-candidate-alt-action-fn ; For "how".
+          (and anything-candidates #'(lambda (fn) (icicle-apply-to-saved-candidate fn t typ)))))
+    (funcall (icicle-alt-act-fn-for-type
+              (if predicate-type-p
+                  (or (cdr (assoc (symbol-name typ) icicle-predicate-types-alist)) (symbol-name typ))
+                (symbol-name typ)))
+             icicle-saved-completion-candidate)))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-types ()
+    "Return list of types defined in `anything-sources'.  See `anything.el'."
+    (and (boundp 'anything-sources) (consp anything-sources)
+         (let ((types  ())
+               type)
+           (dolist (source  (anything-get-sources))
+             (if (setq type  (assoc-default 'type source))
+                 (push (symbol-name type) types)
+               (when (setq type  (assoc-default 'name source)) (push type types))))
+           (setq types
+                 (mapcar #'(lambda (typ)
+                             (setq typ  (copy-sequence typ))
+                             (put-text-property 0 (length typ) 'face 'icicle-special-candidate typ)
+                             typ)
+                         (icicle-remove-duplicates types)))))))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-candidates-of-type (type)
+    "Return list of Anything candidates for type TYPE.
+Used only when `anything-sources' is non-nil - see `anything.el'."
+    (and (boundp 'anything-sources) (consp anything-sources)
+         (let ((anything-candidate-cache  ())
+               (candidates                nil))
+           (dolist (source  (anything-get-sources))
+             (let ((init-fn  (assoc-default 'init source))) (when init-fn (funcall init-fn)))
+             (when (or (eq type (assoc-default 'type source))
+                       (string= (symbol-name type) (assoc-default 'name source)))
+               (setq candidates  (icicle-get-anything-cached-candidates source))))
+           (when (and (not (functionp candidates)) (consp candidates))
+             (mapcar #'(lambda (cand) (if (consp cand) cand (list cand))) candidates))
+           candidates))))
+
+;; Similar to `anything-get-cached-candidates' in `anything.el', but ignores processes.
+;; Free var here: `anything-candidate-cache'.
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-cached-candidates (source)
+    "Return cached value of candidates for Anything SOURCE.
+Cache the candidates if there is not yet a cached value."
+    (let* ((source-name      (assoc-default 'name source))
+           (candidate-cache  (assoc source-name anything-candidate-cache))
+           candidates)
+      (if candidate-cache
+          (setq candidates  (cdr candidate-cache))
+        (setq candidates  (icicle-get-anything-candidates source))
+        (when (processp candidates) (setq candidates  ()))
+        (setq candidate-cache  (cons source-name candidates))
+        (push candidate-cache anything-candidate-cache))
+      candidates)))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-candidates (source)
+    "Return the list of candidates from Anything SOURCE."
+    (let* ((candidate-source  (assoc-default 'candidates source))
+           (candidates
+            (cond ((functionp candidate-source)
+                   `(lambda (string pred mode)
+                     (let ((anything-pattern  icicle-current-input))
+                       (setq string  anything-pattern)
+                       (let ((all-cands  (funcall ,candidate-source)))
+                         (setq all-cands
+                               (icicle-remove-if-not
+                                #'(lambda (cand)
+                                    (string-match (if (eq 'prefix icicle-current-completion-mode)
+                                                      (concat "^" (regexp-quote string))
+                                                    string)
+                                                  cand))
+                                all-cands))
+                         (cond ((eq mode t) all-cands)
+                               ((eq mode nil)
+                                (icicle-expanded-common-match icicle-current-input all-cands))
+                               ((eq mode 'lambda) t))))))
+                  ((listp candidate-source) candidate-source)
+                  ((and (symbolp candidate-source) (boundp candidate-source))
+                   (symbol-value candidate-source))
+                  (t
+                   (error
+                    (concat "Source `candidates' value is not a function, variable or list: %s")
+                    candidate-source)))))
+      (if (or (not icicle-anything-transform-candidates-flag) (processp candidates))
+          candidates
+        (anything-transform-candidates candidates source)))))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-actions-for-type (type)
+    "Set and return `icicle-candidates-alist' of actions for type TYPE.
+The display string for each action is highlighted using face
+`icicle-special-candidate'."
+    (setq icicle-candidates-alist  ())
+    (let ((all-sources-actions  ())
+          this-source-actions  faced-act)
+      (dolist (source  (anything-get-sources))
+        (when (or (eq type (assoc-default 'type source))
+                  (string= (symbol-name type) (assoc-default 'name source)))
+          (setq this-source-actions  (assoc-default 'action source))
+          (dolist (action  this-source-actions)
+            (unless (member action all-sources-actions)
+              (setq faced-act  (copy-sequence (car action))) ; Highlight Anything action.
+              (put-text-property 0 (length faced-act) 'face 'icicle-special-candidate faced-act)
+              (push (cons faced-act (cdr action)) all-sources-actions)))))
+      (setq icicle-candidates-alist  (sort all-sources-actions
+                                           #'(lambda (a1 a2)
+                                               (funcall icicle-sort-comparer (car a1) (car a2))))))))
+(when (> emacs-major-version 21)
+  (defun icicle-choose-anything-candidate (type candidates default-actions actions)
+    "Read an Anything object of type TYPE with completion, and return it.
+During completion, you can act on selected completion candidates, in
+turn, using the action keys (`C-RET', `C-mouse-2', `C-down', etc.).
+CANDIDATES is the list of candidates of type TYPE.
+DEFAULT-ACTIONS is the list of default actions for type TYPE.
+ACTIONS is the list of all actions for type TYPE."
+    (let* ((win                                         (selected-window))
+           (icicle-sort-comparer                        nil)
+           (icicle-transform-function                   nil)
+           (icicle-Completions-display-min-input-chars  (icicle-get-anything-req-pat-chars type))
+           (icicle-incremental-completion-delay         (icicle-get-anything-input-delay type))
+           (icicle-whole-candidate-as-text-prop-p       icicle-anything-transform-candidates-flag)
+           (icicle-candidates-alist
+            (if (or (functionp candidates) icicle-whole-candidate-as-text-prop-p)
+                candidates
+              icicle-candidates-alist))
+           (icicle-candidate-action-fn
+            #'(lambda (obj)
+                (when icicle-whole-candidate-as-text-prop-p
+                  (setq obj  (icicle-anything-candidate-value obj)))
+                (let ((enable-recursive-minibuffers  t))
+                  (with-selected-window win
+                    (if (null (cdr default-actions))
+                        (funcall (cdar default-actions) obj)
+                      (funcall (completing-read "How (action): " default-actions nil t) obj))))
+                (select-window (minibuffer-window))
+                (select-frame-set-input-focus (selected-frame))
+                (icicle-raise-Completions-frame)))
+           (icicle-candidate-alt-action-fn
+            `(lambda (obj)
+              (when icicle-whole-candidate-as-text-prop-p
+                (setq obj  (icicle-anything-candidate-value obj)))
+              (let ((icicle-show-Completions-initially-flag  t)
+                    (icicle-saved-completion-candidate       obj)
+                    (icicle-candidates-alist                 actions)
+                    (enable-recursive-minibuffers            t))
+                (with-selected-window win
+                  (icicle-apply-to-saved-candidate
+                   (let ((enable-recursive-minibuffers      t)
+                         (icicle-last-completion-candidate  icicle-last-completion-candidate)
+                         (icicle-candidate-alt-action-fn    nil)
+                         (icicle-candidate-action-fn
+                          `(lambda (actn) (with-selected-window win
+                                            (let ((enable-recursive-minibuffers  t)
+                                                  (icicle-candidates-alist       actions))
+                                              (icicle-apply-to-saved-candidate actn t ,type))))))
+                     (completing-read "How (action): " actions nil t))
+                   t
+                   ,type)))))
+           (orig-action-fn  icicle-candidate-action-fn)
+           (icicle-candidate-help-fn
+            (if icicle-whole-candidate-as-text-prop-p
+                #'(lambda (obj)
+                    (let ((icicle-candidate-help-fn  nil))
+                      (icicle-help-on-candidate-symbol
+                       (intern (icicle-anything-candidate-value obj)))))
+              icicle-candidate-help-fn))
+           (icicle-candidate-action-fn
+            (if icicle-whole-candidate-as-text-prop-p
+                #'(lambda (obj)
+                    (let ((icicle-last-input  (icicle-anything-candidate-value obj)))
+                      (funcall orig-action-fn obj)))
+              icicle-candidate-action-fn)))
+      (if icicle-whole-candidate-as-text-prop-p
+          (icicle-anything-candidate-value
+           (completing-read (concat "Which (" (symbol-name type) "): ") candidates nil t))
+        (completing-read (concat "Which (" (symbol-name type) "): ") candidates nil t)))))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-req-pat-chars (type)
+    "Return max `required-pattern' value for sources of type TYPE.
+The value returned is also always at least as big as
+`icicle-Completions-display-min-input-chars'."
+    (let ((req-pat              icicle-Completions-display-min-input-chars)
+          (req-pat-this-source  nil))
+      (dolist (source  (anything-get-sources))
+        (when (and (or (eq type (assoc-default 'type source))
+                       (string= (symbol-name type) (assoc-default 'name source)))
+                   (setq req-pat-this-source  (assoc-default 'requires-pattern source)))
+          (setq req-pat  (max req-pat req-pat-this-source))))
+      req-pat)))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-input-delay (type)
+    "Return max `delay' value for sources of type TYPE.
+The value returned is also always at least as big as
+`icicle-incremental-completion-delay'."
+    (let ((delay              icicle-incremental-completion-delay)
+          (delay-this-source  nil))
+      (dolist (source  (anything-get-sources))
+        (when (and (or (eq type (assoc-default 'type source))
+                       (string= (symbol-name type) (assoc-default 'name source)))
+                   (setq delay-this-source  (and (assoc 'delayed source) anything-idle-delay)))
+          (setq delay  (max delay delay-this-source))))
+      delay)))
+
+(when (> emacs-major-version 21)
+  (defun icicle-anything-candidate-value (candidate)
+    "Return the real value associated with string CANDIDATE."
+    (or (cdr-safe (funcall icicle-get-alist-candidate-function candidate)) candidate)))
+
+(when (> emacs-major-version 21)
+  (defun icicle-get-anything-default-actions-for-type (type)
+    "Set and return `icicle-candidates-alist' of default actions for type TYPE."
+    (setq icicle-candidates-alist  ())
+    (let ((all-sources-actions  ())
+          this-source-actions)
+      (dolist (source  (anything-get-sources))
+        (when (or (eq type (assoc-default 'type source))
+                  (string= (symbol-name type) (assoc-default 'name source)))
+          (setq this-source-actions  (assoc-default 'action source))
+          (unless (memq (car this-source-actions) all-sources-actions)
+            (push (car this-source-actions) all-sources-actions))))
+      (setq icicle-candidates-alist
+            (sort all-sources-actions   ; Must sort, or `icicle-candidate-nb' will be wrong.
+                  #'(lambda (a1 a2) (funcall icicle-sort-comparer (car a1) (car a2))))))))
+
+(defun icicle-choose-candidate-of-type (type)
+  "Read an object of type TYPE (a symbol) with completion, and return it.
+These options, when non-nil, control buffer candidate matching and
+filtering:
+ `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
+ `icicle-buffer-extras'               - Extra buffers to display
+ `icicle-buffer-match-regexp'         - Regexp that buffers must match
+ `icicle-buffer-no-match-regexp'      - Regexp buffers must not match
+ `icicle-buffer-predicate'            - Predicate buffer must satisfy
+ `icicle-buffer-sort'                 - Sort function for candidates"
+  (let ((icicle-orig-window  (selected-window))) ; For alternative actions.
+    (case type
+      (buffer
+       (let* ((completion-ignore-case
+               (or (and (boundp 'read-buffer-completion-ignore-case)
+                        read-buffer-completion-ignore-case)
+                   completion-ignore-case))
+              (icicle-must-match-regexp                icicle-buffer-match-regexp)
+              (icicle-must-not-match-regexp            icicle-buffer-no-match-regexp)
+              (icicle-must-pass-after-match-predicate  icicle-buffer-predicate)
+              (icicle-require-match-flag               icicle-buffer-require-match-flag)
+              (icicle-extra-candidates                 icicle-buffer-extras)
+              (icicle-ignore-space-prefix-flag         icicle-buffer-ignore-space-prefix-flag)
+              (icicle-delete-candidate-object          'icicle-kill-a-buffer) ; `S-delete' kills buf
+              (icicle-transform-function               'icicle-remove-dups-if-extras)
+              (icicle--temp-orders
+               (append (list '("by last access") ; Renamed from "turned OFF'.
+                             '("*...* last" . icicle-buffer-sort-*...*-last)
+                             '("by buffer size" . icicle-buffer-smaller-p)
+                             '("by major mode name" . icicle-major-mode-name-less-p)
+                             (and (fboundp 'icicle-mode-line-name-less-p)
+                                  '("by mode-line mode name" . icicle-mode-line-name-less-p))
+                             '("by file/process name" . icicle-buffer-file/process-name-less-p))
+                       (delete '("turned OFF") (copy-sequence icicle-sort-orders-alist))))
+              ;; Put `icicle-buffer-sort' first.  If already in list, move it, else add it, to start.
+              (icicle-sort-orders-alist
+               (progn (when (and icicle-buffer-sort-first-time-p icicle-buffer-sort)
+                        (setq icicle-sort-comparer             icicle-buffer-sort
+                              icicle-buffer-sort-first-time-p  nil))
+                      (if icicle-buffer-sort
+                          (let ((already-there  (rassq icicle-buffer-sort icicle--temp-orders)))
+                            (if already-there
+                                (cons already-there (setq icicle--temp-orders
+                                                          (delete already-there icicle--temp-orders)))
+                              (cons `("by `icicle-buffer-sort'" . ,icicle-buffer-sort)
+                                    icicle--temp-orders)))
+                        icicle--temp-orders)))
+              (icicle-candidate-alt-action-fn
+               (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+              (icicle-all-candidates-list-alt-action-fn
+               (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer"))))
+         (get-buffer-create
+          (completing-read "Which (buffer): " (mapcar #'(lambda (buf) (list (buffer-name buf)))
+                                                      (buffer-list))
+                           nil
+                           (and (fboundp 'confirm-nonexistent-file-or-buffer) ; Emacs 23.
+                                (confirm-nonexistent-file-or-buffer))
+                           nil 'buffer-name-history nil nil))))
+      (color (icicle-read-color 1))     ; Use the color name (only).
+      (command (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (commandp (intern s))))
+                     (icicle-candidate-alt-action-fn
+                      (or icicle-candidate-alt-action-fn
+                          (icicle-alt-act-fn-for-type "command")))
+                     (icicle-all-candidates-list-alt-action-fn
+                      (or icicle-all-candidates-list-alt-action-fn
+                          (icicle-alt-act-fn-for-type "command"))))
+                 (intern (completing-read "Which (command): " obarray))))
+      (face (let ((icicle-candidate-alt-action-fn
+                   (or icicle-candidate-alt-action-fn
+                       (icicle-alt-act-fn-for-type "face")))
+                  (icicle-all-candidates-list-alt-action-fn
+                   (or icicle-all-candidates-list-alt-action-fn
+                       (icicle-alt-act-fn-for-type "face"))))
+              (intern (completing-read "Which (face): " (mapcar #'(lambda (x) (list (format "%s" x)))
+                                                                (face-list))))))
+      (file (let ((icicle-candidate-alt-action-fn
+                   (or icicle-candidate-alt-action-fn
+                       (icicle-alt-act-fn-for-type "file")))
+                  (icicle-all-candidates-list-alt-action-fn
+                   (or icicle-all-candidates-list-alt-action-fn
+                       (icicle-alt-act-fn-for-type "file")))
+                  (icicle-delete-candidate-object  'icicle-delete-file-or-directory)) ; `S-delete'
+              (read-file-name "Which (file): " nil
+                              (and (eq major-mode 'dired-mode)
+                                   (fboundp 'dired-get-file-for-visit) ; Emacs 22+.
+                                   (condition-case nil ; E.g. error because not on file line (ignore)
+                                       (abbreviate-file-name (dired-get-file-for-visit))
+                                     (error nil))))))
+      (frame (let ((frame-alist  (icicle-make-frame-alist))
+                   (icicle-candidate-alt-action-fn
+                    (or icicle-candidate-alt-action-fn
+                        (icicle-alt-act-fn-for-type "frame")))
+                   (icicle-all-candidates-list-alt-action-fn
+                    (or icicle-all-candidates-list-alt-action-fn
+                        (icicle-alt-act-fn-for-type "frame"))))
+               (cdr (assoc (completing-read "Which (frame): " frame-alist) frame-alist))))
+      (function (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (fboundp (intern s))))
+                      (icicle-candidate-alt-action-fn
+                       (or icicle-candidate-alt-action-fn
+                           (icicle-alt-act-fn-for-type "function")))
+                      (icicle-all-candidates-list-alt-action-fn
+                       (or icicle-all-candidates-list-alt-action-fn
+                           (icicle-alt-act-fn-for-type "function"))))
+                  (intern (completing-read "Which (function): " obarray))))
+      (option (let ((icicle-must-pass-after-match-predicate  #'(lambda (s)
+                                                                 (user-variable-p (intern s))))
+                    (icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "option")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "option"))))
+                (intern (completing-read "Which (user option): " obarray))))
+      (process (let ((icicle-candidate-alt-action-fn
+                      (or icicle-candidate-alt-action-fn
+                          (icicle-alt-act-fn-for-type "process")))
+                     (icicle-all-candidates-list-alt-action-fn
+                      (or icicle-all-candidates-list-alt-action-fn
+                          (icicle-alt-act-fn-for-type "process"))))
+                 (get-process
+                  (completing-read
+                   "Which (process): " (mapcar #'(lambda (proc) (list (process-name proc)))
+                                               (process-list))))))
+      (symbol (let ((icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "symbol")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "symbol"))))
+                (intern (completing-read "Which (symbol): " obarray))))
+      (variable (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (boundp (intern s))))
+                      (icicle-candidate-alt-action-fn
+                       (or icicle-candidate-alt-action-fn
+                           (icicle-alt-act-fn-for-type "variable")))
+                      (icicle-all-candidates-list-alt-action-fn
+                       (or icicle-all-candidates-list-alt-action-fn
+                           (icicle-alt-act-fn-for-type "variable"))))
+                  (intern (completing-read "Which (variable): " obarray))))
+      (window (let ((icicle-candidate-alt-action-fn
+                     (or icicle-candidate-alt-action-fn
+                         (icicle-alt-act-fn-for-type "window")))
+                    (icicle-all-candidates-list-alt-action-fn
+                     (or icicle-all-candidates-list-alt-action-fn
+                         (icicle-alt-act-fn-for-type "window")))
+                    (buffers  ()))
+                (walk-windows #'(lambda (win)
+                                  (push (list (format "%s" (window-buffer win))) buffers))
+                              nil t)
+                (get-buffer-window (completing-read "Window showing buffer: " buffers) 0)))
+      (otherwise (error "Bad object type: %S" type)))))
+
+(defun icicle-read-var-value-satisfying (pred)
+  "Read a variable that satisfies predicate PRED and returns its value."
+  (symbol-value
+   (let ((icicle-orig-window                      (selected-window))
+         (icicle-must-pass-after-match-predicate  `(lambda (s)
+                                                    (setq s  (intern s))
+                                                    (and (boundp s)
+                                                     (funcall ',pred (symbol-value s)))))
+         (icicle-candidate-alt-action-fn          (or icicle-candidate-alt-action-fn
+                                                      (icicle-alt-act-fn-for-type "variable")))
+         (icicle-all-candidates-list-alt-action-fn
+          (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "variable"))))
+     (intern (completing-read (format "Which (%s value of variable): " pred) obarray)))))
+
+(defvar icicle-key-prefix nil
+  "A prefix key.")
+
+(defvar icicle-key-prefix-2 nil
+  "A prefix key.")
+
+(defvar icicle-active-map nil
+  "An active keymap.")
+
+(defvar icicle-orig-buff-key-complete nil
+  "Current buffer when you invoked `icicle-complete-keys'.")
+
+(defvar icicle-orig-extra-cands ()
+  "Value of `icicle-extra-candidates', before command.")
+
+(defvar icicle-orig-show-initially-flag nil
+  "Value of `icicle-show-Completions-initially-flag', before command.")
+
+(defvar icicle-orig-sort-orders-alist ()
+  "Value of `icicle-sort-orders-alist', before command.")
+
+(defvar icicle-orig-win-key-complete nil
+  "Selected window when you invoked `icicle-complete-keys'.")
+
+(defvar icicle-this-cmd-keys ()
+  "Value of `this-command-keys-vector' at some point in key completion.")
+
+(when (fboundp 'map-keymap)             ; Emacs 22+.
+
+  (defun icicle-complete-keys ()        ; Bound to prefix keys followed by `S-TAB' (unless defined).
+    "Complete a key sequence for the currently invoked prefix key.
+Input-candidate completion and cycling are available.
+
+You can navigate the key-binding hierarchy (prefix-key hierarchy),
+just as would navigate a file-system hierarchy (to complete directory
+and file names) or a menu hierarchy (to complete submenu and menu-item
+names).
+
+Completion candidates generally have the form `KEY  =  COMMAND'.
+
+If COMMAND is `...', then KEY is a prefix key; choosing it updates the
+completion candidates list to the keys under that prefix.  For
+example, choosing `C-x = ...' changes the candidates to those with
+prefix `C-x'.
+
+The special candidate `..' means to go up one level of the key-binding
+hierarchy and complete candidates there.  For example, if you are
+currently completing prefix key `C-x 5', and you choose candidate
+`..', then you will be completing prefix `C-x', the parent of `C-x 5'.
+
+Except at the top level, the default value for completion is `..'.
+
+You can use `C-M-,' at any time to switch between sorting with local
+bindings first and sorting with prefix keys first.  You can use `C-,'
+at any time to change the sort order among these two and sorting by
+command name.
+
+If option `icicle-complete-keys-self-insert-ranges' is non-nil, then
+some keys bound to `self-insert-command' are included as possible
+key-completion candidates; otherwise they are not.  The default is
+nil.
+
+For Emacs 22, the option is effectively Boolean: any non-nil value
+means allow all self-inserting keys as candidates.
+
+In Emacs 23+, there are thousands of self-inserting keys, so it is not
+practical to allow all as candidates.  Instead, a non-nil value is a
+list of character ranges of the form (MIN . MAX).  Characters in the
+inclusive range MIN through MAX are possible key-completion
+candidates.
+
+For Emacs 23+, if you use a non-nil value for
+`icicle-complete-keys-self-insert-ranges' then use only small ranges
+for good performance.  In general, you will want to leave this option
+value as nil and use the vanilla Emacs 23+ command `ucs-insert' to
+insert characters by completing against their Unicode names.  With
+Icicles key completion you do not complete against the Unicode names.
+Instead, you can see the characters in `*Completions*'.
+
+While cycling, these keys describe candidates:
+
+`C-RET'   - Describe command of current completion candidate only
+`C-down'  - Move to next completion candidate and describe
+`C-up'    - Move to previous completion candidate and describe
+`C-next'  - Move to next apropos-completion candidate and describe
+`C-prior' - Move to previous apropos-completion candidate and describe
+`C-end'   - Move to next prefix-completion candidate and describe
+`C-home'  - Move to previous prefix-completion candidate and describe
+`C-!'     - Describe *all* candidates (or all that are saved),
+            successively - use the [back] button in buffer *Help* to
+            visit the descriptions
+
+When candidate action and cycling are combined (e.g. `C-next'), option
+`icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
+`C-g' to quit.  This is an Icicles command - see command
+`icicle-mode'."
+    (interactive)
+    (let* ((icicle-transform-function               'icicle-remove-duplicates)
+           (icicle-orig-sort-orders-alist           icicle-sort-orders-alist) ; For recursive use.
+           (icicle-orig-show-initially-flag         icicle-show-Completions-initially-flag)
+           (icicle-show-Completions-initially-flag  t)
+           (icicle-candidate-action-fn              'icicle-complete-keys-action)
+           (enable-recursive-minibuffers            t)
+           (icicle-orig-buff-key-complete           (current-buffer))
+           (icicle-orig-win-key-complete            (selected-window))
+           (icicle-completing-keys-p                t) ; Provide a condition to test key completion.
+           (icicle-sort-comparer                    'icicle-local-keys-first-p)
+           (icicle-alternative-sort-comparer        'icicle-prefix-keys-first-p)
+           (icicle-sort-orders-alist
+            '(("by key name, local bindings first" . icicle-local-keys-first-p)
+              ("by key name, prefix keys first" . icicle-prefix-keys-first-p)
+              ("by command name" . icicle-command-names-alphabetic-p)
+              ("turned OFF")))
+           (icicle-hist-cands-no-highlight          '("..")))
+      (icicle-complete-keys-1 (icicle-this-command-keys-prefix))))
+
+  (defun icicle-this-command-keys-prefix ()
+    "Return the prefix of the currently invoked key sequence."
+    (let ((this-key  (this-command-keys))) (substring this-key 0 (1- (length this-key)))))
+
+  ;; Free vars here: `icicle-complete-keys-alist' is bound in `icicles-var.el'.
+  (defun icicle-complete-keys-1 (prefix) ; PREFIX is a free var in `icicle-complete-keys-action'.
+    "Complete a key sequence for prefix key PREFIX (a vector)."
+    ;; `icicle-orig-extra-cands' is free in `icicle-complete-keys-action'.
+    (let ((icicle-orig-extra-cands  icicle-extra-candidates)
+          (icicle-key-prefix        prefix))
+      (unwind-protect
+           (progn
+             (icicle-keys+cmds-w-prefix prefix)
+             (unless icicle-complete-keys-alist (error "No keys for prefix `%s'" prefix))
+             (let* ((icicle-this-cmd-keys ; For error report - e.g. mouse command.
+                     (this-command-keys-vector)) ; Free var in `icicle-complete-keys-action'.
+                    (icicle-key-prefix-description
+                     (icicle-key-description prefix (not icicle-key-descriptions-use-<>-flag)))
+                    (prompt  (concat "Complete keys"
+                                     (and (not (string= "" icicle-key-prefix-description))
+                                          (concat " " icicle-key-prefix-description))
+                                     ": ")))
+               (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+               (icicle-complete-keys-action
+                (completing-read prompt icicle-complete-keys-alist nil t nil nil
+                                 ;;$$ (if (equal [] prefix) nil "\\.\\.")
+                                 ))))
+        (dolist (cand  icicle-complete-keys-alist)
+          (put (car cand) 'icicle-special-candidate nil))))) ; Reset the property.
+
+  ;; Free vars here:
+  ;; `icicle-orig-buff-key-complete', `icicle-orig-win-key-complete', bound in `icicle-complete-keys'.
+  ;; `icicle-orig-extra-cands', `icicle-this-cmd-keys', `icicle-key-prefix',
+  ;; bound in `icicle-complete-keys-1'.
+  (defun icicle-complete-keys-action (candidate)
+    "Completion action function for `icicle-complete-keys'."
+    (let* ((key+binding    (cdr-safe (assq (intern candidate) icicle-complete-keys-alist)))
+           (key            (car-safe key+binding))
+           (binding        (cdr-safe key+binding))
+           (cmd-name       nil)
+           (action-window  (selected-window)))
+      (unwind-protect
+           (progn
+             (set-buffer icicle-orig-buff-key-complete)
+             (select-window icicle-orig-win-key-complete)
+             (if (string= ".." candidate)
+                 (setq cmd-name  "..")
+               (unless (and (string-match "\\(.+\\)  =  \\(.+\\)" candidate) (match-beginning 2))
+                 (error "No match"))
+               (setq cmd-name  (substring candidate (match-beginning 2) (match-end 2))))
+             (cond ((string= ".." cmd-name) ; Go back up to parent prefix.
+                    (setq last-command  'icicle-complete-keys)
+                    (icicle-complete-keys-1 (vconcat (nbutlast (append icicle-key-prefix nil)))))
+                   ((and key (string= "..." cmd-name)) ; Go down to prefix.
+                    (setq last-command  'icicle-complete-keys)
+                    (icicle-complete-keys-1 (vconcat icicle-key-prefix key)))
+                   (t
+                    (setq this-command             binding
+                          last-command             binding
+                          icicle-extra-candidates  icicle-orig-extra-cands) ; Restore it.
+                    (when (eq 'self-insert-command binding)
+                      (unless key (error "Cannot insert `%s'" key))
+                      (setq last-command-char  (aref key 0)))
+                    (when (eq 'digit-argument binding)
+                      (setq last-command-char  (aref key 0))
+                      (icicle-msg-maybe-in-minibuffer "Numeric argument"))
+                    (when (eq 'negative-argument binding)
+                      (icicle-msg-maybe-in-minibuffer "Negative argument"))
+                    (setq last-nonmenu-event  1) ; So `*Completions*' mouse-click info is ignored.
+                    ;; Bind so vanilla context when invoke chosen command.
+                    (let ((icicle-candidate-action-fn              nil)
+                          (icicle-completing-keys-p                nil)
+                          (icicle-sort-orders-alist                icicle-orig-sort-orders-alist)
+                          (icicle-sort-comparer                    'icicle-case-string-less-p)
+                          (icicle-alternative-sort-comparer
+                           'icicle-historical-alphabetic-p)
+                          (icicle-show-Completions-initially-flag
+                           icicle-orig-show-initially-flag))
+                      (call-interactively binding nil icicle-this-cmd-keys)))))
+        (select-window action-window))))
+
+  (defun icicle-keys+cmds-w-prefix (prefix)
+    "Fill `icicle-complete-keys-alist' for prefix key PREFIX (a vector)."
+    (let ((prefix-map           nil)
+          (icicle-key-prefix-2  prefix))
+      (setq icicle-complete-keys-alist  ())
+      (dolist (icicle-active-map  (current-active-maps t))
+        (setq prefix-map  (lookup-key icicle-active-map prefix))
+        ;; NOTE: `icicle-add-key+cmd' uses `icicle-key-prefix-2' and `icicle-active-map' as free vars.
+        (when (keymapp prefix-map) (map-keymap #'icicle-add-key+cmd prefix-map)))
+      (unless (equal [] prefix)
+        (push (list (intern (propertize ".." 'face 'icicle-multi-command-completion)))
+              icicle-complete-keys-alist))
+      icicle-complete-keys-alist))
+
+  ;; Free vars here: `icicle-key-prefix-2' and `icicle-active-map' are bound in
+  ;; `icicle-keys+cmds-w-prefix'.
+  (defun icicle-add-key+cmd (event binding)
+    "Add completion for EVENT and BINDING to `icicle-complete-keys-alist'."
+    (cond
+      ;; (menu-item ITEM-STRING): non-selectable item - skip it.
+      ((and (eq 'menu-item (car-safe binding))
+            (null (cdr-safe (cdr-safe binding))))
+       (setq binding  nil))             ; So `keymapp' test, below, fails.
+
+      ;; (ITEM-STRING): non-selectable item - skip it.
+      ((and (stringp (car-safe binding)) (null (cdr-safe binding)))
+       (setq binding  nil))             ; So `keymapp' test, below, fails.
+
+      ;; (menu-item ITEM-STRING REAL-BINDING . PROPERTIES)
+      ((eq 'menu-item (car-safe binding))
+       (let ((enable-condition  (memq ':enable (cdr-safe (cdr-safe (cdr-safe binding))))))
+         (if (or (not enable-condition)
+                 (condition-case nil    ; Don't enable if we can't check the condition.
+                     (eval (cadr enable-condition))
+                   (error nil)))
+             (setq binding  (car-safe (cdr-safe (cdr-safe binding))))
+           (setq binding  nil))))
+
+      ;; (ITEM-STRING . REAL-BINDING) or
+      ;; (ITEM-STRING [HELP-STRING] . REAL-BINDING) or
+      ;; (ITEM-STRING [HELP-STRING] (KEYBD-SHORTCUTS) . REAL-BINDING)
+      ((stringp (car-safe binding))
+       (setq binding  (cdr binding))
+       ;; Skip HELP-STRING
+       (when (stringp (car-safe binding)) (setq binding  (cdr binding)))
+       ;; Skip (KEYBD-SHORTCUTS): cached key-equivalence data for menu items.
+       (when (and (consp binding) (consp (car binding))) (setq binding  (cdr binding)))))
+
+    ;; Follow indirections to ultimate symbol naming a command.
+    (while (and (symbolp binding) (fboundp binding) (keymapp (symbol-function binding)))
+      (setq binding  (symbol-function binding)))
+
+    ;; `icicle-key-prefix-2' and `icicle-active-map' are free here, bound in
+    ;; `icicle-keys+cmds-w-prefix'.
+    (cond ((and (eq binding 'self-insert-command) ; Insert `self-insert-command' char ranges.
+                icicle-complete-keys-self-insert-ranges
+                (consp event)           ; Emacs 23+ uses char ranges.
+                (fboundp 'characterp) (characterp (car event)))
+           (let ((chr1  (car event))
+                 (chr2  (cdr event)))
+             (loop for range in icicle-complete-keys-self-insert-ranges do
+                   (loop for char from (max chr1 (car range)) to (min chr2  (cdr range)) do
+                         (let* ((key-desc   (propertize (single-key-description
+                                                         char
+                                                         (not icicle-key-descriptions-use-<>-flag))
+                                                        'face 'icicle-candidate-part))
+                                (candidate  (intern (concat key-desc "  =  self-insert-command"))))
+                           (push (cons candidate (cons (vector char) 'self-insert-command))
+                                 icicle-complete-keys-alist)
+                           (when (eq icicle-active-map (current-local-map))
+                             (put candidate 'icicle-special-candidate t)))))))
+          ((and (or (keymapp binding)
+                    (and (commandp binding)
+                         (equal binding (key-binding (vconcat icicle-key-prefix-2 (vector event))))
+                         (not (eq binding 'icicle-complete-keys))))
+                (or (not (eq binding 'self-insert-command)) ; Command, keymap.
+                    (and icicle-complete-keys-self-insert-ranges ; Insert char (Emacs 22).
+                         (char-valid-p event))))
+           (let* ((key-desc   (propertize (single-key-description
+                                           event
+                                           (not icicle-key-descriptions-use-<>-flag))
+                                          'face 'icicle-candidate-part))
+                  (candidate  (intern (concat key-desc "  =  " (if (keymapp binding)
+                                                                   "..."
+                                                                 (prin1-to-string binding))))))
+             ;; Skip keys bound to `undefined'.
+             (unless (string= "undefined" (prin1-to-string binding))
+               (push (cons candidate (cons (vector event) binding)) icicle-complete-keys-alist))
+             (when (eq icicle-active-map (current-local-map))
+               (put candidate 'icicle-special-candidate t))))
+          ((and (integerp event) (generic-char-p event) ; Insert generic char (Emacs 22).
+                (eq 'self-insert-command binding))
+           (ignore))))                  ; Placeholder for future use.
+
+  ;; $$ No longer used.  Was used in `icicle-complete-keys-1'.
+  (defun icicle-read-single-key-description (string need-vector &optional no-angles)
+    "If STRING contains a space, then the vector containing the symbol named STRING.
+Otherwise, call `icicle-read-kbd-macro'.
+Other args are as for `icicle-read-kbd-macro'."
+    (cond ((and no-angles (string-match " " string)) (vector (intern string)))
+          ((string-match "^<\\([^>]* [^>]*\\)>" string)
+           (vector (intern (substring string (match-beginning 1) (match-end 1)))))
+          (t (icicle-read-kbd-macro string need-vector no-angles))))
+
+  ;; $$ No longer used.  Was used as `icicle-candidate-action-fn' in `icicle-complete-keys'.
+  (defun icicle-complete-keys-help (candidate)
+    "Describe the command associated with the current completion candidate."
+    (interactive)                       ; Interactively, just describes itself.
+    (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+    (string-match "\\(.+\\)  =  \\(.+\\)" candidate)
+    (let ((frame-with-focus  (selected-frame))
+          (cmd               (intern-soft (substring candidate (match-beginning 2) (match-end 2)))))
+      (if (not (fboundp cmd))
+          (icicle-msg-maybe-in-minibuffer "No help")
+        (describe-function cmd))
+      (icicle-raise-Completions-frame)
+      ;; This is a hack for MS Windows - otherwise, we can't continue to get more candidates,
+      ;; because the *Help* frame takes the focus away from the minibuffer frame.
+      ;; MS Windows always gives focus to a newly created frame - in this case, *Help*.
+      (let* ((help-window  (get-buffer-window "*Help*" 0))
+             (help-frame   (and help-window (window-frame help-window))))
+        (when help-frame (redirect-frame-focus help-frame frame-with-focus))))
+    (message nil))                      ; Let minibuffer contents show immediately.
+
+  (defun icicle-read-kbd-macro (start &optional end no-angles)
+    "Read the region as a keyboard macro definition.
+The region is interpreted as spelled-out keystrokes, e.g., \"M-x abc RET\".
+See documentation for `edmacro-mode' for details.
+Leading/trailing \"C-x (\" and \"C-x )\" in the text are allowed and ignored.
+The resulting macro is installed as the \"current\" keyboard macro.
+
+In Lisp, may also be called with a single STRING argument in which case
+the result is returned rather than being installed as the current macro.
+The result will be a string if possible, otherwise an event vector.
+Second argument NEED-VECTOR means to return an event vector always.
+
+Optional argument NO-ANGLES non-nil means to expect key
+descriptions not to use angle brackets (<...>).  For example:
+
+ (icicle-read-kbd-macro \"\" t)   returns [mode-line]
+ (icicle-read-kbd-macro  \"mode-line\"  t t) returns [mode-line]"
+    (interactive "r")
+    (if (stringp start)
+        (icicle-edmacro-parse-keys start end no-angles)
+      (setq last-kbd-macro
+            (icicle-edmacro-parse-keys (buffer-substring start end) nil no-angles))))
+
+  (defun icicle-edmacro-parse-keys (string &optional need-vector no-angles)
+    "Same as `edmacro-parse-keys', but with added NO-ANGLES argument.
+NO-ANGLES is the same as for `icicle-read-kbd-macro'."
+    (let ((case-fold-search  nil)
+          (pos               0)
+          (res               []))
+      (while (and (< pos (length string))
+                  (string-match "[^ \t\n\f]+" string pos))
+        (let ((word   (substring string (match-beginning 0) (match-end 0)))
+              (key    nil)
+              (times  1))
+          (setq pos  (match-end 0))
+          (when (string-match "\\([0-9]+\\)\\*." word)
+            (setq times  (string-to-number (substring word 0 (match-end 1)))
+                  word   (substring word (1+ (match-end 1)))))
+          (cond ((string-match "^<<.+>>$" word)
+                 (setq key  (vconcat (if (eq (key-binding [?\M-x])
+                                             'execute-extended-command)
+                                         [?\M-x]
+                                       (or (car (where-is-internal
+                                                 'execute-extended-command))
+                                           [?\M-x]))
+                                     (substring word 2 -2) "\r")))
+                ((or (equal word "REM") (string-match "^;;" word))
+                 (setq pos  (string-match "$" string pos)))
+                ((and (string-match (if no-angles
+                                        "^\\(\\([ACHMsS]-\\)*\\)\\(..+\\)$"
+                                      "^\\(\\([ACHMsS]-\\)*\\)<\\(..+\\)>$")
+                                    word)
+                      (or (not no-angles)
+                          (save-match-data (not (string-match "^\\([ACHMsS]-.\\)+$" word))))
+                      (progn
+                        (setq word  (concat (substring word (match-beginning 1)
+                                                       (match-end 1))
+                                            (substring word (match-beginning 3)
+                                                       (match-end 3))))
+                        (not (string-match
+                              "\\<\\(NUL\\|RET\\|LFD\\|ESC\\|SPC\\|DEL\\)$"
+                              word))))
+                 (setq key  (list (intern word))))
+                (t
+                 (let ((orig-word  word)
+                       (prefix     0)
+                       (bits       0))
+                   (while (string-match "^[ACHMsS]-." word)
+                     (incf bits (cdr (assq (aref word 0)
+                                           '((?A . ?\A-\^@) (?C . ?\C-\^@)
+                                             (?H . ?\H-\^@) (?M . ?\M-\^@)
+                                             (?s . ?\s-\^@) (?S . ?\S-\^@)))))
+                     (incf prefix 2)
+                     (callf substring word 2))
+                   (when (string-match "^\\^.$" word)
+                     (incf bits ?\C-\^@)
+                     (incf prefix)
+                     (callf substring word 1))
+                   (let ((found  (assoc word '(("NUL" . "\0") ("RET" . "\r")
+                                               ("LFD" . "\n") ("TAB" . "\t")
+                                               ("ESC" . "\e") ("SPC" . " ")
+                                               ("DEL" . "\177")))))
+                     (when found (setq word  (cdr found))))
+                   (when (string-match "^\\\\[0-7]+$" word)
+                     (loop for ch across word
+                           for n = 0 then (+ (* n 8) ch -48)
+                           finally do (setq word  (vector n))))
+                   (cond ((= bits 0)
+                          (setq key  word))
+                         ((and (= bits ?\M-\^@) (stringp word)
+                               (string-match "^-?[0-9]+$" word))
+                          (setq key  (loop for x across word collect (+ x bits))))
+                         ((/= (length word) 1)
+                          (error "%s must prefix a single character, not %s"
+                                 (substring orig-word 0 prefix) word))
+                         ((and (/= (logand bits ?\C-\^@) 0) (stringp word)
+                               ;; We used to accept . and ? here,
+                               ;; but . is simply wrong,
+                               ;; and C-? is not used (we use DEL instead).
+                               (string-match "[@-_a-z]" word))
+                          (setq key  (list (+ bits (- ?\C-\^@) (logand (aref word 0) 31)))))
+                         (t
+                          (setq key  (list (+ bits (aref word 0)))))))))
+          (when key
+            (loop repeat times do (callf vconcat res key)))))
+      (when (and (>= (length res) 4)
+                 (eq (aref res 0) ?\C-x)
+                 (eq (aref res 1) ?\()
+                 (eq (aref res (- (length res) 2)) ?\C-x)
+                 (eq (aref res (- (length res) 1)) ?\)))
+        (setq res  (edmacro-subseq res 2 -2)))
+      (if (and (not need-vector)
+               (loop for ch across res
+                     always (and (char-valid-p ch)
+                                 (let ((ch2  (logand ch (lognot ?\M-\^@))))
+                                   (and (>= ch2 0) (<= ch2 127))))))
+          (concat (loop for ch across res
+                        collect (if (= (logand ch ?\M-\^@) 0)
+                                    ch (+ ch 128))))
+        res))))
+
+(when (fboundp 'define-minor-mode)      ; Emacs 21+ ------------
+  (eval '(define-minor-mode icicle-ido-like-mode
+          "Ido-like mode for use with Icicles.
+No, this mode does not pretend to give you exactly the Ido behavior.
+
+Turning the mode ON sets these options to t:
+ `icicle-show-Completions-initially-flag'
+ `icicle-top-level-when-sole-completion-flag'
+Turning the mode OFF sets those options to non-nil.
+
+A positive prefix arg turns the mode on and also sets option
+`icicle-max-candidates' to the prefix-arg numeric value.  By default,
+that option is nil, meaning that there is no limit to the number of
+completion candidates.
+
+Since Ido shows only a few completion candidates, you might want to
+customize that option or use a prefix arg with this mode to set it.
+You can also use `C-x #' in the minibuffer to increment or decrement
+the option at any time during completion.
+
+Turning the mode off by toggling (no prefix arg) resets option
+`icicle-max-candidates' to nil.  If you have customized that option to
+a non-nil value and do not want to lose that preference, then use a
+zero or negative prefix arg to turn the mode off.
+
+See also these options, which control how much time you have to edit
+input before automatic incremental completion and automatic acceptance
+of a sole candidate kick in:
+
+ `icicle-incremental-completion-delay'
+ `icicle-top-level-when-sole-completion-delay'
+
+When you use this mode, you might also want to use nil or t as the
+value of option `icicle-default-value', in order to not insert the
+default value in the minibuffer.  If you want to change that option
+dynamically for the mode, use `icicle-ido-like-mode-hook'.  E.g.:
+
+ (add-hook 'icicle-ido-like-mode-hook
+           (lambda () (setq icicle-default-value
+                       (if icicle-ido-like-mode t 'insert-end))))"
+          nil nil nil :global t :group 'Icicles-Miscellaneous
+          (setq
+           icicle-show-Completions-initially-flag      icicle-ido-like-mode
+           icicle-top-level-when-sole-completion-flag  icicle-ido-like-mode)
+          (if icicle-ido-like-mode
+              (when (and current-prefix-arg (not (eq 'toggle current-prefix-arg)))
+                (setq icicle-max-candidates  (prefix-numeric-value current-prefix-arg)))
+            (unless (and current-prefix-arg (not (eq 'toggle current-prefix-arg)))
+              (setq icicle-max-candidates  nil))))))
+
+(defun icicle-set-TAB-methods-for-command (command methods &optional arg msgp)
+  "Set the possible TAB completion methods for COMMAND.
+This works by advising COMMAND.
+With a negative prefix arg, restore the original, unadvised behavior.
+With a non-negative prefix arg, advise but do not enable the advice.
+ You can later enable the advice and activate it, using
+ `ad-enable-advice' and `ad-activate'.  The advice name is
+ `icicle-TAB-completion-methods' (same name as option).
+See also `icicle-set-S-TAB-methods-for-command'."
+  (interactive (icicle-read-args-for-set-completion-methods 'icicle-TAB-completion-methods))
+  (icicle-set-completion-methods-for-command
+   command methods 'icicle-TAB-completion-methods arg msgp))
+
+(defun icicle-set-S-TAB-methods-for-command (command methods &optional arg msgp)
+  "Set the possible S-TAB completion methods for COMMAND.
+This works by advising COMMAND.
+With a negative prefix arg, restore the original, unadvised behavior.
+With a non-negative prefix arg, advise but do not enable the advice.
+ You can later enable the advice and activate it, using
+ `ad-enable-advice' and `ad-activate'.  The advice name is
+ `icicle-S-TAB-completion-methods-alist' (same name as option).
+See also `icicle-set-TAB-methods-for-command'."
+  (interactive (icicle-read-args-for-set-completion-methods 'icicle-S-TAB-completion-methods-alist))
+  (icicle-set-completion-methods-for-command
+   command methods 'icicle-S-TAB-completion-methods-alist arg msgp))
+
+(defun icicle-read-args-for-set-completion-methods (var)
+  "Read arguments for `icicle-set-(S-)TAB-methods-for-command'.
+VAR is symbol `icicle-(S-)TAB-completion-methods(-alist)'."
+  (let ((command  (intern (let ((icicle-must-pass-after-match-predicate
+                                 #'(lambda (c) (commandp (intern c)))))
+                            (completing-read "Command: " obarray nil t))))
+        (methods  ()))
+    (unless (< (prefix-numeric-value current-prefix-arg) 0)
+      (let ((prompt  (if (eq var 'icicle-TAB-completion-methods) "TAB methods: " "S-TAB methods: "))
+            (cmeths  (symbol-value var))
+            meth)
+        (setq cmeths  (if (consp (car cmeths))
+                          cmeths
+                        (mapcar (lambda (m) (list (symbol-name m))) cmeths)))
+        (while (not (string= "" (setq meth  (completing-read prompt cmeths nil t))))
+          (if (eq var 'icicle-TAB-completion-methods)
+              (push (intern meth) methods)
+            (push (assoc meth icicle-S-TAB-completion-methods-alist) methods)))
+        (setq methods  (nreverse methods))))
+    (list command methods current-prefix-arg (prefix-numeric-value current-prefix-arg))))
+
+(defun icicle-set-completion-methods-for-command (command methods var arg msgp)
+  "Set the possible completion methods for COMMAND.
+This works by advising COMMAND.
+VAR is the methods option to affect, `icicle-TAB-completion-methods'
+ or `icicle-S-TAB-completion-methods-alist'.
+Negative ARG means restore the original, unadvised behavior.
+Non-negative ARG means advise but do not enable the advice.
+Null ARG means advise and enable."
+  (let ((type  (if (eq var 'icicle-TAB-completion-methods) "TAB methods" "S-TAB methods")))
+    (cond ((< (prefix-numeric-value arg) 0)
+           (condition-case nil
+               (ad-remove-advice command 'around var)
+             (error nil))
+           (ad-activate command)        ; This restores original definition unless otherwise advised.
+           (when msgp (message "`%s' now uses default %s" command type)))
+          (t
+           (ad-add-advice command `(,var
+                                    nil ,(not arg)
+                                    (advice . (lambda () (let ((,var  ',methods)) ad-do-it))))
+                          'around 'first)
+           (ad-activate command)
+           (when msgp (message "`%s' %s: %s" command type
+                               (if (consp (car methods)) (mapcar #'car methods) methods)))))))
+ 
+;;(@* "Icicles Commands for Other Packages")
+;;; ** Icicles Commands for Other Packages **
+
+;;; Library `highlight.el' - Icicles multi-commands.  Emacs 21+.
+;;;
+;;;###autoload (autoload 'icicle-choose-faces           "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-choose-invisible-faces "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-choose-visible-faces   "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-hide-faces             "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-hide-only-faces        "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-show-faces             "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-show-only-faces        "icicles-cmd2.el")
+(eval-after-load "highlight"
+  '(when (fboundp 'next-single-char-property-change) ; Don't bother, for Emacs 20.
+
+    (icicle-define-command icicle-choose-faces
+      "Choose a list of face names (strings).
+Option `hlt-act-on-any-face-flag' determines whether only highlighting
+faces in the buffer are candidates.  The list of names (strings) is
+returned."
+      (lambda (name) (push name face-names)) ; Action function
+      prompt                            ; `completing-read' args
+      (mapcar #'icicle-make-face-candidate
+              (if hlt-act-on-any-face-flag
+                  (face-list)
+                (hlt-highlight-faces-in-buffer (point-min) (point-max))))
+      nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+      (if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
+      ((icicle-list-nth-parts-join-string  ": ") ; Additional bindings
+       (icicle-list-join-string            ": ")
+       ;; $$$$$$ (icicle-list-end-string             "")
+       (icicle-list-use-nth-parts          '(1))
+       (prompt                             (copy-sequence "Choose face (`RET' when done): "))
+       (face-names                         ()))
+      (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
+      nil                               ; Undo code.
+      (prog1 (setq face-names  (delete "" face-names)) ; Return the list of faces.
+        (when (interactive-p) (message "Faces: %S" face-names))))
+
+    (icicle-maybe-byte-compile-after-load icicle-choose-faces)
+
+
+    (icicle-define-command icicle-choose-invisible-faces
+      "Choose a list of face names (strings) from currently invisible faces.
+Option `hlt-act-on-any-face-flag' determines whether only highlighting
+faces in the buffer are candidates.  The list of names (strings) is
+returned."
+      (lambda (name) (push name face-names)) ; Action function
+      prompt                            ; `completing-read' args
+      (mapcar #'icicle-make-face-candidate
+              (icicle-remove-if-not #'icicle-invisible-face-p
+                                    (if hlt-act-on-any-face-flag
+                                        (face-list)
+                                      (hlt-highlight-faces-in-buffer (point-min) (point-max)))))
+      nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+      (if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
+      ((icicle-list-nth-parts-join-string  ": ") ; Additional bindings
+       (icicle-list-join-string            ": ")
+       ;; $$$$$$ (icicle-list-end-string             "")
+       (icicle-list-use-nth-parts          '(1))
+       (prompt                             (copy-sequence "Choose face (`RET' when done): "))
+       (face-names                         ()))
+      (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
+      nil                               ; Undo code.
+      (prog1 (setq face-names  (delete "" face-names)) ; Return the list of faces.
+        (when (interactive-p) (message "Faces: %S" face-names))))
+
+    (icicle-maybe-byte-compile-after-load icicle-choose-invisible-faces)
+
+
+    (icicle-define-command icicle-choose-visible-faces
+      "Choose a list of face names (strings) from currently visible faces.
+Option `hlt-act-on-any-face-flag' determines whether only highlighting
+faces in the buffer are candidates.  The list of names (strings) is
+returned."
+      (lambda (name) (push name face-names)) ; Action function
+      prompt                            ; `completing-read' args
+      (mapcar #'icicle-make-face-candidate
+              (icicle-remove-if #'icicle-invisible-face-p
+                                (if hlt-act-on-any-face-flag
+                                    (face-list)
+                                  (hlt-highlight-faces-in-buffer (point-min) (point-max)))))
+      nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+      (if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history) nil nil
+      ((icicle-list-nth-parts-join-string  ": ") ; Additional bindings
+       (icicle-list-join-string            ": ")
+       ;; $$$$$$ (icicle-list-end-string             "")
+       (icicle-list-use-nth-parts          '(1))
+       (prompt                             (copy-sequence "Choose face (`RET' when done): "))
+       (face-names                         ()))
+      (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code.
+      nil                               ; Undo code.
+      (prog1 (setq face-names  (delete "" face-names)) ; Return the list of faces.
+        (when (interactive-p) (message "Faces: %S" face-names))))
+  
+    (icicle-maybe-byte-compile-after-load icicle-choose-visible-faces)
+
+
+    (defun icicle-show-only-faces (&optional start end faces)
+      "Show only the faces you choose, hiding all others.
+Non-nil `hlt-act-on-any-face-flag' means choose from among all
+faces.  Nil means choose only from among faces used to highlight.
+
+When choosing faces, completion and cycling are available. During
+cycling, these keys with prefix `C-' act on the current face name:
+
+`C-mouse-2', `C-RET' - Choose current face candidate only
+`C-down'  - Choose, then move to next prefix-completion candidate
+`C-up'    - Choose, then move to previous prefix-completion candidate
+`C-next'  - Choose, then move to next apropos-completion candidate
+`C-prior' - Choose, then move to previous apropos-completion candidate
+`C-!'     - Choose *all* matching face names"
+      (interactive `(,@(hlt-region-or-buffer-limits)
+                     ,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
+      (dolist (face (if hlt-act-on-any-face-flag
+                        (face-list)
+                      (hlt-highlight-faces-in-buffer start end)))
+        (if (memq face faces)
+            (hlt-show-default-face face)
+          (hlt-hide-default-face start end face))))
+  
+    (icicle-maybe-byte-compile-after-load icicle-show-only-faces)
+
+
+    (defun icicle-hide-only-faces (&optional start end faces)
+      "Hide only the faces you choose, showing all others.
+Non-nil `hlt-act-on-any-face-flag' means choose from among all
+faces.  Nil means choose only from among faces used to highlight.
+
+When choosing faces, completion and cycling are available. During
+cycling, these keys with prefix `C-' act on the current face name:
+
+`C-mouse-2', `C-RET' - Choose current face candidate only
+`C-down'  - Choose, then move to next prefix-completion candidate
+`C-up'    - Choose, then move to previous prefix-completion candidate
+`C-next'  - Choose, then move to next apropos-completion candidate
+`C-prior' - Choose, then move to previous apropos-completion candidate
+`C-!'     - Choose *all* matching face names"
+      (interactive `(,@(hlt-region-or-buffer-limits)
+                     ,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
+      (dolist (face (if hlt-act-on-any-face-flag
+                        (face-list)
+                      (hlt-highlight-faces-in-buffer start end)))
+        (if (memq face faces)
+            (hlt-hide-default-face start end face)
+          (hlt-show-default-face face))))
+
+    (icicle-maybe-byte-compile-after-load icicle-hide-only-faces)
+
+
+    (defun icicle-show-faces (faces)
+      "Show invisible faces that you choose.  Do nothing to other faces.
+Non-nil `hlt-act-on-any-face-flag' means choose from among all
+invisible faces.  Nil means choose only from among invisible faces
+used to highlight.
+
+When choosing faces, completion and cycling are available. During
+cycling, these keys with prefix `C-' act on the current face name:
+
+`C-mouse-2', `C-RET' - Choose current face candidate only
+`C-down'  - Choose, then move to next prefix-completion candidate
+`C-up'    - Choose, then move to previous prefix-completion candidate
+`C-next'  - Choose, then move to next apropos-completion candidate
+`C-prior' - Choose, then move to previous apropos-completion candidate
+`C-!'     - Choose *all* matching face names"
+      (interactive
+       (list (let ((fs  (icicle-remove-if-not #'icicle-invisible-face-p
+                                              (if hlt-act-on-any-face-flag
+                                                  (face-list)
+                                                (hlt-highlight-faces-in-buffer
+                                                 (point-min) (point-max))))))
+               (if fs
+                   (mapcar #'intern (icicle-choose-invisible-faces)) ; An Icicles multi-command
+                 (error "No%s faces are invisible"
+                        (if hlt-act-on-any-face-flag "" " highlight"))))))
+      (dolist (face faces) (hlt-show-default-face face)))
+  
+    (icicle-maybe-byte-compile-after-load icicle-show-faces)
+
+
+    (defun icicle-hide-faces (&optional start end faces)
+      "Hide visible faces that you choose.  Do nothing to other faces.
+Non-nil `hlt-act-on-any-face-flag' means choose from among all
+visible faces.  Nil means choose only from among visible faces used to
+highlight.
+
+When choosing faces, completion and cycling are available. During
+cycling, these keys with prefix `C-' act on the current face name:
+
+`C-mouse-2', `C-RET' - Choose current face candidate only
+`C-down'  - Choose, then move to next prefix-completion candidate
+`C-up'    - Choose, then move to previous prefix-completion candidate
+`C-next'  - Choose, then move to next apropos-completion candidate
+`C-prior' - Choose, then move to previous apropos-completion candidate
+`C-!'     - Choose *all* matching face names"
+      (interactive `(,@(hlt-region-or-buffer-limits)
+                     ,(mapcar #'intern (icicle-choose-faces)))) ; An Icicles multi-command
+      (dolist (face faces) (hlt-hide-default-face start end face)))
+
+    (icicle-maybe-byte-compile-after-load icicle-hide-faces)
+
+    ))
+
+
+;;; Library `palette.el' - Icicles multi-commands.
+;;;
+;;;###autoload (autoload 'icicle-pick-color-by-name "icicles-cmd2.el")
+(eval-after-load "palette"
+  '(progn
+
+    (icicle-define-command icicle-pick-color-by-name ; Bound to `c' in color palette.
+      "Set the current color to a color you name.
+Instead of a color name, you can use an RGB string #XXXXXXXXXXXX,
+where each X is a hex digit.  The number of Xs must be a multiple of
+3, with the same number of Xs for each of red, green, and blue.
+If you enter an empty color name, then a color is picked randomly.
+The new current color is returned."     ; Doc string
+      icicle-pick-color-by-name-action  ; Action function
+      "Color (name or #R+G+B+): "       ; `completing-read' arguments
+      (hexrgb-defined-colors-alist) nil nil nil nil nil nil
+      ((completion-ignore-case  t)))    ; Bindings
+
+    (icicle-maybe-byte-compile-after-load icicle-pick-color-by-name)
+
+
+    (defun icicle-pick-color-by-name-action (color)
+      "Action function for `icicle-pick-color-by-name'."
+      (if (string= "" color)
+          (let* ((colors  (hexrgb-defined-colors))
+                 (rand    (random (length colors)))) ; Random color.
+            (setq color  (elt colors rand)))
+        (let ((hex-string  (hexrgb-rgb-hex-string-p color t)))
+          (when (and hex-string (not (eq 0 hex-string))) (setq color  (concat "#" color))) ; Add #.
+          (if (not (or hex-string (if (fboundp 'test-completion) ; Not defined in Emacs 20.
+                                      (test-completion color (hexrgb-defined-colors-alist))
+                                    (try-completion color (hexrgb-defined-colors-alist)))))
+              (error "No such color: %S" color)
+            (setq color  (hexrgb-color-name-to-hex color))))
+        (setq palette-last-color  palette-current-color)
+        (save-selected-window
+          (setq color  (hexrgb-color-name-to-hex color)) ; Needed if not interactive.
+          (palette-set-current-color color)
+          (palette-where-is-color color)
+          (palette-brightness-scale)
+          (palette-swatch))
+        palette-current-color))
+
+    (icicle-maybe-byte-compile-after-load icicle-pick-color-by-name-action)
+
+
+    (define-key palette-mode-map "c"  'icicle-pick-color-by-name)
+    (define-key palette-popup-map [pick-color-by-name] ; Use same name as in `palette.el'.
+      `(menu-item "Choose Color By Name" icicle-pick-color-by-name
+        :help "Set the current color to a color you name"))
+    ))
+
+
+;;; Library `synonyms.el' - Icicles multi-commands.
+;;;
+;;;###autoload (autoload 'synonyms                        "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-synonyms                 "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-insert-thesaurus-entry   "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-complete-thesaurus-entry "icicles-cmd2.el")
+(eval-after-load "synonyms"
+  '(progn
+
+    (defalias 'synonyms 'icicle-synonyms)
+    (icicle-define-command icicle-synonyms ; Command
+      "Show synonyms that match a regular expression (e.g. a word or phrase).
+You are prompted for the regexp.  By default, it is the text
+of the region, if it is active and `transient-mark-mode' is enabled,
+or the nearest word to the cursor, if not.
+
+Option `synonyms-match-more-flag' non-nil means additional thesaurus
+  entries can be matched.  This can be more time-consuming.  It means
+  two things:
+
+  1) Input can match parts of synonyms, in addition to whole synonyms.
+  2) All synonyms are shown, even if input matches a thesaurus entry.
+
+Option `synonyms-append-result-flag' non-nil means to append search
+  result to previous results.
+
+A prefix argument toggles the meaning of each of those options for the
+duration of the command:
+
+  If `C-u' or `C-u C-u', then toggle `synonyms-match-more-flag'.
+  If negative or `C-u C-u', then toggle `synonyms-append-result-flag'.
+
+\(`C-u C-u' thus means toggle both options.)
+
+When called from Lisp, optional second argument REGEXP is the regexp
+to match (no prompting)."               ; Doc string
+      synonyms-action                   ; Action function,  defined in `synonyms.el'.
+      "Show synonyms for word or phrase (regexp): " ; `completing-read' arguments
+      synonyms-obarray nil nil nil 'synonyms-history (synonyms-default-regexp) nil
+      ((num-arg (prefix-numeric-value current-prefix-arg)) ; Bindings
+       (morep (eq synonyms-match-more-flag (atom current-prefix-arg)))
+       (appendp (eq synonyms-append-result-flag (and (wholenump num-arg) (/= 16 num-arg))))
+       (icicle-sort-function 'icicle-case-insensitive-string-less-p))
+      (synonyms-ensure-synonyms-read-from-cache)) ; Fill `synonyms-obarray' initially, for completion.
+
+    (icicle-maybe-byte-compile-after-load icicle-synonyms)
+
+
+    (icicle-define-command icicle-insert-thesaurus-entry ; Command name
+      "Insert an entry from a thesaurus.
+Library `synonyms.el' is needed for this.  If you have never used
+command `synonyms' before, then the first use of
+`icicle-insert-thesaurus-entry' will take a while, because it will
+build a cache file of synonyms that are used for completion.  See
+`synonyms.el'.
+
+Remember that you can use `\\\
+\\[icicle-toggle-incremental-completion] to toggle incremental completion." ; Doc string
+      icicle-insert-thesaurus-entry-cand-fn ; Action function
+      "Thesaurus entry to match: " synonyms-obarray ; `completing-read' args
+      nil t nil 'icicle-dictionary-history nil nil
+      ((icicle-track-pt  (point)))      ; Bindings
+      (progn                            ; First code
+        (unless (or (boundp 'synonyms-obarray) (require 'synonyms nil t))
+          (error "You must first load library `synonyms.el'"))
+        (synonyms-ensure-synonyms-read-from-cache))
+      nil                               ; Undo code
+      (when (window-live-p icicle-orig-window) ; Last code
+        (select-window icicle-orig-window)
+        (select-frame-set-input-focus (selected-frame))
+        (goto-char icicle-track-pt)))
+
+    (icicle-maybe-byte-compile-after-load icicle-insert-thesaurus-entry)
+
+
+    ;; Free vars here: `icicle-orig-buff' is bound in `icicle-insert-thesaurus-entry'.
+    (defun icicle-insert-thesaurus-entry-cand-fn (string)
+      "Action function for `icicle-insert-thesaurus-entry'.
+Insert STRING, followed by a space, at position TRACK-PT of buffer
+ORIG-BUFF."
+      (set-buffer icicle-orig-buff)
+      (goto-char icicle-track-pt)
+      (insert string " ")
+      (setq icicle-track-pt  (point))
+      (unless (pos-visible-in-window-p) (recenter icicle-recenter))
+      (with-current-buffer (window-buffer (minibuffer-window)) (icicle-clear-minibuffer))
+      (save-selected-window (icicle-remove-Completions-window)))
+
+    (icicle-maybe-byte-compile-after-load icicle-insert-thesaurus-entry-cand-fn)
+
+
+    (defun icicle-complete-thesaurus-entry (word) ; Bound to `C-c /' in Icicle mode.
+      "Complete WORD to an entry from a thesaurus.
+The default value of WORD is the word at the cursor.
+Library `synonyms.el' is needed for this.  If you have never used
+command `synonyms' before, then the first use of
+`icicle-insert-thesaurus-entry' will take a while, because it will
+build a cache file of synonyms that are used for completion.  See
+`synonyms.el'."
+      (interactive (list (word-at-point)))
+      (unless word (error "No word at point to complete"))
+      (unless (or (boundp 'synonyms-obarray) (require 'synonyms nil t))
+        (error "You must first load library `synonyms.el'"))
+      (synonyms-ensure-synonyms-read-from-cache)
+      (when (and (looking-at "\\b") (not (looking-at "\\s-"))) (forward-word 1))
+      (delete-region (progn (forward-word -1) (point)) (progn (forward-word 1) (point)))
+      (insert (completing-read "Thesaurus entry to match: " synonyms-obarray
+                               nil nil word 'icicle-dictionary-history word))
+      (unless (looking-at "\\s-") (insert " ")))
+
+    (icicle-maybe-byte-compile-after-load icicle-complete-thesaurus-entry)
+
+    ))
+
+;;; Library `Bookmark+' - Icicles multi-commands.
+;;;
+;;;###autoload (autoload 'icicle-tag-a-file                              "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-untag-a-file                            "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-tagged                        "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-tagged-other-window           "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-all-tags                      "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-all-tags-other-window         "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-all-tags-regexp               "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-all-tag-regexp-other-windows  "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-some-tags                     "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-some-tags-other-window        "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-some-tags-regexp              "icicles-cmd2.el")
+;;;###autoload (autoload 'icicle-find-file-some-tags-regexp-other-window "icicles-cmd2.el")
+(eval-after-load "bookmark+"
+  '(progn
+
+    (icicle-define-file-command icicle-bookmark-a-file ; `C-x p c a'
+      "Bookmark a file (create an autofile bookmar).
+\(You need library `Bookmark+' for this command.)
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file.
+The autofile bookmark created has the same name as the file.
+
+During file-name completion:
+ You can use `C-x a +' or `C-x a -' to add or remove tags from the
+  current-candidate file.  You are prompted for the tags.
+  (This action requires library `Bookmark+'.)
+ You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+ You can use `C-c +' to create a new directory.
+ You can use `M-|' to open Dired on currently matching file names.
+ You can use `S-delete' to delete a candidate file or (empty) dir."
+      (lambda (file) (bmkp-bookmark-a-file file nil nil 'MSG))
+      "File to bookmark (autofile): " nil nil nil nil nil ; `read-file-name' args
+      (icicle-file-bindings             ; Bindings
+       ((icicle-use-candidates-only-once-flag  t)
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+      (icicle-bind-file-candidate-keys) ; First code
+      nil                               ; Undo code
+      (icicle-unbind-file-candidate-keys)) ; Last code
+
+    (icicle-maybe-byte-compile-after-load icicle-bookmark-a-file)
+
+
+    (icicle-define-file-command icicle-tag-a-file ; `C-x p t + a'
+      "Tag a file (an autofile bookmark) with one or more tags.
+You are prompted for the tags, then the file name.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.  Completion is lax: you are
+not limited to existing tags.
+
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file.
+
+The tags are added to an autofile bookmark for the same file name and
+directory.  If the bookmark does not yet exist it is created.
+Candidate help shows information about the file's autofile bookmark if
+it already exists, or the file itself if not."
+      (lambda (file) (bmkp-autofile-add-tags file tags nil nil 'MSG))
+      "File to tag: " nil nil nil nil nil ; `read-file-name' args
+      (icicle-file-bindings             ; Bindings
+       ((tags                                  (bmkp-read-tags-completing))
+        (icicle-use-candidates-only-once-flag  t))))
+
+    (icicle-maybe-byte-compile-after-load icicle-tag-a-file)
+
+
+    (icicle-define-file-command icicle-untag-a-file ; `C-x p t - a'
+      "Remove one or more tags from a file (an autofile bookmark).
+You are prompted for the tags, then the file name.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.  Completion is lax: you are
+not limited to existing tags.
+
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file.
+
+The tags are removed from an autofile bookmark for the same file name
+and directory.  During file-name completion, only files tagged with
+all of the given input tags are completion candidates."
+      (lambda (file)
+        (bmkp-autofile-remove-tags file tags nil nil 'MSG))
+      "File to untag: " nil nil t nil nil ; `read-file-name' args
+      (icicle-file-bindings             ; Bindings
+       ((tags                                  (bmkp-read-tags-completing)) ; Pre bindings
+        (icicle-use-candidates-only-once-flag  t))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         #'(lambda (ff)
+             ;; Expand relative file name, using directory from minibuffer.
+             (setq ff  (expand-file-name ff (icicle-file-name-directory-w-default
+                                             (icicle-input-from-minibuffer))))
+             (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                    (btgs  (and bmk (bmkp-get-tags bmk))))
+               (and btgs  (catch 'icicle-untag-a-file
+                            (dolist (tag  tags) (when (not (member tag btgs))
+                                                  (throw 'icicle-untag-a-file nil)))
+                            t))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-untag-a-file)
+
+
+    ;;$$$  Do not bother with autofiles that have a PREFIX.
+    (icicle-define-command icicle-find-file-tagged ; Command name
+      "Find one or more files with tags that match your input.
+By default, only tagged files are candidates.  With a prefix argument,
+all autofiles are candidates.  (Autofiles are autofile bookmarks - you
+need library `Bookmark+' for this command.)
+
+Each completion candidate is a multi-completion composed of these
+fields: an absolute file name plus the file's tags, all separated by
+`icicle-list-join-string' (\"^G^J\", by default).  As always, you can
+type `C-M-j' to insert this separator into the minibuffer.
+
+For this command, by default `.' in your input matches any character,
+including a newline.  As always, you can use `C-M-.' to toggle
+this (so `.' does not match newline).
+
+You can match your input against the file name or tags or both.
+
+E.g., type:
+
+ `red S-TAB'                    to match all files with the tag `red'
+ `red M-SPC green M-SPC blue'   to match all files with tags `red',
+                                `green', and `blue' (in any order)
+
+That assumes that these tags do not also match any file names.
+
+If you need to match against a particular field (e.g. the file name or
+a specific tag position), then use the field separator.  Otherwise,
+just use progressive completion, as shown above.
+
+E.g., to match only tags and not the filename, start with `C-M-j' to
+get past the file-name field.  To match both file name and tags, type
+something to match the file name before the `C-M-j'.  E.g., type:
+
+ `2011 C-M-j red M-SPC blue'    to match all files tagged `red' and
+                                `blue' that have `2011' in their names
+
+During completion (`*': requires library `Bookmark+'):
+
+ *You can use `C-x a +' or `C-x a -' to add or remove tags from the
+   current-candidate file.  You are prompted for the tags.
+ *You can use `C-x m' to access file bookmarks (not just autofiles).
+  You can use `C-c C-d' (a la `cd') to change the `default-directory'.
+  You can use `C-c +' to create a new directory.
+  You can use `M-|' to open Dired on currently matching file names.
+  You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
+      (lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
+      prompt icicle-abs-file-candidates ; `completing-read' args
+      nil nil nil 'icicle-filetags-history nil nil
+      (icicle-file-bindings             ; Bindings
+       ((prompt                             "FILE `C-M-j' TAGS: ")
+        (icicle-full-cand-fn                (lambda (file)
+                                              (list (cons file
+                                                          (bmkp-get-tags
+                                                           (bmkp-get-autofile-bookmark file))))))
+        (icicle-abs-file-candidates     ; An alist whose items are ((FILE TAG...)).
+         (let ((result  ()))
+           (dolist (autofile  (bmkp-autofile-alist-only))
+             (let ((tags  (bmkp-get-tags autofile)))
+               (when (or tags current-prefix-arg)
+                 (push (list (cons (bookmark-get-filename autofile) tags)) result))))
+           result))
+        (icicle-dot-string                      (icicle-anychar-regexp))
+        (icicle-candidate-properties-alist      '((1 (face icicle-candidate-part))))
+        (icicle-list-use-nth-parts              '(1))
+        (icicle-whole-candidate-as-text-prop-p  t)))
+      (progn                            ; First code
+        (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+        (icicle-highlight-lighter)
+        (message "Gathering tagged files...")
+        (icicle-bind-file-candidate-keys))
+      nil                               ; Undo code
+      (icicle-unbind-file-candidate-keys)) ; Last code
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-tagged)
+
+
+    (icicle-define-command icicle-find-file-tagged-other-window ; Command name
+      "Same as `icicle-find-file-tagged', except uses another window." ; Doc string
+      (lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
+      prompt icicle-abs-file-candidates ; `completing-read' args
+      nil nil nil 'icicle-filetags-history nil nil
+      (icicle-file-bindings             ; Bindings
+       ((prompt                                 "FILE `C-M-j' TAGS: ")
+        (icicle-full-cand-fn                    (lambda (file)
+                                                  (list (cons file
+                                                              (bmkp-get-tags
+                                                               (bmkp-get-autofile-bookmark file))))))
+        (icicle-abs-file-candidates     ; An alist whose items are ((FILE TAG...)).
+         (let ((result  ()))
+           (dolist (autofile  (bmkp-autofile-alist-only))
+             (let ((tags  (bmkp-get-tags autofile)))                  
+               (when (or tags current-prefix-arg)
+                 (push (list (cons (bookmark-get-filename autofile) tags)) result))))
+           result))
+        (icicle-dot-string                      (icicle-anychar-regexp))
+        (icicle-candidate-properties-alist      '((1 (face icicle-candidate-part))))
+        (icicle-list-use-nth-parts              '(1))
+        (icicle-whole-candidate-as-text-prop-p  t)))
+      (progn                            ; First code
+        (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+        (icicle-highlight-lighter)
+        (message "Gathering tagged files...")
+        (icicle-bind-file-candidate-keys))
+      nil                               ; Undo code
+      (icicle-unbind-file-candidate-keys)) ; Last code
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-tagged-other-window)
+
+
+;;; These are like multi-command versions of `bmkp-find-file-all-tags' etc.,
+;;; except that the predicate is applied after matching the user's input
+;;; (`icicle-must-pass-after-match-predicate').
+
+    (icicle-define-file-command icicle-find-file-all-tags ; `C-x j t a *'
+      "Visit a file or directory that has all of the tags you enter.
+This is otherwise like `icicle-find-file'.
+You are prompted for the tags, then the file name.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.  Completion is lax: you are
+not limited to existing tags.
+
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only 'find-file)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (tags           (bmkp-read-tags-completing))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff) (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bmk (bmkp-get-tags bmk))))
+                        (and btgs  (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-all-tags)
+
+
+    (icicle-define-file-command icicle-find-file-all-tags-other-window ; `C-x 4 j t a *'
+      "Same as `icicle-find-file-all-tags', except uses another window."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (tags           (bmkp-read-tags-completing))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff) (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bmk (bmkp-get-tags bmk))))
+                        (and btgs  (bmkp-every #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-other-window)
+
+
+    (icicle-define-file-command icicle-find-file-all-tags-regexp ; `C-x j t a % *'
+      "Visit a file or directory that has each tag matching a regexp you enter.
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only 'find-file)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (regexp         (read-string "Regexp for tags: "))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff)
+           (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                  (btgs  (and bmk (bmkp-get-tags bmk))))
+             (and btgs  (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
+                                    btgs))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-regexp)
+
+
+    (icicle-define-file-command icicle-find-file-all-tags-regexp-other-window ; `C-x 4 j t a % *'
+      "Same as `icicle-find-file-all-tags-regexp', except uses another window."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (regexp         (read-string "Regexp for tags: "))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff)
+           (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                  (btgs  (and bmk (bmkp-get-tags bmk))))
+             (and btgs  (bmkp-every #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
+                                    btgs))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-all-tags-regexp-other-window)
+
+
+    (icicle-define-file-command icicle-find-file-some-tags ; `C-x j t a +'
+      "Visit a file or directory that has at least one of the tags you enter.
+This is otherwise like `icicle-find-file'.
+You are prompted for the tags, then the file name.
+Hit `RET' to enter each tag, then hit `RET' again after the last tag.
+You can use completion to enter each tag.  Completion is lax: you are
+not limited to existing tags.
+
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only 'find-file)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (tags           (bmkp-read-tags-completing))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff) (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bmk (bmkp-get-tags bmk))))
+                        (and btgs  (bmkp-some  #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-some-tags)
+
+
+    (icicle-define-file-command icicle-find-file-some-tags-other-window ; `C-x 4 j t a +'
+      "Same as `icicle-find-file-some-tags', except uses another window."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (tags           (bmkp-read-tags-completing))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff) (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                             (btgs  (and bmk (bmkp-get-tags bmk))))
+                        (and btgs  (bmkp-some #'(lambda (tag) (bmkp-has-tag-p bmk tag)) tags))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-other-window)
+
+
+    (icicle-define-file-command icicle-find-file-some-tags-regexp ; `C-x j t a % +'
+      "Visit a file or directory that has a tag matching a regexp you enter.
+When prompted for the file you can use `M-n' to pick up the file name
+at point, or if none then the visited file."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only 'find-file)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (regexp         (read-string "Regexp for tags: "))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff)
+           (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                  (btgs  (and bmk (bmkp-get-tags bmk))))
+             (and btgs  (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
+                                   btgs))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-regexp)
+
+
+    (icicle-define-file-command icicle-find-file-some-tags-regexp-other-window ; `C-x 4 j t a % +'
+      "Same as `icicle-find-file-some-tags-regexp', except uses another window."
+      (lambda (file)                    ; Function to perform the action
+        (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
+                         (or (and init-pref-arg        (not current-prefix-arg))
+                             (and (not init-pref-arg)  current-prefix-arg))
+                       init-pref-arg))
+               (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
+          (funcall fn file 'WILDCARDS)))
+      "Find file: " nil nil t nil nil
+      (icicle-file-bindings             ; Bindings
+       ((init-pref-arg  current-prefix-arg) ; Pre bindings
+        (regexp         (read-string "Regexp for tags: "))
+        (icicle-all-candidates-list-alt-action-fn ; `M-|'
+         (lambda (files) (let ((enable-recursive-minibuffers  t))
+                           (dired-other-window (cons (read-string "Dired buffer name: ") files))))))
+       ((icicle-must-pass-after-match-predicate ; Post bindings
+         (lambda (ff)
+           (let* ((bmk   (bmkp-get-autofile-bookmark ff))
+                  (btgs  (and bmk (bmkp-get-tags bmk))))
+             (and btgs  (bmkp-some #'(lambda (tag) (string-match regexp (bmkp-tag-name tag)))
+                                   btgs))))))))
+
+    (icicle-maybe-byte-compile-after-load icicle-find-file-some-tags-regexp-other-window)
+
+    ))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-cmd2)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-cmd2.el ends here
diff --git a/auto-install/icicles-doc1.el b/auto-install/icicles-doc1.el
new file mode 100644
index 0000000..05bcf1c
--- /dev/null
+++ b/auto-install/icicles-doc1.el
@@ -0,0 +1,7244 @@
+;;; icicles-doc1.el --- Minibuffer input completion and cycling.
+;;
+;; Filename: icicles-doc1.el
+;; Description: Minibuffer completion and cycling.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Tue Aug  1 14:21:16 1995
+;; Version: 22.0
+;; Last-Updated: Sat Sep 10 11:47:15 2011 (-0700)
+;;           By: dradams
+;;     Update #: 26187
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-doc1.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Icicles documentation, part 1.
+;;
+;;  Files `icicles-doc1.el' and `icicles-doc2.el' contain the doc for
+;;  Icicles, including how to install and use Icicles.  You can also
+;;  read the Icicles doc, in formatted form, on the Emacs-Wiki Web
+;;  site: http://www.emacswiki.org/cgi-bin/wiki/Icicles.  Emacs Wiki
+;;  also has a few addtional pages about Icicles.  In particular, if
+;;  you are new to Emacs, as well as Icicles, see this page:
+;;  http://www.emacswiki.org/cgi-bin/wiki/EmacsNewbieWithIcicles.
+ 
+;;(@* "Installing Icicles")
+;;
+;;  To use this library:
+;;
+;;    Add this to your initialization file (~/.emacs or ~/_emacs):
+;;
+;;      (require 'icicles) ; Load this library.
+;;      (icicle-mode 1)    ; Turn on Icicle mode.
+;;
+;;    It is best to add this code *after* any code that creates or
+;;    changes key bindings, so Icicles can pick up all of your key
+;;    definitions (bindings).  However, if you make new bindings, you
+;;    can always exit and then reenter Icicle mode to pick them up.
+;;
+;;    You will need all of these libraries (loaded by `icicles.el'):
+;;
+;;     `icicles-chg.el'  (not loaded - change logs only)
+;;     `icicles-cmd1.el'
+;;     `icicles-cmd2.el'
+;;     `icicles-doc1.el' (not loaded - doc only)
+;;     `icicles-doc2.el' (not loaded - doc only)
+;;     `icicles-face.el'
+;;     `icicles-fn.el'
+;;     `icicles-mac.el'
+;;     `icicles-mcmd.el'
+;;     `icicles-mode.el'
+;;     `icicles-opt.el'
+;;     `icicles-var.el'
+;;
+;;    The following libraries are recommended but optional (loaded by
+;;    `icicles.el' if in your `load-path').  They are enhanced by
+;;    Icicles, or Icicles is enhanced by them, or both.  They are all
+;;    available at Emacs Wiki,
+;;    http://www.emacswiki.org/cgi-bin/wiki/ElispArea.
+;;
+;;     `apropos-fn+var.el' - Apropos enhancements for fns and vars.
+;;     `bookmark+.el'      - Many bookmark enhancements.
+;;     `col-highlight.el'  - Required by `crosshairs.el'.  Emacs 22+
+;;     `crosshairs.el'     - Highlight target positions.  Emacs 22+
+;;     `doremi.el' and
+;;     `doremi-frm.el'     - Incremental changes.
+;;     `frame-cmds.el'     - Frame and window commands.
+;;     `fuzzy-match.el'    - Fuzzy completion (matching).
+;;     `hexrgb.el'         - Color manipulation.
+;;     `hl-line+.el'       - Required by `crosshairs.el'.  Emacs 22+
+;;     `icomplete+.el'     - Enhancements to `icomplete.el'
+;;     `info+.el'          - Enhancements to `info'.
+;;     `lacarte.el'        - Keyboard access to the menubar menus.
+;;     `mb-depth+.el'      - Minibuffer depth indicator.  Emacs 22+
+;;     `pp+.el'            - Pretty-printing for `M-:'.
+;;     `synonyms.el'       - A hypertext thesaurus.
+;;     `thingatpt+.el'     - Better defaults for commands, `M-.'.
+;;     `vline.el'          - Required by `crosshairs.el'.  Emacs 22+
+;;
+;;    Be aware that some of these libraries in turn require other
+;;    libraries.  For example, library `frame-cmds.el' requires
+;;    library `frame-fns.el'.
+;;
+;;    Depending on your platform, if you use Icicles in a text
+;;    terminal (that is, without a window system/manager), then you
+;;    might need to change some of the key bindings, if some of the
+;;    default bindings are not available to you.
+;;
+;;    If on your platform, for example, Emacs in a text terminal does
+;;    not recognize a key such as `S-TAB' (as something different from
+;;    `TAB'), then you will want to change that key binding.  To
+;;    customize Icicles key bindings, see
+;;    (@file :file-name "icicles-doc2.el" :to "Customizing Key Bindings").
+;;    You might also want to customize some of the Icicles faces,
+;;    since a text terminal is sometimes limited in the colors it can
+;;    handle.
+;;
+;;    It is of course best to byte-compile all of the libraries
+;;    (except `icicle-chg.el', `icicles-doc1.el', and
+;;    `icicles-doc2.el').  You will likely get some byte-compiler
+;;    warning messages.  These are probably benign - ignore them.
+;;    Icicles is designed to work with multiple versions of Emacs, and
+;;    that fact provokes compiler warnings.  If you get byte-compiler
+;;    errors (not warnings), then please report a bug, using `M-x
+;;    icicle-send-bug-report'.
+;;
+;;    Whenever you update Icicles (i.e., download new versions of
+;;    Icicles source files), I recommend that you do the following:
+;;
+;;      1. Delete all existing byte-compiled Icicles files
+;;         (icicles*.elc).
+;;      2. Load Icicles (`load-library' or `require').
+;;      3. Byte-compile the source files.
+;;
+;;    In particular, always load `icicles-mac.el' (not
+;;    `icicles-mac.elc') before you byte-compile new versions of the
+;;    files, in case there have been any changes to Lisp macros (in
+;;    `icicles-mac.el').
+;;
+;;    After startup, you can turn Icicle mode on or off at any time
+;;    interactively, using command `icy-mode' (aka `icicle-mode' -
+;;    prefix `icy' is unique to this command, so it is easier to
+;;    complete).
+;;
+;;    Note: If you turn on Icicle mode in your init file, it's
+;;    generally best to do so as late as possible - after you or any
+;;    libraries that you load do any key binding.  This is because
+;;    Icicles uses the current global key bindings to determine which
+;;    keys to bind for minibuffer completion and cycling.  To pick up
+;;    the latest bindings at any time, you can of course enter Icicle
+;;    mode interactively using command `icy-mode' (if necessary, exit,
+;;    then re-enter).
+;;
+;;    Note: Icicles redefines some functions when you are in Icicle
+;;    mode (it restores them when you leave Icicle mode).  It
+;;    generally does not use `defadvice' to alter the functions; it
+;;    redefines them instead.  Because of this, there can be
+;;    incompatibilities with other libraries that also change the same
+;;    functions (using `defadvice' or otherwise).  An example is Viper
+;;    mode.  If you load Viper before Icicles, then you will run into
+;;    problems with function `read-file-name' because it is tweaked by
+;;    both Viper and Icicles.  If you load Icicles before Viper, you
+;;    should not encounter this problem (but you might encounter other
+;;    problems: both Icicles and Viper try to control the minibuffer).
+ 
+;;(@* "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index and render it more readable.  Likewise, for
+;;  the cross-references and section headings throughout this file.
+;;  You can get `linkd.el' here:
+;;  http://www.emacswiki.org/cgi-bin/wiki/linkd.el.
+;;
+;;  (@* "Documentation in File `icicles-doc1.el'")
+;;  ----------------------------------------------
+;;
+;;  (@> "Nutshell View of Icicles")
+;;    (@> "README for NON-Readers")
+;;    (@> "README")
+;;    (@> "Toggle Options on the Fly")
+;;    (@> "Cycle Completion Candidates")
+;;    (@> "Display Completion Candidates")
+;;    (@> "Prefix Completion and Apropos Completion")
+;;    (@> "Chains of Simple Match Patterns - Progressive Completion")
+;;    (@> "Chip Away the Non-Elephant")
+;;    (@> "Choose Before You Act")
+;;    (@> "Help on Completion Candidates")
+;;    (@> "Perform Multiple Operations in One Command")
+;;    (@> "Perform Alternative Operations on the Fly")
+;;    (@> "Completion Status Indicators")
+;;    (@> "Icicles Search")
+;;    (@> "Complete Key Sequences Too")
+;;    (@> "Available for Almost Any Input")
+;;    (@> "Component Icicles Libraries")
+;;    (@> "If You Are an Emacs-Lisp Programmer")
+;;
+;;  (@> "Inserting Text Found Near the Cursor")
+;;    (@> "FFAP: Find File At Point")
+;;    (@> "Proxy Candidates, `M-.'")
+;;    (@> "Repeat `M-.' To Grab More or Different")
+;;    (@> "Resolve File Names")
+;;  (@> "Background on Vanilla Emacs Input Completion")
+;;  (@> "Cycling Completions")
+;;  (@> "Traversing Minibuffer Histories")
+;;  (@> "Apropos Completions")
+;;  (@> "Expanded-Common-Match Completion")
+;;  (@> "Progressive Completion")
+;;    (@> "`M-*': Matching Additional Regexps")
+;;    (@> "Successive Approximation...")
+;;    (@> "`M-&': Satisfying Additional Predicates")
+;;
+;;  (@> "Regressive Completion")
+;;  (@> "Completion On Demand")
+;;  (@> "Moving Between the Minibuffer and Other Buffers")
+;;  (@> "Inserting a Regexp from a Variable or Register")
+;;  (@> "Special Characters in Input Patterns")
+;;  (@> "Exiting the Minibuffer Without Confirmation")
+;;  (@> "Ido and IswitchB")
+;;  (@> "*Completions* Display")
+;;  (@> "Icompletion")
+;;    (@> "icomplete+.el Displays the Number of Other Prefix Candidates")
+;;    (@> "Icicles Highlights the Input that Won't Complete")
+;;    (@> "Icompletion in *Completions*: Apropos and Prefix Completion")
+;;
+;;  (@> "Sorting Candidates and Removing Duplicates")
+;;    (@> "Changing the Sort Order")
+;;    (@> "Defining New Sort Orders")
+;;    (@> "Different Sorts for Different Sorts of Uses")
+;;  (@> "Get Help on Candidates")
+;;    (@> "Use Candidate Help Like You Use Emacs Command `apropos'")
+;;    (@> "Other Icicles Apropos Commands")
+;;
+;;  (@> "Multi-Commands")
+;;    (@> "What Is a Multi-Command?")
+;;    (@> "How Does a Multi-Command Work?")
+;;
+;;  (@> "More about Multi-Commands")
+;;    (@> "Alternative Actions")
+;;    (@> "Deleting Objects")
+;;    (@> "Option `icicle-use-C-for-actions-flag'")
+;;    (@> "Accessing Saved Locations (Bookmarks) on the Fly")
+;;
+;;  (@> "Icicles Tripping")
+;;    (@> "Highlighting the Destination")
+;;
+;;  (@> "Key Completion")
+;;    (@> "Completing Keys")
+;;    (@> "`S-TAB' Is Everywhere - Start With It")
+;;    (@> "Completing Keys By Name")
+;;    (@> "Completing Prefix Keys")
+;;    (@> "Meta Key Bindings")
+;;    (@> "Navigate the Key-Binding Hierarchy")
+;;    (@> "Local Bindings Are Highlighted")
+;;    (@> "Completing Keys By Just Hitting Them")
+;;    (@> "Key and Command Help")
+;;    (@> "`S-TAB' Is a Multi-Command")
+;;    (@> "Possible Source of Confusion")
+;;    (@> "Three-Key Emacs")
+;;    (@> "Entering Special and Foreign Characters")
+;;    (@> "Handling Keymaps That Are Inaccessible From the Global Map")
+;;
+;;  (@> "Icicles Multi `M-x'")
+;;    (@> "Examples of Using Multi `M-x'")
+;;      (@> "What about describe-variable and describe-function?")
+;;    (@> "Multi `M-x' Turns Every Command into a Multi-Command")
+;;
+;;  (@> "Choose All Completion Candidates")
+;;  (@> "Sets of Completion Candidates")
+;;    (@> "Saving and Retrieving Completion Candidates")
+;;    (@> "Different Places for Saving and Retrieving Candidates")
+;;    (@> "Set Operations")
+;;  (@> "Google Matching")
+;;    (@> "Domain of Discourse")
+;;    (@> "Global Filtering")
+;;    (@> "Word Matching and String Matching")
+;;    (@> "AND Matching and OR Matching")
+;;    (@> "NOT Matching")
+;;
+;;  (@> "Buffer-Name Input")
+;;
+;;  (@> "File-Name Input and Locating Files Anywhere")
+;;    (@> "Function `read-file-name'")
+;;    (@> "Function `completing-read'")
+;;    (@> "Icicles Commands that Read File Names")
+;;    (@> "Absolute File Names and Different Directories")
+;;
+;;  (@> "Persistent Sets of Completion Candidates")
+;;    (@> "Saving Candidates in Cache Files")
+;;    (@> "Filesets and Icicles Saved Completion Sets")
+;;    (@> "Improving Performance with Persistent Sets")
+;;      (@> "Avoid Remote File-Name Completion")
+;;      (@> "Avoid Generating A Large Completion Set")
+;;
+;;  (@> "Dealing With Large Candidate Sets")
+;;  (@> "History Enhancements")
+;;    (@> "What Input, What History?")
+;;    (@> "Overview of Minibuffer History Enhancements")
+;;    (@> "Using Completion to Insert Previous Inputs: `M-o'")
+;;    (@> "Putting Previous Candidates First: `C-M-,'")
+;;    (@> "Matching Only Historical Candidates: `M-h' and `M-pause'")
+;;    (@> "Using Other Histories; Commands Any Which Way")
+;;      (@> "Completing Against All Interactive Commands")
+;;      (@> "Using an Alternative History")
+;;    (@> "Cleaning Up History Lists")
+;;
+;;  (@> "Isearch Enhancements")
+;;    (@> "Launch Occur using the Isearch Search String")
+;;    (@> "Launch Icicles Search using the Isearch Search String")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Documentation in File `icicles-doc2.el'")
+;;  -----------------------------------------------------------
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;    (@file :file-name "icicles-doc2.el" :to "Introduction: On Beyond Occur...")
+;;    (@file :file-name "icicles-doc2.el" :to "How Icicles Search Works")
+;;    (@file :file-name "icicles-doc2.el" :to "Why Use 2 Search Patterns?")
+;;    (@file :file-name "icicles-doc2.el" :to "Search Outside the Defined Search Contexts?")
+;;    (@file :file-name "icicles-doc2.el" :to "Search Multiple Buffers, Files, and Bookmarks")
+;;    (@file :file-name "icicles-doc2.el" :to "User Options for Icicles Searching")
+;;    (@file :file-name "icicles-doc2.el" :to "Using Regexps with Icicles Search")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Search and Replace")
+;;  (@file :file-name "icicles-doc2.el" :to "Other Icicles Search Commands")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles Imenu")
+;;      (@file :file-name "icicles-doc2.el" :to "Type-Specific Imenu Commands")
+;;      (@file :file-name "icicles-doc2.el" :to "Imenu Commands that Search Full Definitions")
+;;      (@file :file-name "icicles-doc2.el" :to "Icicles Imenu Combines Benefits of Imenu and Emacs Tags")
+;;
+;;    (@file :file-name "icicles-doc2.el" :to "Compile/Grep Search")
+;;    (@file :file-name "icicles-doc2.el" :to "Input Reuse in Interactive Interpreter Modes")
+;;    (@file :file-name "icicles-doc2.el" :to "Define Your Own Icicles Search Commands")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Bookmark Enhancements")
+;;    (@file :file-name "icicles-doc2.el" :to "Saving Regions and Selecting Them")
+;;    (@file :file-name "icicles-doc2.el" :to "Setting a Bookmark and Jumping to a Bookmark")
+;;    (@file :file-name "icicles-doc2.el" :to "Jumping to a Bookmark")
+;;    (@file :file-name "icicles-doc2.el" :to "Searching Bookmarked Objects")
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Enhancements for Emacs Tags")
+;;    (@file :file-name "icicles-doc2.el" :to "`icicle-find-tag': Find Tags in All Tags Tables")
+;;    (@file :file-name "icicles-doc2.el" :to "`icicle-find-first-tag': Find First Tag in Current Table")
+;;    (@file :file-name "icicles-doc2.el" :to "`icicle-tags-search': Search and Replace Using Tags")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Shell-Command Enhancements")
+;;    (@file :file-name "icicles-doc2.el" :to "Shell Command Completion as File-Name Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Gotcha: `$' in Shell Commands")
+;;    (@file :file-name "icicles-doc2.el" :to "Known Shell Commands as Proxy Candidates")
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Dired Enhancements")
+;;    (@file :file-name "icicles-doc2.el" :to "Search-and-Replace Marked Files")
+;;    (@file :file-name "icicles-doc2.el" :to "Save Marked Files as Completion Candidates")
+;;    (@file :file-name "icicles-doc2.el" :to "Open Dired for a Set of File Names")
+;;    (@file :file-name "icicles-doc2.el" :to "Marked Files as a Project")
+;;    (@file :file-name "icicles-doc2.el" :to "Shell Commands on Marked Files")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Info Enhancements")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles Completion for Info")
+;;      (@file :file-name "icicles-doc2.el" :to "Virtual Info Books")
+;;
+;;    (@file :file-name "icicles-doc2.el" :to "Using Icicle-Search With Info")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Support for Projects")
+;;    (@file :file-name "icicles-doc2.el" :to "Bookmarks for Project Access and Organization")
+;;    (@file :file-name "icicles-doc2.el" :to "A Tags File Can Define a Project")
+;;    (@file :file-name "icicles-doc2.el" :to "Navigating Among Code Definitions")
+;;    (@file :file-name "icicles-doc2.el" :to "Searching Project Files")
+;;    (@file :file-name "icicles-doc2.el" :to "Defining and Saving Sets of Files or Buffers")
+;;    (@file :file-name "icicles-doc2.el" :to "Retrieving and Reusing a Saved Project")
+;;    (@file :file-name "icicles-doc2.el" :to "Semantics? Roll Your Own?")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Using Complex Completion Candidates")
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles OO: Object-Action Interaction")
+;;    (@file :file-name "icicles-doc2.el" :to "Apropos Completion as OO")
+;;    (@file :file-name "icicles-doc2.el" :to "M-RET")
+;;    (@file :file-name "icicles-doc2.el" :to "`icicle-object-action' and `icicle-anything'")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles with Anything")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Multi-Completions")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles Multi-Completion Commands")
+;;    (@file :file-name "icicles-doc2.el" :to "How Multi-Completions Work")
+;;    (@file :file-name "icicles-doc2.el" :to "Multi-Completions vs `completing-read-multiple'")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Dot, Dot, Dot")
+;;  (@file :file-name "icicles-doc2.el" :to "Fuzzy Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Partial Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Scatter-Match Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Swank (Fuzzy Symbol) Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Fuzzy-Match Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Levenshtein Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Jaro-Winkler Completion")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Completion in Other Buffers")
+;;    (@file :file-name "icicles-doc2.el" :to "Dynamic Abbreviation")
+;;    (@file :file-name "icicles-doc2.el" :to "BBDB Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Thesaurus Lookup and Completion")
+;;    (@file :file-name "icicles-doc2.el" :to "Completion in Comint Modes")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Customization and General Tips")
+;;    (@file :file-name "icicles-doc2.el" :to "Using Icicles with Delete Selection Mode")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles User Options and Faces")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "File-Name and Directory-Name Completion Tips")
+;;  (@file :file-name "icicles-doc2.el" :to "Key Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Global Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles-Mode Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Minibuffer Bindings")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Customizing Key Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Customizing Global Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Customizing Icicle Mode Bindings")
+;;    (@file :file-name "icicles-doc2.el" :to "Customizing Minibuffer Bindings")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Redefines Some Standard Functions")
+;;  (@file :file-name "icicles-doc2.el" :to "Programming with Fancy Candidates")
+;;  (@file :file-name "icicles-doc2.el" :to "Programming Multi-Completions")
+;;    (@file :file-name "icicles-doc2.el" :to "Variable icicle-list-use-nth-parts")
+;;    (@file :file-name "icicles-doc2.el" :to "Variable icicle-candidate-properties-alist")
+;;    (@file :file-name "icicles-doc2.el" :to "What You See Is Not What You Get")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Candidates with Text Properties")
+;;    (@file :file-name "icicles-doc2.el" :to "Using Property icicle-special-candidate")
+;;    (@file :file-name "icicles-doc2.el" :to "Applying Text Properties to a Candidate String")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Icicles Commands (Including Multi-Commands)")
+;;    (@file :file-name "icicles-doc2.el" :to "Nothing To It!")
+;;    (@file :file-name "icicles-doc2.el" :to "Multi-Commands Are Easy To Define Too")
+;;    (@file :file-name "icicles-doc2.el" :to "Are Users Dependent on Icicles To Use Multi-Commands?")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Icicles Tripping Commands")
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Multiple-Choice Menus")
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Icicles Multi `M-x'")
+;;    (@file :file-name "icicles-doc2.el" :to "How Multi `M-x' is Defined")
+;;
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Multi-Commands the Hard Way")
+;;  (@file :file-name "icicles-doc2.el" :to "Global Filters")
+;;  (@file :file-name "icicles-doc2.el" :to "Specifying Match Functions for Commands")
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Buffer-Text Completion for Comint Modes")
+;;  (@file :file-name "icicles-doc2.el" :to "Note to Programmers")
+;;  (@file :file-name "icicles-doc2.el" :to "La Petite Histoire")
+;;  (@file :file-name "icicles-doc2.el" :to "Note on Non-`nil' `pop-up-frames' on MS Windows")
+ 
+;;(@* "Nutshell View of Icicles")
+;;
+;;  Nutshell View of Icicles
+;;  ------------------------
+;;
+;;(@* "README for NON-Readers")
+;;  ** README for NON-Readers **
+;;
+;;  Load library `icicles.el', turn on Icicle mode, and you're good to
+;;  go.  You can turn Icicle mode off or on at any time with command
+;;  `icy-mode'.  When you turn it off, you're back in vanilla Emacs.
+;;
+;;  Beyond that, the most important thing to know about Icicles is
+;;  that you can get help on Icicle mode during minibuffer input.  You
+;;  do that either by using item Help of the menu-bar Icicles menu or
+;;  Minibuf menu, or by hitting `C-?' (`icicle-minibuffer-help').
+;;
+;;  You now know enough to use Icicles.  If you have doc-phobia or are
+;;  easily overwhelmed by explanations, then *read no more* - just try
+;;  it!
+;;
+;;  If you want a little more explanation than the help page (`C-?'),
+;;  then read the rest of section (@> "Nutshell View of Icicles"), but
+;;  no more.  It shows a sample of what you can do in Icicle mode.
+;;
+;;  If you want to know more about Icicles by reading instead of just
+;;  trying, then read beyond section (@> "Nutshell View of Icicles").
+;;  There is a lot you can learn, but there is not much that you need
+;;  to learn, to use Icicles usefully.  Do not be afraid to get in and
+;;  get wet.  Above all, do not be overwhelmed by the doc - if it
+;;  helps, fine.
+;;
+;;  One good way to start is to explore menus `Icicles' and `Minibuf';
+;;  you can access most Icicles features using these menus, without at
+;;  the same time struggling to learn new key bindings.  The `Icicles'
+;;  menu is available all of the time (that is, whenever you are in
+;;  Icicle mode), and the `Minibuf' menu is available whenever the
+;;  minibuffer is active.
+;;
+;;  During minibuffer input completion, you can also press Control and
+;;  right-click (`C-mouse-3') on a completion candidate in buffer
+;;  `*Completions*', and choose from a contextual popup menu,
+;;  `Completion'.
+;;
+;;  You can customize this menu.  By default, submenu `This Candidate'
+;;  has menu items that apply to the candidate you clicked to pop up
+;;  the menu.  The other submenus have items that apply to all
+;;  candidates, candidates you have selected (the region in
+;;  `*Completions*'), or candidates you have saved (marked).
+;;
+;;  Altogether there are many menu items in the popup menu.  Think of
+;;  the menu as a learning device and a way to remind you of possible
+;;  operations on completion candidates and the keys they are bound
+;;  to.  In this it is similar to the help you get when you use `C-?'
+;;  in the minibuffer, but with the menu you can also act, not just be
+;;  reminded.
+;;
+;;  See Also: (@> "*Completions* Display").
+;;
+;;(@* "README")
+;;  ** README **
+;;
+;;  Icicles enhances minibuffer completion.  It does so generally,
+;;  throughout Emacs.  It does this by improving the basic Emacs
+;;  functions that read minibuffer input with completion:
+;;  `completing-read', `read-file-name', and `read-from-minibuffer'.
+;;
+;;  This means that Icicles affects every kind of minibuffer
+;;  completion, not just buffers or files or commands or variables or
+;;  faces or...  Every kind.  (You can even complete key sequences.)
+;;  Lisp code need not call a special completion function to get this
+;;  advantage - each call to `completing-read' etc. benefits
+;;  automatically.
+;;
+;;  Icicles has this effect only when you are in Icicle minor mode.
+;;  Turn off Icicle mode and Emacs behaves as usual (vanilla).
+;;
+;;  To best understand what Icicles offers you, you need to think a
+;;  bit differently about minibuffer completion.
+;;
+;;  During (vanilla) Emacs completion:
+;;
+;;  v1. You type some input.  Then you ask Emacs (`TAB') to look for a
+;;      match of your input against the domain of input possibilities:
+;;      the completion candidates.  If a match is found, your input is
+;;      completed and you hit `RET' to accept it (commit it as your
+;;      final input).  If there are several matches you type some more
+;;      text and recomplete ... until there is only one match.  Then
+;;      you hit `RET'.
+;;
+;;  v2. The goal here is to complete and then enter your input, as
+;;      easily and rapidly as possible.
+;;
+;;  v3. The process starts with a domain of possible inputs: the
+;;      initial set of candidates.  This domain can be realized
+;;      intensionally, via a function, or more commonly extensionally,
+;;      via an explicit set.
+;;
+;;  v4. Sometimes completion is "lax" instead of "strict", meaning
+;;      that you can input any text you like in the end (`RET'), but a
+;;      set of candidates is still provided for the convenience of
+;;      completion (`TAB').
+;;
+;;  v5. When you hit `TAB' to complete, your current input in the
+;;      minibuffer (the contents) filters the domain, narrowing it
+;;      down to the set of matching candidates, which is shown in
+;;      buffer `*Completions*'.
+;;
+;;  See Also: (@> "Background on Vanilla Emacs Input Completion").
+;;
+;;  For Icicles it is the completion *process* that is important, and
+;;  this process can serve several goals.  So instead of focusing on
+;;  the goal of entering a final input (v2), let's consider the
+;;  overall process: There is a set (domain) of possible candidates
+;;  (v3) that you filter with your input (v1).
+;;
+;;  If you edit your input and recomplete using `TAB', then the domain
+;;  is refiltered to a different set of matching completion
+;;  candidates.  Each time you do this your input corresponds to a
+;;  different set.  The process of completion thus provides a great
+;;  way to filter a set interactively.
+;;
+;;  Now if all you do in the minibuffer at the end of the day is enter
+;;  your final input (`RET'), then changing your input and
+;;  recompleting (`TAB') is pretty much a waste of time, a detour.
+;;  But if you can do more along the way, if you can make use of the
+;;  current set of matches in some way, then the story is different.
+;;
+;;  This is the key to understanding what Icicles offers.  Think of
+;;  minibuffer completion as a pattern-matching user interface, a
+;;  general way to interact with sets of named objects.
+;;
+;;  No doubt you have already used completion sometimes as more than
+;;  just a means toward the end of inputting a value.  Perhaps you
+;;  have used `TAB' during file-name completion to take a look at the
+;;  nearby directory structure, possibly even finishing with `C-g'
+;;  instead of entering any file name definitively (`RET').  In that
+;;  scenario, you are exploring the set of file-name candidates, using
+;;  minibuffer completion as a help feature.
+;;
+;;  Icicles binds different keys in the minibuffer keymaps to provide
+;;  different ways to interact with the current set of matches
+;;  (completion candidates).  To exploit the possibilities of
+;;  filtering a set dynamically by pattern matching, Icicles provides
+;;  different features that work together.
+;;
+;;  These are the most important Icicles features:
+;;
+;;  i1. Incremental completion.  By default, each change you make to
+;;      your minibuffer input automatically rematches and recompletes
+;;      it (v5).  IOW, the set of current candidates is updated
+;;      dynamically, incrementally.  You can always see (in the
+;;      `*Completions*' window) what your current input (the
+;;      minibuffer content) matches.  This is a help and exploration
+;;      feature.
+;;
+;;  i2. Cycling and the current candidate.  You can cycle among the
+;;      current set of candidates (minibuffer matches).  The current
+;;      candidate is placed in the minibuffer as you do this, for
+;;      possible editing.  You can of course hit `RET' to commit the
+;;      current candidate, edited or not, as your final input.
+;;
+;;  i3. Help, multiple actions, alternative actions.  But you can also
+;;      instead hit a key to provide information (help) about the
+;;      current candidate; hit a key to act on it (accept it as input
+;;      but without ending the minibuffer); hit a key to perform some
+;;      alternative action on it (without ending the minibuffer); and
+;;      so on.  Candidate help is perhaps the Icicles feature used
+;;      most often.
+;;
+;;  i4. Multi-commands.  A command that lets you act on a candidate
+;;      without ending the minibuffer, so that you can thus act on
+;;      several candidates, is called a "multi-command".  Not every
+;;      command is a multi-command.
+;;
+;;  i5. Set operations.  You can hit a key to act not on any
+;;      particular matching candidate but on each of them individually
+;;      or on all of them collectively.  Among the collective set
+;;      operations are union, intersection, difference/complementing,
+;;      and saving for later reuse.
+;;
+;;  i6. Progressive completion.  Set intersection can take a couple of
+;;      forms.  The most useful is "progressive completion": use the
+;;      current set of matching candidates as the domain for a
+;;      recursive minibuffer.  That is, start over and match different
+;;      inputs against a subset of the original domain that was
+;;      defined by the previous matching operation.  This is analogous
+;;      to piping `grep' outputs through additional `grep' filters.
+;;
+;;  i7. More powerful matching.  Using your input (minibuffer content)
+;;      as a dynamic filter is very important in Icicles.  In line
+;;      with this, you can employ different matching methods.  The
+;;      most powerful is regexp matching (which includes substring
+;;      matching).
+;;
+;;  i8. Candidate sorting.  You can sort the current candidates on the
+;;      fly in different ways, so that you can cycle them in different
+;;      orders.  The possible sort orders at any time depend on the
+;;      context and type of candidates.  You can define your own sort
+;;      orders.
+;;
+;;  Most of these features are unique to Icicles.  Others were
+;;  original with Icicles but have since been copied by vanilla Emacs
+;;  or other libraries.  But only Icicles offers these features (and
+;;  more) together, combining them cooperatively.
+;;
+;;  Icicles is very general.  It affects many aspects of minibuffer
+;;  completion.  As you learn to take advantage of its features it can
+;;  change how you use Emacs.  But Icicles also stays out of the way
+;;  if you do not ask for its help.  If you just use `TAB' completion
+;;  and you use none of the keys bound specially during completion
+;;  (for cycling, progressive completion, etc.), then you will hardly
+;;  notice Icicles.
+;;
+;;  All Lisp code that uses minibuffer completion automatically takes
+;;  advantage of Icicles.  But some other libraries go beyond this by
+;;  defining Icicles multi-commands or otherwise making some special
+;;  use of Icicles features.  None of these libraries are required in
+;;  order to use Icicles, but they are recommended because of the
+;;  synergy they provide.  See (@> "Installing Icicles").
+;;
+;;(@* "Toggle Options on the Fly")
+;;  ** Toggle Options on the Fly **
+;;
+;;  There are many user options that affect the behavior of Icicles
+;;  features.  Some of these are Boolean (on/off) or allow for simple
+;;  alternation or cycling of the possible values.  Many of those
+;;  options are associated with toggle commands that are bound to keys
+;;  whenever the minibuffer is active, or at least active for
+;;  completion.
+;;
+;;  Throughout this doc you will see references to such options and
+;;  their toggles.  For example: "You can toggle case-sensitivity at
+;;  any time using `C-A' (that is, `C-S-a') in the minibuffer."
+;;
+;;  The reason for making it so easy to change the values of these
+;;  options on the fly is that different kinds of completion, in
+;;  different contexts, can take advantage of different option values.
+;;  Icicles completion is very general, and a single option value is
+;;  not always optimal for all contexts.
+;;
+;;  You will become acquainted with a few of these toggle keys and
+;;  remember them, but you will forget others.  What is important to
+;;  point out here is that `C-?'  (`icicle-minibuffer-help') is your
+;;  friend in the minibuffer.  During completion, the help it displays
+;;  includes, near the top, a list of the toggle keys and the
+;;  corresponding current values of their options.
+;;
+;;  Whenever you use an Icicles toggle command, a momentary message
+;;  shows you the new option value.  So as an alternative to using
+;;  `C-?' to see the current value of an option, you can just toggle
+;;  it twice.
+;;
+;;(@* "Cycle Completion Candidates")
+;;  ** Cycle Completion Candidates **
+;;
+;;   M-x  t o o l  next
+;;
+;;  That is, type "tool" and then hit the `next' key, which is often
+;;  labeled "Page Down".  Each time you hit `next', another match for
+;;  your input (`tool') replaces it in the minibuffer:
+;;
+;;   M-x ediff-toggle-use-toolbar  next
+;;   M-x scroll-bar-toolkit-scroll next
+;;   M-x tool-bar-mode             next
+;;   M-x tooltip-mode              next
+;;   M-x ediff-toggle-use-toolbar ; Back to the beginning
+;;
+;;  Keys `next' and `prior' ("Page Up") cycle among all of the
+;;  commands that contain (match) the minibuffer input - `tool', in
+;;  this case.  Just hit `RET' (Return) when you get to the command
+;;  you want.
+;;
+;;  (Note: The particular candidates shown here and in other examples
+;;  might be different from what you see, depending on your version of
+;;  Emacs and what other libraries you might have loaded.)
+;;
+;;  You can use a regular expression, to narrow the field of matching
+;;  inputs:
+;;
+;;   M-x  i s e . + c h a r          next
+;;   M-x isearch-delete-char         next
+;;   M-x isearch-other-control-char  next
+;;   ...
+;;
+;;  Note that when you cycle, a one-line description of the current
+;;  candidate is shown in the mode line (of buffer `*Completions*' if
+;;  visible; otherwise of the current buffer).  You can get more
+;;  detailed info about individual candidates by holding the Control
+;;  and Meta keys (e.g. `C-M-next') while you cycle - see
+;;  (@> "*Completions* Display") and (@> "Help on Completion Candidates").
+;;
+;;  Try cycling candidates for `C-h v' for instance, using `next'.
+;;  Look for their descriptions in the mode line.  Now try cycling
+;;  using `C-M-next' - complete candidate help is shown in buffer
+;;  `*Help*'.
+;;
+;;  See (@> "Cycling Completions") for more about cycling completion
+;;  candidates.
+;;
+;;(@* "Display Completion Candidates")
+;;  ** Display Completion Candidates **
+;;
+;;  You can display all of the matches for the current minibuffer
+;;  input, in the `*Completions*' buffer, using `S-TAB' (Shift TAB).
+;;  So, for instance, `S-TAB' with `M-x ise.+char' in the minibuffer
+;;  displays all commands whose names contain `ise' followed
+;;  (somewhere) by `char'.
+;;
+;;  See (@> "*Completions* Display") for more about using the
+;;  `*Completions*' window.
+;;
+;;(@* "Prefix Completion and Apropos Completion")
+;;  ** Prefix Completion and Apropos Completion **
+;;
+;;  You can get the standard Emacs "prefix" completion, instead of the
+;;  "apropos" completion just described, by using `TAB' instead of
+;;  `S-TAB'.  You can cycle prefix-completion candidates by using the
+;;  `end' and `home' keys instead of `next' and `prior'.  (All four of
+;;  these keys are typically together in a central keypad to the right
+;;  of the main keyboard.)
+;;
+;;  You can also cycle candidates according to the current completion
+;;  mode, prefix or apropos, using either the mouse wheel or the arrow
+;;  keys `down' and `up'.  These are all called the "modal" cycling
+;;  keys because they respect the current completion mode.
+;;
+;;  The current completion mode is determined by the last completion
+;;  key you used, `TAB' or `S-TAB'.  If you have not used either so
+;;  far during the current minibuffer invocation, then the modal keys
+;;  cycle according to the value of option
+;;  `icicle-default-cycling-mode'.  By default the option value is
+;;  `prefix', which means that you can use `down', `up', or the mouse
+;;  wheel to cycle prefix completions without needing to first hit
+;;  `TAB'.
+;;
+;;  The non-modal cycling keys, `next', `prior', `end', and `home'
+;;  automatically set the completion mode and update the candidate
+;;  completions.  The modal cycling keys just cycle according to the
+;;  current completion mode, whether it is apropos or prefix.
+;;
+;;  To cycle using the mouse wheel, the mouse must not be over the
+;;  `*Completions*' window; if it is, then the wheel scrolls that
+;;  window instead of cycling candidates - see (@> "*Completions* Display").
+;;
+;;  As an alternative to using `end' or `next', you can cycle
+;;  candidates downward (forward) by just repeating the same
+;;  completion key: `TAB' or `S-TAB'.  For example:
+;;
+;;   M-x tool           TAB ; Display candidates with prefix `tool'
+;;   M-x tool-bar-mode  TAB
+;;   M-x tooltip-mode   TAB
+;;   M-x tool-bar-mode      ; Back to the beginning
+;;
+;;  Or:
+;;
+;;   M-x tool                      S-TAB ; Display matching candidates
+;;   M-x ediff-toggle-use-toolbar  S-TAB
+;;   M-x scroll-bar-toolkit-scroll S-TAB
+;;   M-x tool-bar-mode             S-TAB
+;;   M-x tooltip-mode              S-TAB
+;;   M-x ediff-toggle-use-toolbar        ; Back to the beginning
+;;
+;;  Changing to a different completion key (`TAB' to `S-TAB' or vice
+;;  versa) always switches completion type and completes, but you can
+;;  then repeat that new completion key to cycle among the candidates.
+;;
+;;  Note: In vanilla Emacs, repeating `TAB' scrolls the
+;;  `*Completions*' window.  In Icicles, you can use `C-v' to scroll
+;;  `*Completions*' down and `M-v' to scroll up.  You can also use the
+;;  mouse wheel to scroll `*Completions*'.
+;;
+;;  See (@> "Apropos Completions") for more about apropos and prefix
+;;  completion.
+;;
+;;(@* "Chains of Simple Match Patterns - Progressive Completion")
+;;  ** Chains of Simple Match Patterns - Progressive Completion **
+;;
+;;  To see which functions contain `char', `delete', and `back' in
+;;  their names, in any order:
+;;
+;;   C-h f  c h a r  S-TAB - Display all function names that contain
+;;   `char'.
+;;
+;;   M-*  d e l e t e  - Narrow that set of names to those that also
+;;   contain `delete'.
+;;
+;;   M-*  b a c k  - Narrow the set of matching names further, to
+;;   those that also contain `back'.
+;;
+;;  This displays a list of functions like this in buffer
+;;  `*Completions*' (your list might be somewhat different):
+;;
+;;    backward-delete-char        backward-delete-char-untabify
+;;    delete-backward-char        icicle-backward-delete-char-untabify
+;;    icicle-delete-backward-char
+;;    quail-conversion-backward-delete-char
+;;
+;;  Since you are completing input to `C-h f', you can then cycle to a
+;;  name using `next' and hit `RET', or click `mouse-2', to see the
+;;  doc for that function.  If, instead, you were completing input to
+;;  `M-x', you could choose a command to execute.  And so on.
+;;
+;;  The thing to notice here is that you can use `M-*' to input chains
+;;  of multiple simple regexps, to narrow down the set of completion
+;;  candidates progressively.  This is analogous to piping the result
+;;  of `grep' to another `grep', and piping that result to another
+;;  `grep'...
+;;
+;;  Here are a couple others to try (I'm always forgetting the order
+;;  in these compound names):
+;;
+;;   C-h f  w i n d o w  S-TAB M-*  f r a m e
+;;
+;;   C-h f  w i n d o w  S-TAB M-*  b u f f e r
+;;
+;;  As a shortcut, you can use just `S-SPC' instead of `S-TAB M-*'.
+;;  See (@> "Progressive Completion") for more about progressive
+;;  completion with `M-*'.
+;;
+;;(@* "Chip Away the Non-Elephant")
+;;  ** Chip Away the Non-Elephant **
+;;
+;;  There's a joke about a sculptor who, when asked how he created
+;;  such a life-like statue of an elephant, said that he just chipped
+;;  steadily away, removing marble that did not resemble an elephant.
+;;  (Actually, Michelangelo supposedly said something similar.)
+;;
+;;  Icicles lets you sculpt this way too - it is in fact a common
+;;  Icicles usage idiom.  There are two ways to say, "I do not want
+;;  that" when it comes to possible completions:
+;;
+;;  * The `delete' key or `S-mouse-2' says, "Get rid of this
+;;    completion candidate."
+;;
+;;  * `C-~' says "I want all possible completions *except* those that
+;;    are the current matches."  That is, "Remove all of this, and let
+;;    me see what's left."  `C-~' takes the complement of the current
+;;    set of matches, using the initial set of possible candidates as
+;;    the universe of discourse.
+;;
+;;  In other words, instead of coming up with input that you want a
+;;  completion to match, get rid of one or all of the candidates that
+;;  do match.  You can keep clicking `mouse-2' while holding Shift, or
+;;  keep hitting `delete' (without Shift), to chip away at the set of
+;;  possible completions.  If there are several candidates in a row
+;;  that you want to eliminate, just hold down the `delete' key until
+;;  they're gone.
+;;
+;;  So that you can use `delete' this way to delete candidates one
+;;  after the other, in order, the next candidate is chosen each time
+;;  you delete one.  This means that it becomes the current candidate
+;;  in the minibuffer.  You can, however, use `M-k' to clear the
+;;  minibuffer or use `C-l' (bound to command
+;;  `icicle-retrieve-previous-input') to clear the minibuffer and
+;;  retrieve your last real input - see (@> "History Enhancements").
+;;
+;;  `delete' works well to delete isolated candidates or groups of
+;;  candidates that are in order (the current sort order), one right
+;;  after the other, and you can of course combine it with positive
+;;  matching.
+;;
+;;  Note: In Emacs releases prior to Emacs 22, `delete' has no real
+;;  effect on file-name completion candidates (but it works fine on
+;;  non file-name candidates).  It removes them temporarily, but they
+;;  are not really removed as possible candidates, so `TAB' and
+;;  `S-TAB' will still show them as candidates.
+;;
+;;  `C-~' is particularly handy in combination with progressive
+;;  completion (`M-*') to narrow down a set of candidates, especially
+;;  when you are not exactly sure what you are looking for.  You can
+;;  repeat `C-~' with different inputs to eliminate everything matched
+;;  by each of them.  In other words, this is a variable-size chisel,
+;;  and you can use it to remove very large chips.
+;;
+;;  For instance, suppose you are looking for a standard Emacs command
+;;  involving buffers.  You try `M-x buff S-TAB', but that shows
+;;  zillions of matches.  Suppose that you know you do not want a
+;;  command in some 3rd-party package.  You proceed to eliminate
+;;  those, progressively, using something like this:
+;;
+;;    M-* ediff C-~ ibuffer C-~ icicle C-~ Buffer-menu C-~ ps- C-~
+;;        ido C-~ search-buffers C-~ moccur C-~ swbuff C-~
+;;
+;;  And so on.  That is, instead of using `M-*' repeatedly to specify
+;;  multiple patterns that candidates must match, you use `C-~'
+;;  repeatedly (after an initial `M-*'), to chip away candidates you
+;;  do not want.  You could, alternatively, hold down the `delete' key
+;;  to eliminate each of these groups of command names.  There are
+;;  over 100 commands whose names begin with `ediff', however, so `M-*
+;;  C-~' can be quicker in that case.  It can definitely be quicker
+;;  when apropos matching is involved.  And you can of course combine
+;;  the fine chiseling of `delete' with the variable-size chiseling of
+;;  `C-~'.
+;;
+;;  See (@> "Sets of Completion Candidates") for more about `C-~'.
+;;
+;;(@* "Choose Before You Act")
+;;  ** Choose Before You Act **
+;;
+;;  The opposite operation from chipping away at a set of candidates
+;;  to refine it is to build up a set of candidates that you want to
+;;  act on.  This too is easy with Icicles.  In some user interfaces,
+;;  including Dired in Emacs, you can mark items in a checklist and
+;;  then, when you've selected the items you want and verified the
+;;  list, act on those that are selected.  You might do this, for
+;;  instance, if you were deleting some files.  Icicles lets you
+;;  interact with completion candidates this same way.
+;;
+;;  You do this by building up a saved set of candidates, and then
+;;  retrieving these saved candidates later.  You can use the
+;;  retrieved candidates just as you would any current set of
+;;  candidates.  One of the things you can do is act on all of them,
+;;  that is, act on each, in turn.  You do that with `C-!'.
+;;
+;;  Of course, if you can use a regexp to match exactly the candidates
+;;  you want to act on, then you need not bother to save and retrieve
+;;  them, before acting on them: you can see them all alone in buffer
+;;  `*Completions*'.  Here's an exercise in choosing candidates to
+;;  save with the mouse in `*Completions*':
+;;
+;;  C-x C-f  i c i  TAB - Match all file names that begin with `ici'.
+;;
+;;  Click `mouse-1' inside (or to the left of) `icicles-face.el'. [*]
+;;  Click `mouse-3' inside (or to the right of) `icicles-mode.el'.
+;;  Click `mouse-3' again, in the same place.
+;;  Click `M-S-mouse-2' on each of `icicles.el' and `icicles-cmd1.el'.
+;;
+;;  [* If you click `mouse-1' on a candidate and (starting with Emacs
+;;  22) `mouse-1-click-follows-link' is an integer, then you will need
+;;  to hold the mouse button depressed longer than that many seconds,
+;;  or else that candidate will simply by chosen.  If the value is
+;;  `t', then this will not work at all.  Any other value presents no
+;;  problem.  (Personally, I use `nil'.)]
+;;
+;;  The candidates that you selected - those between `icicles-face.el'
+;;  and `icicles-mode.el', inclusive, plus `icicles.el' and
+;;  `icicles-cmd1.el', are highlighted specially in buffer
+;;  `*Completions*', and feedback in the minibuffer tells you that
+;;  they were "saved", which you can also think of as "marked".
+;;
+;;  Next, use `C-M-<'.  This retrieves the set of saved candidates;
+;;  that is, it replaces the current set of candidates with the saved
+;;  candidates.  If you now use `C-!', it applies the action to each
+;;  candidate.  In this case, the action is to visit the file (`C-x
+;;  C-f').
+;;
+;;  The combination of saving (marking) candidates and then retrieving
+;;  only those you have saved is like progressive completion or
+;;  chipping away: it is another way of progressively narrowing the
+;;  set of candidates that you act on.
+;;
+;;  See (@> "Choose All Completion Candidates") for more about `C-!'.
+;;  See (@> "Sets of Completion Candidates") for more about saving and
+;;  retrieving sets of candidates.
+;;
+;;(@* "Help on Completion Candidates")
+;;  ** Help on Completion Candidates **
+;;
+;;  Sometimes, you'd like to be able to ask for help about individual
+;;  completion candidates while you're in the process of choosing one.
+;;  That is the purpose of the Icicles `C-M-' key bindings available
+;;  during completion.
+;;
+;;  The simplest such bindings are `C-M-RET' and `C-M-mouse2'.  They
+;;  each do the same thing: provide help on the current candidate.
+;;  You can use them during cycling or whenever you've narrowed the
+;;  choice down to a single candidate.  You can check this way, before
+;;  you execute a command you're unsure of.
+;;
+;;  During completion, you can also cycle among the doc strings for
+;;  the candidates that match your input, by holding `C-M-' while
+;;  using any of the cycling keys:
+;;
+;;  - `C-M-down', `C-M-up', or `C-M-' + wheel - current-mode matching
+;;  - `C-M-next', `C-M-prior'                 - apropos matching
+;;  - `C-M-end',  `C-M-home'                  - prefix matching
+;;
+;;  See (@> "Prefix Completion and Apropos Completion")).
+;;
+;;  This gives you a very useful on-the-fly apropos feature - use it
+;;  while you're completing a command, to check the difference between
+;;  several possible commands.  Or just use it to browse doc strings,
+;;  to learn more about Emacs.
+;;
+;;  See (@> "Get Help on Candidates") for more about this.
+;;
+;;(@* "Perform Multiple Operations in One Command")
+;;  ** Perform Multiple Operations in One Command **
+;;
+;;    C-x C-f  i c i  TAB - Find a file whose name starts with `ici'.
+;;
+;;    down (that is, the down arrow) ... until you get to candidate
+;;                                       `icicles-cmd1.el'
+;;
+;;    RET - Open file `icicles-cmd1.el'.
+;;
+;;  Nothing new here.  Now try the same thing, but use `C-RET' instead
+;;  of `RET'.  The command is not ended, and you can continue to
+;;  choose files to open:
+;;
+;;    C-x C-f  i c i  TAB - Find a file whose name starts with `ici'.
+;;
+;;    down ... until you get to `icicles-cmd1.el'
+;;
+;;    C-RET - Open file `icicles-cmd1.el'.
+;;
+;;    down ... until you get to `icicles-opt.el'
+;;
+;;    C-RET - Open file `icicles-opt.el'.
+;;
+;;    down ... until you get to `icicles.el'
+;;
+;;    RET - Open file `icicles.el' (end).
+;;
+;;  You just opened three files in a single command.  Command
+;;  `icicle-file' (`C-x C-f') is an Icicles multi-command.  You can
+;;  tell if a command is a multi-command when you execute it - if so,
+;;  the input prompt is prefixed by `+'.  So, for example, when you
+;;  used `C-x C-f', the prompt was "+ File or directory:".  Icicles
+;;  menu items that are multi-commands are also prefixed by `+'.
+;;
+;;  In addition to using `down' (or `end' or `next') and choosing
+;;  (acting on) candidates with `C-RET', you can combine these
+;;  operations by using `C-down' (or `C-next'): act on candidates in
+;;  succession.  And, as mentioned, you can use `C-!'  to act on all
+;;  candidates at once.
+;;
+;;  There are many possible uses of multi-commands.  They all make use
+;;  of the same key bindings, which begin with `C-'.  These keys are
+;;  analogous to the `C-M-' keys that provide help on completion
+;;  candidates.
+;;
+;;  See (@> "Multi-Commands") for more information about Icicles
+;;  multi-commands.
+;;
+;;(@* "Perform Alternative Operations on the Fly")
+;;  ** Perform Alternative Operations on the Fly **
+;;
+;;  (If this section seems a bit weird or advanced to you, just skip
+;;  it the first time through.)
+;;
+;;    C-x C-f  i c i TAB - Find a file whose name starts with `ici'.
+;;
+;;    down ... until you get to candidate `icicles-cmd1.el'
+;;
+;;    C-S-RET - You are prompted to choose a function to apply.
+;;
+;;    f i n d e TAB RET - Choose function `finder-commentary'.
+;;
+;;    down ... until you get to candidate `icicles-fn.el'
+;;
+;;    C-S-RET TAB TAB ... until you get to `find-file-read-only'.
+;;
+;;    RET - Visit file `icicles-fn.el' in read-only mode.
+;;
+;;    C-k TAB - Kill rest of input, then complete the prefix `ici'.
+;;
+;;    C-|  b y t e - c TAB - Byte-compile all files matching `ici'.
+;;
+;;    TAB ... until you get to `icicles-doc1.el', then RET to visit.
+;;
+;;  What's going on?  `C-S-RET' invokes an alternative action on the
+;;  current completion candidate.  Here, you do this, in turn, for the
+;;  file-name candidates `icicles-cmd1.el' and `icicles-fn.el'.  `C-|'
+;;  invokes an alternative action on *all* of the current completion
+;;  candidates.  Here, you do this for all file names that begin with
+;;  `ici'.  Finally, you cycle to `icicles-doc1.el' and hit RET to
+;;  visit that file.
+;;
+;;  The alternative action for `C-x C-f' (command `icicle-file')
+;;  prompts you for a function to apply to the current completion
+;;  candidate (for `C-S-RET') or to all candidates (for `C-|').
+;;
+;;  Here, you choose function `finder-commentary' to visit the
+;;  Commentary of file `icicles-cmd1.el', function
+;;  `find-file-read-only' to visit file `icicles-fn.el' in read-only
+;;  mode, and function `byte-compile-file' to byte-compile all files
+;;  whose names start with `ici'.
+;;
+;;  You can use `C-u' with a function you choose, to pretty-print its
+;;  result (in buffer `*Pp Eval Output*', if too large for the echo
+;;  area).  That is useful for functions that have no side effects.
+;;  For this to work, use `C-RET', not `RET', to choose the function.
+;;
+;;  Each command defines its own alternative action, but many Icicles
+;;  commands have the behavior described here for `icicle-file': their
+;;  alternative action is to let you apply any function that is
+;;  appropriate for the given type of candidate (here, file names).
+;;
+;;  You can even enter an appropriate lambda expression, instead of
+;;  completing to one of the function candidates provided.  For
+;;  example, you could use `C-|' with the following input to copy all
+;;  Icicles libraries to directory `ICICLES':
+;;
+;;    (lambda (f) (copy-file f "ICICLES" t))
+;;
+;;  Note that function `copy-file' is effectively curried here, to
+;;  create a function of a single argument on the fly.
+;;
+;;  See Also: (@> "Alternative Actions").
+;;
+;;(@* "Completion Status Indicators")
+;;  ** Completion Status Indicators **
+;;
+;;  You can always know whether completion is possible when you are
+;;  inputting text in the minibuffer and, if so, what kind of
+;;  completion.  Completion status is indicated in two places: (1) at
+;;  the beginning of the minibuffer prompt and (2) in the `Icy'
+;;  minor-mode lighter in the mode line.  The second is optional,
+;;  controlled by option `icicle-highlight-lighter-flag'.
+;;
+;;  Whenever input completion is available, the prompt is prefixed by
+;;  `.' or `+', indicating simple or multi-command completion,
+;;  respectively.  If completion is strict (your input must match one
+;;  of the candidates), then this character is enclosed in a box.  If
+;;  completion is lax (permissive), there is no box.
+;;
+;;  The `Icy' minor-mode lighter text is highlighted red during
+;;  completion.  `+' is added to the lighter (`Icy+') for
+;;  multi-command completion, and the lighter is boxed for strict
+;;  completion.  When minibuffer input is read without completion, the
+;;  lighter is not highlighted in any way.
+;;
+;;  If the list of candidates shown in `*Completions*' is truncated
+;;  (because of option `icicle-max-candidates'), then the lighter text
+;;  is suffixed by `...'.  So if you see `...' then you know that if
+;;  you increase `icicle-max-candidates' (e.g. by using `C-x #' during
+;;  completion) then more candidates will be available.  See
+;;  (@file :file-name "icicles-doc2.el" :to "Customization and General Tips")
+;;  for info about `C-x #' and option `icicle-max-candidates'.
+;;
+;;  In addition, the lighter text (with or without `+' and `...') is
+;;  `Icy' if completion is case-sensitive and `ICY' if not.  You can
+;;  toggle case-sensitivity at any time using `C-A' (that is, `C-S-a')
+;;  in the minibuffer.
+;;
+;;  The faces used for this highlighting in the minibuffer and the
+;;  mode line are `icicle-completion',
+;;  `icicle-multi-command-completion', and
+;;  `icicle-mustmatch-completion'.  Consult their doc strings for more
+;;  information.  These faces are combined to produce the various
+;;  highlighting effects - keep that in mind if you customize them.
+;;
+;;  When you are inputting, keep an eye out for this highlighting.  If
+;;  you do not see it when you are prompted for input, it means that
+;;  input completion is not available.  This in turn means that
+;;  `S-TAB' is available, not for input completion, but for key
+;;  completion - see (@> "Key Completion").
+;;
+;;(@* "Icicles Search")
+;;  ** Icicles Search **
+;;
+;;  Icicles provides a unique way of searching incrementally.  Command
+;;  `icicle-search' (`C-c `') is a multi-command.  In this case, the
+;;  completion candidates are the buffer occurrences that match a
+;;  regexp that you input.  `C-RET' visits a search-hit candidate, and
+;;  `C-next' visits a candidate and prepares to visit the next in
+;;  succession.  If you visit file `icicles-doc1.el', which contains
+;;  the text you are reading now, do this in that buffer:
+;;
+;;    C-c `
+;;
+;;    Search within contexts (regexp): . * r e c u r s i v e . *  RET
+;;
+;;    Search within contexts defined by the regexp `.*recursive.*'.
+;;
+;;    Choose an occurrence: S-TAB - Show the search hits, in buffer
+;;    `*Completions*' (optional).
+;;
+;;    C-next ... - Cycle among the search hits, navigating to them in
+;;    turn.
+;;
+;;    S-TAB next ... - Cycle among the search hits without navigating.
+;;
+;;    next ... C-RET next ... C-RET - Cycle to particular hits and
+;;    visit (only) those hits.
+;;
+;;    next ... RET - Cycle to a hit and stay there (end).
+;;
+;;
+;;    C-c `
+;;
+;;    Search within contexts (regexp): M-p RET
+;;
+;;    Search again within `.*recursive.*' (`M-p' uses input history).
+;;
+;;    S-TAB e d i t C-next ... - Search for the substring `edit'
+;;    within all search hits for `.*recursive.*'.  Cycle among the
+;;    matches.  The substring `edit' is highlighted inside the
+;;    (differently) highlighted `.*recursive.*' hits.  Whatever you
+;;    type filters the initial set of hits.
+;;
+;;    M-k - Empty the minibuffer, then S-TAB.  All `.*recursive.*'
+;;    hits are restored as candidates.  Again, whatever your input is
+;;    (nothing, now), the set of candidates is dynamically updated to
+;;    match it.
+;;
+;;    t \ w + n S-TAB C-next ... - Search for matches of the regexp
+;;    `t\w+n' within all search hits for `.*recursive.*' - that is,
+;;    `t' followed by at least one other word character, followed by
+;;    `n'.  Whatever the regexp `t\w+n' matches (`thin', `then',
+;;    `traighten', `tion') is highlighted inside each candidate.
+;;
+;;    RET - Stop searching at the current candidate (end).
+;;
+;;  Now try the same thing, but first use `C-^' in the minibuffer
+;;  (e.g. after you enter `.*recursive.*').  That toggles an Icicles
+;;  search option for highlighting your input matches.  The behavior
+;;  is the same as before, except that all matches to your input are
+;;  highlighted at once, not just the current match.  And not only the
+;;  exact match is highlighted, but the longest common match among all
+;;  input matches is highlighted: If your input is `edi', then `edi'
+;;  is highlighted (there is no longer common match), but if you input
+;;  the four characters `e d i t', then ``abort-recursive-edit'' is
+;;  highlighted.  You can use `C-^' at any time during searching to
+;;  change the highlighting behavior.
+;;
+;;  Now try the same thing, but first select some text.  The search is
+;;  confined to the active region (selection) instead of the entire
+;;  buffer.
+;;
+;;  Now try the same thing (without a region), but use a negative
+;;  prefix argument such as `C--' with `C-c `'.  This time, after you
+;;  input the regexp to search for, you are prompted for one or more
+;;  files to search.  This too is multi-command input: you can input
+;;  any number of file names, using completion.
+;;
+;;    C-- C-c `
+;;
+;;    Search within contexts (regexp): . * r e c u r s i v e . *  RET
+;;
+;;    Search within contexts defined by the regexp `.*recursive.*'.
+;;
+;;    Choose file (`RET' when done): i c i TAB - Choose among file
+;;    candidates that begin with `ici' (shown in `*Completions*').
+;;
+;;    C-! - Choose all matching file names: icicles-cmd1.el,
+;;    icicles-cmd2.el, icicles-doc1.el, icicles-doc2.el,
+;;    icicles-face.el, icicles-fn.el, icicles-mac.el, icicles-mcmd.el,
+;;    icicles-mode.el, icicles-opt.el, icicles-var.el, and icicles.el.
+;;
+;;    Choose an occurrence: S-TAB - Show the hits in buffer
+;;    `*Completions*' (optional).
+;;
+;;    C-next ... - Cycle among the search hits in all chosen
+;;    files...
+;;
+;;  Just as you can choose particular search hits to visit, using
+;;  `C-RET', so you can use `C-RET' to choose particular files (whose
+;;  names match the input, e.g. ici) to search.  Just as you can visit
+;;  search hits in order, using `C-next' (or `C-end' or `C-down'), so
+;;  you can use `C-next' (or `C-end' or `C-down') to choose files to
+;;  visit, one after the other.
+;;
+;;  When you input the initial regexp (`.*recursive.*' in the example
+;;  above) to `icicle-search', you can use completion to retrieve a
+;;  regexp that you entered previously.
+;;
+;;  You can use `C-`' in the minibuffer to toggle escaping of regexp
+;;  special characters.  Use that if you want to find a literal string
+;;  - for example, if you want to search for the string `form.' and
+;;  not text that matches the regexp `form.' (`form' followed by any
+;;  character except newline).  If you use `C-`' during Icicles
+;;  search, start the search over again for the toggle to take effect.
+;;
+;;  Oh, can you use progressive completion with Icicles search?  Sure.
+;;  And chipping away the non-elephant (complementing)?  Yep.  Try
+;;  using vanilla Emacs incremental search to find a line that
+;;  contains a given set of words in any (unknown) order and that also
+;;  does not contain another given set of words.  No can do.  But that
+;;  is simple using Icicles search.  (Yes, you can do it using
+;;  `grep'.)
+;;
+;;  And while you're searching, you can perform on-the-fly, on-demand
+;;  replacement.  You tell Emacs whenever you want to replace text,
+;;  instead of replying to an endless litany of `query-replace'
+;;  queries.  Unlike `query-replace', you need not visit search
+;;  matches successively or exhaustively.  You can visit and replace
+;;  selected matches in any order.  And you can even change the order
+;;  (using `C-,') in which search hits appear and are navigated
+;;  sequentially.
+;;
+;;  In addition to Icicles search (which is also incremental), Icicles
+;;  offers some enhancements to the standard Emacs incremental search,
+;;  Isearch:
+;;
+;;  * You can reuse a previous Isearch search string, choosing it
+;;    using Icicles completion.  Hit `M-o' during Isearch, type some
+;;    input to complete against the search history, and hit `RET' or
+;;    click `mouse-2' to choose a string and continue Isearch with it.
+;;
+;;  * You can start Icicles search from Isearch.  The current Isearch
+;;    search string becomes the starting point for the Icicles search
+;;    regexp.  You can edit it or type something different.  And you
+;;    can complete what you type against the Isearch regexp history.
+;;    You can optionally define search contexts with a regexp and then
+;;    search for the Isearch string within those contexts.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;    for more about searching with Icicles.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Search and Replace")
+;;    for information about replacing selected search hits.
+;;
+;;  * (@> "Expanded-Common-Match Completion") for more about Icicles
+;;    expansion of your input to a common match among all candidates.
+;;
+;;  * (@> "Isearch Enhancements")
+;;
+;;  * (@> "Using Completion to Insert Previous Inputs: `M-o'") for
+;;    more about `M-o' - you can use it anywhere to complete against
+;;    previous inputs.
+;;
+;;(@* "Complete Key Sequences Too")
+;;  ** Complete Key Sequences Too **
+;;
+;;  Try `S-TAB' at the top level (without first invoking a command
+;;  that reads input).  Icicles presents all of the possible keys and
+;;  their bindings in the current context - for completion.  For
+;;  example, if you are in Dired mode, the completion candidates
+;;  include all key sequences in the global map and the Dired-mode map
+;;  (and any current minor-mode maps, such as Icicle mode).
+;;
+;;  (The documentation always refers to the key that performs key
+;;  completion as `S-TAB'.  Actually, it is `S-TAB' only by default.
+;;  You can customize it, using option `icicle-key-complete-keys'.)
+;;
+;;  You can then type part of a key name or a command name, and hit
+;;  `S-TAB' again to apropos-complete your input.  You can navigate
+;;  down the key-sequence hierarchy by completing a key sequence piece
+;;  by piece:
+;;
+;;    S-TAB to see the available keys at top level
+;;
+;;    Click (using `mouse-2') candidate `C-x  =  ...', to see the keys
+;;    that start with `C-x'
+;;
+;;    Click `r  =  ...', to see the keys that start with `C-x r'
+;;
+;;    Click `b  =  bookmark-jump', to invoke that command and visit a
+;;    bookmark
+;;
+;;  Whenever you're completing a prefix key, such as `C-x', you can
+;;  click `..' to navigate back up the key-sequence hierarchy.  For
+;;  instance, if you are completing `C-x p', click `..' to go back to
+;;  completing `C-x', and then click `..' to go back to the top level.
+;;
+;;  The available keys at any level include the following important
+;;  keys, which means that you can use Icicles key completion to do
+;;  almost anything in Emacs:
+;;
+;;  * `M-x' - Execute an arbitrary command.
+;;    `M-x' is treated as `ESC-x', so complete first `ESC  =  ...',
+;;    then `x = icicle-execute-extended-command'.
+;;
+;;  * `M-:' - Evaluate any Emacs-Lisp expression.
+;;    If command remapping is available (Emacs 22 or later), and if
+;;    option `icicle-top-level-key-bindings' remaps `eval-expression'
+;;    to `icicle-pp-eval-expression' (which it does, by default), then
+;;    complete first `remapped  =  ...', then `eval-expression  =
+;;    icicle-pp-eval-expression'.  Otherwise, complete first `ESC  =
+;;    ...', then `:  =  eval-expression'.
+;;
+;;    In Icicles, `M-:' gives you a quick pop-up mode for evaluating a
+;;    Lisp sexp.  Most of the normal Emacs-Lisp mode bindings are in
+;;    effect, except that `RET' evaluates the minibuffer contents and
+;;    pretty-prints the result.  You can also use it with a prefix arg
+;;    (`C-u M-:') to insert the result of such an on-the-fly Lisp
+;;    evaluation into the current buffer (including the minibuffer).
+;;
+;;  * `menu-bar  =  ...' - Invoke any menu-bar menu.
+;;    Continue completing, to navigate the entire menu hierarchy.
+;;
+;;  You can start directly with a key prefix, and then hit `S-TAB' to
+;;  complete it - you need not start with `S-TAB'.  You can use
+;;  Icicles key completion to learn key bindings - `C-M-mouse-2'
+;;  displays help on any key.
+;;
+;;  Instead of clicking a completion candidate with `mouse-2', you can
+;;  of course type part of the key name or command name, and then
+;;  complete the name and enter it.  Gotcha: `S-TAB' uses apropos
+;;  completion, by default, so remember that typing `.' matches any
+;;  character (except a newline).  To match only `..' (to go up a
+;;  level), either use prefix completion (`TAB') or escape the regexp
+;;  special character: `\.\.' (or use `^\.').  Or cycle to it.
+;;
+;;  See (@> "Key Completion") for more about Icicles key completion.
+;;
+;;(@* "Available for Almost Any Input")
+;;  ** Available for Almost Any Input **
+;;
+;;  All of this works not only for the input of commands, with `M-x',
+;;  but for the input of nearly anything.  For instance, you can use
+;;  `C-x b' (`switch-to-buffer') and cycle among buffer names.  Or use
+;;  `C-h v' (`describe-variable') and cycle among variable names.  It
+;;  works whenever a command reads input with completion.
+;;
+;;  Whenever you're in Icicle mode, you see "Icy" in the mode-line.
+;;
+;;(@* "Component Icicles Libraries")
+;;  ** Component Icicles Libraries **
+;;
+;;  Icicles is composed of the following libraries.  When you load the
+;;  driver library, `icicles.el', the others are all loaded
+;;  automatically .
+;;
+;;    `icicles.el'      - driver library
+;;    `icicles-doc1.el' - first part of the doc (this!)
+;;    `icicles-doc2.el' - second part of the doc
+;;    `icicles-cmd1.el' - top-level commands (part 1)
+;;    `icicles-cmd2.el' - top-level commands (part 2)
+;;    `icicles-face.el' - faces
+;;    `icicles-fn.el'   - non-interactive functions
+;;    `icicles-mac.el'  - macros
+;;    `icicles-mcmd.el' - minibuffer commands
+;;    `icicles-mode.el' - Icicle mode definition
+;;    `icicles-opt.el'  - user options (variables)
+;;    `icicles-var.el'  - internal variables
+;;
+;;  Libraries `icicles-doc1.el' and `icicles-doc2.el' are not really
+;;  libraries.  They contain only comments, with the Icicles doc.
+;;
+;;  Library `lacarte.el' is not part of Icicles, but it is especially
+;;  useful when used with Icicles.
+;;
+;;(@* "If You Are an Emacs-Lisp Programmer")
+;;  ** If You Are an Emacs-Lisp Programmer **
+;;
+;;  If you are an Emacs-Lisp programmer, this is the no-brainer,
+;;  nutshell view of how to take advantage of Icicles in your own code
+;;  that calls `completing-read' or `read-file-name':
+;;
+;;    Add this line to your library: (require 'icicles nil t)
+;;
+;;  That is really all you need to do.  And there is no consequence if
+;;  users do not have Icicles (no load error is raised, because of the
+;;  non-`nil' third argument).  In other words, there is no reason not
+;;  to add this soft `require', unless your library somehow conflicts
+;;  with Icicles features.  (Even then, users will not be affected
+;;  unless they turn on Icicle mode.)
+;;
+;;
+;;  For more (and there is a lot more), read on...
+ 
+;;(@* "Inserting Text Found Near the Cursor")
+;;
+;;  Inserting Text Found Near the Cursor
+;;  ------------------------------------
+;;
+;;  Most of Icicles is about completing text that you type in the
+;;  minibuffer against some set of possible completion candidates.
+;;  This feature is not.  It is related only in the sense that it is
+;;  also about inputting text that is already available elsewhere.
+;;
+;;  Some Emacs commands provide, as the default value for minibuffer
+;;  input, a word or other text at the cursor position (aka "point").
+;;  You can insert this default value in the minibuffer with `M-n'.
+;;  Icicles option `icicle-default-value' can be used to automatically
+;;  insert the default value into the minibuffer as an initial value,
+;;  if you prefer that optional behavior (I do; many people do not).
+;;
+;;
+;;(@* "FFAP: Find File At Point")
+;;  ** FFAP: Find File At Point **
+;;
+;;  Sometimes you would like to use the text at the cursor, but the
+;;  command asking for input does not let you retrieve that text as
+;;  the default value.  For example, if the text at point is a file
+;;  name, you might like to use it with `C-x C-f' to open that file.
+;;  Or, if the text is a URL, you might want to visit it using a Web
+;;  browser.
+;;
+;;  Some Emacs-Lisp libraries, such as `ffap.el', have as their
+;;  specific purpose to help you do this.  "Ffap" stands for
+;;  `find-file-at-point', the main command in that library.  It tries
+;;  to interpret the text at point and "do the right thing" with it:
+;;  visit a file, open a URL in a Web browser, and so on.
+;;
+;;  If you like, you can use library `ffap.el' with Icicles.  All
+;;  Icicles features are then available during file-name and URL
+;;  completion.  And if you like `ffap.el', you might also like to try
+;;  my extension library `ffap-.el'.  However, if you use ffap with
+;;  Icicles, you might not want to use the ffap key bindings,
+;;  preferring the Icicles bindings or the standard Emacs bindings for
+;;  keys such as `C-x C-f'.  (In that case, do not call function
+;;  `ffap-bindings'.)
+;;
+;;  Icicles provides a couple of simple ways to take advantage of
+;;  `ffap-guesser', which is the ffap function that guesses which
+;;  string at the cursor position you want to grab, without
+;;  sacrificing any key bindings to ffap.  One way is to use `M-.'
+;;  (command `icicle-insert-string-at-point') at any time in the
+;;  minibuffer.  It grabs text at or near the cursor and yanks it into
+;;  the minibuffer.  One of the alternative types of thing it grabs is
+;;  whatever text `ffap-guesser' guesses.
+;;
+;;(@* "Proxy Candidates, `M-.'")
+;;  ** Proxy Candidates, `M-.' **)
+;;
+;;;;  Another way is to use one of the proxy completion candidates
+;;  `*point file name*' or `*mouse-2 file name*' whenever Emacs asks
+;;  you to input a file name (provided option
+;;  `icicle-add-proxy-candidates-flag' is non-`nil' - toggle with
+;;  `C-M-_').  The former picks up the file name at point, just like
+;;  `M-.'.  The latter lets you click a file name anywhere with
+;;  `mouse-2' to pick up the name.
+;;
+;;  Using `M-.' or a proxy candidate on demand, instead of binding
+;;  keys to ffap commands, lets you control which buffer text you use
+;;  as minibuffer input and how that text should be interpreted (file
+;;  name, URL, and so on).  You can change the behavior of `M-.'
+;;  (which string-inserting functions are used) by customizing user
+;;  option `icicle-thing-at-point-functions'.
+;;
+;;(@* "Repeat `M-.' To Grab More or Different")
+;;  ** Repeat `M-.' To Grab More or Different **
+;;
+;;  Actually, `M-.' acts differently if you use it successively.
+;;  Successive uses of `M-.' grab and insert either 1) alternative
+;;  bits of text (different text "things") or 2) successive bits of
+;;  text.  The default behavior is #1, but you can change this choice
+;;  by customizing option `icicle-default-thing-insertion' (setting it
+;;  to `more-of-the-same', instead of `alternatives').
+;;
+;;  As an example of grabbing successive bits of text (#2), suppose
+;;  that the cursor is at the beginning of the word "use" in the
+;;  previous paragraph.  Then, during minibuffer input, suppose that
+;;  you use `M-. M-. M-.'.  Each time you hit `M-.', another word is
+;;  inserted in the minibuffer:
+;;
+;;    use
+;;    use it
+;;    use it successively
+;;    ...
+;;
+;;  The rest of this section is a bit technical, so you might want to
+;;  skip it if you are reading the Icicles doc for the first time.  It
+;;  details the behavior and definitions of options
+;;  `icicle-default-thing-insertion' and
+;;  `icicle-thing-at-point-functions', and how to temporarily override
+;;  those settings interactively.
+;;
+;;  Option `icicle-thing-at-point-functions' controls which text at or
+;;  near the cursor `M-.' inserts into the minibuffer.  It is a cons
+;;  cell, that is, an ordered pair:
+;;
+;;  * The car (first part) is a list of functions that grab different
+;;    kinds of strings at or near point (#1, above).  Any number of
+;;    functions can be used.  They are used in sequence by `M-.'.  I
+;;    recommend that you also use library `thingatpt+.el', so that
+;;    `M-.' can take advantage of the string-grabbing functions it
+;;    defines.
+;;
+;;  * The cdr (second part) is a function that advances point one text
+;;    thing (#2, above).  Each time command `M-.' is used
+;;    successively, this is called to grab more things of text (of the
+;;    same kind).  The default function grabs successive words.
+;;
+;;  If either the car or cdr is empty, then the other alone determines
+;;  the behavior of `M-.'.  Otherwise, option
+;;  `icicle-default-thing-insertion' determines whether the car or the
+;;  cdr is used by `M-.'.
+;;
+;;  For example, if the value of `icicle-default-thing-insertion' is
+;;  `alternatives' (the default value), then repeated use of `M-.'
+;;  inserts a different kind of thing at point each time.  By default,
+;;  these are the thing types, in order:
+;;
+;;    `non-nil-symbol-name-nearest-point' (*) or `symbol-at-point'
+;;    `word-nearest-point' (*) or the word at point
+;;    `list-nearest-point-as-string' (*), the first enclosing list
+;;    `list-nearest-point-as-string' (*), the second enclosing list
+;;    `list-nearest-point-as-string' (*), the third enclosing list
+;;    `ffap-guesser'
+;;    `thing-at-point-url-at-point'
+;;
+;;  The alternatives marked with an asterisk (*) are available only if
+;;  you use library `thingatpt+.el'.  Alternative `ffap-guesser' is
+;;  used only if you use library `ffap.el'.
+;;
+;;  The first alternative inserts text that has the syntax of an
+;;  Emacs-Lisp symbol name.  In practice, this can also be a file
+;;  name or a URL - it can include characters such as -, /, +, ., :,
+;;  @, and _.
+;;
+;;  The second alternative inserts a word, which includes letters, ',
+;;  and -.
+;;
+;;  The third, fourth, and fifth alternatives insert a (non-`nil')
+;;  list that is around point - three different enclosing levels.
+;;
+;;  The sixth alternative inserts whatever `ffap-guesser' returns: a
+;;  file name or a URL at point.
+;;
+;;  The seventh alternative inserts a URL at point, adding prefix
+;;  "http://" if needed.
+;;
+;;  This means that you can quickly pick up a symbol name, a list, a
+;;  file name, or a URL at point.
+;;
+;;  If you use library `thingatpt+.el' then the first two alternatives
+;;  pick up the symbol or word nearest point - the cursor need not be
+;;  exactly on the symbol or word.
+;;
+;;  You can of course add to or replace any of the alternatives that
+;;  are provided by default.
+;;
+;;  If you set `icicle-default-thing-insertion' to `more-of-the-same'
+;;  instead of `alternatives', then repeated use of `M-.' inserts
+;;  successive words into the minibuffer, as shown in the example
+;;  above.
+;;
+;;  You need not make a final choice once and for all between
+;;  `alternatives' and `more-of-the-same'.  You can also make an
+;;  interactive choice by using a prefix argument (`C-u') at any time
+;;  to override the value of `icicle-default-thing-insertion'.  If you
+;;  use plain `C-u', then `M-.' inserts alternative strings.  If you
+;;  use a numeric prefix argument N (not just plain `C-u'), then it is
+;;  the same as using `M-.' N times with `more-of-the-same' as the
+;;  value of `icicle-default-thing-insertion'.
+;;
+;;  And, if the numeric argument is negative, then text is grabbed to
+;;  the left of the cursor, instead of to the right.  In the example
+;;  above, if you used `M-- M-. M-. M-.', then the successive
+;;  insertions would be as follows:
+;;
+;;  differently
+;;  differently if
+;;  differently if you
+;;  ...
+;;
+;;  If you used `M--3 M-.', then you would immediately insert
+;;  `differently if you'.
+;;
+;;(@* "Resolve File Names")
+;;  ** Resolve File Names **
+;;
+;;  Finally, something that is not directly related to the topic of
+;;  this page, but fits here as well as anywhere: you can use `C-x
+;;  C-f' in the minibuffer to resolve a file name to its true,
+;;  absolute name.  Yes, that's the same key that is bound at top
+;;  level to `icicle-file' or `find-file' or whatever, but this is
+;;  about its use when you are already in the minibuffer.
+;;
+;;  `C-x C-f' (`icicle-resolve-file-name'), replaces a file name at or
+;;  near point (in the minibuffer) with its true, absolute name.  (For
+;;  it to work near but not precisely at point, you need library
+;;  `thingatpt+.el'.)  If the file name is relative, it first converts
+;;  it to absolute (using the default directory).  It then converts an
+;;  absolute name that is a symbolic link to its target name.  You can
+;;  use this anytime in the minibuffer, and you can use it on multiple
+;;  parts of the same minibuffer input (e.g. shell command arguments).
+;;  (This feature does not work for Emacs 20 or 21.)
+;;
+;;  See Also:
+;;
+;;  * (@> "Inserting a Regexp from a Variable or Register") for
+;;    information on inserting text saved in a variable or register.
+;;
+;;  * (@> "Moving Between the Minibuffer and Other Buffers") for
+;;    another way to insert buffer text in the minibuffer.
+ 
+;;(@* "Background on Vanilla Emacs Input Completion")
+;;
+;;  Background on Vanilla Emacs Input Completion
+;;  --------------------------------------------
+;;
+;;  This section reviews standard Emacs behavior regarding input
+;;  completion.  It does not describe any Icicles completion features.
+;;  See also (@> "README").
+;;
+;;  When you are prompted in the minibuffer to enter something, you
+;;  are sometimes presented with a default value.  This might be
+;;  automatically inserted after the prompt, initially.  If not, you
+;;  can retrieve the default value yourself, using `M-n' (Emacs 21 or
+;;  later).
+;;
+;;  Often, there is more than one reasonable default value that might
+;;  make sense.  Depending on what you're being asked to enter, these
+;;  "candidate default values" might be command names, buffer names,
+;;  existing file names, variable names, and so on.
+;;
+;;  For most Emacs functions that prompt you for input, the person who
+;;  wrote the function decided on the reasonable set of default
+;;  values, and passed these to an "input-completing function" such as
+;;  `completing-read' or `read-file-name', which prompts you and reads
+;;  your input.  The programmer also decided whether you will be
+;;  *required* to pick one of the default values or you will be free
+;;  to enter something else.  The programmer might also have told the
+;;  input-completing function to require that your input pass some
+;;  special test (predicate).
+;;
+;;  Be aware that standard Emacs terminology does not refer to such a
+;;  set of default values as "default values"; they are called
+;;  "completions".  By "default value", standard Emacs terminology
+;;  means only the values that you can access via `M-n'.  Icicles
+;;  refers to all such potential inputs indifferently as "default
+;;  values", "completions", "completion candidates", and "candidates".
+;;  Whenever completion is not requiring you to pick one of the
+;;  available candidates, they are effectively only default choices.
+;;
+;;  So, how do you get access to the default values that the
+;;  programmer has made available to you, in order to choose one?  You
+;;  hit certain keys to complete the current contents of the
+;;  minibuffer (excluding the prompt).  This current, partial input is
+;;  considered as a prefix of one of the default values, and it is
+;;  completed in the minibuffer to the entire default value
+;;  (completion).
+;;
+;;  Keys `TAB', `RET' (Return), and `SPC' (Space) perform different
+;;  degrees of this "prefix completion" in standard Emacs.  If you
+;;  type a prefix of one of the available default values, you can
+;;  complete the value this way in the minibuffer, and then enter
+;;  (commit) it, using `RET'.
+;;
+;;  But if your partial input matches the prefix of more than one
+;;  default value, then completion pops up the list of all matching
+;;  completions for you to choose from (in buffer `*Completions*').
+;;  You choose a candidate by clicking it with `mouse-2' or placing
+;;  the cursor on it and hitting `RET'.
+;;
+;;  Because this is the way you access the default values supplied to
+;;  an input-completing function, I call those values
+;;  "prefix-completion candidates".  If there is no partial input yet
+;;  (empty minibuffer), then the entire list of default values
+;;  supplied to the input-completing function appears in the pop-up
+;;  `*Completions*' buffer.  See the Emacs manual (`C-h i') for more
+;;  on this general mechanism of prefix completion (called simply
+;;  "completion" there).
+;;
+;;  Calls to `completing-read' and `read-file-name' are not the only
+;;  places where input completion is used.  When you use `M-x'
+;;  (command `execute-extended-command'), completion is also
+;;  available.
+ 
+;;(@* "Cycling Completions")
+;;
+;;  Cycling Completions
+;;  -------------------
+;;
+;;  Icicles lets you use the `end' and `home' keys to cycle through
+;;  the list of candidate prefix completions that match whatever input
+;;  is present in the minibuffer (or all candidate completions, if
+;;  there is no input in the minibuffer).  In the minibuffer, each
+;;  candidate replaces your partial input, in turn, when you cycle.
+;;  The prefix (root) that was completed is underlined in the
+;;  minibuffer completion candidate.
+;;
+;;  As an alternative to using `end' to cycle forward, you can hit
+;;  `TAB' repeatedly.  See (@> "Prefix Completion and Apropos Completion").
+;;
+;;  Suppose you use `C-x b' (command `switch-to-buffer').  You can
+;;  then use `end' until the right buffer name appears in the
+;;  minibuffer, then hit `RET'.  Or you can type some text that begins
+;;  one or more of the buffer names, and then use `end' to cycle among
+;;  those names that match that prefix.  If there are many candidates,
+;;  typing part of the name to narrow the field can save time.
+;;
+;;  Another example: Suppose you use `C-h v' (`describe-variable') and
+;;  type `cal'.  Use `end' to cycle among all variables that start
+;;  with `cal', until you find the one you want (then hit `RET').
+;;
+;;  In other words, the current partial input in the minibuffer
+;;  determines a matching set of default values, and those are the
+;;  values that you can cycle through.  You can at any time erase or
+;;  change the partial input - the list of matching candidates
+;;  automatically reflects the change.
+;;
+;;  This also means that it's good to have a quick way to clear the
+;;  minibuffer of any input, so Icicles also provides minibuffer key
+;;  binding `M-k' to do that.
+;;
+;;  A visible and audible signal lets you know when you have reached
+;;  one end of the list of completion candidates, but you can of
+;;  course continue to cycle, wrapping around.
+;;
+;;  If the completion candidates are already displayed in buffer
+;;  `*Completions*' when you try to cycle among them (because you hit
+;;  `TAB'), then the current candidate is highlighted in
+;;  `*Completions*' as you access it in the minibuffer with the `home'
+;;  and `end' keys.  If you change the minibuffer input, then the
+;;  `*Completions*' list is updated accordingly, to reflect the new
+;;  set of matching candidates.  The root that was completed (the
+;;  minibuffer input) is highlighted in each candidate of the
+;;  `*Completions*' display.  The `*Completions*' window is
+;;  automatically scrolled as needed, to show the current candidate.
+;;
+;;  Do not become a cycling drone!  Input some text to narrow the set
+;;  of candidates, before cycling among them to choose one.  This is a
+;;  good habit to adopt, generally, in Icicles.  Most of the power of
+;;  Icicles comes in your ability to filter a set of candidates.  This
+;;  is especially true when it comes to regexp filtering (see
+;;  (@> "Apropos Completions")).
+;;
+;;  Cycling and filtering work hand in hand.  If the set of candidates
+;;  is small to begin with, then just cycling might be quick enough -
+;;  that is the case if you move among a small set of buffers, for
+;;  instance.  But with Icicles you can profitably use cycling on even
+;;  a very large set of candidates - by filtering the set first.  The
+;;  reason this is not very practical with vanilla Emacs is that
+;;  filtering by a prefix only is not very potent.
+;;
+;;  Tip: Whenever you type or delete text in the minibuffer, your
+;;  partial input is remembered.  When you cycle completion
+;;  candidates, your input is replaced by each candidate, but you can
+;;  at any time refresh the minibuffer to retrieve what you last
+;;  typed.  You do this with `C-l', which is bound in the minibuffer
+;;  to command `icicle-retrieve-previous-input'.  Editing a completion
+;;  candidate that you have cycled into the minibuffer counts as
+;;  input.  Editing tells Icicles to remember what is in the
+;;  minibuffer as your last real input.  If you want to replace the
+;;  candidate and go back to editing the input you had already typed
+;;  before cycling, then use `C-l' - do not just delete characters
+;;  from the candidate.  See (@> "History Enhancements").
+;;
+;;  You can change the keys that are bound to completion-candidate
+;;  cycling.  And you can change whether `down' and `up' start off by
+;;  cycling prefix completions or apropos completions.
+;;  See (@file :file-name "icicles-doc2.el" :to "Customizing Key Bindings").
+;;
+;;  Finally, you can use the mouse wheel (Emacs 22 or later) to cycle
+;;  candidates according to the current completion mode (prefix or
+;;  apropos).  See (@> "Prefix Completion and Apropos Completion").
+;;
+;;  Mouse-wheel cycling works also with modifier keys: `C-M-' for
+;;  candidate help, `C-' for candidate actions, and `C-S-' for
+;;  alternative candidate actions.  In particular, `C-' with the wheel
+;;  gives you a very quick way to visit search hits during Icicles
+;;  search (and `C-S-' works for search-and-replace).
+;;  (See (@> "Icicles Search Commands, Overview").)
+;;
+;;  If you are an Emacs-Lisp programmer, then you can use
+;;  `completing-read' and `read-file-name' to define your own
+;;  commands, enabling them to take advantage of Icicles completion
+;;  and cycling.  The definition of command `icicle-recent-file' is a
+;;  good model to follow.  Emacs has a `recentf-mode' that lets you
+;;  open recently accessed files.  But this mode makes you open a file
+;;  using a menu interface.  Command `icicle-recent-file' lets you use
+;;  the usual `find-file' minibuffer interface, with completion and
+;;  cycling among your recent files.  See sections
+;;  (@> "Defining Icicles Commands") and
+;;  (@file :file-name "icicles-doc2.el" :to "Note to Programmers")
+;;  for more on defining your own commands with `completing-read' and
+;; `read-file-name'.
+ 
+;;(@* "Traversing Minibuffer Histories")
+;;
+;;  Traversing Minibuffer Histories
+;;  -------------------------------
+;;
+;;  Perhaps you are already used to accessing past inputs with vanilla
+;;  Emacs using the `down' and `up' arrow keys (or `M-n', `M-p', and
+;;  `next').  If not, try it (not in Icicle mode).  You can go
+;;  backward and forward in the minibuffer histories (there are
+;;  different history lists for different kinds of input).  You cannot
+;;  really cycle them (with wraparound), but when you get to one end
+;;  you can reverse the direction.
+;;
+;;  Anyway, the input-cycling behavior that Icicles offers is in
+;;  addition to this standard traversal of histories.  Since there
+;;  are, by default, several extra pairs of keys used for history
+;;  traversal, rebinding some of them to use for Icicles completion is
+;;  no real loss.
+;;
+;;  By default, Icicles rebinds the arrow keys `down' and `up' for
+;;  current-mode completion cycling.  Icicles also rebinds `end' and
+;;  `home' for prefix-completion cycling, and `next' and `prior' for
+;;  apropos-completion cycling.  But you still have `M-n' and `M-p'
+;;  available to access past inputs (history).  And the rebindings are
+;;  only for minibuffer input; global bindings are not affected.
+;;
+;;  You can at any time switch back and forth between input-history
+;;  traversal (`M-n', `M-p') and completion cycling (`down', `up',
+;;  `next', `prior', `end', `home').
+;;
+;;  See Also:
+;;
+;;  * (@> "History Enhancements") for new ways to use Emacs history
+;;    lists with Icicles
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Customizing Key Bindings")
+;;    for how to change the default Icicles key bindings, including
+;;    the keys used for candidate cycling
+ 
+;;(@* "Apropos Completions")
+;;
+;;  Apropos Completions
+;;  -------------------
+;;
+;;  Icicles offers a new way to complete your partial input in the
+;;  minibuffer.  Instead of considering the string of input characters
+;;  to be the prefix of various complete names, you can look for names
+;;  that match that string anywhere.
+;;
+;;  This is the single most important feature that Icicles offers.
+;;
+;;  This is similar in effect to using command `apropos' to find
+;;  "apropos completions" of a string (except it works also for file
+;;  and buffer names), so that's the term I use for this: apropos
+;;  completion.  The more correct characterization of this is that of
+;;  the previous paragraph, however: names that match the given
+;;  string.
+;;
+;;  Just as with prefix completion, Icicles lets you cycle among the
+;;  apropos candidates.  To do this, you use keys `next' and `prior'.
+;;  The root that was completed is underlined in the minibuffer
+;;  completion candidate.
+;;
+;;  For example, suppose you use `M-x' to enter a command.  You do not
+;;  remember the exact command name, but it has something to do with
+;;  lines, so you type `M-x line', then hit `next' repeatedly, until
+;;  you see the right "line" command - `transpose-lines', perhaps.
+;;  Prefix completion cannot find this command, because "line" is not
+;;  a prefix of "transpose-lines".
+;;
+;;  Because `M-x' expects a command name, only command names are
+;;  inserted into the minibuffer as the apropos-completion candidates
+;;  for `M-x'.  Likewise, in other contexts, where names of other
+;;  kinds of object are expected, apropos completion inserts only
+;;  names of objects of the appropriate type.  Prefix completion works
+;;  the same way.
+;;
+;;  For example, using `next' and `prior' with `C-x b at' lets you
+;;  cycle through all buffers (such as `*scratch*') that have "at" in
+;;  their name - only buffer names appear as candidates.
+;;
+;;  As an alternative to using `next' to cycle forward, you can hit
+;;  `S-TAB' repeatedly.  Similarly, for prefix completion you can
+;;  repeat `TAB' to cycle forward.  See
+;;  (@> "Prefix Completion and Apropos Completion").
+;;
+;;  Apropos completion uses a regular expression (regexp) as its input
+;;  string.  You can type `M-x \bes', for instance, to find commands
+;;  with "es" at the start of a word within the command name (`\b'
+;;  matches the start of a word).  It will find `eshell-test' and
+;;  `color-theme-blue-eshell', but not `count-lines' - "es" does not
+;;  start a word in `count-lines'.  Similarly, for file names, buffer
+;;  names, and so on.
+;;
+;;  Prefix completion is actually a special case of apropos
+;;  completion, where the regexp starts with "^".  (That is not how it
+;;  is implemented, however.)
+;;
+;;  What if you want to see the list of all completion candidates that
+;;  match the minibuffer input?  Instead of cycling candidates
+;;  blindly, just hit `S-TAB' (Shift TAB) at any time to display the
+;;  matching candidates in pop-up buffer `*Completions*'.  This is
+;;  analogous to `TAB' for prefix completion.
+;;
+;;  (The documentation always refers to the key that performs apropos
+;;  completion as `S-TAB'.  Actually, it is `S-TAB' only by default.
+;;  You can customize it, using option
+;;  `icicle-apropos-complete-keys'.)
+;;
+;;  Everything said in section (@> "Cycling Completions") about the
+;;  `*Completions*' buffer for prefix completion is also true for
+;;  apropos completion.  It is updated to reflect the current set of
+;;  matching candidates, and the current completion is highlighted.
+;;  The root that was completed is highlighted within each candidate
+;;  (first occurrence only).  Root highlighting is more important in
+;;  the case of apropos completion, because the match position is
+;;  different in different candidates.  In the case of apropos
+;;  completion, the root is not the input string, taken literally, but
+;;  the part of a candidate that the input matches.  See
+;;  (@> "*Completions* Display") for additional ways to use the
+;;  minibuffer with `*Completions*'.
+;;
+;;  Regexp matching is one of the most powerful features of Icicles.
+;;  Enjoy!  Explore!  You can at any time switch back and forth
+;;  between prefix completion (`end', `home'), apropos completion
+;;  (`next', `prior'), and input history traversal (`M-n', `M-p').
+ 
+;;(@* "Expanded-Common-Match Completion")
+;;
+;;  Expanded-Common-Match Completion
+;;  --------------------------------
+;;
+;;  Apropos (regexp) matching and prefix completion each match a
+;;  pattern against a completion candidate.  This operation concerns
+;;  only a single candidate; it does not take into account the fact
+;;  that there are others.  Since the matching operation is repeated
+;;  anyway for each candidate, however, we can also find an expanded
+;;  string that includes the same match (apropos or prefix) for all
+;;  candidates.
+;;
+;;  For prefix completion, Emacs completes your input to the longest
+;;  common prefix match.  Icicles uses a similar notion for apropos
+;;  completion.
+;;
+;;  For example, if you enter `M-x minib' and hit `TAB', Emacs
+;;  completes your input to `minibuffer', which is the longest prefix
+;;  match for `minib' among all command names.  The actual string that
+;;  matches prefix `minib' among all candidates is, itself, `minib'.
+;;
+;;  If you hit `S-TAB', then each matching candidate contains a
+;;  substring that matches your regexp input `minib'.  In this case,
+;;  that substring is `minib', just as in the prefix-matching case.
+;;  And, as in the prefix case, each matching candidate also includes
+;;  a longer substring, `minibuffer', which includes what your input
+;;  matches for each candidate.
+;;
+;;  Icicles replaces your regexp input in the minibuffer by a common
+;;  substring.  Icicles highlights this expanded common match in
+;;  buffer `*Completions*' using face
+;;  `icicle-common-match-highlight-Completions' (magenta foreground,
+;;  by default).  What your input matches directly is highlighted in
+;;  `*Completions*' using face `icicle-match-highlight-Completions'
+;;  (red foreground, by default).
+;;
+;;  It is of course possible that a given regexp match different
+;;  candidates differently, so that there is no common match.  In that
+;;  case, only the individual matches are highlighted in
+;;  `*Completions*' - you will see only red, no magenta, highlighting.
+;;  For example, if your regexp input is `min.*buf' then various
+;;  different substrings (such as `minibuf' from `minibuffer-complete'
+;;  and `mint-truncate-buf' from `comint-truncate-buffer') are
+;;  highlighted in red, but these share no common substring.
+;;
+;;  You will also see only red highlighting if what your input matches
+;;  directly is the same as the expanded common match.  For example,
+;;  if a function `moccur-regexp-read-from-minibuf' is defined (it is
+;;  in library `color-moccur.el'), and your input to `C-h f' is
+;;  `min[^-]*buf', then only `minibuf' is highlighted in red.
+;;
+;;  Expanded-common-match completion is convenient, but when
+;;  apropos-completing you often need to try variants of a regexp,
+;;  editing it and observing which candidates match in
+;;  `*Completions*', until you get the regexp right.
+;;  Expanded-common-match completion has the disadvantage that you
+;;  lose your regexp as input, which makes it hard to edit it!
+;;
+;;  To retrieve it, use `C-l' (`icicle-retrieve-previous-input')
+;;  during completion.  You can repeat `C-l' to retrieve older
+;;  completion inputs, cycling among them, and you can use `C-S-l'
+;;  (that is, `C-L') to cycle previous inputs in the other direction -
+;;  see (@> "History Enhancements").  You can set option
+;;  `icicle-expand-input-to-common-match-flag' to `nil' to turn off
+;;  expanded-common-match completion altogether, if you prefer.  You
+;;  can also toggle it from the minibuffer at any time, using `C-;'.
+;;
+;;  Just what is meant by the "expanded common match" that Icicles
+;;  finds?  It is the longest match of your input pattern that is
+;;  common to all candidates and also contains the first input match
+;;  in the first or second candidate, whichever is longer.
+;;
+;;  For apropos completion, this is not always the longest common
+;;  match of your input, but in most cases it is, and it is quicker to
+;;  compute.  In general, the longest common match does not
+;;  necessarily contain the first match of your input with either the
+;;  first candidate or the second candidate.  It might contain a
+;;  different input match from the first in both the first and second
+;;  candidates.
+;;
+;;  For example, with input `a' and candidates `abacb', `abbac', and
+;;  `bacba' (in that order), `bac' is the longest common match.  But
+;;  `a' is the longest common match that contains the first match in
+;;  the first candidate.  It is the second match of `a' against
+;;  `abacb' that yields `bac'.  Likewise for the second candidate: it
+;;  is the second match of `a' against `abbac' that yields `bac'.
+;;
+;;  So in this case Icicles will use `a' as the expanded input and
+;;  miss the longest common match.  If the candidate order is
+;;  different, so that `bacba' is either the first or the second
+;;  candidate, then Icicles finds the longest common match, because
+;;  the first match of `a' against `bacba' yields `bac'.
+;;
+;;  The reason that Icicles common-match expansion typically finds the
+;;  longest common match is that your input typically matches the
+;;  first or the second candidate in only one place.  And the longer
+;;  the input you type, the more likely this is.  In practice, it is
+;;  only with very short input such as `a' that Icicles expansion
+;;  sometimes misses the longest common match.  Icicles independently
+;;  tries two candidates (first and second) as its starting point, to
+;;  increase the probability of finding the longest common match.
+;;
+;;  It is also technically incorrect to speak of "the" longest common
+;;  match: in general, there can be more than one.  For example, if
+;;  the input is `a' and the candidates are `abab', `abba', and
+;;  `baba', then both `ab' and `ba' are longest common substrings.
+;;  Again, however, for typical input and typical candidates there is
+;;  a single longest common match, and Icicles finds it.
+;;
+;;  Note that Icicles expanded common match is not just a common
+;;  substring among all of the candidates that are matched by your
+;;  input pattern.  It is a substring common to all candidates matched
+;;  by your input, but a substring that also matches your input.  For
+;;  example, with apropos completion input `a.z' and candidates `abz'
+;;  and `apz', there is no expanded common match.  The substring `a'
+;;  is common to both candidates, but it is not matched by the
+;;  (complete) input pattern.
+;;
+;;  Finally, note that in Emacs 20 no common match is found if your
+;;  input or any of the candidates contains binary data.  This is
+;;  because function `string-match' cannot handle strings with binary
+;;  data in Emacs 20.
+ 
+;;(@* "Progressive Completion")
+;;
+;;  Progressive Completion
+;;  ----------------------
+;;
+;;  Perhaps the best way to explain this feature is to use a familiar
+;;  analogy.  Unix or GNU/Linux command `grep' takes a
+;;  regular-expression argument, and matches it against lines in
+;;  files.  A common idiom that people use is to chain, or cascade,
+;;  multiple calls to `grep', using the output of one as the input to
+;;  the next.  For example:
+;;
+;;    grep plant *.txt | grep food | grep mineral
+;;
+;;  The output of the search for "plant" is used as the input for the
+;;  search for "food", and the output of that search serves as the
+;;  input for the search for "mineral".  The order of the three
+;;  component searches can make a difference in terms of performance,
+;;  but not in terms of the result, which is always the set of lines
+;;  in files *.txt that match "plant" AND "food" AND "mineral", in any
+;;  order.  Each of the `grep' operations defines a set of matches,
+;;  and the chain of `grep' operations effects the intersection of
+;;  those sets.
+;;
+;;  Of course, you could try to accomplish the same thing with a
+;;  single call to `grep' using a complex regexp.  But why would you?
+;;
+;;  Moreover, it is in fact impossible to express such an unordered
+;;  set intersection using a single regexp.  On their own, regular
+;;  expressions cannot express set intersection (conjunction) or
+;;  complementing (negation).  (However, most `grep' programs provide
+;;  a way to obtain the lines that do not match a regexp.)
+;;
+;;  The same idea of combining multiple regexp matches is behind the
+;;  Icicles feature of progressive completion: instead of trying to
+;;  come up with a single complex regexp that does what you want, try
+;;  getting there a step at a time:
+;;
+;;   1. Match an input regexp against the set of all possible
+;;      completions.
+;;
+;;   2. Narrow the set of matched candidates by matching them against
+;;      another input regexp (or by filtering them with a predicate).
+;;
+;;   3. Narrow those results down by matching them against a third
+;;      input regexp (or by filtering them with another predicate).
+;;
+;;   4... And so on.
+;;
+;;(@* "`M-*': Matching Additional Regexps")
+;;  ** `M-*': Matching Additional Regexps **
+;;
+;;  During completion, `M-*' is bound in the minibuffer to command
+;;  `icicle-narrow-candidates', which prompts for a new regexp and
+;;  matches it against the current set of completion candidates.
+;;
+;;  For example, suppose that you want to know about an Emacs function
+;;  that deletes the character to the left of point (that is,
+;;  backward).  You do not recall if it is `delete-character-back',
+;;  `delete-backward-char', `character-delete-backward', or whatever.
+;;  You take a guess that the name contains `delete', `char', and
+;;  `back'.
+;;
+;;   1. `C-h f char S-TAB' displays function names that contain
+;;      `char'.
+;;
+;;   2. `M-* delete' narrows that set of function names to those that
+;;      also contain `delete'.
+;;
+;;   3. `M-* back' narrows the set of matching names further, to those
+;;      that also contain `back'.
+;;
+;;  This displays a list of functions like this in `*Completions*'
+;;  (your list might be somewhat different):
+;;
+;;    backward-delete-char        backward-delete-char-untabify
+;;    delete-backward-char        icicle-backward-delete-char-untabify
+;;    icicle-delete-backward-char
+;;    quail-conversion-backward-delete-char
+;;
+;;  Then, of course, you can pick one (or you can use `C-M-next'
+;;  repeatedly to view the doc of each of these functions in turn -
+;;  see (@> "Get Help on Candidates")).
+;;
+;;  You get the idea.  This feature is both very simple to use and
+;;  very useful.  It's easy to appreciate using multiple simple
+;;  matching steps (regexp or not) instead of a single regexp.  Try it
+;;  once, and you'll be hooked.
+;;
+;;(@* "Successive Approximation...")
+;;  ** Successive Approximation... **
+;;
+;;  You can use as many invocations of `M-*' (and of `M-&', described
+;;  in the next section) as you like, in any order.  It works with
+;;  both prefix completion and apropos completion.  You can, for
+;;  instance, first use `TAB' to require the target to start with some
+;;  string, and then use `M-*' to specify other patterns that parts of
+;;  it must also match.  However, it of course makes no sense to use
+;;  `TAB' instead of `S-TAB' after you use `M-*': once you've said
+;;  that the target must start with "fo" there is no sense saying that
+;;  it also starts with "ti"!
+;;
+;;  As a shortcut, instead of using `S-TAB' followed by `M-*', you can
+;;  use `S-SPC' (command `icicle-apropos-complete-and-narrow') to do
+;;  the same thing.  You can thus use only `S-SPC', any number of
+;;  times, to choose a candidate by narrowing down the matches.
+;;
+;;  I call this process of completion by successive approximation, or
+;;  progressively narrowing the candidate set, "progressive
+;;  completion".  If the name "incremental completion" (= icompletion)
+;;  were not already taken to mean incremental completion *help*
+;;  (which performs no completion), then that might be a good name for
+;;  this.  This might also be called "stepped", "cascaded", or
+;;  "piecewise" completion.
+;;
+;;  Another possible name for it would be "multiple completion", but I
+;;  use that to stand for simultaneous (parallel) completion of
+;;  multiple parts of a compound target, which is something different
+;;  (see (@file :file-name "icicles-doc2.el" :to "Multi-Completions")).
+;;  Progressive completion is a set of mini-completions that are wired
+;;  in series, not in parallel.
+;;
+;;  Note that when you use `M-*' (or `S-SPC') in the minibuffer, it
+;;  calls `completing-read' or `read-file-name', which creates a
+;;  recursive minibuffer.  That is, the minibuffer depth is increased.
+;;  (This is not the case for `M-&', however.)  In vanilla Emacs,
+;;  there is no indicator of the current minibuffer depth, and this
+;;  can sometimes be disorienting.  Each time you use `M-*' you push
+;;  down one level of minibuffer recursion (that is, minibuffer depth
+;;  is incremented).  Each time you use, say, `C-g', you pop up one
+;;  level of minibuffer recursion (that is, minibuffer depth is
+;;  decremented).
+;;
+;;  If you use library `mb-depth.el', which is included with Emacs 23
+;;  and which also works with Emacs 22, Icicle mode takes advantage of
+;;  this library by indicating the current depth in the minibuffer.  I
+;;  recommend you also use my library `mb-depth+.el', which lets you
+;;  customize the form and face of the depth indicator.
+;;
+;;  If you use my library `oneonone.el', then you get visual feedback
+;;  on the current minibuffer depth.  One-On-One Emacs gives you a
+;;  standalone minibuffer frame, and it changes the background hue
+;;  (color) of that frame slightly with each change in minibuffer
+;;  depth.  This is especially helpful with Icicles, where use of
+;;  `M-*' (or `S-SPC') is common.
+;;
+;;  There is a slight difference in behavior between Icicles commands
+;;  and some other Emacs commands when you accept input after `M-*'.
+;;  When possible, Icicles accepts your input and passes it
+;;  immediately to the top level, bypassing any intermediate recursive
+;;  minibuffer levels that are waiting for input.  However, Emacs
+;;  commands that are defined with literal-string `interactive' specs,
+;;  such as (interactive "fFile: "), do not use `completing-read' or
+;;  `read-file-name', so there is no way for Icicles to take this
+;;  shortcut with them.  In that case, you will simply need to hit
+;;  `RET' again to accept your input at each recursive minibuffer
+;;  level, until you get back to the top level.  Sorry for this
+;;  inconvenience!  If you are an Emacs-Lisp programmer, note that
+;;  this is one reason to use `completing-read' and `read-file-name'
+;;  when you write commands that use completion.
+;;
+;;  Note: If you use progressive completion with file names in Emacs
+;;  20 or 21, `M-*' calls `completing-read', not `read-file-name'.
+;;  This is because `read-file-name' does not accept a PREDICATE
+;;  argument before Emacs 22.  The effect is that instead of there
+;;  being a default directory for completion, the current directory at
+;;  the time you hit `M-*' is tacked onto each file name, to become
+;;  part of the completion candidates themselves.  Yes, this is a
+;;  hack.  It works, but be aware of the behavior.
+;;
+;;  Progressive completion lets you match multiple regexps, some of
+;;  which could of course be literal substrings, with their regexp
+;;  special characters, if any, escaped.  If you need to match such
+;;  substrings at particular locations in the target completion
+;;  candidate, then progressive completion will not do the job - it
+;;  matches its component regexps independently.  You can regexp-quote
+;;  (escape) parts or all of your input using `M-%'
+;;  (`icicle-regexp-quote-input').
+;;  See (@> "Quoting (Escaping) Special Characters")
+;;
+;;(@* "`M-&': Satisfying Additional Predicates")
+;;  ** `M-&': Satisfying Additional Predicates **
+;;
+;;  If you use Icicles, then you will use `M-*' very often.  This
+;;  section describes a seldom-used feature that can be useful in
+;;  certain contexts.  If you are new to Icicles or you are unfamiliar
+;;  with Emacs Lisp, then you might want to just skim this section or
+;;  skip it and come back to it later.
+;;
+;;  Just as you can use `M-*' to narrow the set of candidates by
+;;  matching an additional regexp, so you can use `M-&' (bound to
+;;  `icicle-narrow-candidates-with-predicate') to narrow by satisfying
+;;  an additional predicate.  The idea is the same; the only
+;;  difference is that, instead of typing a regexp to match, you type
+;;  a predicate to satisfy.
+;;
+;;  The predicate is a Boolean function of a single completion
+;;  candidate.  At the prompt, you enter its name or its
+;;  lambda-expression definition (anonymous function).  The predicate
+;;  is used the same way as the PREDICATE argument to
+;;  `completing-read' and `read-file-name'.  This means that the
+;;  candidate argument to the predicate is whatever is used in the
+;;  original call to `completing-read' or `read-file-name'; it is not
+;;  just a string such as you see in buffer `*Completions*'.  To
+;;  provide an appropriate predicate, you must be familiar with the
+;;  kind of candidate expected by the command you invoked before just
+;;  before `M-&'.
+;;
+;;  For example:
+;;
+;;  * Command `describe-function' (`C-h f') uses candidates that are
+;;    symbols.  An appropriate predicate would accept a symbol as
+;;    argument.
+;;
+;;  * Command `icicle-search' (`C-c `') uses candidates that have this
+;;    form: (CONTEXT . MARKER), where CONTEXT is a string, the search
+;;    hit (search context), and MARKER is a buffer marker that locates
+;;    the CONTEXT.  An appropriate predicate would accept such a
+;;    candidate as argument.
+;;
+;;  Although entering a lambda expression at a prompt might not seem
+;;  too convenient, you can at least retrieve previously entered
+;;  predicates (using `M-p' and so on).
+;;
+;;  You can also use `C-M-&' (bound to
+;;  `icicle-save-predicate-to-variable') at any time during completion
+;;  to save the current predicate as a string-valued variable.  By
+;;  default, the variable is `icicle-input-string'.  You can then
+;;  retrieve the saved string later, using `C-=' at the prompt for
+;;  `M-&'.  The current predicate is what is saved.  You can build up
+;;  a complex predicate, and then save it for later use.
+;;
+;;  The inconvenience of typing an Emacs-Lisp sexp must be balanced
+;;  against the power of applying predicates on the fly.  Whereas
+;;  regexp matching is purely syntactic, with a predicate you can
+;;  perform semantic tests.  During search, for instance, you can look
+;;  not only for a syntax match; you can look for matching search
+;;  candidates that also belong to a particular class of objects
+;;  (e.g. function, variable, type) or that satisfy some other
+;;  semantic property.
+;;  See also (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview").
+;;
+;;  See Also:
+;;
+;;  * (@> "Sets of Completion Candidates") for another way to perform
+;;    a set intersection on sets of candidate completions.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;    for a way to search using two regexps - command `icicle-search'
+;;    uses the same idea as that behind progressive completion.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Compile/Grep Search")
+;;    for a way to grep files using multiple levels of regexps, and
+;;    performing selected replacements.
+ 
+;;(@* "Regressive Completion")
+;;
+;;  Regressive Completion
+;;  ---------------------
+;;
+;;  Though generally less useful than progressive completion, you can
+;;  also widen, instead of narrow, the current set of completion
+;;  candidates, by providing an alternative pattern (regexp) to match.
+;;  By analogy, I call this "regressive completion".
+;;
+;;  The analogy is not exact.  By definition, your current input is
+;;  always matched against all candidates in the domain of discourse.
+;;  With progressive completion, a recursive minibuffer is entered for
+;;  each new pattern to match.  The candidates that matched the
+;;  previous input of the progression become the new domain of
+;;  discourse for the current act (recursive level) of completion.
+;;
+;;  That same technique is not applicable for widening.  Instead, you
+;;  enter, using `RET', a new pattern to match as an alternative, and
+;;  Icicles changes the current input to a regexp that matches either
+;;  what the previous input matched or the alternative pattern.  In
+;;  other words, it is just a short cut for typing a regexp that
+;;  matches a choice: \(...\|...\).  The domain of discourse remains
+;;  the same - in particular, there is no way to widen the domain of
+;;  discourse like narrowing narrows it.
+;;
+;;  You use `M-+' (`icicle-widen-candidates') for regressive
+;;  completion - think of the `+' as set union (OR), just as you think
+;;  of the `*' in `M-*' as set intersection (AND).  And, just as for
+;;  progressive completion, there is a shortcut, `S-backspace', for
+;;  `S-TAB' followed by `M-+'.
+;;
+;;  For example, if you want to see all of the candidates that contain
+;;  either `for' or `back', you could type `\(for\|back\)' in the
+;;  minibuffer, or you could just type `for', then `S-backspace' (or
+;;  `S-TAB' followed by `M-+'), then `back'.  Icicles replaces your
+;;  input by `\(for\|back\)'.  You can continue with additional
+;;  alternative match patterns.  And you can combine narrowing with
+;;  widening, that is, progressive with regressive completion.
+;;
+;;  You can of course cycle among all matching candidates, regardless
+;;  of which alternative they match.  One use of regressive completion
+;;  is with Icicles search - it corresponds to the OR searching of
+;;  common search engines.
+;;
+;;  Gotcha: When completing file names that are not absolute
+;;  (e.g. using `C-x C-f', not `C-u C-x C-f'), be sure that the
+;;  default directory is not included in your minibuffer input when
+;;  you hit `M-+'.  You do not want the overall regexp that `M-+'
+;;  constructs to be something like \(/my/default/dir/foo\|bar\) - you
+;;  want it to be just \(foo\|bar\).  For absolute file name
+;;  completion there is no such problem, because the completion
+;;  candidates themselves have a directory component.  So either use a
+;;  `nil' value of `insert-default-directory' or use `M-k' to remove
+;;  the directory component before hitting `M-+'.
+ 
+;;(@* "Completion On Demand")
+;;
+;;  Completion On Demand
+;;  --------------------
+;;
+;;  When the minibuffer is active for your input, completion is not
+;;  always available.  Functions such as `completing-read' and
+;;  `read-file-name' provide completion, but other functions that read
+;;  input in the minibuffer, such as `read-from-minibuffer' and
+;;  `read-string', do not provide completion.
+;;  (See (@> "Completion Status Indicators"), for how to tell when
+;;  completion is available in Icicles.)
+;;
+;;  But in Icicles you can always invoke (lax) completion to insert
+;;  some completed text in the minibuffer - this is completion on
+;;  demand.
+;;
+;;  On-demand completion is always available to insert a file name.
+;;  You invoke this using `C-M-F', that is, `C-M-S-f'
+;;  (`icicle-read+insert-file-name').  A recursive minibuffer is used
+;;  to perform the completion.  The result of completing is inserted
+;;  at point in the parent minibuffer, without replacing any other
+;;  text that might already be there.
+;;
+;;  You can use this feature to add multiple file or directory names
+;;  to the same minibuffer input.  In this way, for instance, you can
+;;  use it to add particular file or directory names as arguments to a
+;;  shell command that you input in the minibuffer.  By default, a
+;;  relative name is inserted, but if you use a prefix argument then
+;;  the directory component is included.
+;;
+;;  Similarly, you can use `C-M-C', that is, `C-M-S-c'
+;;  (`icicle-completing-read+insert'), to invoke non file-name
+;;  completion.  This, however, is available only if the command
+;;  reading from the minibuffer allows it, by defining a set of
+;;  possible completions.
+;;
+;;  The actual keys used for on-demand completion are customizable,
+;;  using options `icicle-read+insert-file-name-keys' and
+;;  `icicle-completing-read+insert-keys'.  The default values are
+;;  `C-M-S-f' and `C-M-S-c'.
+;;
+;;  Another kind of on-demand completion is provided by `M-o'
+;;  (`icicle-insert-history-element').  Again, this is always
+;;  available in the minibuffer, regardless of whether input is being
+;;  read with completion.  This invokes completion against the entries
+;;  in the current minibuffer history.
+;;  See (@> "History Enhancements").
+ 
+;;(@* "Moving Between the Minibuffer and Other Buffers")
+;;
+;;  Moving Between the Minibuffer and Other Buffers
+;;  -----------------------------------------------
+;;
+;;  Sometimes, when the minibuffer is active, you might want to move
+;;  the cursor and focus from the minibuffer back to the original
+;;  buffer from which you activated the minibuffer.  When you are in
+;;  Icicle mode, the `pause' key is bound (by default) to command
+;;  `icicle-switch-to/from-minibuffer', which does that.  This lets
+;;  you start minibuffer input (with or without completion), and then
+;;  interrupt it to search, edit, and so on, in the original buffer.
+;;  This same command (bound to `pause') then lets you switch back to
+;;  the minibuffer - it acts as a toggle for the input focus; go back
+;;  and forth as much as you like.
+;;
+;;  This can be especially useful when you use multi-commands (see
+;;  (@> "Multi-Commands")).  In that case, you often keep the
+;;  minibuffer active for completion while performing multiple
+;;  completion actions.  It can be handy to interrupt this to perform
+;;  some normal editing or search, and then resume multi-command
+;;  actions.
+;;
+;;  Another use for this feature is to select text in the original
+;;  buffer and then insert it in the minibuffer.  See also
+;;  (@> "Inserting Text Found Near the Cursor") for another way to do
+;;  that.
+;;
+;;  A somewhat related toggle is available using `C-insert'.  This
+;;  lets you switch the focus between the minibuffer and buffer
+;;  `*Completions*'.  See (@> "*Completions* Display") for more
+;;  information.
+ 
+;;(@* "Inserting a Regexp from a Variable or Register")
+;;
+;;  Inserting a Regexp from a Variable or Register
+;;  ----------------------------------------------
+;;
+;;  Regexps are powerful, but they can sometimes be complex to compose
+;;  and hard to remember once composed.  A shortcut is to compose a
+;;  regexp that you want to use and assign it to an Emacs variable or
+;;  register.
+;;
+;;  If you assign it to a register (using `C-x r s'), then you can use
+;;  `C-x r i' (`insert-register') in the minibuffer to insert it.  If
+;;  you assign it to a string, then you can use `C-='
+;;  (`icicle-insert-string-from-variable') to insert it.
+;;
+;;  If you use `C-u C-=' (provide a prefix argument) then you are
+;;  prompted for the variable to use.  Completion candidates for this
+;;  include all string-valued variables.
+;;
+;;  Without `C-u', the default variable is used (no prompting),
+;;  `icicle-input-string'.  So for example, if `icicle-input-string'
+;;  had value "[a-zA-Z]+" then it would match any completion candidate
+;;  composed only of letters.  You can customize
+;;  `icicle-input-string'.
+;;
+;;  For convenience, instead of using Lisp evaluation of a sexp such
+;;  as (setq icicle-input-string "[a-zA-Z]+") or (setq my-var ".*"),
+;;  you can use Icicles command `icicle-save-string-to-variable' to
+;;  save a regexp to a variable.  You are prompted for the regexp to
+;;  save.  Just as for `icicle-insert-string-from-variable', with a
+;;  prefix argument you are prompted for the variable to use (all
+;;  variables are completion candidates).  With no prefix argument the
+;;  regexp is saved to variable `icicle-input-string'.
+;;
+;;  Another way of inserting a string into the minibuffer is to use a
+;;  negative prefix arg with `M-:' (e.g. `M-- M-:') during minibuffer
+;;  input.  With this method, you can type not only a string-valued
+;;  variable name but any Emacs-Lisp expression.  The expression need
+;;  not evaluate to a string - whatever the result of evaluation is,
+;;  it is pretty-printed in the minibuffer, to be used as part of your
+;;  input text.
+;;
+;;  These shortcut features are especially convenient for use with
+;;  command `icicle-search' - you can use it to search text for
+;;  sentences, paragraphs, file names, URLs, dates, times, function
+;;  definitions, and any other text entities that you can specify by
+;;  regexp.  Create a library of regexp-valued variables that are
+;;  useful to you, and use `C-=' to quickly access them in
+;;  `icicle-search'.  See
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;  for more information.
+;;
+;;  These shortcuts are also handy for Isearch, in particular, regexp
+;;  search.  Use `M-e' after `C-M-s', to edit the search string (which
+;;  puts you in a minibuffer), then use `C-u C-=' or `C-x r i' to
+;;  insert a saved regexp.
+;;
+;;  See Also: (@> "Inserting Text Found Near the Cursor").
+ 
+;;(@* "Special Characters in Input Patterns")
+;;
+;;  Special Characters in Input Patterns
+;;  ------------------------------------
+;;
+;;  Regular-expression syntax treats some characters specially, but
+;;  some of these special characters have another special meaning in
+;;  Emacs when used with file-name inputs.  What about the conflict
+;;  between interpreting characters such as `$', `\', `.', `?', and
+;;  `*' as 1) regexp special characters and 2) special characters for
+;;  file-name input?  For example, when inputting a file name, should
+;;  `*' be treated as a regexp multiple-occurrences operator or as a
+;;  file-name wildcard?
+;;
+;;  In Emacs file-name input:
+;;
+;;  - `$' can be used to prefix environment variables.
+;;
+;;  - `*' and `?' can be used as wildcards, effectively inputting
+;;    multiple file names at once.
+;;
+;;  - `.' and `..' can be used to navigate a directory hierarchy.
+;;
+;;  - `\' is a directory separator, like `/', on MS Windows, at least.
+;;
+;;  Icicles handles the conflict by interpreting such characters as
+;;  regexp special characters only during input completion and cycling
+;;  - and then only if you do not escape them (with `\').  If present
+;;  in the input when you finally accept it (using `RET'), they take
+;;  on their normal Emacs meanings for file-name input:
+;;  environment-variable prefix, wildcard, directory abbreviation, or
+;;  directory separator.
+;;
+;;  That is, whenever there is a potential conflict of interpretation,
+;;  the regexp meaning is used for completion and cycling, and the
+;;  standard interpretation for file-name input is used for accepting
+;;  the input.  So, for example, to get the wildcard interpretation of
+;;  `*', just forego regexp completion and cycling.  And vice versa:
+;;  forego the wildcard interpretation to use regexp completion and
+;;  cycling.
+;;
+;;  This is in any case the behavior of vanilla Emacs as well.  If, in
+;;  vanilla Emacs, you use `ici*' or `ici*.el' as input to `find-file'
+;;  and hit `TAB', there is no completion available.  File-name
+;;  globbing and completion are independent.
+;;
+;;  Note: Because `?' is useful in regexp syntax, the standard Emacs
+;;        minibuffer binding of `?', which just displays the
+;;        completion-candidates list, is not used in Icicles.  In
+;;        Icicles, `?' self-inserts in the minibuffer, like any other
+;;        printable character.  (Use `TAB' or `S-TAB' to display the
+;;        list.)  In standard Emacs, you must quote `?' or
+;;        copy-and-paste it, to insert it in the minibuffer for use as
+;;        a file-name wildcard.
+;;
+;;  The interpretation conflict for `\' (on MS Windows) is not really
+;;  a problem, anyway.  Although you cannot use a backslash (`\') as a
+;;  directory separator during apropos completion and cycling, you can
+;;  always use a slash (`/') instead - even on MS Windows.  The best
+;;  practice is to just break with MS-Windows syntax, and get in the
+;;  habit of always using `/' as the directory-separator character.
+;;
+;;  But what if you copy an absolute filename from some MS Windows
+;;  application, so it has backslashes, and you want to use it in
+;;  Emacs?  You can go ahead and paste it in the minibuffer for
+;;  filename completion, as long as you are not doing regexp
+;;  completion.  You can (a) use prefix completion with it, (b) use
+;;  `C-`' to turn on regexp quoting for apropos completion (so you can
+;;  complete a substring), or (c) change the backslashes to slashes.
+;;
+;;  Even if you always use only slash, not backslash, as a directory
+;;  separator when inputting, however, it is possible that you could
+;;  run into some trouble on MS Windows.  You might (knowingly or not)
+;;  use `\' as a directory separator in the values of environment
+;;  variables that you use as part of file-name input.  If you are
+;;  regexp completing, then those backslashes will be treated as
+;;  regexp escapes.  So you should use only non-regexp completion with
+;;  input that includes environment variables whose expansions might
+;;  include backslashes.
+;;
+;;  The interpretation conflict for `$' is also not a real problem.
+;;  You can get the effect of both interpretations of `$' at the same
+;;  time, because Icicles recognizes that `$' at the end of input
+;;  cannot be an environment-variable prefix.  This means, for
+;;  example, that you can use a pattern such as `$HOME.*t$' to match
+;;  the files in your home directory whose names end in `t'.
+;;
+;;  The first `$' here is not treated specially during regexp matching
+;;  and cycling; the environment variable `$HOME' is expanded by the
+;;  shell to a directory name.  The second `$' is treated as the
+;;  regexp special character that matches at the end of a line.  When
+;;  using environment variables, you can also enclose them in braces:
+;;  `${HOME}', for example.
+;;
+;;  Note: Starting with Emacs 23, if option
+;;  `icicle-TAB-completion-methods' includes `vanilla', and you choose
+;;  `vanilla' completion for `TAB' (by cycling using `C-(' or by
+;;  customizing `icicle-TAB-completion-methods' to use `vanilla' as
+;;  the default), then Icicles `TAB' completion will complete an
+;;  environment variable during file-name completion.  This is in
+;;  addition to the traditional shell expansion of a variable when you
+;;  hit `RET'.
+;;
+;;  Tip: Because slash (`/') is about the only non-word syntax
+;;       character that is likely to appear in file-name completions,
+;;       you can usually use `\W$' to match only directories (by
+;;       matching the `/' at the end of their names).  `\W' is the
+;;       regexp pattern that matches any character that does not
+;;       appear in words.  For example, you can use `${HOME}\W$' to
+;;       match all direct subdirectories in your home directory.
+;;
+;;(@* "Quoting (Escaping) Special Characters")
+;;  ** Quoting (Escaping) Special Characters **
+;;
+;;  You can toggle interpretation vs escaping of regexp special
+;;  characters at any time, using `C-`' in the minibuffer (command
+;;  `icicle-toggle-regexp-quote').  Escaping special characters this
+;;  way means they are no longer special; they simply match
+;;  themselves.  This has the effect of reducing apropos completion to
+;;  simple substring completion.  If you never want to use regexp
+;;  matching (*not* recommended!), you can customize user option
+;;  `icicle-regexp-quote-flag', setting it to non-`nil'.
+;;
+;;  Apropos (regexp) completion contains literal substring completion
+;;  as a (common) special case.  Sometimes you want to use regexp
+;;  completion, but you also want to match a literal substring that
+;;  contains special characters.  You can of course quote (escape)
+;;  each of these characters by hand.  Alternatively, you can use
+;;  `M-%' (`icicle-regexp-quote-input') to quote the text that you
+;;  want to match literally.  If the region is active, then it is
+;;  quoted; otherwise, your entire minibuffer input is quoted.
+;;
+;;  Note that if a substring that you want to match literally can
+;;  occur anywhere in the target completion candidate, then it is
+;;  simpler to just use progressive completion.  Quoting a literal
+;;  substring is useful when the overall regexp requires it to be at a
+;;  certain location in the target.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Dired Enhancements")
+;;    for how to use Icicles regexp-matching to open Dired on sets of
+;;    files that you might not be able to specify using file-name
+;;    wildcards.
+;;
+;;  * (@> "Multi-Commands") for a way to open multiple files whose
+;;    names match a regular expression.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "File-Name and Directory-Name Completion Tips")
+;;    for:
+;;    - Information about abbreviating your home directory as `~' or
+;;      expanding it.
+;;    - A way to locate and open files by regexp anywhere in your file
+;;      system - that is, match against directory-name as well as
+;;      file-name components.
+;;
+;;  * (@> "Progressive Completion")
+ 
+;;(@* "Exiting the Minibuffer Without Confirmation")
+;;
+;;  Exiting the Minibuffer Without Confirmation
+;;  -------------------------------------------
+;;
+;;  Normally, if you exit the minibuffer with input that only
+;;  partially matches a completion candidate, the value you input is
+;;  exactly what you typed.  That is, exiting does not automatically
+;;  complete your input - what you type is what you get.  This is
+;;  "lax" (or "permissive") completion, and it is desirable most of
+;;  the time, because it lets you input a value that does not
+;;  correspond to any of the completion candidates.  This is how, for
+;;  instance, you can use `C-x C-f' to open a new file or `C-x b' to
+;;  create a new buffer.
+;;
+;;  However, some people prefer "strict" completion: limiting input to
+;;  the available completion candidates.  This can be handy in the
+;;  case of switching to a buffer, for instance.  If you have a buffer
+;;  named `new-ideas.txt', you might like to be able to type only
+;;  `new' followed by `RET', and not have to first complete the input
+;;  text.  This is the behavior of libraries `ido.el' and
+;;  `iswitchb.el'.
+;;
+;;  It is the command you use that decides whether `RET' first
+;;  completes your input before exiting the minibuffer (strict
+;;  completion) or not (lax completion).  This is done in the command
+;;  definition by providing a non-`nil' or `nil' REQUIRE-MATCH
+;;  argument to function `completing-read', which prompts you and
+;;  reads your input, possibly completing it.
+;;
+;;  If you use standard Emacs command `switch-to-buffer' then
+;;  completion is lax: `RET' does not complete your input `new' to
+;;  `new-ideas.txt'; it simply accepts your input as is, and creates a
+;;  new buffer with that name, `new'.
+;;
+;;(@* "Using `S-RET' to Accept a Partial Match")
+;;  ** Using `S-RET' to Accept a Partial Match **
+;;
+;;  By default, Icicles command `icicle-buffer', not vanilla command
+;;  `switch-to-buffer', is bound to `C-x b' in Icicle mode.  The
+;;  default behavior of `icicle-buffer' is the same as the behavior of
+;;  `switch-to-buffer' with respect to `RET'.  However, you can obtain
+;;  the complete-and-exit `RET' behavior with `icicle-buffer' by
+;;  setting option `icicle-buffer-require-match-flag' to
+;;  `partial-match-ok'.  This value overrides the REQUIRE-MATCH
+;;  argument to `completing-read', in effect forcing it to `t'.
+;;
+;;  Whenever completion is strict, requiring a match against one of
+;;  the completion candidates (typically, an existing file or buffer
+;;  name), you can complete and exit the minibuffer all at once, with
+;;  only partial input in the minibuffer, by using `RET'.  But what
+;;  about apropos completion?  Simply use `S-RET'
+;;  (`icicle-apropos-complete-and-exit') instead of `RET': `RET' is
+;;  standard in Emacs and uses prefix completion; `S-RET' is specific
+;;  to Icicles and uses apropos completion.  For example, you can type
+;;  `idea' followed by `S-RET' to switch to buffer `new-ideas.txt'.
+;;
+;;  Note: You can customize `icicle-top-level-key-bindings' to prevent
+;;  the rebinding of `C-x b' in Icicle mode.
+;;
+;;(@* "Accepting Partial Matches by Default")
+;;  ** Accepting Partial Matches by Default **
+;;
+;;  For those people who prefer that a partial match always be
+;;  accepted immediately, regardless of the context (whether a match
+;;  is required or not) and without having to use `RET' or `S-RET',
+;;  there is Icicles user option
+;;  `icicle-top-level-when-sole-completion-flag'.  If you set this to
+;;  non-`nil', then, whenever your input matches only one candidate
+;;  completion, that candidate is used immediately.  I do not
+;;  recommend this practice generally, but some people might prefer
+;;  it.
+;;
+;;  Option `icicle-top-level-when-sole-completion-delay' is the number
+;;  of seconds Icicles waits, before returning to top level with the
+;;  sole completion.  It has no effect if
+;;  `icicle-top-level-when-sole-completion-flag' is `nil'.  The delay
+;;  gives you a chance to forestall acceptance of the sole completion:
+;;  editing the completion (typing or deleting a character) before the
+;;  delay expires prevents its automatic acceptance.
+;;
+;;  See Also: (@* "Ido and IswitchB")
+ 
+;;(@* "Ido and IswitchB")
+;;
+;;  Ido and IswitchB
+;;  ----------------
+;;
+;;  Libraries Ido and IswitchB are alternatives to Icicles that also
+;;  enhance minibuffer completion in various ways.  Their UIs are
+;;  similar to each other - Ido essentially extends IswitchB's
+;;  buffer-name completion to file names as well.  Neither completes
+;;  other kinds of candidates.  They work only for buffer names or
+;;  file names, but you can advise the standard completion functions
+;;  to get them to use Ido completion more generally.
+;;
+;;  The behavior of Ido and IswitchB is different from the default
+;;  Icicles behavior.  If you prefer their behavior for buffers then
+;;  you can just use IswitchB and Icicles together.  You cannot use
+;;  Icicles and Ido together, however - they use the minibuffer in
+;;  incompatible ways.
+;;
+;;  The default behavior of Icicles is different, but you can make
+;;  Icicles behave more like Ido if you like.  It would be a mistake
+;;  to look for a complete reproduction of the Ido behavior in
+;;  Icicles, however.  If you want exactly the same behavior as Ido,
+;;  then use Ido. ;-)
+;;
+;;  The Icicles UI is different by design.  Some of this difference in
+;;  approach has to do with the fact that Ido is specialized to
+;;  buffer- and file-name completion.  The generality of Icicles makes
+;;  a different approach appropriate.  Icicles has many additional
+;;  features that are not available in other libraries, but its main
+;;  advantage is its generality: you use the same user interface for
+;;  input of any kind.  As you learn more about Icicles you may begin
+;;  to appreciate its approach, even if you are a diehard Ido addict.
+;;
+;;  This section summarizes some differences between Icicles and Ido
+;;  and tells you how you can get more Ido-like behavior in Icicles if
+;;  that's what you prefer.  It does not cover Icicles features that
+;;  have no counterpart in Ido or features that they have in common
+;;  (except to emphasize some differences).
+;;
+;;  If you have the Ido habit but want to give Icicles a try, then
+;;  this section is for you.  I recommend, however, that you give the
+;;  default Icicles behavior a good try before convincing yourself
+;;  that you still prefer a more Ido-like approach.
+;;
+;;  See also the references at the section end for other sections that
+;;  go into more detail about some of the things mentioned here.
+;;  
+;;  1. Incremental completion.  By default, Icicles does not turn on
+;;     incremental completion until you have hit `TAB' or `S-TAB' to
+;;     display the matching candidates.  Ido turns it on immediately.
+;;     You can get that behavior by setting option
+;;     `icicle-show-Completions-initially-flag' to `t'.
+;;
+;;     You can get an intermediate behavior in this regard by instead
+;;     setting option `icicle-incremental-completion-flag' to a value
+;;     other than `nil' and `t'.  That makes Icicles show the matching
+;;     candidates as soon as you start typing input.  See also option
+;;     `icicle-incremental-completion-delay'.
+;;
+;;  2. Matching.  By default, Ido uses substring matching for
+;;     completion.  You can hit a key to switch to prefix matching,
+;;     "flex" matching, or regexp matching.  Icicles gives you these
+;;     same matching possibilities, and more.  (What Ido calls "flex"
+;;     matching Icicles calls "scatter" matching.)  The main
+;;     difference here is that Icicles regexp support is general and
+;;     complete.  Regexp-matching in Ido does not work with Ido-style
+;;     completion.
+;;
+;;  3. Current candidate, cycling, sorting.  Both Ido and Icicles have
+;;     a notion of "current candidate".  In Ido, completion candidates
+;;     are presented in a predefined sort order, most recently used
+;;     first.  The current candidate is the first one.  You cycle
+;;     candidates by moving the first to last or the last to first.
+;;
+;;     In Icicles, you can switch among any number of sort orders at
+;;     any time by hitting a key.  (And you can easily define your own
+;;     sort orders.)  When you cycle candidates, the candidates stay
+;;     in order.  If the candidates are displayed in `*Completions*'
+;;     then the current one is highlighted there, in place.  The
+;;     highlight moves, not the candidate.
+;;
+;;  4. Input editing.  In Ido, cycling does not replace your input by
+;;     the current candidate.  To edit the current candidate you hit a
+;;     key to enter an edit mode (recursive minibuffer).  In Icicles,
+;;     cycling replaces your input in the minibuffer by the current
+;;     candidate, so you can just edit it there normally.  You can use
+;;     `C-l' to retrieve your original input.
+;;
+;;  5. Completions shown.  In Ido, a limited number of matching
+;;     completion candidates are shown in the minibuffer.  You can hit
+;;     a key to see all matches in a separate buffer.
+;;
+;;     In Icicles, completion candidates are always shown in buffer
+;;     `*Completions*', not in the minibuffer.  You can limit the
+;;     number of matches shown by customizing option
+;;     `icicle-max-candidates'.  Only the first
+;;     `icicle-max-candidates' (in the current sort order) are shown.
+;;
+;;     You can also increment and decrement this truncation value on
+;;     the fly during completion, by hitting `C-x #' and then using
+;;     the vertical arrow keys or the mouse wheel.  (For that feature
+;;     you also need library `doremi.el'.)
+;;
+;;  6. Auto-choice of sole candidate.  In Ido, if there is only one
+;;     match for your input then `TAB', which normally completes, also
+;;     chooses that candidate - you do not need to hit `RET'.  By
+;;     default, Icicles always requires you to explicitly choose with
+;;     `RET' (or `C-RET').  If you set option
+;;     `icicle-top-level-when-sole-completion-flag' to non-`nil', then
+;;     Icicles provides similar behavior to Ido.  See also option
+;;     `icicle-top-level-when-sole-completion-delay'.
+;;
+;;(@* "Ido-Like Behavior Everywhere: `icicle-ido-like-mode'")
+;;  ** Ido-Like Behavior Everywhere: `icicle-ido-like-mode' **
+;;
+;;  If you want Icicles to be Ido-like in general, then turn on global
+;;  minor mode `icicle-ido-like-mode' (not available in Emacs 20).
+;;  Doing that sets options `icicle-show-Completions-initially-flag'
+;;  and `icicle-top-level-when-sole-completion-flag' to `t'.  Turning
+;;  the mode off sets them to `nil'.
+;;
+;;  You can simultaneously set option `icicle-max-candidates' when you
+;;  turn on `icicle-ido-like-mode', by using a positive prefix
+;;  argument.  If you want the option to keep that value when you turn
+;;  the mode off, then use a zero or negative prefix argument.
+;;  Otherwise, it is reset to `nil' (no limit on the number of
+;;  candidates displayed).
+;;
+;;  When you use this mode, you might also want to use `nil' or `t' as
+;;  the value of option `icicle-default-value', in order to not insert
+;;  the default value in the minibuffer.  If you want to change that
+;;  option dynamically for the mode, use `icicle-ido-like-mode-hook'.
+;;  E.g.:
+;;
+;;  (add-hook 'icicle-ido-like-mode-hook
+;;            (lambda () (setq icicle-default-value
+;;                        (if icicle-ido-like-mode t 'insert-end))))
+;;  
+;;(@* "Ido-Like Behavior for Buffers and Files")
+;;  ** Ido-Like Behavior for Buffers and Files **
+;;
+;;  If you want Ido-like behavior in Icicles for buffers or files, but
+;;  not in general, then customize either or both options
+;;  `icicle-buffers-ido-like-flag' and `icicle-files-ido-like-flag' to
+;;  non-`nil'.
+;;
+;;  See Also:
+;;
+;;  * (@> "Exiting the Minibuffer Without Confirmation")
+;;  * (@file :file-name "icicles-doc2.el" :to "Customization and General Tips"):
+;;     `icicle-buffer-require-match-flag',
+;;     `icicle-deletion-action-flag',
+;;     `icicle-file-require-match-flag',
+;;     `icicle-show-Completions-initially-flag',
+;;     `icicle-incremental-completion-flag',
+;;     `icicle-incremental-completion-delay',
+;;     `icicle-max-candidates',
+;;     `icicle-regexp-quote-flag',
+;;     `icicle-top-level-when-sole-completion-flag',
+;;     `icicle-top-level-when-sole-completion-delay',
+;;  * (@file :file-name "icicles-doc2.el" :to "Fuzzy Completion")
+;;  * (@> "Special Characters in Input Patterns")
+;;  * (@> "Prefix Completion and Apropos Completion")
+;;  * http://www.emacswiki.org/emacs/IciclesDiscussion#IdoAndIcicles
+;;    (out-of-date discussion, but it might be helpful)
+ 
+;;(@* "*Completions* Display")
+;;
+;;  *Completions* Display
+;;  ---------------------
+;;
+;;  Icicles enhances the `*Completions*' display in several ways.  The
+;;  following features are available whenever buffer `*Completions*'
+;;  is displayed.
+;;
+;;  * In buffer `*Completions*', you can use the arrow keys (`down',
+;;    `up', `right', `left') to navigate among the candidate
+;;    completions.  The current candidate (under the cursor) is
+;;    highlighted.
+;;
+;;  * When you cycle completions in the minibuffer:
+;;
+;;    - The current candidate is highlighted in `*Completions*'.
+;;
+;;    - Help on the current candidate (typically, the first line of a
+;;      doc string) is displayed in the mode line, provided user
+;;      option `icicle-help-in-mode-line-delay' is greater than zero.
+;;
+;;  * The total number of completion candidates is displayed in the
+;;    mode-line of buffer `*Completions*' - e.g. `567 candidates'.
+;;    If the number of candidates is currently truncated (because of
+;;    option `icicle-max-candidates' - see
+;;    (@file :file-name "icicles-doc2.el" :to "Customization and General Tips"),
+;;    then the total number of candidates before truncation is also
+;;    shown - e.g. `149 shown / 567'.
+;;
+;;  * You can use `C-insert' to move back and forth between the
+;;    minibuffer and `*Completions*'.  In each direction, the current
+;;    candidate is tracked in the destination buffer.  For example, if
+;;    the candidate in the minibuffer is `foobar', after you hit
+;;    `C-insert' the cursor is on `foobar' in `*Completions*'.  In the
+;;    other direction, if the cursor is on `foobar' in
+;;    `*Completions*', after you hit `C-insert' the current input in
+;;    the minibuffer is `foobar'.
+;;
+;;  * `*Completions*' can also serve as a new kind of icompletion help
+;;    - see (@> "Icompletion").
+;;
+;;  * You can choose multiple candidates during completion, by
+;;    clicking them with `mouse-2' while holding the Control key
+;;    pressed.  See (@> "Multi-Commands").  You can choose a set of
+;;    candidates in additional ways, and then act on all of them - see
+;;    (@> "Sets of Completion Candidates").
+;;
+;;  * Icicles dynamically resizes the `*Completions*' window
+;;    vertically, to fit the current set of completion candidates.
+;;    The window is not resized, however, if buffer `*Completions*'
+;;    appears in its own frame.  (It is also not resized in Emacs
+;;    releases prior to 21.)
+;;
+;;    You can control this automatic resizing generally or on a
+;;    per-command basis:
+;;
+;;     * User option `icicle-Completions-window-max-height' is the
+;;       maximum number of lines to show in the `*Completions*'
+;;       window.
+;;
+;;     * You can override the behavior of option
+;;       `icicle-Completions-window-max-height' for any given command,
+;;       by setting property `icicle-Completions-window-max-height' on
+;;       the command symbol to a different maximum window height
+;;       value.  This property value is predefined for commands, such
+;;       as `icicle-buffer' and `icicle-file', that do not involve the
+;;       content of the current buffer during completion.  A large
+;;       value is used for these commands, so that nearly all of the
+;;       frame real estate is given to the `*Completions*' window.
+;;
+;;    For example, you can use the following code to set the maximum
+;;    `*Completions*' height for command `foo' to 100 and turn off
+;;    per-command control of the height for command `bar'.  If you use
+;;    such code, evaluate it after you load Icicles.
+;;
+;;       (put 'foo 'icicle-Completions-window-max-height 100)
+;;       (put 'bar 'icicle-Completions-window-max-height nil)
+;;
+;;  * Starting with Emacs 23, if you also use Do Re Mi library
+;;    `doremi-frm.el', then you can use `C-x -' in the minibuffer to
+;;    zoom the `*Completions*' buffer text, shrinking or enlarging it
+;;    incrementally using `-' or `=', respectively (`=' is typically
+;;    on the same keyboard key as `+', but it needs no Shift).
+;;
+;;    Also starting with Emacs 23 (whether or not you use
+;;    `doremi-frm.el'), you can specify an initial text-scale amount
+;;    for the `*Completions*' text, by customizing option
+;;    `icicle-Completions-text-scale-decrease'.  This controls the
+;;    default appearance.
+;;
+;;    You typically use these features to make the `*Completions*'
+;;    text a bit smaller and thus save screen real estate - show more
+;;    candidates in less space.  However, Emacs 23 text-scaling does
+;;    not by itself let you recuperate the saved window space - it
+;;    shrinks the text, but it does not shrink the window accordingly.
+;;    For that, you also need library `face-remap+.el' and its option
+;;    `text-scale-resize-window', which lets you resize the window or
+;;    not, horizontally, vertically, or in both directions.
+;;
+;;    (For example, you might set `split-width-threshold' to a small
+;;    number, so `*Completions*' appears on the side rather than above
+;;    or below other windows, and in that case you might want to
+;;    resize it only horizontally.)
+;;
+;;    If you use library `oneonone.el' with a standalone
+;;    `*Completions*' frame, then see option
+;;    `1on1-completions-frame-zoom-font-difference'.
+;;
+;;  * Icicles varies the number of columns used to display completion
+;;    candidates, for a better fit.  You can tweak this with options
+;;    `icicle-candidate-width-factor' and
+;;    `icicle-inter-candidates-min-spaces'.
+;;
+;;    If you use Do Re Mi (library `doremi.el'), then you can modify
+;;    these options incrementally during completion, seeing the effect
+;;    as they change.  Use `C-x w' or `C-x |' from the minibuffer,
+;;    then use the arrow keys or the mouse wheel to increment and
+;;    decrement the current value.  WYSIWYG.
+;;
+;;    Why is this important enough to merit changing it dynamically,
+;;    instead of just customizing the options once and for all?
+;;    Because different sets of candidates have different candidate
+;;    lengths and distributions of those lengths.  Play with it a bit
+;;    and you will see.  One size does not fit all in an ideal way.
+;;
+;;  * You can use `C-x .' (`icicle-toggle-hiding-common-match') in the
+;;    minibuffer at any time during completion to toggle hiding of the
+;;    matched portions of the candidates in `*Completions*'.  This
+;;    portion is replaced by ellipsis, `...'.  (In Emacs 20, it is
+;;    replaced by nothing.)
+;;
+;;    This can be useful when you do not care about the text that
+;;    matches or when that text is particularly long.  For example, if
+;;    you use `icicle-find-file-absolute' (`C-u C-x C-f') and the
+;;    completion candidates are absolute file names that share a
+;;    common directory, it can be convenient to hide the directory
+;;    portion that is common to all candidates.
+;;
+;;  * Starting with Emacs 22, thumbnail images are shown in
+;;    `*Completions*' for candidates that are (relative or absolute)
+;;    names of image files, if option
+;;    `icicle-image-files-in-Completions' is non-`nil' (it is `t' by
+;;    default).  If the option value is `image-only', then only the
+;;    thumbnail images are shown.  If it is otherwise non-`nil' then
+;;    the file names are also shown.  You can cycle the option value
+;;    using `C-x t' in the minibuffer at any time during completion.
+;;
+;;  * You can scroll `*Completions*' down using `C-v', and up using
+;;    `M-v'.  You can use `C-u' at any time to reverse the scroll
+;;    directions.  In Emacs 22 or later, you can also use the mouse
+;;    wheel to scroll `*Completions*'.
+;;
+;;  * You can lay completion candidates out vertically, if you like,
+;;    instead of horizontally (the default).  To do that, customize
+;;    option `icicle-completions-format' to have the value `vertical'.
+;;
+;;    Starting with Emacs 23.2, this is also possible in vanilla
+;;    Emacs, and the vanilla option for this is `completions-format'.
+;;    The default value of `icicle-completions-format' is the value of
+;;    `completions-format', so if you prefer you can simply use the
+;;    vanilla Emacs option.  Vertical layout works in Icicles for all
+;;    Emacs versions, starting with Emacs 20.
+;;
+;;    Unlike the case for vanilla Emacs, in Icicles the arrow keys in
+;;    buffer `*Completions*' correctly reflect the candidate order
+;;    (e.g. as currently sorted).  This also means that candidate
+;;    cycling acts properly for a vertical layout.
+;;
+;;    Note: For visual clarity, a `vertical' value is overridden
+;;    (ignored) when multi-line multi-completions are used - the
+;;    layout is horizontal.  See (@> "Customization and General Tips")
+;;    for more information.
+;;
+;;  * In some cases, Icicles adds one or more additional, proxy
+;;    completion candidates.  These are placeholders for real
+;;    candidates.  If you choose a proxy candidate, then the real
+;;    candidate that is referred to is used.  Typical proxy candidates
+;;    include a reference to a name under the cursor, a reference to
+;;    whatever you then click `mouse-2' on, and a reference to a name
+;;    that is the value of a variable.
+;;
+;;    The inclusion of proxy candidates is controlled by user option
+;;    `icicle-add-proxy-candidates-flag'.  You can toggle this
+;;    inclusion at any time during completion, using `C-M-_'.  For
+;;    performance reasons, you must re-invoke some commands after
+;;    toggling the flag on, to make the proxy candidates available.
+;;
+;;    Examples:
+;;
+;;     . When you read a file name with completion, the proxy
+;;       candidates include the following (reading a face name is
+;;       similar):
+;;
+;;       - `*mouse-2 file name*' - proxy for a file name that you
+;;         click with `mouse-2'.
+;;
+;;       - `*point file name*' - proxy for the file name at point (if
+;;         available).
+;;
+;;       - Single-quoted names of file-name variables - proxy for the
+;;         variable value.
+;;
+;;     . When a command reads input using `icicle-read-number' or
+;;       `icicle-read-string-completing', the proxy candidates are all
+;;       variables whose values are numbers or strings, respectively.
+;;       You can choose such a proxy candidate to use its value.  (All
+;;       candidates are proxy candidates for these functions.)
+;;
+;;     . When you use command `icicle-read-color', the proxy
+;;       candidates include the following:
+;;
+;;       - `*point foreground*' - proxy for the foreground color at
+;;         the cursor position (point).
+;;
+;;       - `*mouse-2 foreground*' - proxy for the foreground color
+;;         where you then click `mouse-2'.
+;;
+;;       - `*copied foreground*' - proxy for a previously copied
+;;         foreground color, the value of variable
+;;         `eyedrop-picked-foreground'.
+;;
+;;       - Background versions of the first three: `*copied
+;;         background*' etc.
+;;
+;;       - Single-quoted names of color-valued variables - proxy for
+;;         the variable value.
+;;
+;;    See Also:
+;;    (@> "Different Places for Saving and Retrieving Candidates")
+;;    for information about using `C-M-{' in the minibuffer to
+;;    retrieve the value of any variable as minibuffer input.
+;;
+;;    Gotcha: Your minibuffer input is matched against proxy
+;;    candidates, as usual.  If `insert-default-directory' is
+;;    non-`nil' when you use `C-x d' (`icicle-dired') then the default
+;;    directory is inserted as part of your input.  If you use `TAB'
+;;    for completion then you will first need to use `M-k' to remove
+;;    the directory, as it will not match any of the proxy candidates.
+;;
+;;  * Clicking `C-mouse-3' on a candidate in `*Completions*' pops up a
+;;    contextual menu for acting on completion candidates.  You can
+;;    customize the menu using option
+;;    `icicle-Completions-mouse-3-menu-entries'.  By default, the menu
+;;    has the following submenus:
+;;
+;;     . `This Candidate' - Act on the candidate that you clicked to
+;;       pop up the menu.  Or act on all current candidates,
+;;       individually or collectively.
+;;
+;;     . `Sorting' - Change the current candidate sort order.
+;;
+;;     . `Save/Retrieve' - Save (mark) candidates or retrieve them,
+;;       including to/from a variable or a cache file.
+;;
+;;     . `Sets' - Perform operations on sets of candidates, in
+;;       particular, the set of current candidates and the set of
+;;       saved candidates.
+;;
+;;     . `Toggle/Cycle/Change' - Toggle, cycle, or otherwise change an
+;;       Icicles setting, altering the behavior on the fly.
+;;
+;;     . `Miscellaneous' - Other candidate operations and general
+;;       help.
+;;
+;;    The popup menu is contextual.  In particular, the available
+;;    items can change depending on whether you use a prefix argument
+;;    (`C-u C-mouse-3') and whether you have selected candidates using
+;;    the region (e.g. mouse drag).  The menu also provides a good
+;;    reminder of key bindings available during completion.
+;;
+;;  There are lots more Icicles features that enhance the display and
+;;  behavior of `*Completions*' in some way.  Read on...
+;;
+;;  See Also: 
+;;
+;;  * (@> "Moving Between the Minibuffer and Other Buffers"), for
+;;    information on the `pause' key, which is somewhat related to
+;;    using `C-insert'.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Candidates with Text Properties")
+;;    and (@file :file-name "icicles-doc2.el" :to "Programming Multi-Completions")
+;;    for information about using text properties in `*Completions*'.
+;;    These sections are for Emacs-Lisp programmers.
+ 
+;;(@* "Icompletion")
+;;
+;;  Icompletion
+;;  -----------
+;;
+;;  Emacs incremental completion, or icompletion, provided by standard
+;;  library `icomplete.el', displays matching prefix completions in
+;;  the minibuffer.  This display is updated incrementally as you type
+;;  characters.  In spite of the name, icompletion does not, in fact,
+;;  provide any completion; it provides completion help, letting you
+;;  know which (prefix) completions are available.
+;;
+;;  Icicles enhances Emacs icompletion in three ways:
+;;
+;;  1. It works with my library `icomplete+.el' to provide minibuffer
+;;     feedback on the number of completion candidates.
+;;
+;;  2. It highlights the part of your input that does not match any
+;;     completion candidate.
+;;
+;;  3. It provides a new kind of icompletion, using buffer
+;;     `*Completions*'.
+;;
+;;(@* "icomplete+.el Displays the Number of Other Prefix Candidates")
+;;  ** icomplete+.el Displays the Number of Other Prefix Candidates **
+;;
+;;  Library `icomplete+.el' enhances `icomplete.el' in various ways.
+;;  One of these ways is to complement Icicles by displaying the
+;;  number of other prefix-completion candidates when cycling.  This
+;;  number is displayed whenever you change direction when cycling.
+;;  For example:
+;;
+;;      M-x forward-line   [Matched]  (13 more)
+;;
+;;  Like `icomplete.el', `icomplete+.el' provides help for only prefix
+;;  completions, not apropos completions.  (Reminder: There is no
+;;  icompletion for file-name completion - see standard library
+;;  `icomplete.el'.)
+;;
+;;(@* "Icompletion in *Completions*: Apropos and Prefix Completion")
+;;  ** Icompletion in *Completions*: Apropos and Prefix Completion **
+;;
+;;  Buffer `*Completions*' shows you the current set of candidates for
+;;  either prefix or apropos completion.  Together, user options
+;;  `icicle-incremental-completion-flag',
+;;  `icicle-incremental-completion-delay', and
+;;  `icicle-incremental-completion-threshold' control incremental
+;;  updating of `*Completions*'.
+;;
+;;  If `icicle-incremental-completion-flag' is non-`nil', then
+;;  `*Completions*' is automatically updated when you change your
+;;  input in the minibuffer - that is, with each character that you
+;;  type or delete.  This is another form of icompletion, unique to
+;;  Icicles.  It uses buffer `*Completions*', instead of the
+;;  minibuffer, to show the completion help.
+;;
+;;  The particular non-`nil' value of
+;;  `icicle-incremental-completion-flag' determines when
+;;  `*Completions*' is displayed and updated.  The default value, `t',
+;;  means that `*Completions*' is updated only if it is already
+;;  displayed.  Use `t' if you do not want `*Completions*' to be too
+;;  intrusive but you want it to provide the most help when you ask
+;;  for help (via `TAB' or `S-TAB').
+;;
+;;  Any other non-`nil' value displays and updates `*Completions*'
+;;  whenever there is more than one completion candidate.  That can be
+;;  more helpful, but it can also be more distracting.  A value of
+;;  `nil' turns off automatic updating altogether - `*Completions*' is
+;;  then displayed only upon demand.  I find that `t' represents a
+;;  good compromise, providing help when I ask for it, and then
+;;  continuing to help until I've finished choosing a candidate.
+;;
+;;  Option `icicle-incremental-completion-delay' is the number of
+;;  seconds to wait before updating `*Completions*' incrementally.  It
+;;  has an effect only when the number of completion candidates is
+;;  greater than `icicle-incremental-completion-threshold'.  This
+;;  delay can improve performance when there are many candidates.  It
+;;  lets you type ahead before any redisplay occurs; otherwise,
+;;  redisplay occurs for each character you type or delete.
+;;
+;;  You can toggle incremental completion at any time (changing
+;;  `icicle-incremental-completion-flag' between `nil' and `t') using
+;;  command `icicle-toggle-incremental-completion', which is bound to
+;;  `C-#' in the minibuffer.  If the number of completion candidates
+;;  is very large, then use `C-#' to toggle incremental completion off
+;;  - that will save time by not updating `*Completions*'.  See also
+;;  (@> "Dealing With Large Candidate Sets") for other ways to deal
+;;  with a large number of candidates.
+;;
+;;  Note: Incremental completion is effectively turned off when a
+;;  remote file name is read, that is, whenever your file-name input
+;;  matches a remote-file syntax.
+;;
+;;  There are several advantages of using `*Completions*' for
+;;  icompletion, as opposed to the minibuffer:
+;;
+;;  1. Many more candidates can be displayed in `*Completions*' than
+;;     can be displayed by standard icompletion, which uses the
+;;     minibuffer for feedback.
+;;
+;;  2. Standard (minibuffer) icompletion provides feedback only on
+;;     matches for prefix completion.  If you use both standard
+;;     icompletion and Icicles icompletion, you can have incremental
+;;     help for both prefix completion and apropos completion at the
+;;     same time, one in the minibuffer and the other in
+;;     `*Completions*'.
+;;
+;;  3. The other Icicles `*Completions*' features are available for
+;;     the current set of matching candidates: cycling, highlighting
+;;     of match root, highlighting of previously used candidates, and
+;;     so on.  See (@> "*Completions* Display").
+;;
+;;(@* "Icicles Highlights the Input that Won't Complete")
+;;  ** Icicles Highlights the Input that Won't Complete **
+;;
+;;  When you are typing or correcting your input during completion,
+;;  Icicles highlights the part of your minibuffer input that prevents
+;;  it from matching any completion candidates, by default.  This
+;;  works for both prefix completion and apropos completion.  For
+;;  both, it highlights your input from the leftmost mismatch through
+;;  the input end.
+;;
+;;  You can use `C-M-l' to move the cursor to the start of the
+;;  highlighted, mismatched part of your input.  Repeat `C-M-l' to
+;;  kill the highlighted portion.  (Because it is killed, `C-y' yanks
+;;  it back.)
+;;
+;;  User options `icicle-incremental-completion-flag',
+;;  `icicle-test-for-remote-files-flag',
+;;  `icicle-highlight-input-completion-failure',
+;;  `icicle-highlight-input-completion-failure-delay', and
+;;  `icicle-highlight-input-completion-failure-threshold' control this
+;;  highlighting, which is done using face
+;;  `icicle-input-completion-fail' (for strict completion) or
+;;  `icicle-input-completion-fail-lax' (for lax completion).
+;;
+;;  If either `icicle-incremental-completion-flag' or
+;;  `icicle-highlight-input-completion-failure' is `nil', then no such
+;;  highlighting is done.  Remember that you can toggle incremental
+;;  completion using `C-#' in the minibuffer.
+;;
+;;  Because this highlighting can have a negative impact on
+;;  performance, you can fine-tune when you want it to occur.  The
+;;  value of `icicle-highlight-input-completion-failure' determines
+;;  when this highlighting can take place.
+;;
+;;  In particular, highlighting the non-matching part of remote file
+;;  names can be slow.  Two values of the option allow remote file
+;;  name highlighting: `always' and `explicit-remote'.  The other
+;;  values do not highlight remote file names.  You probably do not
+;;  want to use a value of `always'.
+;;
+;;  If the value is `nil', then highlighting never occurs.  If the
+;;  value is `explicit-strict', `explicit', or `explicit-remote', then
+;;  highlighting occurs only upon demand: when you hit `TAB' or
+;;  `S-TAB' to request completion.  If the value is `implicit-strict',
+;;  `implicit', or `always', then highlighting occurs also when you
+;;  update input during incremental completion (if incremental
+;;  completion is turned on).
+;;
+;;  I use a value of `implicit' myself, but the default value is
+;;  `implicit-strict' because, depending on your setup and use cases,
+;;  `implicit' can impact performance for file-name completion (which
+;;  is lax, not strict).  I suggest you try `implicit' to see - this
+;;  feature is especially useful for file names.
+;;
+;;    TIP: An alternative way to be informed about a file name
+;;         mismatch (when you use `TAB' or `S-TAB') is to use
+;;         `icicle-no-match-hook' to signal you using a visual or
+;;         audible cue.  For example:
+;;
+;;         (add-hook 'icicle-no-match-hook
+;;                   (lambda ()
+;;                     (when (icicle-file-name-input-p) (ding))))
+;;
+;;  Summary of `icicle-highlight-input-completion-failure' choices:
+;;
+;;  `nil'             Never
+;;  `explicit-strict' Only on demand and only during strict completion
+;;  `explicit'        Only on demand (lax and strict completion)
+;;  `explicit-remote' Only on demand, even for remote file names
+;;  `implicit-strict' Incremental or explicit completion - strict only
+;;  `implicit'        Incremental/explicit, lax/strict completion
+;;  `always'          Always (including for remote file names)
+;;
+;;  These values are listed here in terms of increasing
+;;  permissiveness, which also can mean increasing performance impact.
+;;  That is, a value of `implicit' is more likely to affect
+;;  performance than a value of `explicit'.  The greatest performance
+;;  hit comes from file-name matching, in particular if remote files
+;;  are involved.
+;;
+;;  If you know that you will not be using remote file names for a
+;;  while, you can let Icicles and Tramp know this by using the toggle
+;;  `C-^' in the minibuffer to turn off option
+;;  `icicle-test-for-remote-files-flag'.  When this is off, you cannot
+;;  use remote files.
+;;
+;;  Turning off `icicle-test-for-remote-files-flag' using `C-^' turns
+;;  off Tramp's remote file-name completion and remote file handling.
+;;  If you turn off the option using `C-^', then turn it back on using
+;;  `C-^' also (instead of just setting the option to non-`nil'), in
+;;  order to re-enable Tramp's file-name handling and completion.
+;;
+;;  Turning off `icicle-test-for-remote-files-flag' can slightly speed
+;;  up file-name completion for local files, by avoiding any check for
+;;  remote file names.  If you seldom use remote files, then you might
+;;  want to customize `icicle-test-for-remote-files-flag' to `nil' and
+;;  use `C-^' to toggle it back on whenever you do use remote files.
+;;
+;;  A `nil' value of `icicle-test-for-remote-files-flag' also
+;;  overrides the `icicle-highlight-input-completion-failure' values
+;;  `implicit-strict', and `explicit-strict' for file-name completion,
+;;  treating them the same as `implicit'.  It is assumed that you use
+;;  those values only to avoid the cost of remote file-name matching.
+ 
+;;(@* "Sorting Candidates and Removing Duplicates")
+;;
+;;  Sorting Candidates and Removing Duplicates
+;;  ------------------------------------------
+;;
+;;  By default, completion candidates are usually presented in buffer
+;;  `*Completions*' in alphabetic order.  But some commands use
+;;  different sort orders by default.  Whatever sort order is used for
+;;  `*Completions*' is also the order of cycling among candidates.
+;;
+;;  Also, duplicate candidates are typically removed as completion
+;;  choices, by default.  But for some commands duplicates are
+;;  appropriate, so they are not removed.  For example, command
+;;  `icicle-search' (`C-c `') uses completion to navigate among search
+;;  hits.  Duplicate search hits are retained.  Although some
+;;  search-hit candidates might have the same text, they are located
+;;  at different buffer positions.
+;;
+;;  You can interactively control the order of candidates and whether
+;;  duplicates are removed.  Use `C-,' during completion to choose a
+;;  different sort order or to turn off sorting altogether (one of the
+;;  available sort orders is in fact called "turned OFF").  Use `C-$'
+;;  to toggle the removal of duplicate candidates.  A few commands,
+;;  for which sorting is inappropriate, prevent you from sorting.
+;;
+;;  The available sort orders for `C-,' are those defined by user
+;;  option `icicle-sort-orders-alist' - see
+;;  (@> "Defining New Sort Orders"), below.  However, some commands
+;;  adjust this list of possibilities by adding command-relevant sort
+;;  orders or removing some that might be inappropriate.
+;;
+;;  The sort order generally remains as you last set it, for
+;;  subsequent commands.  However, if the last order you set is
+;;  inappropriate for the current command then sorting is turned off.
+;;  You can then use `C-,' to choose a sort order appropriate for the
+;;  current command.
+;;
+;;(@* "Changing the Sort Order")
+;;  ** Changing the Sort Order **
+;;
+;;  There are a couple of ways to use `C-,' (bound to command
+;;  `icicle-change-sort-order').  Its behavior depends on the value of
+;;  user option `icicle-change-sort-order-completion-flag', which is
+;;  `nil' by default.  This value means to simply cycle to the next
+;;  sort order each time you hit `C-,'.  A non-`nil' value means to
+;;  use completion to choose another sort order.  If you have many
+;;  available sort orders, then you might prefer a non-`nil' value.
+;;  In any case, you can also change this behavior on the fly: using
+;;  plain `C-u' (no number) with `C-,' reverses the meaning of
+;;  `icicle-change-sort-order-completion-flag' for `C-,'.
+;;
+;;  However, a numeric prefix argument, such as `C-9', means to simply
+;;  reverse the direction of the current sort order; it invokes
+;;  command `icicle-reverse-sort-order'.  For example, if candidates
+;;  are sorted alphabetically from A to Z, then `C-9 C-,' flips the
+;;  sort order, so that from then on sorting is from Z to A.  If
+;;  buffer names are sorted from small to large buffer size, then `C-9
+;;  C-,' sorts large buffers first.  This works for all sort orders.
+;;  The new sort order is echoed, so you can use this twice to just
+;;  remind yourself of the current sort order.
+;;
+;;  In addition to the current sort order, which is defined by the
+;;  value of user option `icicle-sort-comparer', an alternative sort
+;;  order is available at all times.  It is the value of option
+;;  `icicle-alternative-sort-comparer'.  By default, this sorts
+;;  candidates into two alphabetical groups: those previously used as
+;;  accepted input, followed by those not yet used.
+;;
+;;  Just as you can choose a different current sort order using `C-,',
+;;  so you can choose a different alternative sort order using `M-,'.
+;;
+;;  How do you actually use the alternative sort order?  Use `C-M-,'
+;;  (command `icicle-toggle-alternative-sorting') to swap the
+;;  alternative sort for the current sort.  This is the quickest way
+;;  to flip between two sort orders.  If, for example, you set your
+;;  alternative sort order to "turned OFF", then this is a quick way
+;;  to toggle sorting on and off.
+;;
+;;  The first time during a session that you use a command that
+;;  completes a buffer name or a file name, sorting changes to (that
+;;  is, `icicle-sort-comparer' is set to) whatever is specified by
+;;  user option `icicle-buffer-sort' or `icicle-file-sort',
+;;  respectively, provided the option is non-`nil'.  This gives you a
+;;  way to privilege a particular sorting method for each of these
+;;  kinds of completion.
+;;
+;;(@* "Defining New Sort Orders")
+;;  ** Defining New Sort Orders **
+;;
+;;  When you use `C-,' or `M-,', the sort orders that you can choose
+;;  from are those in user option `icicle-sort-orders-alist'.  You can
+;;  customize this option to add or remove available sort orders.  A
+;;  better way to define a new sort order is to use macro
+;;  `icicle-define-sort-command' in your Emacs init file (~/.emacs).
+;;  This defines a new Icicles command, named `icicle-sort-ORDER',
+;;  where `ORDER' is the name of the new sort order.  The definition
+;;  of the "alphabetical" sort order provides an example:
+;;
+;;    (icicle-define-sort-command "alphabetical"
+;;                                icicle-case-string-less-p
+;;      "Sort completion candidates alphabetically.")
+;;
+;;  The first argument, "alphabetical", is a string naming the new
+;;  sort order.  When you change to this sort order, a message says
+;;  "Sorting is now alphabetical".  Whatever sort-order name you
+;;  provide is used in the message.
+;;
+;;  The second argument is the actual function used for sorting.  It
+;;  can be any function, including a lambda expression.  The function
+;;  takes two string arguments and returns non-`nil' if and only if
+;;  the first string sorts before (is "less than") the second.  In
+;;  this case, function `icicle-case-string-less-p' is used, which
+;;  compares its two arguments alphabetically (lexicographically).
+;;  The third argument is the doc string for the new sorting command.
+;;
+;;  The result of this definition is:
+;;
+;;  1. The creation of command `icicle-sort-alphabetical'.
+;;  2. The addition of an entry for the new sort order in option
+;;     `icicle-sort-orders-alist'.  The entry associates sort order
+;;     "alphabetical" with comparison function
+;;     `icicle-case-string-less-p'.
+;;
+;;  You can invoke the new sorting command any time using `M-x', but
+;;  you can also change to the new sort order using `C-,' (or `M-,')
+;;  during minibuffer completion.
+;;
+;;(@* "Different Sorts for Different Sorts of Uses")
+;;  ** Different Sorts for Different Sorts of Uses **
+;;
+;;  There are many different uses of completion in Emacs, and this
+;;  means that sorting candidates needs to be flexible - there cannot
+;;  be a single sort order, or even a single set of sort orders, that
+;;  is useful for all purposes.  Completion, and therefore also
+;;  sorting of completion candidates, needs to deal with different
+;;  types of candidates and different numbers of them, in different
+;;  contexts.
+;;
+;;  Icicles predefines many sort functions, and you can easily define
+;;  more of your own.  You can choose a different sort at any time, as
+;;  mentioned above.  A good sort order can be a big help, depending
+;;  on the context.  However, sorting is not free, and it can be
+;;  helpful to think for a moment about some of the consequences of
+;;  sorting, in terms of performance.
+;;
+;;  What does a sort function do?  It determines which of two strings
+;;  should come first, that is, which is "less than" the other.
+;;  During sorting, pairs of candidates are compared using the sort
+;;  function.  And each time you change your input by typing or
+;;  deleting a character, the new set of matching candidates is sorted
+;;  (if `icicle-incremental-completion-flag' is non-`nil').
+;;
+;;  The number of candidates to be sorted depends on the kind of
+;;  completion and how you use Icicles.  Some Icicles users like to
+;;  use cycling more and completion less, which means sorting more
+;;  candidates.  Other users favor using completion to narrow down the
+;;  number of matches (which I recommend).  Some commands typically
+;;  have few possible completion candidates; others have many.
+;;  Buffer-name completion, for example, typically involves relatively
+;;  few candidates, whereas file-name completion typically involves
+;;  many.
+;;
+;;  If there are many candidates matching your input, then many
+;;  comparisons will be made each time the candidate set is sorted.
+;;  This means that if your sort function is complex, response can be
+;;  slow.  A complex sort function might be OK for sorting a small or
+;;  medium set of candidates, but it might not be appropriate for
+;;  sorting a very large set.
+;;
+;;  Only you, as a user, can control which sort makes the best sense
+;;  for you in any given situation.  If you are likely to have
+;;  zillions of candidates in some context, then you probably will
+;;  want to change to a sort that computes quickly.  You can, of
+;;  course, even choose not to sort at all, but simple sort
+;;  comparisons do not noticeably impact performance, even for a very
+;;  large number of candidates.
+;;
+;;  Icicles could offer a threshold option similar to
+;;  `icicle-incremental-completion-threshold' (or it could reuse that
+;;  option), and not bother to sort if the number of candidates passed
+;;  the threshold, but there can be many sort orders of differing
+;;  complexity, so a set of thresholds would really be needed, perhaps
+;;  one per sort order.
+;;
+;;  Rather than having you try to manage such complexity ahead of time
+;;  using options, it's better to just let you manage it at completion
+;;  time: Choose the sort order with knowledge of the possible
+;;  candidate set.  For example, if the set of candidates to sort will
+;;  include every file on your file system, then you probably will
+;;  want to use a simple sort.  On the other hand, there are
+;;  situations where you might nevertheless prefer to wait a few
+;;  seconds, in order to perform a complex sort that is of particular
+;;  use.
+;;
+;;  In sum, Icicles keeps it simple, and leaves it up to you to choose
+;;  the appropriate sort order for any given context.  This design
+;;  choice is one reason why Icicles makes it easy to choose a sort
+;;  even while you are completing input - each act of completion is
+;;  different.
+;;
+;;  It can help you choose, however, to know which of the predefined
+;;  Icicles sort orders are more complex, and therefore tend to be
+;;  slower.  Here they are:
+;;
+;;    Sort Order                      Sort Function Used
+;;    ----------                      ------------------
+;;    by previous use alphabetically  `icicle-historical-alphabetic-p'
+;;    by last use                     `icicle-most-recent-first-p'
+;;
+;;  The reason these sorts are slower is that they check the current
+;;  minibuffer history, to see whether, and where, each candidate is
+;;  located in the history list.  If you, like I, have very long
+;;  history lists, then this can take a while.  I use histories of
+;;  virtually unlimited length - I let library `savehist-20+.el' save
+;;  all of my histories from one Emacs session to the next.
+;;
+;;  Here are some of the Icicles sort orders that exist by default:
+;;
+;;    - alphabetical - see
+;;      (@> "Putting Previous Candidates First: `C-M-,'")
+;;    - case-insensitive - (@> "Completion Status Indicators")
+;;    - by last use as input
+;;    - by previous use alphabetically - see
+;;      (@> "Putting Previous Candidates First: `C-M-,'")
+;;      by color name (colors) - see
+;;      (@file :file-name "icicles-doc2.el" :to "Candidates with Text Properties")
+;;      by hue (colors)
+;;      by purity/saturation (colors)
+;;      by brightness/value/luminance (colors)
+;;      by all HSV components, in order (colors)
+;;      by HSV distance from a base color (colors)
+;;      by amount of red (colors)
+;;      by amount of green (colors)
+;;      by amount of blue (colors)
+;;      by all RGB components, in order (colors)
+;;      by RGB distance from a base color (colors)
+;;   22 by key name, prefix keys first (keys)- see (@> "Completing Prefix Keys")
+;;   22 by key name, local bindings first (keys)- see
+;;      (@> "Local Bindings Are Highlighted")
+;;   22 by command name (commands)
+;;    - by abbrev frequency (commands) - see
+;;      (@> "Multi `M-x' Turns Every Command into a Multi-Command")
+;;      by buffer size (buffer names)
+;;      *...* buffers last (buffer names)
+;;      by major mode name (buffer names)
+;;   22 by mode-line mode name (buffer names)
+;;      by file/process name (buffer names)
+;;    - by last file modification time (file names) - see
+;;      (@> "Icicles Commands that Read File Names")
+;;    - by file type (extension) (file names)
+;;    - by directories first or last (file names)
+;;    - in book order (Info) - see
+;;      (@file :file-name "icicles-doc2.el" :to "Icicles Completion for Info")
+;;    - special candidates first - see
+;;      (@> "Local Bindings Are Highlighted"),
+;;      (@file :file-name "icicles-doc2.el" :to "Candidates with Text Properties"),
+;;      (@file :file-name "icicles-doc2.el" :to "Icicles OO: Object-Action Interaction")
+;;    - proxy candidates first - see (> "*Completions* Display")
+;;    - extra candidates first - see
+;;      (@file :file-name "icicles-doc2.el" :to "Global Filters")
+;;    - by second multi-completion part (multi-completions) - see
+;;      (@file :file-name "icicles-doc2.el" :to "Sorting Candidates by Their Second Part")
+;;    - turned OFF  (does not sort at all)
+;;
+;;  As you can see, some are appropriate for color-name completion,
+;;  some for buffer-name completion, and some for file-name
+;;  completion.  Some are general, appropriate for most kinds of
+;;  completion.
+;;
+;;  Those marked above with the label `22' can be used only with Emacs
+;;  22 or later.  Those marked with a hyphen (-) are defined using
+;;  `icicle-define-sort-command', so they correspond to explicit
+;;  commands whose doc you can examine.  The command names in this
+;;  case are `icicle-sort-' followed by the sort-order names (with
+;;  hyphens substituted for spaces) - for example,
+;;  `icicle-sort-by-directories-last' and `icicle-sort-turned-OFF'.
+;;
+;;(@* "Adding a Saved Sort Order")
+;;  ** Adding a Saved Sort Order **
+;;
+;;  There are many predefined sort orders (see
+;;  (@> "Different Sorts for Different Sorts of Uses")), and you can
+;;  define your own new sort orders (see
+;;  (@> "Defining New Sort Orders")).  This section is about a unique
+;;  Icicles feature that lets you combine any number of sort orders
+;;  interactively, melding them together.
+;;
+;;  You do this as follows:
+;;
+;;  1. Start with a given sort order (use `C-u C-,' to choose one).
+;;
+;;  2. Save the set of candidates you are interested in, using `C-M->'
+;;     (see (@> "Saving and Retrieving Completion Candidates")).  This
+;;     saves the candidates in their current order at the time of the
+;;     save: the saved order.
+;;
+;;  3. Choose a different sort order (e.g., use `C-u C-,').
+;;
+;;  4. Use `C-M-+' (`icicle-plus-saved-sort') to combine the two sort
+;;     orders, that is, the (new) current order and the saved order.
+;;
+;;  What `icicle-plus-saved-sort' does is sum, for each completion
+;;  candidate, its ranks (indexes) in the two sort orders, and then
+;;  reorder candidates based on the summed ranks.
+;;
+;;  For example, if a given candidate is the 4th candidate in the
+;;  current list of candidates, and it is the 7th candidate in the
+;;  saved list of candidates, then its combined sort rank is 4 + 7 =
+;;  11.  With a score of 11 it sorts after a candidate whose score is,
+;;  for example, 6, and before a candidate whose score is, for
+;;  example, 13.
+;;
+;;  The candidates are reordered according to the combined sort
+;;  orders, forming a new current order.
+;;
+;;  When you use `C-M-+' it does not matter what order the saved
+;;  candidates are in or what order you used to sort the current
+;;  candidates.  (But you will generally want to use the same set of
+;;  candidates.)  In particular, after using `C-M-+' the candidates
+;;  are typically in an order that corresponds to no predefined sort -
+;;  that's OK.
+;;
+;;  You can use `C-M-+' again if you like, to add in the saved sort
+;;  order again with the new current order.  This gives the saved
+;;  order more weight than the original current sort order.  Continued
+;;  repetition of `C-M-+' gives the saved sort order more and more
+;;  weight.  Eventually a fixed point is reached: `C-M-+' produces no
+;;  further change in the order.
+;;
+;;  For example, consider `icicle-read-color'.  With user option
+;;  `icicle-WYSIWYG-Completions-flag' non-`nil' (e.g. a string) it
+;;  lets you see the effect of `C-M-+' in a striking, graphical way.
+;;  However, to see the effect you will first want to use `S-pause'
+;;  (`icicle-toggle-highlight-saved-candidates') to turn off
+;;  highlighting of the saved candidates, since that highlighting
+;;  obscures the color highlighting.
+;;
+;;  Sorting by color hue shows essentially a single rainbow of
+;;  candidates in `*Completions*': pinks, followed by magentas,
+;;  purples, blues, cyans, greens, yellows, browns, reds, and grays.
+;;  Sorting by color brightness shows a single value gamut, the
+;;  brightest colors followed by dimmer and dimmer colors, down to the
+;;  dimmest (black).
+;;
+;;  Try `M-x icicle-read-color', sorting (`C-u C-,') first by hue.
+;;  Save the completion candidates (`C-M->').  Now sort by brightness
+;;  (`C-u C-,' again).  Now use `C-M-+' to add/merge the two sort
+;;  orders.  You now see essentially a series of rainbows, from
+;;  brighter to dimmer and dimmer.
+;;
+;;  Use `C-M-+' again, to give hue more prominence in the merged sort
+;;  order.  And again.  Keep hitting `C-M-+' until there is no more
+;;  apparent change in the sort order - at this point you are back to
+;;  a pure hue sort.
+;;
+;;  You can also at any time save the candidates again, saving the
+;;  latest order as the new sort order.  Then you can reorder the
+;;  current candidates using a different sort order (`C-,').  And then
+;;  use `C-M-+' again to merge in the newly saved order.  You can play
+;;  this way ad infinitem.
+;;
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Customization and General Tips")
+;;    for more about `icicle-buffer-sort' and other buffer-name
+;;    completion parameters.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Global Filters") for a
+;;    way to filter and sort the domain of discourse, that is, all
+;;    possible candidates, prior to any use of completion.
+ 
+;;(@* "Get Help on Candidates")
+;;
+;;  Get Help on Candidates
+;;  ----------------------
+;;
+;;  General Icicles help is available at any time during minibuffer
+;;  input, by hitting `C-?' (`icicle-minibuffer-help').  This section
+;;  is about specific help on individual completion candidates
+;;  instead.
+;;
+;;  When you cycle among candidates for input, help on the current
+;;  candidate is shown in the mode-line, provided user option
+;;  `icicle-help-in-mode-line-delay' is greater than zero.  This makes
+;;  it easy to see what each candidate means or does.  Similarly, this
+;;  help is shown whenever your input is completed entirely to one of
+;;  the candidates.  If you use library `lacarte.el', then mode-line
+;;  candidate help is even available for menu-item candidates.
+;;
+;;  Typically, this candidate mode-line help is the first line of the
+;;  candidate's doc string, but alternative help sources can be used
+;;  (and a doc string is not available for some kinds of candidates).
+;;
+;;  To see more help than what is shown in the mode-line, for each
+;;  candidate or any given candidate as you cycle, press and hold the
+;;  Control and Meta keys while using the vertical arrow keys, for
+;;  prefix completion, or the `prior' and `next' keys (often labeled
+;;  Page Up and Page Down), for apropos completion.  To show help on
+;;  any individual candidate, navigate to it (by cycling or using
+;;  completion), and hit `C-M-RET' - or press Control and Meta and
+;;  click it with `mouse-2' (`C-M-mouse-2') in buffer `*Completions*'.
+;;
+;;  For example, if you use standard command `switch-to-buffer' and
+;;  you cycle among candidate buffer names using `C-M-end' (prefix
+;;  completion), then the major and minor modes of each candidate
+;;  buffer are described in buffer `*Help*' as the buffer name appears
+;;  in the minibuffer.
+;;
+;;  By default, you need not use the Meta key for candidate help; the
+;;  same bindings work with just the Control key.  So, for example,
+;;  you can click `C-mouse-2' to get help on a candidate or use
+;;  `C-next' to cycle candidate help information.  However, Icicles
+;;  multi-commands often have a different use for these bindings that
+;;  do not include Meta.  It is only by default, when a multi-command
+;;  has not bound a more specific action to the plain Control
+;;  bindings, that you can use the sans-Meta bindings for help on
+;;  candidates.
+;;
+;;  For example, Icicles binds `M-x', `C-x b', and `C-x C-f' to
+;;  multi-commands that execute a command, switch to a buffer, and
+;;  open a file, respectively.  If you use only the Control key,
+;;  without the Meta key, when choosing candidates for these commands,
+;;  you will not get help on the candidates; instead, you will execute
+;;  a candidate command, switch to a candidate buffer, and open a
+;;  candidate file, respectively.  For more information, see
+;;  (@> "Multi-Commands").
+;;
+;;(@* "Use Candidate Help Like You Use Emacs Command `apropos'")
+;;  ** Use Candidate Help Like You Use Emacs Command `apropos' **
+;;
+;;  You can use this candidate-help functionality as a kind of
+;;  expanded `apropos' functionality.  As an example, type `C-h v
+;;  out', then type `S-TAB' to display all variables that match "out"
+;;  (in buffer `*Completions*').  Then use `C-M-next' repeatedly to
+;;  cycle among those variables, displaying their documentation in the
+;;  `*Help*' buffer as they appear one by one in the minibuffer.  Or
+;;  click individual variable names with `C-M-mouse-2', to display
+;;  their documentation.
+;;
+;;  The standard `apropos' commands show only the first doc-string
+;;  line.  Icicles shows that automatically in the mode-line, and it
+;;  shows the complete doc string on demand when you use `C-M-'.  This
+;;  can be handy, for instance, when you are unsure which of several
+;;  similarly named candidates to choose.  Seeing a candidate's
+;;  documentation along with its name can help you decide.
+;;
+;;  You can click links in buffer `*Help*' to look up more info, and
+;;  then resume `C-M-next' where you left off, all without leaving
+;;  completion.
+;;
+;;  This also works with menu items, if you load library `lacarte.el'
+;;  as well as Icicles.  As you cycle among matching menu items, the
+;;  corresponding command documentation is displayed in `*Help*'.
+;;
+;;  If you also use library `help-fns+.el' (Emacs 22 or later) or
+;;  library `help+.el' (or `help+20.el' for Emacs 20), then you can
+;;  use these Icicles features with additional help commands such as
+;;  `describe-file' (`C-h M-f'), `describe-keymap' (`C-h M-k'),
+;;  `describe-command' (`C-h C-c'), `describe-option' (`C-h o'), and
+;;  `describe-option-of-type'.
+;;
+;;  `C-h C-o', which is bound by those libraries to command
+;;  `describe-option-of-type', is bound in Icicle mode to
+;;  `icicle-describe-option-of-type' instead, which uses
+;;  multi-completion and is therefore more powerful.
+;;  See (@file :file-name "icicles-doc2.el" :to "Multi-Completions").
+;;  `C-h C-o' describes a user option that is of a particular custom
+;;  type: you match the type and the option name at the same time.
+;;
+;;  As an example, try `C-h C-o ici C-M-j string S-TAB' (`C-M-j' just
+;;  separates the option name and type parts).  In buffer
+;;  `*Completions*', you see all options whose name contains `ici' and
+;;  whose type (or an inherited type) definition contains `string'.
+;;  That means not only options that are strings, but options that are
+;;  lists that contain string elements, options that can be a string
+;;  or something else, and so on.
+;;
+;;  Browse the doc for these options, one after the other, using
+;;  `C-M-next'.  This is a way to see, at the same time, the
+;;  documentation for individual options (in buffer `*Help*') and the
+;;  types their values must satisfy (in `*Completions*').
+;;
+;;  And remember that you can leave the option-name part or the type
+;;  part empty, to see all options of a certain type or options of all
+;;  types with a certain name pattern.  For example, `C-h C-o .* C-M-j
+;;  string S-TAB' or `C-h C-o ici S-TAB'.
+;;
+;;  And you can of course use progressive completion as well, to
+;;  match, say, a type that has a `string' component and an `integer'
+;;  component - or whatever.  The type part of a completion candidate
+;;  is an entire `defcustom' type, so its `:tag' values are also
+;;  included.  This means that you can also match against the
+;;  descriptive text (tag) that appears next to a value component in
+;;  Customize.
+;;
+;;  `C-h C-o' is a powerful way to browse options and their
+;;  documentation.  See the doc string of
+;;  `icicle-describe-option-of-type' for more possibilities.
+;;
+;;  Candidate help (prefix `C-M-') is available for these types of
+;;  completion candidates, by default:
+;;
+;;  * menu items
+;;  * commands and other functions
+;;  * keymap variables (if `describe-keymap' is defined - see
+;;    library `help-fns+.el')
+;;  * user options and other variables
+;;  * faces
+;;  * fonts (mode-line help only)
+;;  * command abbreviations (using `apropos-command' for matches)
+;;  * property lists
+;;  * buffers
+;;  * files
+;;
+;;  Starting with Emacs 22, if the candidate names an image file and
+;;  you have command-line tool `exiftool' installed and in your
+;;  `$PATH' or `exec-path', then EXIF information (metadata) about the
+;;  image is included.  See standard Emacs library `image-dired.el'
+;;  for more information about `exiftool'.
+;;
+;;  If the same candidate names a function, a variable, and a face, or
+;;  any two of these, then all such documentation is shown (Emacs 22
+;;  and later).
+;;
+;;  In addition to the candidate types listed above, any command that
+;;  uses completion can define its own candidate help action function
+;;  and bind it to `icicle-candidate-help-fn'.
+;;
+;;  A command can also provide its own mode-line and tooltip help for
+;;  any individual candidate.  See
+;;  (@file :file-name "icicles-doc2.el" :to "Applying Text Properties to a Candidate String").
+;;
+;;  For more information about the types of candidates and their
+;;  associated documentation, see the documentation for command
+;;  `icicle-help-on-candidate'.  This command is bound to `C-M-RET',
+;;  `C-M-mouse-2', `C-help', `C-M-help', `C-f1', and `C-M-f1'.  When
+;;  no specific action is defined for candidates, it is also bound to
+;;  `C-RET' and `C-mouse-2'.  You can use this to get help on any
+;;  completion candidate during completion.  See also the related
+;;  help-cycling commands, `icicle-next-candidate-per-mode-help',
+;;  `icicle-help-on-next-apropos-candidate', and so on, bound to
+;;  `C-M-down', `C-M-up', `C-M-next', `C-M-prior', `C-M-end', and
+;;  `C-M-home'.
+;;
+;;  If you use one-buffer-per-frame (`pop-up-frames' non-`nil'), then
+;;  displaying `*Help*' in one frame might interfere with viewing
+;;  `*Completions*' in another.  For that reason, the `*Completions*'
+;;  frame is raised to the front.  Also, if user option
+;;  `icicle-move-Completions-frame' is non-`nil' then the
+;;  `*Completions*' frame is moved to the edge of the display, out of
+;;  the way, whenever you access help on a candidate.  (Default value:
+;;  `right', meaning move it to the right).
+;; 
+;;
+;;(@* "Other Icicles Apropos Commands")
+;;  ** Other Icicles Apropos Commands **
+;;
+;;  There are also Icicles replacements for the standard Emacs
+;;  `apropos' commands.  They act similarly, but they also let you see
+;;  the list of regexp matches incrementally (as with all Icicles
+;;  commands), using `S-TAB'.  If you also use my library
+;;  `apropos-fn+var.el', then these Icicles commands take advantage of
+;;  the apropos enhancements in that library.
+;;
+;;  The Icicles apropos commands are: `icicle-apropos',
+;;  `icicle-apropos-command', `icicle-apropos-function',
+;;  `icicle-apropos-option', `icicle-apropos-variable', and
+;;  `icicle-apropos-zippy'.
+;;
+;;  Another feature of these Icicles commands is that when more than
+;;  one type of object can be a candidate, candidates of a certain
+;;  type are shown in buffer `*Completions*' using face
+;;  `icicle-special-candidate'.  For example, command `icicle-apropos'
+;;  shows function names as special candidates, to help you
+;;  distinguish them from variable names.
+;;
+;;  In addition, Icicles commands `icicle-doc', `icicle-fundoc', and
+;;  `icicle-vardoc' provide the functionality of standard Emacs
+;;  command `apropos-documentation', but with additional features -
+;;  see (@file :file-name "icicles-doc2.el" :to "Multi-Completions").
+;;  In addition, you can use command `icicle-plist' to find symbols
+;;  with certain property-list keys and values, and you can use
+;;  command `icicle-describe-option-of-type' (bound to `C-h C-o') to
+;;  find user options of a certain type.
+;;
+;;  Command `icicle-customize-apropos-options-of-type' is similar to
+;;  `icicle-describe-option-of-type', in that it lets you specify the
+;;  type of matching options.  But instead of describing an option, it
+;;  opens Customize for all options of the specified type that match
+;;  your input regexp.  (Unlike `icicle-describe-option-of-type',
+;;  however, it is not a multi-completion command: you first specify
+;;  the type, then the regexp to match.)
+;;
+;;  One difference between Icicles apropos commands and the standard
+;;  commands, besides the Icicles enhancements already described, is
+;;  that (starting with Emacs 22) the standard commands let you input
+;;  a set of keywords, as an alternative to inputting a regexp.
+;;  Icicles apropos commands do not allow for keyword input, as such.
+;;  However, Icicles progressive completion provides a more powerful
+;;  way to search with multiple keywords (in fact, multiple regexps) -
+;;  you can of course use it with the Icicles apropos commands.  Also,
+;;  there are several problems with the standard Emacs apropos
+;;  commands, with respect to interpreting your input as either a set
+;;  of keywords or a regexp.  Because they allow two very different
+;;  syntaxes as input, the standard apropos commands are forced to
+;;  make some limiting compromises for keyword searching.
+;;
+;;  See Also: (@> "Progressive Completion").
+ 
+;;(@* "Multi-Commands")
+;;
+;;  Multi-Commands
+;;  --------------
+;;
+;;(@* "What Is a Multi-Command?")
+;;  ** What Is a Multi-Command? **
+;;
+;;  A multi-command is a command that lets you make multiple input
+;;  choices in a single command execution: a multiple-choice command.
+;;  You can choose multiple items from a set of choices, using buffer
+;;  `*Completions*' as a multiple-choice "menu".  (It's not necessary
+;;  to display `*Completions*', however.)  Instead of asking you
+;;  "Which file do you want to delete?", a multi-command asks you, in
+;;  effect, "Which file(S) do you want to delete?".
+;;
+;;  Nothing especially new here.  Any Emacs command could be defined
+;;  to use an input loop, asking for file names until you do something
+;;  to signal that you're done inputting.  It could provide for
+;;  file-name completion by calling `read-file-name' to read your
+;;  input.
+;;
+;;  * But what if you could also filter the domain of discourse on the
+;;    fly, so that the candidate files were only those matching a
+;;    regular expression (regexp) that you typed? Then, the command
+;;    definition would need to provide for that behavior too.
+;;
+;;  * And what if you could then take the complement of that set of
+;;    candidate file names, with respect to the complete set of files
+;;    in the directory? Or subtract (exclude) some set of file names
+;;    from the set of matching names, to get the set of possible
+;;    choices?
+;;
+;;  * And what if the set of potential candidates at each step (regexp
+;;    match, complement, set difference) could also be displayed in a
+;;    multiple-choice menu?
+;;
+;;  For such multi-command functionality you need Icicles.
+;;
+;;  You can tell whether a command is a multi-command when you execute
+;;  it: if it is a multi-command, then the prompt is prefixed by `+'.
+;;  For example, multi-command `icicle-file' uses this prompt:
+;;
+;;    + File or directory:
+;;
+;;  Normal, non multi-command `find-file' uses this prompt, which has
+;;  no `+':
+;;
+;;    Find file:
+;;
+;;  Just remember that `+' means that you can choose any number of
+;;  inputs.  For a list of predefined Icicles multi-commands, use
+;;  `C-?' (`icicle-minibuffer-help') in the minibuffer - search for
+;;  `+' at the beginning of a line.
+;;
+;;(@* "How Does a Multi-Command Work?")
+;;  ** How Does a Multi-Command Work? **
+;;
+;;  When an Icicles multi-command prompts you for input, you can make
+;;  a single choice and press `RET' to confirm it, as usual, or you
+;;  can choose any number of completion candidates, using `C-RET' (or
+;;  `C-mouse-2') for each.  You can thus act on multiple candidates,
+;;  or even multiple times on the same candidate, during the same
+;;  execution of the command.
+;;
+;;  But you do not have to - you can use any multi-command just as if
+;;  it were a normal, single-choice command.
+;;
+;;  For example, command `icicle-delete-file' lets you delete a single
+;;  file or a set of files that match your minibuffer input - all in
+;;  the same command execution.  If you type no input, then all files
+;;  in the current directory match, and you can delete any number of
+;;  them individually.  If you type `~$' and hit `S-TAB'
+;;  (`icicle-apropos-complete'), then all files that end in `~' match,
+;;  and you can delete any number of them.  Similarly, command
+;;  `icicle-buffer-other-window' lets you display any number of
+;;  buffers, and so on.
+;;
+;;  You make multiple choices this way by cycling through the
+;;  candidate completions, as usual, and hitting `C-RET' whenever you
+;;  want to choose (act on) the current cycle candidate.  Or just
+;;  press and hold Control while clicking each chosen candidate with
+;;  `mouse-2'.
+;;
+;;  Similarly, you can use `C-down', `C-up', `C-next', `C-prior',
+;;  `C-end', or `C-home' to act on successive candidates, forward or
+;;  backward.  You can thus just hold down the Control key while
+;;  cycling, to act on each candidate in turn, if you want.
+;;
+;;  Instead of, or in addition to, cycling, you can use completion to
+;;  get to a particular candidate you want.  No matter how a candidate
+;;  is made current, you can choose the current candidate (perform the
+;;  action on it) using `C-RET' or `C-mouse-2'.
+;;
+;;  For lax (permissive) completion, you can use `C-RET' to act on
+;;  *any* input text - you need not choose one of the available
+;;  candidates.  This means, for example, that you can create any
+;;  number of new file buffers with a single `C-x C-f' invocation, as
+;;  well as open any number of existing files.
+;;
+;;  As always, hitting `RET' (or `S-RET') ends the command.  For most
+;;  multi-commands, hitting `RET' performs the same action as `C-RET',
+;;  but it is possible to have a command that acts differently for
+;;  `RET' and `C-RET'.  That is the case, for instance, when help is
+;;  displayed via `C-RET'.
+;;
+;;  You can use `C-RET' or `C-mouse-2' repeatedly to act multiple
+;;  times on the same candidate.  A shortcut is to use `C-u' with
+;;  `C-RET' or `C-mouse-2'.  That will work if the candidate action
+;;  function is designed to be `C-u' sensitive.  This is the case for
+;;  the Icicles multi-commands that read the name of a command or
+;;  keyboard macro and execute the command or macro:
+;;  `icicle-execute-extended-command' (`M-x'), `icicle-kmacro'
+;;  (`S-f4'), and `icicle-execute-named-keyboard-macro' (`C-x M-e').
+;;
+;;  So, for example, if you use `C-u 10 C-RET' on command
+;;  `forward-char' during `M-x' command completion, the cursor
+;;  advances 10 characters.  Another example: `C-x M-e C-u 200 C-RET'
+;;  on a keyboard-macro candidate `foo' executes `foo' 200 times.  You
+;;  can use all of the numeric prefix argument shortcuts, such as
+;;  `M--', `M-7', and `C-6', with the exception of `C--', which has a
+;;  different meaning (`icicle-candidate-set-difference') in the
+;;  Icicles minibuffer.
+;;
+;;  Note that you can supply a prefix argument for both the
+;;  multi-command and any of its individual actions.  The command is
+;;  free to interpret these differently.  For example, a prefix arg
+;;  for `icicle-kmacro' provides a default repeat factor, which can
+;;  then be overridden for any individual action by providing a
+;;  different prefix arg.  As another example, a prefix arg used with
+;;  any file-name candidate for command `icicle-find-file' visits the
+;;  file in read-only mode.  But a prefix arg for the command itself
+;;  reverses this effect: read-only becomes the default so that a
+;;  prefix arg for a candidate means visit not read-only.
+;;
+;;  If user option `icicle-use-candidates-only-once-flag' is
+;;  non-`nil', then, when you act on a candidate, it is removed from
+;;  the list of available candidates, for clarity.  Commands where
+;;  this behavior is appropriate bind this option to a non-`nil'
+;;  value.  This is a user option, but you normally will not customize
+;;  it.
+;;
+;;  You can use `C-g' to exit a multi-command at any time, without
+;;  making a final choice using `RET'.  If the actions performed by a
+;;  multi-command are easily reversible, `C-g' will often restore
+;;  things to the way they were before performing the actions.
+;;
+;;  Does this `C-RET' stuff sound familiar?  Using a multi-command is
+;;  similar to accessing help on a candidate
+;;  (see (@> "Get Help on Candidates")).  A multi-command is any
+;;  command that has a special action defined for use with `C-RET'
+;;  (command `icicle-candidate-action') on the current cycle
+;;  candidate.  If no such special action is defined, then help on the
+;;  candidate is displayed - displaying help is just the default
+;;  action for `C-RET', used when no other action is defined.  You can
+;;  always access candidate help using the `C-M-' prefix: `C-M-help',
+;;  `C-M-f1', `C-M-RET', `C-M-mouse-2', `C-M-down', `C-M-up',
+;;  `C-M-next', `C-M-prior', `C-M-end', and `C-M-home'.
+;;
+;;  You can also cycle among elements of a set, performing actions, if
+;;  you use my libraries `doremi.el', `doremi-cmd.el', and
+;;  `doremi-frm.el'.  Like Icicles, Do Re Mi lets you see the effect
+;;  of a choice immediately, whenever you make changes.  Each library
+;;  has its own advantages and special uses.  Advantages of Icicles
+;;  include:
+;;
+;;    - completion to candidate values
+;;    - restoration after making changes, letting you preview changes
+;;      without actually applying them
+;;
+;;  See Also:
+;;
+;;  * (@> "More about Multi-Commands") for more about using
+;;    multi-commands.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Defining Icicles Commands (Including Multi-Commands)")
+;;    for how to define your own multi-commands.
+;;
+;;  * (@> "Moving Between the Minibuffer and Other Buffers").
+ 
+;;(@* "More about Multi-Commands")
+;;
+;;  More about Multi-Commands
+;;  -------------------------
+;;
+;;  A multi-command is any command that uses input completion and lets
+;;  you perform actions on any number of individual completion
+;;  candidates without exiting completion.
+;;
+;;  The default action is invoked on the current candidate by `C-RET'
+;;  (`icicle-candidate-action').  There are three other kinds of
+;;  actions on individual candidates:
+;;
+;;  * alternative actions, invoked by `C-S-RET'
+;;  * deletion actions, invoked by `S-delete'
+;;  * help actions, invoked by `C-M-RET'
+;;
+;;  A given command can define any combination of these four kinds of
+;;  actions: none of them, any one of them, any two of them, any three
+;;  of them, or all four kinds.
+;;
+;;  This section provides information about alternative actions and
+;;  deletion actions.
+;;
+;;  See Also:
+;;
+;;  * (@> "Get Help on Candidates") for information about using
+;;    candidate help.
+;;  * (@file :file-name "icicles-doc2.el" :to "Defining Multi-Commands the Hard Way")
+;;    for information about defining a custom candidate-help action
+;;    for a command.
+;;
+;;(@* "Alternative Actions")
+;;  ** Alternative Actions **
+;;
+;;  Just as you can use `C-RET', `C-mouse-2', `C-next', and so on to
+;;  invoke a command's default action on multiple completion
+;;  candidates individually, so you can use `C-S-RET'
+;;  (`icicle-candidate-alt-action'), `C-S-mouse-2', `C-S-next', and so
+;;  on to invoke an alternative action that is associated with the
+;;  command.  If the main action of a command `my-find-file' is to
+;;  visit a file, and the alternative action is to print a file, then
+;;  you can use `C-S-RET' to print one or more files on the fly, even
+;;  as you are completing the name of a file to be visited.
+;;
+;;  Keys `C-|' and `M-|' apply the alternative action defined for a
+;;  given multi-command to *all* matching candidates at once, in the
+;;  same way that `C-!' and `M-!' apply the main action defined for it
+;;  to all candidates.  For example, in Icicles search (e.g. `C-c `'),
+;;  the alternative action (e.g. `C-S-RET') replaces all or part of
+;;  the current search hit, and `M-|' does the same for all search
+;;  hits.
+;;
+;;  It is the particular command that defines its alternative action.
+;;  Some commands define no such action.  Some commands, as their
+;;  alternative action, prompt you to choose (using completion) a
+;;  function to be applied to the current completion candidate.  In
+;;  this case, a single alternative action effectively provides a set
+;;  of possible actions.
+;;
+;;  To achieve this, such commands use the value of user option
+;;  `icicle-type-actions-alist', which associates lists of possible
+;;  functions with specific candidate types.  For example, for
+;;  file-name candidates, you can choose among functions that act on
+;;  file names.
+;;
+;;  Choosing such a function to apply is itself a multi-command
+;;  operation.  You can thus apply any number of functions to any
+;;  number of candidates.
+;;
+;;  For example, while you are using `C-x C-f', you can, say, print
+;;  one or more candidate files on the fly, or invoke a shell command
+;;  on selected files, or byte-compile them...  This is a particularly
+;;  handy feature, especially if you customize
+;;  `icicle-type-actions-alist' for your own particular use.
+;;
+;;  Some such functions you can choose produce no side effect; they
+;;  simply return a value.  But if you use `C-u' before `C-S-RET',
+;;  then the result of applying the function is pretty-printed (in the
+;;  echo area or buffer `*Pp Eval Output*').  For example, if you use
+;;  `C-x C-f', you hit `C-u C-S-RET' on the candidate file name
+;;  `icicles-doc1.el', and you choose the function candidate
+;;  `file-attributes' at the completion prompt `How (action): ', then
+;;  the properties of the candidate file (`icicles-doc1.el') are
+;;  displayed.  With just `C-S-RET' (no prefix arg), the list of
+;;  properties is computed, but not displayed.
+;;
+;;  Be aware of this gotcha: The alternative action for commands that
+;;  use `icicle-type-actions-alist' prompts for a function.  If you
+;;  want to apply that function to all current completion candidates,
+;;  then you must use `M-|', not `C-|', because `C-|' prompts you for
+;;  each candidate.  `M-|' is designed to do the right thing here: it
+;;  prompts you once for the function to apply, and then applies it to
+;;  each of the current candidates.  Andyou can filter the set of
+;;  current candidates (progressive completion and so on), or retrieve
+;;  a saved set of candidates to operate on.
+;;
+;;  Note that completion while you choose a function to apply is lax.
+;;  This means that you can really enter any function, including a
+;;  lambda expression that you invent on the fly.  Of course, the
+;;  function must accept an object of the appropriate type, (but it
+;;  need not actually use that argument).
+;;
+;;  Using a lambda expression here is a good way to curry a function
+;;  that requires multiple arguments, so that it adapts to expect just
+;;  a single argument of the appropriate object type.  For example,
+;;  (lambda (sym-name) (get (intern (sym-name)) 'invisible))
+;;  transforms function `get', which takes a symbol and a property as
+;;  arguments, to a function that takes a symbol name and looks up the
+;;  `invisible' property of the symbol.
+;;
+;;  Option `icicle-type-actions-alist' is predefined with a number of
+;;  candidate types (buffer, color, command, face, file, frame,
+;;  function, option, process, variable, and window) and their
+;;  associated action functions, but you can add new types or modify
+;;  their associated function lists.  Any Emacs-Lisp functions can be
+;;  used, including lambda expressions.  But each function must accept
+;;  a value of the appropriate type as its sole required argument
+;;  (additional, optional arguments are OK).
+;;
+;;  Sometimes, you might want to define your own alternative action
+;;  function for some command.  Do this if you always want the same
+;;  alternative action, and it is not the predefined one.  To do this,
+;;  just customize option `icicle-alternative-actions-alist'.  The
+;;  associations defined by this option always override any predefined
+;;  alternative actions for the corresponding commands.
+;;
+;;  An alternative to using option `icicle-alternative-actions-alist'
+;;  is to define a new command, wrapping an existing command with a
+;;  `let' binding that defines the action you want.  I recommend using
+;;  the option instead, but you might sometimes prefer this approach.
+;;  For example:
+;;
+;;  (defun my-icicle-find-file (f)
+;;    "`icicle-find-file', but with `w32-browser' as the alt action."
+;;    (interactive
+;;      (let ((icicle-candidate-alt-action-fn  'w32-browser))
+;;        (list (read-file-name "File: "))))
+;;    (icicle-find-file f))
+;;
+;;  If you are familiar with Icicles object-action commands (see
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles OO: Object-Action Interaction")),
+;;  then this idea of choosing an object (completion candidate) and
+;;  then choosing a function to act on it will ring a bell.  And just
+;;  as for the object-action commands, here too Icicles exploits any
+;;  object-action associations ("sources" and "types") defined by
+;;  library Anything (`anything.el'), if you happen to use that, in
+;;  addition to the associations defined by
+;;  `icicle-type-actions-alist'.  And when you do use the Icicles
+;;  object-action commands, the same behavior is available as for
+;;  alternative actions.
+;;
+;;  You might have noticed, above, that a type/actions association is
+;;  predefined for type `function'.  Since the actions you can choose
+;;  are themselves functions, you can even use `C-S-RET' on one of
+;;  them, to apply a function-for-functions (e.g. `find-function' or
+;;  `symbol-function') to it.  This is a curiosity, but it can
+;;  sometimes be useful.
+;;
+;;  Finally, note that the completion candidate to which you apply an
+;;  alternative action is in most cases a string.  In some cases, the
+;;  alternative action functions expect a non-string object, and they
+;;  will raise an error if applied to a string.
+;;
+;;  Icicles takes care of this in the case of buffer-name candidates.
+;;  It assumes that you really want to operate on a buffer, not its
+;;  name (a string), so it automatically calls `get-buffer' before
+;;  applying the alternative action function.
+;;
+;;  See Also:
+;;
+;;  * (@> "Perform Alternative Operations on the Fly")
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles OO: Object-Action Interaction")
+;;  * (@file :file-name "icicles-doc2.el" :to "Search and Replace")
+;;  * (@> "Choose All Completion Candidates")
+;;
+;;(@* "Deleting Objects")
+;;  ** Deleting Objects **
+;;
+;;  When it is defined for a particular command, minibuffer command
+;;  `icicle-delete-candidate-object', bound to `S-delete' (that's the
+;;  `delete' key, Shifted), deletes the object or objects named by the
+;;  completion candidate on which it operates.  (At least that is the
+;;  default behavior - if you customize `icicle-deletion-action-flag'
+;;  to `nil', then `S-delete' has no effect.)
+;;
+;;  Which objects are thus targeted by a given candidate (name) is
+;;  something that must be defined by the particular command.  The doc
+;;  string of a command should always indicate the effect of using
+;;  `S-delete', if a deletion action is defined.
+;;
+;;  As an example of a deletion action, Icicles command
+;;  `icicle-buffer-other-window', bound to `C-x 4 b', opens buffers
+;;  named by the individual candidates you act on, using `C-RET'.  But
+;;  it also lets you kill any buffer that you act on, using
+;;  `S-delete'.  This is not the alternative action for the command
+;;  (which is bound to `C-S-RET'); it is the deletion action.
+;;  Similarly, command `icicle-bookmark' jumps to a bookmark, but you
+;;  can also use `S-delete' with it to delete individual bookmarks.
+;;
+;;  When you use `S-delete' with a command that allows duplicate
+;;  candidate names that represent different candidate objects, it
+;;  deletes only the object associated with the current candidate
+;;  (name).
+;;
+;;  Some multi-commands define a deletion action, so that `S-delete'
+;;  works; some do not.  Consult the doc for any given command to see
+;;  if it does.  Whenever it is defined, the meaning of "delete"
+;;  depends on the particular command you use.
+;;
+;;  `S-delete' deletes only the objects named by the current
+;;  completion candidate.  However, with a prefix argument, it deletes
+;;  *ALL* objects named by the current set of completion candidates,
+;;  after you confirm that this is really what you want to do.  This
+;;  is a quick way to delete things whenever `S-delete' is available:
+;;  Use input patterns, with progressive completion, chipping away,
+;;  and so on, to define the candidates to delete, then use `C-u
+;;  S-delete' and confirm their deletion.  Bye-bye.
+;;
+;;  Do not confuse the unshifted `delete' key with `S-delete'.
+;;  `delete' does not delete any objects; it just removes a completion
+;;  candidate so that you cannot complete to it.  `S-delete' deletes
+;;  an object and removes its name as a completion candidate.
+;;
+;;  If you are an Emacs-Lisp programmer, then you can define your own
+;;  multi-commands that provide a deletion action via `S-delete'.
+;;  There are two ways to do this.  Both involve binding
+;;  `icicle-delete-candidate-object':
+;;
+;;  * Bind it to a deletion function.  The function must accept a
+;;    completion candidate string and perform the deletion.
+;;
+;;  * Bind it to a symbol (variable) whose value is a list of
+;;    completion-candidate objects.  The entries in the list must be
+;;    completion candidates for the current call to `completing-read',
+;;    but the list itself need not be the COLLECTION argument to
+;;    `completing-read'.  The list can be an alist, a list of strings,
+;;    or a list of symbols.  The object that corresponds to the
+;;    current candidate when `S-delete' is invoked is deleted from the
+;;    list.  If, in addition, the list variable is a user option, then
+;;    the updated list value is saved in the user's custom file.
+;;
+;;  For more information about using this feature in Emacs-Lisp code,
+;;  see the doc of function `icicle-delete-current-candidate-object'
+;;  (`S-delete') and variable `icicle-delete-candidate-object'.
+;;
+;;(@* "Option `icicle-use-C-for-actions-flag'")
+;;  ** Option `icicle-use-C-for-actions-flag' **
+;;
+;;  In some contexts, you end up using `C-next' more than `next', and
+;;  likewise for the other keys that combine candidate action and
+;;  cycling.  This is especially true for Icicles multi-commands that
+;;  act like a browser, such as `icicle-search', `icicle-imenu',
+;;  `icicle-find-tag', `icicle-Info-goto-node', and
+;;  `icicle-compilation-search'.  In these cases, you use the action
+;;  keys to navigate among the locations indicated by the completion
+;;  candidates.
+;;
+;;  If you set user option `icicle-use-C-for-actions-flag' to `nil',
+;;  then the keys that cycle are swapped with the keys that both cycle
+;;  and act on a candidate.  You can then use `down', `up', `next',
+;;  `prior', `end', and `home' to both cycle and act (e.g. navigate),
+;;  and `C-down', `C-up', `C-next', `C-prior', `C-end', and `C-home'
+;;  to merely cycle, without acting.  The option has no effect on
+;;  other keys.
+;;
+;;  You can toggle `icicle-use-C-for-actions-flag' at any time using
+;;  `M-g' (`icicle-toggle-C-for-actions') in the minibuffer.
+;;
+;;(@* "Accessing Saved Locations (Bookmarks) on the Fly")
+;;  ** Accessing Saved Locations (Bookmarks) on the Fly **
+;;
+;;  When you complete the names of some kinds of objects, you can use
+;;  `C-x m' to follow bookmarks to objects of that type.  This is
+;;  available only if you use library `bookmark+.el'.
+;;
+;;  For example, when you invoke a command that completes file names,
+;;  you can use `C-x m' to interrupt that operation and complete
+;;  against the names of file bookmarks.  This is a multi-command, so
+;;  you can actually visit any number of file bookmarks.  When
+;;  finished, you can continue with non-bookmark file-name completion.
+;;
+;;  The same thing holds for Info bookmarks when you use
+;;  `icicle-Info-goto-node' (`g' in Info mode); for buffer (non-file)
+;;  bookmarks when you use `icicle-buffer' (`C-x b'); and for Dired
+;;  bookmarks when you use `icicle-dired' (`C-x d').
+;;
+;;  See Also:
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Bookmark Enhancements")
+ 
+;;(@* "Icicles Tripping")
+;;
+;;  Tripping with Icicles
+;;  ---------------------
+;;
+;;  Among the more useful multi-commands are those whose actions take
+;;  you to some location indicated by the completion candidate.  This
+;;  is the way commands such as `icicle-bookmark', `icicle-find-tag',
+;;  `icicle-Info-goto-node', and `icicle-occur' work - you can use
+;;  `next' and so on to move among candidates to choose them to act
+;;  on, but when you do act on them, Icicles takes you to the places
+;;  they name.
+;;
+;;  So just holding down both the Control key and `next' takes you
+;;  from one place to the next.  And `C-mouse-2' takes you directly to
+;;  the location you click.  Typically, `C-g' aborts the trip and puts
+;;  you back at your starting point, and `RET' ends the trip at the
+;;  chosen destination.
+;;
+;;  There are many such Icicles tripping (or navigation or browsing)
+;;  commands, and they all work similarly.  They give you the normal
+;;  cycling behavior provided by vanilla Emacs commands such as
+;;  `find-tag' (via `M-.', `C-u M-.', `M-*' etc.) or
+;;  `set-mark-command' (via `C-u C-SPC').  But unlike the vanilla
+;;  Emacs commands, the keys for this cycling are always the same.
+;;
+;;  More importantly, you need not cycle through all possibilities.
+;;  You can go directly to particular locations with `C-RET',
+;;  `C-mouse-2' or using completion.  And your input filters the
+;;  available candidates, as always.  And you can, as always, use
+;;  progressive completion, chipping away, and so on to define your
+;;  `C-next' trip itinerary using a process of refinement.
+;;
+;;  Whereas vanilla Emacs gives you some commands that let you use
+;;  completion to enter a destination and go there, and it gives you
+;;  other commands that let you cycle among locations, Icicles rolls
+;;  all of that into one.  And you use the same keys, always, to
+;;  navigate.
+;;
+;;  Here are some of the Icicles tripping commands:
+;;
+;;  * Trips among tagged files (delicious-style tagging - requires
+;;    library `bookmark+.el').  (The `a' stands for "autofile".)
+;;    (Use prefix key `C-x 4 j' for other-window commands.)
+;;    `icicle-find-file-tagged'                  (`C-x j t a a')
+;;    `icicle-find-file-all-tags'                (`C-x j t a *')
+;;    `icicle-find-file-all-tags-regexp'         (`C-x j t a % *')
+;;    `icicle-find-file-some-tags'               (`C-x j t a +')
+;;    `icicle-find-file-some-tags-regexp'        (`C-x j t a % +')
+;;
+;;  * `icicle-bookmark-other-window' - (`C-- C-x r m')
+;;    Trip among bookmarks of all types.  (Also bound to `C-x 4 j j'
+;;    if library `bookmark+.el' is used.)
+;;
+;;  * Type-specific bookmark trips (requires library `bookmark+.el').
+;;    (Use prefix key `C-x 4 j' for other-window commands.)
+;;    `icicle-bookmark-non-file'                 (`C-x j b')
+;;    `icicle-bookmark-bookmark-list'            (`C-x j B')
+;;    `icicle-bookmark-dired'                    (`C-x j d')
+;;    `icicle-bookmark-file'                     (`C-x j f')
+;;    `icicle-bookmark-gnus'                     (`C-x j g')
+;;    `icicle-bookmark-info'                     (`C-x j i')
+;;    `icicle-bookmark-desktop'                  (`C-x j K')
+;;    `icicle-bookmark-local-file'               (`C-x j l')
+;;    `icicle-bookmark-man'                      (`C-x j m')
+;;    `icicle-bookmark-region'                   (`C-x j r',
+;;                                                `C-u C-x C-x')
+;;    `icicle-bookmark-remote-file'              (`C-x j n')
+;;    `icicle-bookmark-all-tags'                 (`C-x j t *')
+;;    `icicle-bookmark-some-tags'                (`C-x j t +')
+;;    `icicle-bookmark-all-tags-regexp'          (`C-x j t % *')
+;;    `icicle-bookmark-some-tags-regexp'         (`C-x j t % +')
+;;    `icicle-bookmark-file-all-tags'            (`C-x j t f *')
+;;    `icicle-bookmark-file-all-tags-regexp'     (`C-x j t f % *')
+;;    `icicle-bookmark-file-some-tags'           (`C-x j t f +')
+;;    `icicle-bookmark-file-some-tags-regexp'    (`C-x j t f % +')
+;;    `icicle-bookmark-url'                      (`C-x j u')
+;;    `icicle-bookmark-w3m'                      (`C-x j w')
+;;    `icicle-bookmark-this-buffer'              (`C-x j .')
+;;    `icicle-bookmark-specific-buffers'         (`C-x j = b')
+;;    `icicle-bookmark-specific-files'           (`C-x j = f')
+;;
+;;  * `icicle-buffer' (`C-x b')        - Trip among buffers
+;;  * `icicle-compilation-search' (`C-c `') - Trip among `grep' hits
+;;  * `icicle-dired'                   - Trip among directories
+;;  * `icicle-find-file' (`C-x C-f')   - Trip among files
+;;  * `icicle-find-file-absolute' (`C-u C-x C-f') - Trip among files
+;;  * `icicle-find-file-in-tags-table' - Trip among files listed in
+;;                                       current tags table (project)
+;;  * `icicle-find-file-read-only' (`C-x C-r') - Visit read-only
+;;  * `icicle-find-first-tag' (`C-x 4 .') - Trip among tag hits
+;;  * `icicle-find-tag' (`M-.')        - Trip among tag hits
+;;  * `icicle-goto-global-marker' (`C-- C-x C-SPC') - Trip among
+;;                                       global markers
+;;  * `icicle-goto-marker' (`C-- C-SPC') - Trip among local markers
+;;  * `icicle-imenu' (`C-c =')           - Trip among definitions
+;;    (`icicle-imenu-full' to search full definitions)
+;;
+;;  * Type-specific Imenu trips (library `imenu+.el' recommended).
+;;    (And `*-full' versions of each to search full definitions.)
+;;    `icicle-imenu-command'
+;;    `icicle-imenu-face'
+;;    `icicle-imenu-key-explicit-map'
+;;    `icicle-imenu-key-implicit-map'
+;;    `icicle-imenu-macro'
+;;    `icicle-imenu-non-interactive-function'
+;;    `icicle-imenu-user-option'
+;;    `icicle-imenu-variable'
+
+;;  * `icicle-Info-goto-node' (`g' in Info)- Trip among Info nodes
+;;  * `icicle-Info-index' (`i' in Info) - Trip among Info nodes
+;;  * `icicle-Info-menu' (`m' in Info) - Trip among Info nodes
+;;  * `icicle-locate-file'             - Trip among files
+;;  * `icicle-occur' (`C-c '')         - Trip among `occur' hits
+;;                                       (`icicle-search' among
+;;                                       single-line hits)
+;;  * `icicle-recent-file'             - Trip among recent files
+;;  * `icicle-search' (`C-c `')        - Trip among regexp search hits
+;;  * `icicle-search-bookmarks-together' (`C-u C-c `'),
+;;    `icicle-search-bookmark',        - Search multiple bookmarks
+;;  * Type-specific bookmark searches
+;;    `icicle-search-bookmark-list-bookmark' - Search bookmark lists
+;;    `icicle-search-dired-bookmark'   - Search Dired bookmarks
+;;    `icicle-search-file-bookmark'    - Search file bookmarks
+;;    `icicle-search-gnus-bookmark'    - Search Gnus bookmarks
+;;    `icicle-search-info-bookmark'    - Search Info bookmarks
+;;    `icicle-search-local-file-bookmark'- Search local-file bookmarks
+;;    `icicle-search-man-bookmark'     - Search `man'-page bookmarks
+;;    `icicle-search-non-file-bookmark' - Search non-file bookmarks
+;;    `icicle-search-region-bookmark'  - Search bookmarked regions
+;;    `icicle-search-remote-file-bookmark' - Search remote bookmarks
+;;    `icicle-search-url-bookmark'     - Search URL bookmarks
+;;  * `icicle-search-char-property'    - Trip among buffer strings with
+;;                                       with a text/overlay property
+;;  * `icicle-search-dired-marked'     - Search marked files in Dired
+;;  * `icicle-search-file'             - Search multiple files
+;;  * `icicle-search-ibuffer-marked'   - Search marked bufs in Ibuffer
+;;  * `icicle-search-keywords' (`C-c ^') - Trip among keyword search
+;;                                       hits.
+;;  * `icicle-search-overlay-property' - Trip among buffer strings
+;;    with some overlay property.
+;;  * `icicle-search-pages'            - Search Emacs pages
+;;  * `icicle-search-paragraphs'       - Search Emacs paragraphs
+;;  * `icicle-search-sentences'        - Search sentences as contexts
+;;  * `icicle-search-text-property' (`C-c "') - Trip among buffer
+;;                                       strings with a text property
+;;  * `icicle-search-thing'            - Search thing-at-point things
+;;  * `icicle-search-word' (`C-c $')   - Search whole-word hits
+;;  * `icicle-search-xml-element'      - Search XML elements
+;;  * `icicle-search-xml-element-text-node' - Search text of XML elts
+;;  * `icicle-select-frame' (`C-x 5 o') - Trip among frames, by name
+;;  * `icicle-select-window' (`C-0 C-x o') - Trip among windows, by
+;;                                       buffer name
+;;
+;;(@* "Highlighting the Destination")
+;;  ** Highlighting the Destination **
+;;
+;;  `icicle-bookmark-region-other-window' activates the bookmarked
+;;  region (highlighting it) when you visit it, if you use Transient
+;;  Mark mode (or, e.g., Delete Selection mode).
+;;
+;;  Starting with Emacs 22, most Icicles commands that have single
+;;  positions as their trip visits (e.g. `icicle-bookmark',
+;;  `icicle-Info-goto-node', `icicle-goto-marker', `icicle-find-tag')
+;;  highlight those positions temporarily as they are visited.  Except
+;;  for the Icicles search commands, this highlighting is provided by
+;;  library `crosshairs.el'.  If `crosshairs.el' and the libraries it
+;;  requires are not in your `load-path', then no such highlighting
+;;  occurs.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Commands that Read File Names") for information
+;;    about `icicle-find-file', `icicle-find-file-absolute',
+;;    `icicle-find-file-in-tags-table', `icicle-locate-file', and
+;;    `icicle-recent-file'.
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Enhancements for Emacs Tags")
+;;    for information about `icicle-find-first-tag' and
+;;    `icicle-find-tag'.
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Bookmark Enhancements")
+;;    for information about the bookmark browsing commands.
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Info Enhancements")
+;;    for information about `icicle-Info-goto-node',
+;;    `icicle-Info-index', and `icicle-Info-menu'.
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;    for information about `icicle-occur' and `icicle-search'.
+;;  * (@file :file-name "icicles-doc2.el" :to "Other Icicles Search Commands")
+;;    for information about `icicle-compilation-search',
+;;    `icicle-imenu*' commands, `icicle-search-char-property',
+;;    `icicle-search-keywords', `icicle-search-overlay-property', and
+;;    `icicle-search-text-property'.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Defining Icicles Tripping Commands")
+;;    for information about defining your own tripping commands.
+ 
+;;(@* "Key Completion")
+;;
+;;  Key Completion
+;;  --------------
+;;
+;;  Here's another weird Icicles feature: completing key sequences,
+;;  instead of commands.  (This feature works only for Emacs 22 and
+;;  later.)
+;;
+;;  What on earth for?  Ever want to use one of those myriad `C-x' key
+;;  sequences, but forget just what it was?  The standard solution to
+;;  that is to use `C-x C-h', to display all of the `C-x' bindings
+;;  together with their commands.
+;;
+;;  OK, but then you have to scroll down the list of bindings,
+;;  searching for the command you want, and then use its key binding.
+;;  You can use `C-M-s' to search for a substring of the command name,
+;;  in case you do not recall the exact name, but why not use Icicles
+;;  completion for this?  Why not match against possible key sequences
+;;  and commands?
+;;
+;;(@* "Completing Keys")
+;;  ** Completing Keys **
+;;
+;;  To complete keys in Icicles, start the key sequence as usual, and
+;;  then hit `S-TAB' (command `icicle-complete-keys').  For example,
+;;  use `C-x' or `C-x 4', and then hit `S-TAB' to complete the prefix
+;;  `C-x' or `C-x 4' (or whatever).  You're then completing against
+;;  candidates that are composed of two parts, separated by "  =  ":
+;;
+;;  * a key binding that completes what you've typed so far -
+;;    e.g. `C-j' (that is, `C-x C-j')
+;;
+;;  * the command it is bound to - e.g. `dired-jump-other-window'
+;;
+;;  So, for example, this is a single completion candidate:
+;;
+;;    C-j  =  dired-jump-other-window
+;;
+;;  You can match your minibuffer input against the key name, the
+;;  command name, or both.
+;;
+;;  Suppose, for instance, that you want to use a version-control
+;;  command, and you remember that all such commands are bound to key
+;;  sequences that begin with `C-x v'.  You enter as much of the key
+;;  sequence as you remember (`C-x v'), and then you hit `S-TAB'.  You
+;;  can then use completion (either apropos or prefix) against the
+;;  matching key sequences and command names to invoke the right
+;;  command.  And, as a bonus, you are reminded of its key sequence.
+;;  You can thus use Icicles key completion to execute a command and,
+;;  at the same time, learn its key binding.
+;;
+;;  (The documentation always refers to the key that performs key
+;;  completion as `S-TAB'.  Actually, it is `S-TAB' only by default.
+;;  You can customize it, using option `icicle-key-complete-keys'.)
+;;
+;;(@* "`S-TAB' Is Everywhere - Start With It")
+;;  ** `S-TAB' Is Everywhere - Start With It **
+;;
+;;  In Icicle mode, whenever you are not in the minibuffer or buffer
+;;  `*Completions*', key `S-TAB' initiates key completion.  That is,
+;;  you do not need to first type part of a key sequence to use it -
+;;  you can start with it.  Hit `S-TAB' at any time, and you're
+;;  completing a key sequence, even if you have not yet hit any keys.
+;;  This lets you see all key sequences that are available in a given
+;;  context.  For example, in Dired, keys special to that mode are
+;;  included (and are highlighted as local bindings -
+;;  see (@> "Local Bindings Are Highlighted")).
+;;
+;;  When completing a key sequence, you can type part of a command
+;;  name, then hit `S-TAB' to apropos-complete against the command
+;;  name.  In this respect, `S-TAB' acts like `M-x', but the key
+;;  binding is also part of the completion candidate, so you can also
+;;  match key names.
+;;
+;;(@* "Completing Keys By Name")
+;;  ** Completing Keys By Name **
+;;
+;;  So, just how do you complete input against a set of
+;;  binding-plus-command completion candidates?  You can always cycle
+;;  among the candidates, of course, and then choose one.  But what
+;;  about completion?  Just type text to match candidates, then use
+;;  `S-TAB' or `TAB' as usual to complete the text.  Text?  Yes.
+;;  Completion candidates are always, ultimately, strings.
+;;
+;;  Suppose that you type `C-x S-TAB' to show all key sequences that
+;;  begin with `C-x'.  You might see a candidate that looks like this:
+;;
+;;    C-q  =  toggle-read-only
+;;
+;;  You can then type "C-q" or "d-onl" or any other substring, and
+;;  then use `S-TAB' to complete the candidate.  (This second use of
+;;  `S-TAB' invokes the command `icicle-apropos-complete', which has
+;;  nothing to do with `icicle-complete-keys', which was invoked by
+;;  the first `S-TAB'.  The first was invoked outside the minibuffer;
+;;  the second was invoked from the minibuffer, during completion.)
+;;
+;;(@* "Completing Prefix Keys")
+;;  ** Completing Prefix Keys **
+;;
+;;  What happens if the completion candidate is itself a prefix key?
+;;  For example, `C-x S-TAB' shows some candidates whose commands are
+;;  shown as "...", like this:
+;;
+;;    4  =  ...      5  =  ...
+;;    6  =  ...      C-k  =  ...
+;;    ESC  =  ...    RET  =  ...
+;;
+;;  These represent prefix keys (`C-x 4', `C-x C-k', and so on).  If
+;;  you choose such a candidate, then you just continue completing -
+;;  buffer `*Completions*' is updated to show the completions of the
+;;  compound prefix: `C-x 4', `C-x RET', or whichever you choose.  The
+;;  minibuffer prompt shows the completion so far; if you choose
+;;  `RET', for instance, then it shows `C-x RET' while prompting you
+;;  for the rest of the key sequence.
+;;
+;;  By default, completion candidates are sorted in buffer
+;;  `*Completions*' with local bindings listed first.  You can use
+;;  `C-M-,' at any time during key completion to toggle between this
+;;  order and sorting with the prefix-key candidates shown first.  You
+;;  can use `C-,' at any time to change the sort order among these two
+;;  orders and sorting by command name.
+;;
+;;  Gotcha: Commands that are remapped do not show up with the
+;;  bindings you think they have.  For example, `C-x C-f' is bound to
+;;  `icicle-file' in Icicle mode, by default, but `C-x S-TAB' does not
+;;  include the completion candidate `C-f = icicle-file'.  Instead,
+;;  `S-TAB' at the top level (without first doing `C-x') shows a
+;;  (pseudo) prefix key `remap = ..', and if you follow that then
+;;  you'll see the candidate `find-file = icicle-file'.  The binding
+;;  of `C-x C-f' does not appear as such, because `find-file' is
+;;  remapped to command `icicle-file': whatever `find-file' was bound
+;;  to is indirectly bound to `icicle-file'. This indirection shows up
+;;  in Icicles key completion as (pseudo) prefix key `remap = ..'.
+;;
+;;(@* "Meta Key Bindings")
+;;  ** Meta Key Bindings **
+;;
+;;  If you use `S-TAB' at the top level, and you look for the key
+;;  sequence `M-x' or `M-d', you will not find it.  Meta key bindings
+;;  are there, but many of them are disguised as keys in the `ESC'
+;;  prefix keymap - e.g. `ESC x' for `M-x'.  That is, you must first
+;;  choose the `ESC` prefix key: `ESC = ...', and then choose the `x'
+;;  key or whatever.  That's just the way Emacs works.  So, yes, you
+;;  can use Icicles key completion to execute any Emacs command, even
+;;  one that is not bound to a key sequence, and you can use it to
+;;  evaluate any EmacsLisp expression.  See (@> "Three-Key Emacs").
+;;
+;;(@* "Navigate the Key-Binding Hierarchy")
+;;  ** Navigate the Key-Binding Hierarchy **
+;;
+;;  Choosing a completion candidate such as `C-x  =  ...' effectively
+;;  navigates down the key-binding hierachy (prefix-key hierarchy), to
+;;  complete against all keys with prefix `C-x'.  Choosing `5  =  ...'
+;;  to complete the prefix `C-x' then navigates down another level, to
+;;  complete keys that have prefix `C-x 5'.
+;;
+;;  What about navigating back up the hierarchy, say from the `C-x 5'
+;;  keys to the `C-x' keys, or from the `C-x' keys to the keys with no
+;;  prefix?  The special completion candidate `..' does that.  By
+;;  default, it is always the first candidate in the `*Completions*'
+;;  list.  It is of course not available unless you are completing a
+;;  prefix; that is, it is not available at the top level.
+;;
+;;  This feature means that you can navigate the key-binding hierachy
+;;  just as you would navigate the file-system hierarchy (using, say,
+;;  `C-x C-f') or the menu-bar hierarchy (using library `lacarte.el').
+;;  (In fact, since menu-bar bindings are also key bindings, you can
+;;  also use key completion to navigate the menu-bar hierarchy - just
+;;  complete the prefix key `menu-bar'!  Start with `S-TAB', choose
+;;  `menu-bar  =  ...', then choose a menu, and so on.)
+;;
+;;  Icicles key completion thus provides a general browser for key
+;;  bindings, which you can also use to learn about keys and their
+;;  associated comands, without necessarily executing them - see
+;;  (@> "Key and Command Help").
+;;
+;;  Gotcha: `S-TAB' uses apropos completion, by default, so remember
+;;  that typing `.' matches any character (except a newline).  To
+;;  match only the literal string `..' (to go up a level), do one of
+;;  the following:
+;;
+;;  * Turn on escaping of regexp special characters - use `C-`' in the
+;;    minibuffer to toggle this.
+;;
+;;  * Use prefix completion (`TAB').
+;;
+;;  * Escape the regexp special character explicitly: `\.\.' (or use
+;;    `^\.').
+;;
+;;  * Cycle to candidate `..'.
+;;
+;;(@* "Local Bindings Are Highlighted")
+;;  ** Local Bindings Are Highlighted **
+;;
+;;  Sometimes it helps to know which key sequences are local bindings,
+;;  that is, bindings that are specific to the current mode.  For
+;;  example, Dired mode defines keys specific to Dired buffer, such as
+;;  `* %', `% g', and `!'.  To help you distinguish local key bindings
+;;  from others (global and minor-mode bindings), local bindings are
+;;  highlighted in buffer `*Completions*' using face
+;;  `icicle-special-candidate'.
+;;
+;;(@* "Completing Keys By Just Hitting Them")
+;;  ** Completing Keys By Just Hitting Them **
+;;
+;;  It may seem odd that you must complete a key sequence by entering
+;;  the names of keys, rather than just hitting the keys themselves:
+;;  e.g. typing "C-f" rather than hitting `C-f'.  However, if keys
+;;  themselves were used for completing, then they could not be used
+;;  normally during key-sequence completion.  You could not move the
+;;  cursor around the minibuffer using `C-f' or `right' (right arrow),
+;;  because those keys would be treated as input for completion.  You
+;;  could not use `up' or `down' to cycle among completion candidates
+;;  for the same reason.  Likewise, you could not use printing
+;;  (self-inserting) keys, such as `a' and `$', to match command
+;;  names.  Having to use key names, instead of keys, for completion
+;;  is a small price to pay for being able to complete key sequences.
+;;
+;;  Nevertheless, Icicles also provides a way for you to type key
+;;  sequences directly, even if it is something of a workaround:
+;;  precede each key with `M-q' (`icicle-insert-key-description',
+;;  during key completion) - think of `q' for "quote".  This inserts
+;;  the key description of whatever key you hit next.  This key
+;;  description (name) can be used to match key-completion candidates.
+;;  So, for example, instead of typing "C-f", you can hit `M-q' and
+;;  then hit `C-f'.  The key description "C-f" is inserted in the
+;;  minibuffer.  If you use `M-q C-M-right', then "C-M-right" is
+;;  inserted.  Try it: `S-TAB M-q C-M-right' -> "C-M-right".  Then hit
+;;  `TAB' or `S-TAB' to complete the candidate all the way to this:
+;;
+;;    C-M-right  =  enlarge-frame-horizontally
+;;
+;;  Note: Whether or not angle brackets are used is governed by user
+;;  option `icicle-key-descriptions-use-<>-flag'.  By default, this is
+;;  `nil', so angle brackets are not used, which I think improves
+;;  readability.  If you set this to non-`nil', then you will see
+;;  "" instead of "C-M-right", both as a completion
+;;  candidate and as what is inserted when you use `M-q'.  You can
+;;  also provide a prefix argument to `M-q' to flip the behavior of
+;;  `icicle-key-descriptions-use-<>-flag' for that occurrence only.
+;;
+;;(@* "Key and Command Help")
+;;  ** Key and Command Help **
+;;
+;;  That points out another use of key completion, opposite to
+;;  learning the bindings of commands: learning the commands bound to
+;;  given keys.  In other words, `S-TAB M-q' does both what `C-h w'
+;;  (`where-is') does and what `C-h c' (`describe-key-briefly') does.
+;;  It also does what `C-h b' (`describe-bindings') does.
+;;
+;;  The point here is not that `S-TAB M-q' is quicker than `C-h w' or
+;;  `C-h c' or `C-h b' - it's not.  The point is that key completion
+;;  can be handy in several ways, and it can teach you various things
+;;  about keys and commands as you use it.
+;;
+;;  In addition to this key-completion help about bindings, you can
+;;  display help on the commands that are the right sides of the
+;;  `S-TAB' completion-candidate equations, by using the multi-command
+;;  help keys (see (@> "Help on Completion Candidates")).  That is,
+;;  while completing, you can use `C-M-mouse-2', `C-M-RET',
+;;  `C-M-next', and so on to describe the command named in the current
+;;  completion candidate.
+;;
+;;(@* "`S-TAB' Is a Multi-Command")
+;;  ** `S-TAB' Is a Multi-Command **
+;;
+;;  Yes, `S-TAB' as `icicle-complete-keys' is a multi-command - see
+;;  (@> "Multi-Commands")).  This means that you can, within the same
+;;  execution of `S-TAB', invoke any number of keys by clicking
+;;  (`C-mouse-2') their names in buffer `*Completions*' or choosing
+;;  them any other way (`C-RET', `C-next', and so on).
+;;
+;;  Since you can navigate up and down the key-binding hierarchy, you
+;;  could even stay within a single `S-TAB' invocation to do nearly
+;;  everything you want in Emacs (see (@> "Three-Key Emacs"))!
+;;
+;;(@* "Possible Source of Confusion")
+;;  ** Possible Source of Confusion **
+;;
+;;  Keep in mind that `S-TAB' has two different uses in Icicles when
+;;  you are providing input in the minibuffer:
+;;
+;;  * If input completion is available, then `S-TAB' performs apropos
+;;    completion (it is, in effect, bound to
+;;    `icicle-apropos-complete').
+;;
+;;  * If input completion is not available, then `S-TAB' performs key
+;;    completion (it is, in effect, bound to `icicle-complete-keys').
+;;
+;;  In addition, in buffer `*Completions*' `S-TAB' moves backward
+;;  among the candidate completions.
+;;
+;;  This is by design; it takes advantage of the fact that these
+;;  contexts are mutually exclusive.  However, this economy comes at a
+;;  risk of potential confusion.  It's important that you know whether
+;;  or not completion is available when you are inputting text.  If
+;;  input completion is not available, but you think it is, then
+;;  hitting `S-TAB' might give you a surprise by key completing.  That
+;;  behavior is normal - you can use key-completion to input special
+;;  characters, for instance.  But if you think that you are instead
+;;  completing the original input requested, then you can become
+;;  confused.
+;;
+;;  Icicles provides completion status indicators so that you can
+;;  easily tell when completion is available for minibuffer input.
+;;  There are two indicators: (1) at the beginning of the minibuffer
+;;  prompt and (2) in the `Icy' minor-mode lighter in the mode line.
+;;  See (@> "Completion Status Indicators").  If completion is not
+;;  indicated when you are prompted for input, it means that `S-TAB'
+;;  is available, not for input completion, but for key completion.
+;;  Another clue can be found in the prompt text.  For key completion,
+;;  it says "Complete keys: ".
+;;
+;;  If you nevertheless find the overloaded use of `S-TAB' confusing,
+;;  you can change the bindings of the key `S-TAB' in these different
+;;  contexts.  To do that, you can customize options
+;;  `icicle-apropos-complete-keys', `icicle-key-complete-keys', and
+;;  `icicle-previous-candidate-keys'.
+;;
+;;(@* "Three-Key Emacs")
+;;  ** Three-Key Emacs **
+;;
+;;  Icicles key completion piles a lot of stuff into `S-TAB'.  Just as
+;;  `M-x' lets you execute any Emacs command, so does `S-TAB'.  But
+;;  `S-TAB' also lets you insert characters.  With the exception of
+;;  inserting multi-byte characters, you might say that it gives you
+;;  all of Emacs in one key binding.
+;;
+;;  Of course, you need a couple other keys, as well.  How many?
+;;  Suppose you had limited accessibility in terms of input devices.
+;;  Maybe you use Emacs on a cell phone, without voice recognition -
+;;  or whatever.  How many keys, buttons, or whatnot do you need to
+;;  use Emacs?
+;;
+;;  1. You need one for `C-g', to interrupt commands.
+;;  2. You need one to start telling Emacs what to do.
+;;  3. You might need one to choose from a set of possible things to
+;;     do.
+;;  4. You need one to tell Emacs that you're done telling it what to
+;;     do.
+;;
+;;  (#2 and #3 might be combined somehow.)
+;;
+;;  What does vanilla Emacs offer out of the box in this regard?
+;;
+;;  * You can get by with just `mouse-1' and the menu-bar menus, but
+;;    they do not cover all of Emacs.  You cannot use them to enter
+;;    text, for instance.  Of course, you could add more menus, to be
+;;    able to do more.
+;;
+;;  * You can use `M-x' plus `RET' to execute any command.  But how
+;;    would you insert text?
+;;
+;;  * Similarly, for `M-:', which lets you evaluate any Emacs-Lisp
+;;    sexp.  You still need a way to type characters.
+;;
+;;  Icicles key completion lets you do almost anything in Emacs with
+;;  three or four keys, buttons, or whatever:
+;;
+;;  * `S-TAB' - Offers every key sequence as a possible choice to
+;;              execute.
+;;  * `next'  - Cycles among candidates, for choosing.
+;;  * `RET'   - Chooses the current candidate.
+;;  * And of course `C-g', to cancel the current operation.
+;;
+;;  `S-TAB' includes key `M-x (represented as prefix key `ESC'
+;;  followed by `x'), which offers all commands (even those not bound)
+;;  as possible choices.  It also includes key `M-:' (`ESC' followed
+;;  by `:'), which lets you execute any Emacs-Lisp expression.  That's
+;;  almost all of Emacs!
+;;
+;;  You could even perhaps get away with only three mouse buttons, and
+;;  no keyboard:
+;;
+;;  * `mouse-1' - Choose candidates, scroll, and so on (direct access,
+;;    no cycling).
+;;
+;;  * `mouse-2' - Do what `S-TAB' does (bind it to
+;;    `icicle-complete-keys' and `icicle-apropos-complete').
+;;
+;;  * `mouse-3' - Do what `C-g' does (bind it to `keyboard-quit' and
+;;    `icicle-abort-recursive-edit').
+;;
+;;  Here, `mouse-2' and `mouse-3' are not even used as mouse (pointer)
+;;  functions; any keys or buttons would do.  You could use just
+;;  `mouse-1' plus a Shift key and a Control key.
+;;
+;;  Would you want to use Emacs only this way?  Of course not, if you
+;;  had a choice.  Typing the character `a' by cycling through every
+;;  possible key binding/command combination and hitting `RET' when
+;;  you get to `a  =  self-insert-command' would be the epitome of
+;;  tedium.  Likewise, doing everything with a single pointer-device
+;;  button.  Using only three or four keys or buttons is definitely
+;;  not the ideal way to take advantage of Emacs.
+;;
+;;  But you are probably not limited to just 3 or 4 keys or buttons.
+;;  The real point here is that Icicles `S-TAB' opens the door to
+;;  almost everything in Emacs.  And if you do have a normal keyboard,
+;;  then you can type letters and such to match command names and key
+;;  sequences.  Key `next' matches substrings (regexps, actually),
+;;  which makes choice even quicker.
+;;
+;;(@* "Entering Special and Foreign Characters")
+;;  ** Entering Special and Foreign Characters **
+;;
+;;  Command `self-insert-command' is bound to each key that is
+;;  associated with a character that can be inserted in text.  It is
+;;  the binding of the key `a' and the key `$'.  It is also the
+;;  binding of keys that your keyboard might not even have - keys that
+;;  correspond to special or odd characters and characters in other
+;;  languages.
+;;
+;;  To Icicles key completion, these keys are like other keys.
+;;  However, because there are many, many keys bound to
+;;  `self-insert-command', it can be distracting and slow to allow
+;;  such keys as completion candidates.  If option
+;;  `icicle-complete-keys-self-insert-ranges' is `nil' (the default
+;;  value), then such keys are excluded as candidates.  This is
+;;  probably what you want, always.
+;;
+;;  If the option is non-`nil', then you can use key completion to
+;;  insert the characters whose codes are in the range(s) defined by
+;;  the option value.  This lets you see the candidate characters in
+;;  `*Completions*' (WYSIWYG), but it is not a terribly convenient or
+;;  quick way to insert characters.
+;;
+;;  Starting with Emacs 23, vanilla Emacs has Unicode support, and you
+;;  can insert any Unicode characters using either an input method or
+;;  command `ucs-insert', which lets you complete against the Unicode
+;;  character name.
+;;
+;;  If you do use a non-`nil' value for
+;;  `icicle-complete-keys-self-insert-ranges' then use only small
+;;  ranges for better performance, e.g., `((0 . 687))' covers Latin
+;;  characters.  For Emacs 22, the option is effectively Boolean: any
+;;  non-`nil' value allows all self-inserting keys as candidates
+;;  (there are far fewer available characters in Emacs 22).
+;;
+;;(@* "Handling Keymaps That Are Inaccessible From the Global Map")
+;;  ** Handling Keymaps That Are Inaccessible From the Global Map **
+;;
+;;  Actually, `S-TAB' is not bound to `icicle-complete-keys' in every
+;;  keymap.  That would be inconvenient, in general.  By default, it
+;;  is so bound in each keymap that is accessible from the global
+;;  keymap, as determined by function `accessible-keymaps'.
+;;
+;;  You've seen, above, how you can navigate through prefix keys,
+;;  starting with the global map.  In Dired, for instance, you can use
+;;  `S-TAB' at the top level, then choose the prefix key `*' in
+;;  `*Completions*', then choose a key, such as `/' (to mark
+;;  directories), in the `*' keymap.
+;;
+;;  However, the act of binding of `S-TAB' in keymaps that are
+;;  accessible from the global map does not bind it in the `*' prefix
+;;  keymap itself.  To handle this case, Icicles explicitly does for
+;;  `dired-mode-map' what it does for the global map: it binds `S-TAB'
+;;  in each keymap that is accessible from `dired-mode-map'.  Because
+;;  of this, you can use `* S-TAB' to show all key completions of `*'.
+;;
+;;  This treatment of `dired-mode-map' is done by default.  Similarly
+;;  for a few other keymaps.  But you might have other keymaps that
+;;  you would like to treat similarly - keymaps that Icicles might be
+;;  unaware of.  You do this by including them in the list value of
+;;  user option `icicle-keymaps-for-key-completion', along with
+;;  `dired-mode-map' and the others provided in the default value.
+;;  The list entries are Emacs-Lisp symbols that are bound to keymaps,
+;;  each of which should define at least one prefix key.  If you add a
+;;  keymap variable to this list, then `S-TAB' will be bound so that
+;;  you can use it to complete the prefix keys defined by that map.
+;;
+;;  Notice that there is no keymap variable that corresponds to prefix
+;;  key `*' in Dired mode.  You need only provide a keymap (variable
+;;  `dired-mode-map') from which the prefix key is accessible; it is
+;;  not necessary to also provide a variable that corresponds to the
+;;  prefix keymap itself.
+;;
+;;  If a keymap listed in `icicle-keymaps-for-key-completion' is not
+;;  defined when Icicle mode is entered, then it is ignored.  If you
+;;  later define that keymap, then just exit and reenter Icicle mode
+;;  for the `S-TAB' binding to take effect.  For example, use `M-x
+;;  icy-mode' twice after entering Calendar mode, to be able to
+;;  complete `calendar-mode' prefix keys such as `t' - `t S-TAB'.
+ 
+;;(@* "Icicles Multi `M-x'")
+;;
+;;  Icicles Multi `M-x'
+;;  -------------------
+;;
+;;  How about a multi-command replacement for `M-x'?  Instead of
+;;  executing a single command, it would execute any number of
+;;  commands.  This section describes two such multi-commands,
+;;  `icicle-execute-extended-command' and `icicle-command-abbrev',
+;;  which by default are bound in Icicle mode to `M-x' and `C-x SPC',
+;;  respectively.  See Also:
+;;  (@file :file-name "icicles-doc2.el" :to "Defining Icicles Multi `M-x'").
+;;
+;;(@* "Multi `M-x': `icicle-execute-extended-command'")
+;;  ** Multi `M-x': `icicle-execute-extended-command' **
+;;
+;;  When you use `M-x' in vanilla Emacs, you are actually executing
+;;  the standard Emacs command `execute-extended-command'.  That
+;;  command prompts you for the name of another command, which you
+;;  input.  It uses `completing-read' to do this, which is why you can
+;;  take advantage of Icicles features when you use `M-x'.  Nothing
+;;  new here.
+;;
+;;  Command `icicle-execute-extended-command' is simply a
+;;  multi-command version of `execute-extended-command'.  It does the
+;;  same thing, except that it also lets you execute multiple
+;;  commands, one by one, using `C-RET' (or `C-next' and so on),
+;;  without ever exiting the minibuffer.
+;;
+;;  With the default value of option `icicle-top-level-key-bindings',
+;;  `M-x' is bound to `icicle-execute-extended-command' whenever you
+;;  are in Icicle mode.  If you never use it as a multi-command, you
+;;  will not notice any difference from `execute-extended-command'.
+;;
+;;(@* "Examples of Using Multi `M-x'")
+;;  *** Examples of Using Multi `M-x' ***
+;;
+;;  Example: Repeat a command multiple times.  Yes, `C-x z' does this
+;;  already (and better) - this is just an illustration.  `M-x
+;;  forward-ch TAB' completes to `forward-char'.  Then, use `C-RET' to
+;;  execute that command.  Repeat as many times as you want.  Use a
+;;  prefix arg if you like.
+;;
+;;  To switch to another command in the same `M-x' invocation: Erase
+;;  the minibuffer (`M-k'), complete the second command, then use
+;;  `C-RET'.  As long as you have not yet used `RET', `S-RET', `C-g'
+;;  (or, say, `C-]'), you remain within the same invocation of `M-x'.
+;;
+;;  What about executing a command that, itself, reads an input
+;;  argument?  That's OK.  And if that command reads its input with
+;;  completion, then you can use `C-RET' on the completion candidates
+;;  for that input.
+;;
+;;  Example: `M-x describe-fa TAB C-RET' gives you the prompt for
+;;  command `describe-face'.
+;;
+;;  1. Type `ici S-TAB' to see the available Icicles faces.
+;;
+;;  2. Hit `next' until face `icicle-complete-input' is highlighted.
+;;
+;;  3. Hit `C-RET' to display its documentation.
+;;
+;;  4. Type `C-next' a few times to see the doc of other Icicles
+;;     faces.
+;;
+;;  5. Use `M-k' to erase the minibuffer, then type `search S-TAB' to
+;;     see faces about searching.
+;;
+;;  6. Cycle through them with `next', then use `C-RET' on
+;;     `icicle-search-main-regexp-current' to show its documentation.
+;;
+;;  7. Use `C-next' to do the same for face
+;;     `icicle-search-main-regexp-others'.
+;;
+;;  8. Use `RET' to finish with command `describe-face' - but you're
+;;     still in the same invocation of `M-x'.
+;;
+;;  9. Change the input to `describe-coding-system' and play again,
+;;     this time with coding-system names...
+;;
+;;  Remember, if you get confused or lost: `C-]'
+;;  (`abort-recursive-edit') or `M-x top-level' should always
+;;  straighten you out.
+;;
+;;(@* "What about describe-variable and describe-function?")
+;;  *** What about describe-variable and describe-function? ***
+;;
+;;  Sadly, if you try the last example with `describe-variable' or
+;;  `describe-function', you might be in for a surprise.  In Emacs 20,
+;;  they both work fine.  In later Emacs versions, `describe-variable'
+;;  gives you the message "You did not specify a variable", and
+;;  `describe-function' displays a `*Help*' buffer that says that each
+;;  function you choose is really a keyboard macro!
+;;
+;;  Why?  It's a bit complex, but worth hearing about if you want to
+;;  understand multi M-x better.
+;;
+;;  When you choose a command that reads an argument in the minibuffer
+;;  and you then hit a multi-command key such as `C-RET' to choose an
+;;  argument, Icicles tries to apply the command you chose to the
+;;  argument you chose.  However, completion candidates are always
+;;  strings, and the command you chose might expect something other
+;;  than a string.  That is the case for `describe-variable', for
+;;  instance.  The case of describe-function' is special: it
+;;  interprets a string argument blindly as a keyboard macro sequence.
+;;
+;;  Icicles is smart enough to pick up a `wrong-type-argument' error,
+;;  if the command you choose barfs on a string argument.  In that
+;;  case, Icicles converts the string to a symbol (or a number) and
+;;  tries again, using the symbol (or the number).
+;;
+;;  And that's why `describe-variable' works in Emacs 20 but not in
+;;  later versions: In Emacs 20, `describe-variable' (sanely) raises a
+;;  type error if you pass it a string, and Icicles is able to save
+;;  the day by then passing it the corresponding symbol.  In later
+;;  versions of Emacs, however, instead of raising an error with the
+;;  message "You did not specify a variable", `describe-variable' just
+;;  displays the message - no error, so there is no way for Icicles to
+;;  recuperate.
+;;
+;;  I've reported this design misfeature to the Emacs developers, and
+;;  I hope it will be fixed in a future Emacs version.  Until then, at
+;;  least you know...  The more general lesson is this: Icicles can
+;;  turn every command into a multi-command, but multi-command actions
+;;  will not work for every command.
+;;
+;;(@* "Multi `M-x' Turns Every Command into a Multi-Command")
+;;  *** Multi `M-x' Turns Every Command into a Multi-Command ***
+;;
+;;  Most of the time, of course, you do not execute commands
+;;  successively by name; instead, you use key bindings.  The point
+;;  here is that even if you have a binding for a command, Icicles
+;;  `M-x' lets you use any command as a multi-command, which can
+;;  sometimes be advantageous.
+;;
+;;  For example, Icicles defines and binds a real multi-command to
+;;  `C-x 0' in Icicle mode, which lets you delete any number of
+;;  windows.  But, even without such a multi-command, you can get a
+;;  similar effect by using `M-x delete-windows-on'.  In this way, you
+;;  can turn ordinary Emacs commands that use completion into
+;;  multi-commands.
+;;
+;;  The other point is that you can move from one command to another
+;;  within the same execution of `M-x'.  This is a different feature
+;;  from being able to use any command that uses completion as a
+;;  multi-command.  Both features have their uses.
+;;
+;;(@* "Multi `M-x' with Abbreviations: `icicle-command-abbrev'")
+;;  ** Multi `M-x' with Abbreviations: `icicle-command-abbrev' **
+;;
+;;  The second multi-command that you can use in place of
+;;  `execute-extended-command' is `icicle-command-abbrev', bound in
+;;  Icicle mode to `C-x SPC'.  It is similar to `M-x'
+;;  (`icicle-execute-extended-command'), with the added twist that it
+;;  lets you input command abbreviations, as well as commands.
+;;
+;;  If option `icicle-add-proxy-candidates-flag' is non-`nil', then
+;;  command abbreviations, as well as commands, are available as
+;;  completion candidates.  Otherwise, only commands are available.
+;;  You can toggle this user option using `C-M-_' in the minibuffer.
+;;
+;;  Emacs partial completion and some other libraries provide ways for
+;;  you to enter command abbreviations instead of command names at the
+;;  command prompt (`M-x').  Library `exec-abbrev-cmd.el' by Tassilo
+;;  Horn  is an example.
+;;
+;;  So just what is a command abbreviation?  Hyphens (`-') in command
+;;  names divide them into parts.  For example, `find-file' has two
+;;  parts: `find' and `file'.  Each character of a command
+;;  abbreviation corresponds to one part of each of the commands that
+;;  match the abbreviation.  For example, abbreviation `ff' matches
+;;  commands `find-file' and `focus-frame', and abbreviation `fg'
+;;  matches `find-grep'.
+;;
+;;  If user option `icicle-command-abbrev-match-all-parts-flag' is
+;;  `nil', then an abbreviation need not match all parts of a command
+;;  name; it need match only a prefix.  For example, `nil' means that
+;;  abbreviation `ff' also matches `find-file-other-window' and `fg'
+;;  also matches `find-grep-dired'.
+;;
+;;  In Icicles, you can input both abbreviations and commands at the
+;;  same prompt, and you can take advantage of the multi-command
+;;  feature to execute multiple commands.  You can thus treat command
+;;  abbreviations just like commands.  If an abbreviation matches a
+;;  single command name, then that command is invoked immediately.  If
+;;  it matches more than one, then you can use completion to choose
+;;  one.
+;;
+;;  One or more, that is - multi-command completion is available for
+;;  both abbreviations and commands.  That is, you can invoke any
+;;  number of them within the same use of `C-x SPC'.
+;;
+;;  What happens if your input matches a command name but it is also
+;;  an abbreviation for other command names?  By default, command
+;;  names take precedence: if your input matches a command name then
+;;  that command is invoked.  So, for example, by default the command
+;;  `cd' takes precedence over `cd' as an abbreviation for commands
+;;  such as `compile-defun' and `cancel-debug-on-entry'.  If you
+;;  instead want abbreviations to take precedence over command names,
+;;  then set option `icicle-command-abbrev-priority-flag' to `t'.
+;;
+;;  Abbreviations are completed against the (persistent) list of
+;;  abbreviations you have used in the past.  That list is also
+;;  directly customizable as option `icicle-command-abbrev-alist'.
+;;
+;;  Besides completing against past abbreviations, you can enter new
+;;  abbreviations (the completion is thus lax).  When you exit Emacs,
+;;  your abbreviations list is updated and saved, along with the
+;;  number of times you've used each abbreviation.  The latter
+;;  information is used to sort your abbreviations for completion, so
+;;  that those used most frequently are available first.
+ 
+;;(@* "Choose All Completion Candidates")
+;;
+;;  Choose All Completion Candidates
+;;  --------------------------------
+;;
+;;  The previous section describes how you can use `C-RET'
+;;  (`icicle-candidate-action') to choose (act on) multiple completion
+;;  candidates, individually.  If you hold down the Control key while
+;;  you cycle through the candidates, you can run through each of
+;;  them, one by one.
+;;
+;;  Command `icicle-all-candidates-action', which is bound to `C-!' in
+;;  the minibuffer, is a shorthand way of doing that: act on all
+;;  candidates that match the current input.  In many contexts, `C-!'
+;;  reports on any objects that were not acted upon successfully (in
+;;  buffer `*Help*').
+;;
+;;  All multi-commands let you use `C-!' in this way.  Whenever a
+;;  command defines a special action for `C-RET' to perform on the
+;;  current completion candidate, you can use `C-!' to perform it on
+;;  all candidates at once.
+;;
+;;  Perhaps you already use `% m' (command `dired-mark-files-regexp')
+;;  in Dired to mark all files that match a given regular expression,
+;;  and then operate on all of the marked files in some way (search
+;;  with `A', query-replace with `Q', open with `F', delete with `D',
+;;  and so on).  When you execute a multi-command, `C-!' lets you do
+;;  something similar.
+;;
+;;  How does it work?  It applies `icicle-candidate-action-fn' to each
+;;  completion candidate that (apropos- or prefix-) matches the
+;;  current input in the minibuffer.
+;;
+;;  Most top-level Icicles commands are multi-commands.  Command
+;;  `icicle-delete-file' is an example.  Instead of entering a file
+;;  name at the prompt (e.g. using completion or cycling), you can
+;;  type a regular expression, use `S-TAB' to see all matching files,
+;;  and then use `C-!' to delete all of them at once.
+;;
+;;  You get the idea: Use the minibuffer to determine a set of objects
+;;  by pattern matching, and then act on all elements of the set.
+;;
+;;  In addition to `C-!', keys `M-!', `C-|', and `M-|' act similarly:
+;;
+;;  * `M-!' is like `C-!', but it acts on the list of matching
+;;    candidates as a whole, rather than acting individually on each
+;;    candidate.  For example, with command `icicle-customize-face',
+;;    `M-!' opens a single Customize buffer for all of the matching
+;;    faces, while `C-!' opens a separate Customize buffer for each
+;;    face.
+;;
+;;  * `C-|' and `M-|' are like `C-!' and `M-!', respectively, but they
+;;    apply an alternative action, not the main action, whenever one
+;;    is available.
+;;
+;;  In the definition of a given multi-command, the appropriate action
+;;  functions are bound to variables:
+;;
+;;  * `icicle-candidate-action-fn' (`C-!') - normal single-candidate
+;;    action
+;;
+;;  * `icicle-candidate-alt-action-fn' (`C-|') - alternative
+;;    single-candidate action
+;;
+;;  * `icicle-all-candidates-list-action-fn' (`M-!') - normal
+;;    list-of-candidates action
+;;
+;;  * `icicle-all-candidates-list-alt-action-fn' (`M-|') - alternative
+;;    list-of-candidates action
+;;
+;;  For most multi-commands, however, only the normal single-candidate
+;;  action is defined.  In this case, `M-!' duplicates what `C-!'
+;;  does.  If the corresponding function is not available, each of the
+;;  list-action keys (`M-!', `M-|') behaves the same as the
+;;  corresponding single-candidate key (`C-!', `C-|), and vice versa.
+;;  So for instance, if `icicle-all-candidates-list-action-fn' is
+;;  `nil' when reading some input, then `M-!' acts the same as `C-!'.
+;;
+;;  As a shortcut, if you have saved completion candidates and they
+;;  all belong to the current set of completion candidates, then `C-!'
+;;  acts on the saved candidates instead of the complete set of
+;;  candidates.  This means that you need not first do `C-M-<' to
+;;  retrieve the saved candidates; you can do `C-!' directly to act on
+;;  them.  `C-|', `M-!', and `M-|' work the same way.
+;;
+;;  All of the all-candidates actions inhibit candidate help display
+;;  in the mode line and minibuffer messages that the individual
+;;  actions might effect.  This is to avoid unnecessary delays.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Dired Enhancements")
+;;    for an Icicles alternative to both `A' and `Q' (search and
+;;    replace) in Dired.
+ 
+;;(@* "Sets of Completion Candidates")
+;;
+;;  Sets of Completion Candidates
+;;  -----------------------------
+;;
+;;  Whereas `C-RET' acts on individual objects, `C-!'  acts on an
+;;  entire set of objects at once, via their names: the set of all
+;;  current completion candidates.  There are additional Icicles
+;;  commands that also act, not on individual completion candidates,
+;;  but on one or more sets of completion candidates.
+;;
+;;  One of these is `M-*', which effectively narrows the set of
+;;  completion candidates by taking the intersection of the candidate
+;;  sets defined by various input regexps.
+;;
+;;  This section presents some more Icicles commands that act on sets
+;;  of completion candidates.  The basic idea is that you can perform
+;;  set operations using the current set of completion candidates,
+;;  changing it into a different set.  You can, then, for example, use
+;;  `C-!' to act on everything in a custom-defined set.  Or you can
+;;  define a custom set that you want to use often (for example, a
+;;  list of project files), save it persistently, and then retrieve it
+;;  later to use for completion.
+;;
+;;(@* "Saving and Retrieving Completion Candidates")
+;;  ** Saving and Retrieving Completion Candidates **
+;;
+;;  Set operations such as union and difference act on two sets.  The
+;;  current set of completion candidates is always one of these sets.
+;;  If an operation, such as set complement, acts on a single set,
+;;  then it acts on the current set.
+;;
+;;  When two sets are involved, the other set is called the "saved
+;;  set".  This just means that at some previous time in your sesssion
+;;  you saved some completion candidates as the value of variable
+;;  `icicle-saved-completion-candidates'.
+;;
+;;  In buffer `*Completions*', candidates that have been saved are
+;;  highlighted using face `icicle-saved-candidate'.
+;;
+;;  By default, the saved set is not persistent; it is saved only
+;;  until the next save in the same Emacs session overwrites it or
+;;  adds to it.  See (@> "Persistent Sets of Completion Candidates")
+;;  for ways to save candidates persistently.
+;;
+;;  One way you can save candidates is to use
+;;  `icicle-candidate-set-save', bound to `C-M->'.  This saves all of
+;;  the current candidates.
+;;
+;;  Gotcha: If you use progressive completion and you have not yet
+;;          typed anything after `M-*' or `S-SPC', then there is not
+;;          yet a set of candidates to save.  If you use `C-M->' at
+;;          that point, you will reset the saved candidates to none.
+;;          To define the current candidates, either type something or
+;;          use `S-TAB'.
+;;
+;;  Another way to save candidates, besides `C-M->', is to select
+;;  candidates in buffer `*Completions*' using the (active) region,
+;;  and then use `icicle-candidate-set-save-selected', bound to
+;;  `C-M-)'.  This saves any candidates that are at least partially in
+;;  the region.
+;;
+;;  You can also use `C-M-)' to UNsave all candidates: just select no
+;;  candidates before you hit `C-M-)', to reset the set of saved
+;;  completions to none.  Think of this as replacing the saved set
+;;  with the empty set (no candidates).  And you need not use `TAB' or
+;;  `S-TAB' first to use this, since the current set of candidates is
+;;  not used in any way when you reset the saved set.
+;;
+;;  Command `icicle-mouse-candidate-set-save', bound to `M-S-mouse-3'
+;;  in `*Completions*' combines these two: if the region is active,
+;;  then the selected candidates become the saved set; otherwise, all
+;;  candidates are saved.  This binding makes it easy to save
+;;  candidates using the mouse: select them (e.g. drag or double-click
+;;  `mouse-1', or click `mouse-1' then `mouse-3'), then use
+;;  `M-S-mouse-3' to save. [*]
+;;
+;;  You can process the list of saved candidates in any way you like
+;;  using Emacs Lisp.  For example, you can save a list of file names
+;;  that match a regexp, then print the list or process the individual
+;;  files in some way.  Here, for instance, is how to save the set of
+;;  file names that contain either `dir' or `ici':
+;;
+;;    `C-x C-f \(dir\|ici\) S-TAB C-M-> C-g'
+;;
+;;  You can retrieve a set of saved candidates with command
+;;  `icicle-candidate-set-retrieve', bound to `C-M-<'.  This replaces
+;;  the current set of candidates with those retrieved.  It also acts
+;;  like `M-*' by entering a recursive minibuffer, which removes any
+;;  saved-candidates highlighting.  Using `TAB' or `S-TAB' restores
+;;  the highlighting.
+;;
+;;  You can use `C-<' to retrieve a set of saved candidates and add
+;;  them to the current candidates, instead of replacing those
+;;  candidates.  This way, you can build up the current set of
+;;  candidates by retrieving (combining) several saved sets.
+;;
+;;  In the other direction, you can save additional candidates, adding
+;;  them to a set of candidates already saved, in these ways:
+;;
+;;  * `C->' (`icicle-candidate-set-save-more') adds all of the current
+;;    candidates.
+;;
+;;  * `C-)' (`icicle-candidate-set-save-more-selected') adds any
+;;    candidates that you have selected using the region in
+;;    `*Completions*'.
+;;
+;;  * `M-mouse-3' (`icicle-mouse-candidate-set-save-more') acts the
+;;    same as `C-)' or `C->', depending on whether or not the region
+;;    is active in `*Completions*': it adds selected or all
+;;    candidates.
+;;
+;;  * Extending the region with `mouse-3', and then clicking `mouse-3'
+;;    again in the same place, acts the same as `C-)'.  That is, click
+;;    `mouse-1', then click `mouse-3' twice in another location, to
+;;    save all candidates between the `mouse-1' and `mouse-3'
+;;    positions. [*]
+;;
+;;  * The `insert' key (`icicle-save/unsave-candidate') adds just the
+;;    current completion candidate (e.g. during cycling).  Clicking a
+;;    candidate in `*Completions*' with `M-S-mouse-2'
+;;    (`icicle-mouse-save/unsave-candidate') does the same thing.  If
+;;    you do this to a candidate that has already been saved, then it
+;;    is UNsaved (no longer saved).
+;;
+;;  Note that the `insert' key and `M-S-mouse-2' are toggles for a
+;;  given candidate, saving or unsaving it.  In this sense each is its
+;;  own opposite.  In another sense, the opposite operation of saving
+;;  is simply removing a candidate from the current set of candidates.
+;;  You do that using the `delete' key or `S-mouse-2'.
+;;
+;;  Matching, saving, and retrieving candidates is a powerful way to
+;;  interact with completion.  One important use is to prepare a list
+;;  of candidates on which to act, and then act on them all at once
+;;  using `C-!'.  This is a good way to proceed when you want to
+;;  double-check what to act on, before you actually act.  This is the
+;;  same idea behind marking files in Dired and then operating on the
+;;  marked files, using `x'.  It corresponds to what is represented in
+;;  some user interfaces by filling out a checklist followed by
+;;  clicking `OK'.
+;;
+;;  [* If you click `mouse-1' on a candidate and (starting with Emacs
+;;  22) `mouse-1-click-follows-link' is an integer, then you will need
+;;  to hold the mouse button depressed longer than that many seconds,
+;;  or else that candidate will simply by chosen.  If the value is
+;;  `t', then this will not work at all.  Any other value presents no
+;;  problem.  (Personally, I use `nil'.)]
+;;
+;;(@* "Different Places for Saving and Retrieving Candidates")
+;;  ** Different Places for Saving and Retrieving Candidates **
+;;
+;;  You can save completion candidates to a different variable from
+;;  `icicle-saved-completion-candidates' by using a numeric prefix
+;;  argument to command `icicle-candidate-set-save'; that is, use `C-u
+;;  N C-M->'.  Alternatively, use `C-M-}', which is bound to command
+;;  `icicle-candidate-set-save-to-variable'.  You are prompted for the
+;;  name of the variable, and you can use completion when inputting
+;;  it.  During this completion, the only available candidates are
+;;  variables that you have used for saved candidates (but completion
+;;  is lax, so you can type a new variable name).  The same behavior
+;;  works also for `C->', `C-M-)', and `C-)'.
+;;
+;;  To retrieve completion candidates that were previously saved to a
+;;  variable other than `icicle-saved-completion-candidates', so that
+;;  they become the current set of candidates, use `C-u N C-M-<',
+;;  where N is an integer, or `C-M-{' (`icicle-candidate-set-retrieve'
+;;  or `icicle-candidate-set-retrieve-from-variable').
+;;
+;;  Using a plain prefix argument (`C-u' without a number) with
+;;  `C-M->' and `C-M-<' saves or retrieves a candidate set using a
+;;  cache file, not a variable.  Alternatively, as a shortcut you can
+;;  use `C-}' and `C-{' for this.
+;;  See (@> "Persistent Sets of Completion Candidates") and
+;;  (@file :file-name "icicles-doc2.el" :to "Support for Projects").
+;;
+;;  When you save candidates to a different variable from
+;;  `icicle-saved-completion-candidates', they are not shown in buffer
+;;  `*Completions*' using face `icicle-saved-candidate'.  When you
+;;  save candidates to a cache file, they are also saved to
+;;  `icicle-saved-completion-candidates', so they are shown in
+;;  `*Completions*' using face `icicle-saved-candidate'.
+;;
+;;  `C->' and `C-<' accept the same prefix arguments as `C-M->' and
+;;  `C-M-<' , letting you specify the source or destination (variable,
+;;  cache file) when you save or retrieve additional candidates.
+;;
+;;(@* "Set Operations")
+;;  ** Set Operations **
+;;
+;;  The other available set-operation commands for use with completion
+;;  candidates, besides saving and retrieving, are these:
+;;
+;;  * `icicle-candidate-set-swap', bound to `C-%'.  Swap the saved and
+;;    current sets of completion candidates.
+;;
+;;  * `icicle-candidate-set-define', bound to `C-:'.  Define the
+;;    current set of completion candidates by evaluating an input
+;;    sexp.  The sexp must evaluate to a list of strings, such as is
+;;    returned by `all-completions'.  You can use this to substitute
+;;    any list of strings, and then operate on them as completions,
+;;    using any Icicles functionalities.  Keep in mind, however, that
+;;    the completions must be of the proper type for the context in
+;;    which they are used.  For example, if you are executing a
+;;    command, they must be command names.
+;;
+;;  * `icicle-candidate-set-complement', bound to `C-~'.  Complement
+;;    the current set of candidates: replace the current candidate set
+;;    with its set complement.  This means all possible completions of
+;;    the appropriate type that do *not* match the current input.  You
+;;    can combine this with progressive completion (`M-*') to
+;;    progressively eliminate candidates that match different inputs.
+;;    This process-of-elimination matching is a common Icicles usage
+;;    idiom.
+;;
+;;  * `icicle-candidate-set-union', bound to `C-+'.  Replace the
+;;    current candidate set by its union with the saved set of
+;;    candidates.
+;;
+;;  * `icicle-candidate-set-difference', bound to `C--'.  Replace the
+;;    current candidate set by its set difference with the saved set
+;;    of candidates.  That is, the saved candidates are subtracted
+;;    from the current candidates, and the result becomes the current
+;;    candidate set.  To obtain the opposite set difference,
+;;    subtracting the current candidates from the saved candidates,
+;;    just use `icicle-candidate-set-swap' followed by
+;;    `icicle-candidate-set-difference'.
+;;
+;;  * `icicle-candidate-set-intersection', bound to `C-*'.  Replace
+;;    the current candidate set by its intersection with the saved set
+;;    of candidates.  Unlike the set intersection provided by `M-*',
+;;    `C-*' is, in itself, a one-time operation.  `M-*' can be
+;;    repeated, using the previous intersection as one of the sets to
+;;    be intersected in a new operation.  Both `C-*' and `M-*' use the
+;;    current set of matching candidates as one of the sets being
+;;    intersected.  But `M-*' reads another input regexp to define the
+;;    other set to be intersected, whereas `C-*' uses the saved
+;;    candidates set as the other set.  `M-*' is useful for chaining,
+;;    to achieve progressive approximation.  `C-*' is useful to
+;;    perform an intersection on a set from a previous input reading.
+;;
+;;  * `icicle-candidate-set-truncate', bound to `M-$'.  Truncate the
+;;    set of completion candidates, so that it includes only the first
+;;    N candidates (as displayed in `*Completions*').  You are
+;;    prompted for N.  You can use this when the order of candidates
+;;    represents priority in some way, so that you are interested only
+;;    in the topmost candidates.
+;;
+;;  You can operate on or choose from all input values in the set that
+;;  results from any of these set operations.  For example, you can
+;;  use `C-~' to see the list of objects that do not match the current
+;;  input, to cycle among those objects, or to operate on any or all
+;;  of them.  Use `C-~' at any time to switch to the complement of the
+;;  current set of candidates.
+;;
+;;  Example: To cycle through all files whose names do not end in
+;;           `el', you can do the following:
+;;
+;;  1. Use `C-f' to read a file name.
+;;  2. Type `el$' to match all file names that end in `el'.
+;;  3. Use `S-TAB' to show the matching files.
+;;  4. Use `C-~' to flip to the complement: files not ending in `el'.
+;;  5. Use `next' or `prior' to cycle among the new set of candidates.
+;;
+;;  A minibuffer message briefly confirms each of the set operations.
+;;
+;;  When buffer `*Completions*' is displayed, the union, difference,
+;;  and intersection commands scroll the buffer when repeated.
+;;  Repeating `icicle-candidate-set-complement' complements the
+;;  complement, of course, giving the original set.
+;;
+;;  Once you have established a set of completion candidates using any
+;;  of the candidate-set commands, you can cycle among the candidates
+;;  of that set using either prefix or apropos cycling (`down', `up',
+;;  `next', `prior', `end', or `home').  However, switching from
+;;  prefix to apropos cycling (or completion), or vice versa,
+;;  establishes a new completion set of the appropriate type, as
+;;  usual.  Switching completion type signifies that you are finished
+;;  with the specially defined completion set, and you want to
+;;  redefine it using apropos or prefix cycling or completion.
+;;
+;;  Note: Prefix icompletion (`icomplete.el' or `icomplete+.el' - see
+;;        (@> "Icompletion")) does not take into account the candidate
+;;        set resulting from a set operation: it always displays the
+;;        normal set of prefix completions in the minibuffer.
+;;
+;;  Note: You might have noticed that, as a mnemonic device, the keys
+;;        bound to the various set operations use the corresponding
+;;        binary arithmetic or Boolean operators: `~' (unary negation)
+;;        for complement (not); `*' (multiplication) for intersection
+;;        (and); `+' (addition) for union (or); and `-' (subtraction)
+;;        for difference.  Note too that the `C--' and `C-+' bindings
+;;        mean that you cannot use these key sequences for prefix
+;;        arguments - you must use `C-u N', or `M-N' instead, where N
+;;        is a possibly signed integer.
+;;
+;;  See Also:
+;;
+;;  * (@> "Multi-Commands") for information about `C-RET'.
+;;
+;;  * (@> "Choose All Completion Candidates") for information about
+;;    `C-!'.
+;;
+;;  * (@> "Progressive Completion") for information about `M-*'.
+;;
+;;  * (@> "File-Name Input and Locating Files Anywhere") and
+;;    (@> "Persistent Sets of Completion Candidates"), for information
+;;    about saving completion candidates persistently and retrieving
+;;    them later.
+;;
+;;  * (@> "History Enhancements"), (@> "Google Matching"), and
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview")
+;;    for examples of other set operations on input candidates.
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Dired Enhancements")
+;;    for information about saving and reusing sets of file-name
+;;    candidates with Dired.
+ 
+;;(@* "Google Matching")
+;;
+;;  Google Matching
+;;  ---------------
+;;
+;;  This section presents nothing new - but you might not want to skip
+;;  it.  It points out something that you might not have picked up
+;;  yet.  You've learned about Icicles regexp matching and candidate
+;;  set operations, but it can be worthwhile to compare how Icicles
+;;  matches inputs against completion candidates with how Google
+;;  matches search strings against Web pages.  Summary: You can do
+;;  pretty much the same things, but the way you accomplish them is
+;;  different.
+;;
+;;(@* "Domain of Discourse")
+;;  ** Domain of Discourse **
+;;
+;;  In Google, the domain of discourse, that is, the possible set of
+;;  search hits, is the set of Web pages.  There are also search
+;;  fields that limit the domain of discourse by file type, page
+;;  number, update date, page position, freedom of use, and even
+;;  morality ("Safe Search").
+;;
+;;  In Icicles (Emacs), the domain of discourse changes automatically,
+;;  depending on the current context.  For command-name input, it is
+;;  the set of all named commands; for variable-name input, it is the
+;;  set of variable names; and so on.
+;;
+;;(@* "Global Filtering")
+;;  ** Global Filtering **
+;;
+;;  In Google, you can limit searching to specific Web sites, or
+;;  exclude certain Web sites from searching.
+;;
+;;  In Icicles, you can add extra completion candidates using variable
+;;  `icicle-extra-candidates', and you can filter out (other)
+;;  candidates globally using filter variables
+;;  `icicle-must-match-regexp', `icicle-must-not-match-regexp',
+;;  `icicle-must-pass-predicate', and
+;;  `icicle-must-pass-after-match-predicate'.  These are internal
+;;  Icicles variables.  Normally, you do not change them directly;
+;;  instead, a command can use them to limit or extend the effective
+;;  domain of discourse.
+;;  See (@file :file-name "icicles-doc2.el" :to "Global Filters").
+;;
+;;  Variables `icicle-must-pass-predicate' and
+;;  `icicle-must-pass-after-match-predicate' apply to the textual
+;;  candidates that can be displayed in buffer `*Completions*'.  You
+;;  can also apply a predicate to the full alist-entry or
+;;  obarray-symbol candidates that are supplied to `completing-read'
+;;  or `read-file-name' as its COLLECTION argument.  As a programmer,
+;;  you can of course do that when your code calls these functions.
+;;  As an Icicles user, you can use `M-&' to define and apply
+;;  predicates to such alist-entry candidates on the fly, while
+;;  completing.
+;;  See (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview").
+;;
+;;(@* "Word Matching and String Matching")
+;;  ** Word Matching and String Matching **
+;;
+;;  Google matches words, by default, but you can specify an "exact
+;;  phrase" to get literal string matching.
+;;
+;;  By default, Icicles (apropos-)matches regexps, but you can use
+;;  `\b' in a regexp to perform word matching, and you can use `C-`'
+;;  (`icicle-toggle-regexp-quote') to perform exact (literal)
+;;  matching.  See (@> "What About Special-Character Conflicts?").
+;;
+;;(@* "AND Matching and OR Matching")
+;;  ** AND Matching and OR Matching **
+;;
+;;  Google has search fields for AND matching ("with all of the
+;;  words") and OR matching ("with at least one of the words").
+;;
+;;  In Icicles, you can use progressive completion to perform AND
+;;  matching: use `M-*' to introduce each term to match.
+;;  Alternatively, you can use `C-*'
+;;  (`icicle-candidate-set-intersection').  You can use `C-+'
+;;  (`icicle-candidate-set-union') to perform OR matching.  Note that,
+;;  by definition, unordered AND matching is not possible using a
+;;  single regexp.  See (@> "Progressive Completion") and
+;;  (@> "Sets of Completion Candidates").
+;;
+;;(@* "NOT Matching")
+;;  ** NOT Matching **
+;;
+;;  Google has a search field for terms that must not occur in search
+;;  hits: "without the words".
+;;
+;;  In Icicles, you can use `C-~' (`icicle-candidate-set-complement')
+;;  to exclude matching completion candidates.  You can combine this
+;;  with progressive completion, to exclude any number of terms: `toto
+;;  C-~ M-* titi C-~ M-* foobar' excludes all candidates matching
+;;  toto, titi, or foobar.  Use this process-of-eliminiation technique
+;;  to progressively pare down the set of possible candidates.  Note
+;;  that such generalized complementing (as opposed to complementing a
+;;  character set) is not possible using a single regexp - you cannot
+;;  use a regular expression to say "Show me everything that does
+;;  *not* match this".  See (@> "Sets of Completion Candidates") and
+;;  (@> "Progressive Completion").
+ 
+;;(@* "Buffer-Name Input")
+;;
+;;  Buffer-Name Input
+;;  -----------------
+;;
+;;  The Icicles commands that read buffer names are multi-commands
+;;  (see (@> "Multi-Commands")), so you can act on more than one
+;;  buffer during a given command invocation.
+;;
+;;  These commands all let you use a prefix argument to control which
+;;  buffers are completion candidates.  It is the numeric value of the
+;;  prefix arg that matters:
+;;
+;;  * Positive: only buffers visiting files
+;;  * Zero:     only buffers with the same mode as the current buffer
+;;  * Negative: only buffers associated with the selected frame
+;;
+;;  In addition to the usual Icicles key bindings, during buffer-name
+;;  completion you can use the following keys:
+;;
+;;  * `C-x M' (`icicle-filter-buffer-cands-for-mode') to filter the
+;;    buffer-name candidates to keep only those with a given major
+;;    mode.  You are prompted for the mode.
+;;
+;;  * `C-x m' (`icicle-bookmark-non-file-other-window') to visit a
+;;    bookmarked buffer.  This is available only if you use library
+;;    `bookmark+.el'.  This too is a multi-command, so you can
+;;    actually visit any number of buffer bookmarks with one use of
+;;    `C-x m'.  When finished, you can continue with non-bookmark
+;;    buffer-name completion.
+;;
+;;  * `S-delete' to kill the buffer named by the current completion
+;;    candidate.
+;;
+;;  During completion, candidate sorting is specific to buffer names.
+;;  `C-,' cycles among the following sort orders:
+;;
+;;  * by last access
+;;  * `*...*' last: put buffers such as `*Messages*' and `*Help*' last
+;;  * by buffer size
+;;  * by major mode name
+;;  * by mode-line mode name (mode name that appears in the mode line)
+;;  * by (absolute) file or process name
+;;
+;;  Finally, several user options control the completion behavior.
+;;  See (@file :file-name "icicles-doc2.el" :to "Customization and General Tips")
+;;  and (@file :file-name "icicles-doc2.el" :to "Global Filters").
+;;
+;;
+;;  See Also:
+;;
+;;  * (@> "Ido and IswitchB") to use Icicles with a buffer-switching
+;;    behavior that is similar to Ido and IswitchB
+;;  * (@> "`M-&': Satisfying Additional Predicates") to filter the
+;;    buffer candidates on the fly in multiple ways (e.g. size)
+ 
+;;(@* "File-Name Input and Locating Files Anywhere")
+;;
+;;  File-Name Input and Locating Files Anywhere
+;;  -------------------------------------------
+;;
+;;  Emacs offers two main functions for reading minibuffer input with
+;;  completion: `completing-read' and `read-file-name'.  Icicles uses
+;;  both of these, and it enhances each of them in various ways for
+;;  use in your own Emacs-Lisp code.  These two functions can each be
+;;  used to read file-name input, but they do so in very different
+;;  ways.
+;;
+;;  In addition to the usual Icicles key bindings, during file-name
+;;  completion you can use the following keys:
+;;
+;;  * `C-backspace' (`icicle-up-directory') to navigate up the
+;;    directory hierarchy.  It removes the last directory component
+;;    (and any partial file name) from your minibuffer input.
+;;
+;;    (For Emacs versions before Emacs 22, this feature is available
+;;    only for completion of absolute file names.)
+;;
+;;  * `C-c +' (`icicle-make-directory') to create a directory on the
+;;    fly.
+;;
+;;  * `C-x m' (`icicle-bookmark-file-other-window') to visit a
+;;    bookmarked file or directory.  This is available only if you use
+;;    library `bookmark+.el'.  It is a multi-command, so you can
+;;    actually visit any number of file bookmarks.  When finished, you
+;;    can continue with non-bookmark file-name completion.
+;;
+;;  * `S-delete' to delete the file named by the current completion
+;;    candidate.
+;;
+;;  * `M-|' (`icicle-all-candidates-list-alt-action') to open Dired on
+;;    the currently matching file names.  That is, it opens a special
+;;    Dired buffer that contains only the matching files.  You are
+;;    prompted for the Dired buffer name.  See (@> "Alternative Actions").
+;;
+;;  In many cases for Icicles multi-commands that read a file name,
+;;  you can use `M-n' to pick up the file name at point, or if none
+;;  then the name of the file you are currently visiting.
+;;
+;;  Note: Whether a command supports file-name globbing wildcards such
+;;  as `*' is independent of whether it uses `read-file-name' or
+;;  `completing-read'.  It is the command itself that offers such
+;;  support or not.  Globbing takes place only after the file name
+;;  (with wildcards) is read.  All Icicles commands that visit files
+;;  (all of the commands mentioned in this section) let you use
+;;  globbing wildcards.  Remember also that file-name globbing, with
+;;  its special wildcards, has nothing to do with regexp completion
+;;  matching.  See (@> "What About Special-Character Conflicts?") for
+;;  more information about file-name globbing.
+;;
+;;(@* "Function `read-file-name'")
+;;  ** Function `read-file-name' **
+;;
+;;  Function `read-file-name' is specialized for file-name input with
+;;  completion.  It knows about files and file names for your current
+;;  platform.  It knows about Emacs remote file name syntax (Tramp,
+;;  Ange FTP).  And starting with Emacs 23, `TAB' also completes
+;;  environment variables during `read-file-name' completion.
+;;
+;;  Using `read-file-name' is the most flexible way to read a file
+;;  name in Emacs, and it is the traditional way.  Unless stated
+;;  otherwise, "file-name completion", even in the Icicles doc, refers
+;;  to `read-file-name' completion.
+;;
+;;  When `read-file-name' reads input, only the file name itself, not
+;;  the directory portion, is used for matching.  The directory is
+;;  understood to be the value of variable `default-directory' (which
+;;  you can change using command `cd', for instance).  The behavior is
+;;  thus the same whether or not the directory name is present in the
+;;  minibuffer.  If you prefer, you can delete the directory name
+;;  first, using `M-k'.
+;;
+;;  With `read-file-name', you can thus use apropos completion to
+;;  match a file-name substring, without needing to prefix the
+;;  substring with `.*' in the minibuffer.  For example, to match the
+;;  file named `favorite-foo-file.bar' in directory
+;;  `/some/path/to/my/', you need not use `/some/path/to/my/.*foo'; it
+;;  is sufficient to use either `foo' or `/some/path/to/my/foo'.
+;;
+;;  An additional feature of `read-file-name' in Icicle mode is that
+;;  candidates that are directory names are highlighted in buffer
+;;  `*Completions*' using face `icicle-special-candidate'.
+;;
+;;(@* "Function `completing-read'")
+;;  ** Function `completing-read' **
+;;
+;;  Function `completing-read' is a general function for reading input
+;;  with completion.  It is not specially designed for reading file
+;;  names.  It knows nothing about files and file names. It knows
+;;  nothing about remote file-name syntax.  When `completing-read'
+;;  reads input, it makes no use of `default-directory'.  The
+;;  completion candidates are treated as simple strings; they are not
+;;  really treated as file names.
+;;
+;;  Icicles commands that use `completing-read' to read a file name
+;;  typically read an absolute name, that is, a name that includes the
+;;  directory portion.  This means that you can match against any part
+;;  of the full name, including any directory components.  The
+;;  directory portions of the candidate file names need not be the
+;;  same - you can thus complete against a set of files in multiple
+;;  directories.
+;;
+;;(@* "Icicles Commands that Read File Names")
+;;  ** Icicles Commands that Read File Names **
+;;
+;;  Icicles commands that use `read-file-name' include all
+;;  multi-commands, such as `icicle-find-file', that are defined using
+;;  `icicle-define-file-command'.  Vanilla Emacs command `find-file'
+;;  is another example of a command that uses `read-file-name'.
+;;
+;;  Icicles commands that use `completing-read' to read file names
+;;  include the multi-commands `icicle-find-file-absolute',
+;;  `icicle-find-file-in-tags-table', `icicle-recent-file',
+;;  `icicle-locate-file', and `icicle-locate-file-no-symlinks'.  These
+;;  are defined using `icicle-define-command', not
+;;  `icicle-define-file-command'.
+;;
+;;  There are also `-other-window' versions of all of the Icicles
+;;  commands that read file names.
+;;
+;;  The Icicles commands that use `completing-read' to read file names
+;;  have an additional feature: you can use a prefix argument to tell
+;;  them to combine the last modification date with the file name, as
+;;  a multi-completion - see
+;;  (@file :file-name "icicles-doc2.el" :to "Multi-Completions").
+;;  This means that you can easily look up files whose modification
+;;  time or date matches some (regexp) criterion, such as being
+;;  sometime in July 2008.
+;;
+;;  When using a command that reads an absolute file name, remember
+;;  that, to save space, you can use `C-x .' to toggle hiding of the
+;;  common match portions of the candidates in `*Completions*'.  This
+;;  portion is often a long directory substring.
+;;
+;;  Command `icicle-file' is bound, by default, to `C-x C-f' in Icicle
+;;  mode, thus taking the place of `find-file'.  It combines
+;;  `icicle-find-file' and `icicle-find-file-absolute'.  With no
+;;  prefix argument, it matches relative file names; with a prefix
+;;  argument, it matches absolute names (as ordinary strings).  With a
+;;  negative prefix argument, you can match also the modification
+;;  date.
+;;
+;;  An additional feature of `icicle-find-file-absolute' and
+;;  `icicle-find-file-absolute-other-window' is that candidates that
+;;  are directory names are highlighted in buffer `*Completions*'
+;;  using face `icicle-special-candidate'.
+;;
+;;  Commands `icicle-find-file-in-tags-table' and
+;;  `icicle-find-file-in-tags-table-other-window' let you visit files
+;;  that are listed in the current Emacs tags table.  You can think of
+;;  these potential completion candidates as all of the files in a
+;;  project defined by the tags table.
+;;
+;;  You can use `icicle-recent-file' to open any file that you have
+;;  visited recently, perhaps in a previous Emacs session.
+;;
+;;  You can use `icicle-locate-file' to find a file when you do not
+;;  know what directory it is in.  It looks throughout a given
+;;  directory, including throughout all of its subdirectories.
+;;  Command `icicle-locate-file-no-symlinks' is the same, except that
+;;  it does not follow symbolic links.  Both of these locate commands
+;;  respect option `icicle-ignored-directories', which is a list of
+;;  directories to ignore - by default, version-control directories.
+;;
+;;  By default, the target directory for `icicle-locate-file' is the
+;;  current directory, but if you supply a non-negative numeric prefix
+;;  argument (non-positive means include the date), then you are
+;;  prompted for the directory to search.  If you use the root of your
+;;  file system as the search directory, then the locate-file commands
+;;  will match completion candidates anywhere in your file system.
+;;
+;;  This can be quite useful.  It gives you much of the power of the
+;;  Unix `find' command just for completing input!  And with
+;;  incremental completion (see (@> "Icompletion")), you can see what
+;;  matches your input as you type.
+;;
+;;  Obviously, if you use your entire file system as the set of
+;;  completion candidates, then gathering and matching such a large
+;;  set of file names can take some time.  On my hard drive, for
+;;  instance, there are 36 GB full of files, and it takes about 40
+;;  seconds to gather all of the file names.  In spite of this
+;;  inconvenience, this functionality can be useful.  And of course
+;;  searching a shallower directory tree presents less of a
+;;  performance penalty - you pay for what you get.
+;;
+;;  There is a way, however, of having your cake and eating it too.
+;;  You can gather all of the file names in your file system once, and
+;;  save that list of completion candidates to a cache file on disk,
+;;  as a snapshot.
+;;  See (@> "Persistent Sets of Completion Candidates"), for how to do
+;;  this.
+;;
+;;(@* "Absolute File Names and Different Directories")
+;;  ** Absolute File Names and Different Directories **
+;;
+;;  Since `completing-read' has no understanding of file-name syntax,
+;;  including remote file-name syntax, `icicle-find-file-absolute'
+;;  (`C-u C-x C-f') and similar commands are similarly ignorant.  (You
+;;  can nevertheless use `C-.' with these Icicles commands, to toggle
+;;  respect of `completion-ignored-extensions'.)  In particular, these
+;;  commands will not let you complete to a remote file name if the
+;;  current directory is local.  They also will not let you complete
+;;  to a file name in a different local directory.
+;;
+;;  Because all Icicles commands that read file names use lax
+;;  completion, you can nevertheless visit a file in a different
+;;  directory (remote or local) from the current one, even though you
+;;  cannot complete your input to such a name.  That is, you can
+;;  always use `RET' with any file name as minibuffer input.
+;;
+;;  So how can you complete your input to an absolute file-name in a
+;;  different directory?  By retrieving a saved candidate set that has
+;;  such absolute names and then completing against that set.  For
+;;  example, you can retrieve a set that represents files on a remote
+;;  machine and complete to their names even from a local directory.
+;;  All that counts for `completing-read' is that your input can match
+;;  candidates, where that matching is ordinary (apropos or prefix)
+;;  string matching.
+;;
+;;  To create such a saved set of names, you can visit the directory
+;;  (perhaps remote) that contains the files and then use `C-u C-x
+;;  C-f' and `C-}' to save the candidates.  You can later retrieve
+;;  this saved set for completion, no matter what the current
+;;  directory is.  As another example, you can use
+;;  `icicle-locate-file' in a remote directory to create a saved set
+;;  that includes remote files that are all somewhere under that
+;;  remote directory.
+;;
+;;  In addition, you can add more file names to an existing saved set
+;;  using `C->', `C-)', `M-mouse-3', `insert', or `M-S-mouse-2' - see
+;;  (@> "Sets of Completion Candidates"). The added names can come
+;;  from a different directory than files already in the saved set. In
+;;  this way, you can build up a saved set that includes files from
+;;  any directories, some of which can be local and some remote, some
+;;  remote from one host, some remote from another, and so on. You can
+;;  create a saved set with any mix of absolute file names from any
+;;  locations.
+;;
+;;  Remember this:
+;;
+;;  * To create and add to a saved set of absolute file names, use a
+;;    command that expects absolute file names, and do this from the
+;;    directory that contains the files you want to add.
+;;
+;;  * When you retrieve a saved set of file-name candidates for
+;;    completion, use a command that expects the same kind of file
+;;    names, relative or absolute, as the saved names.  For example,
+;;    if you save a set of project files that are spread over
+;;    different directories (and hence are absolute), then retrieve
+;;    that candidate set using, say, `C-u C-x C-f' (absolute), not
+;;    `C-x C-f' (relative).
+;;
+;;  Finally, although the commands that read absolute file names are
+;;  essentially ignorant of directory hierarchies and of file names as
+;;  such, so that they treat their candidates only as simple strings,
+;;  a few of these commands nevertheless define their domain of
+;;  possible file-name candidates relative to some starting directory.
+;;
+;;  This is the case for `icicle-find-file-absolute' and
+;;  `icicle-locate-file' (and their variants).  For these commands,
+;;  you can use `C-c C-d' (think UNIX command `cd') during completion
+;;  to change the current working directory (`default-directory') on
+;;  the fly.  You are prompted for the directory.  The domain of
+;;  possible candidates is recomputed relative to the new
+;;  `default-directory'.
+;;
+;;  Use `C-c C-d' this way as many times as you like.  You can use
+;;  this feature to add file names from different directories to a
+;;  saved set of candidates.  When the command is finished, the
+;;  original `default-directory' is restored.
+;;
+;;  See Also:
+;;
+;;  * (@> "Persistent Sets of Completion Candidates") for information
+;;    about saving a set of file names persistently
+;;  * (@> "Sets of Completion Candidates") for information about
+;;    creating, saving, and retrieving sets of file names
+;;  * (@> "Dealing With Large Candidate Sets") for ways to deal with a
+;;    large number of candidates
+;;  * (@file :file-name "icicles-doc2.el" :to "Multi-Completions")
+;;  * (@file :file-name "icicles-doc2.el" :to "Support for Projects")
+;;    for more about `icicle-find-file-in-tags-table'
+;;  * (@> "Completion On Demand") for information about on-demand
+;;    insertion of file names, using completion, from any minibuffer
+
+ 
+;;(@* "Persistent Sets of Completion Candidates")
+;;
+;;  Persistent Sets of Completion Candidates
+;;  ----------------------------------------
+;;
+;;  Section (@> "Sets of Completion Candidates") describes how you can
+;;  save the current set of completion candidates and reuse it later.
+;;  This is not a persistent save, however; the candidates are simply
+;;  saved in variable `icicle-saved-completion-candidates' for the
+;;  duration of your Emacs session (or until you save candidates
+;;  again).
+;;
+;;  You can save the current set of completions (whatever it is)
+;;  persistently by supplying a plain prefix argument (`C-u') when you
+;;  use `C-M->' (`icicle-candidate-set-save') during completion.
+;;  Alternatively, you can use `C-}', bound to
+;;  `icicle-candidate-set-save-persistently', which does the same
+;;  thing.  To retrieve completion candidates that were previously
+;;  saved to a cache file, so that they become the current set of
+;;  candidates, use either `C-u C-M-<' or `C-{'
+;;  (`icicle-candidate-set-retrieve' or
+;;  `icicle-candidate-set-retrieve-persistent').
+;;
+;;  Tip: Suppose you have already saved a set of candidates, but not
+;;       persistently, and you now want to write this saved set to a
+;;       cache file.  Use `C-M-<' followed by `TAB' or `S-TAB',
+;;       followed by `C-}'.  That is, retrieve the saved candidates
+;;       and then save the retrieved candidates persistently.  (You
+;;       use `TAB' or `S-TAB' because retrieval opens a recursive
+;;       minibuffer.)
+;;
+;;  Note that using a numeric prefix argument (`C-u' with a number)
+;;  with `C-M->' and `C-M-<' saves or retrieves a
+;;  completion-candidates set using a variable that you name, not a
+;;  cache file.  See (@> "Sets of Completion Candidates").
+;;
+;;(@* "Saving Candidates in Cache Files")
+;;  ** Saving Candidates in Cache Files **
+;;
+;;  If you have used the Emacs file-name cache (see the Emacs manual,
+;;  node "File Name Cache"), then you have already used a cache file
+;;  of (file-name) completion candidates.  In vanilla Emacs, you use
+;;  `C-TAB' during file-name input to complete to a cached file name.
+;;  In Icicles, you use `C-{'.
+;;
+;;  In Icicles, the cached candidates are not limited to file names,
+;;  and you can have any number of cache files, to save different sets
+;;  of completion candidates.  Each cache file saves the set of
+;;  candidates that was current when you created (saved) the set.
+;;
+;;  The fact that a cache file can contain just those candidates that
+;;  were current when you saved it is a considerable advantage, when
+;;  combined with Icicles features for sculpting the current set of
+;;  matching candidates.  As far as I know, Icicles is the only
+;;  package to offer this feature.  You spend a few moments to
+;;  fine-tune a set of candidates, using, for example, `M-*', `C-~',
+;;  and `delete', and then save it for later use.  From then on, you
+;;  can match against exactly those candidates anytime you want.
+;;
+;;  For example, you might have a software project that involves only
+;;  certain directories and perhaps only certain kinds of files in
+;;  those directories are of interest as completion candidates.  Those
+;;  directories and files can even be in disparate locations.
+;;
+;;  Start with command `icicle-locate-file' (or
+;;  `icicle-locate-file-no-symlinks').  Then use progressive
+;;  completion to match the directories and files you want and chip
+;;  away at those you do not want.  Once you get just the set you need
+;;  for your project, save that set using `C-}'.  You can have any
+;;  number of saved sets, for different projects or different purposes
+;;  in the same project.
+;;
+;;  You name the sets of saved candidates, and these names are
+;;  associated with the cache files in user option
+;;  `icicle-saved-completion-sets'.  This is an alist of entries, each
+;;  of which is of the form (SET-NAME . CACHE-FILE-NAME).  You can
+;;  customize this option, or set it in your init file (~/.emacs).
+;;
+;;  You can use command `icicle-add/update-saved-completion-set' to
+;;  add a new set to `icicle-saved-completion-sets' or update
+;;  (replace) an existing such set.  You can use command
+;;  `icicle-remove-saved-completion-set' to remove a saved set.
+;;
+;;  As an alternative to customizing `icicle-saved-completion-sets' or
+;;  using command `icicle-add/update-saved-completion-set', you can
+;;  simply try to save a set of completion candidates persistently,
+;;  using `C-u C-M->' or `C-}'.  You are then prompted for the names
+;;  of the candidate set and cache file to use, and the names you
+;;  enter are automatically entered in option
+;;  `icicle-saved-completion-sets'.  That option is automatically
+;;  saved to your custom file, so the next time you use Emacs you can
+;;  retrieve any saved set of candidates that you like.
+;;
+;;  When you try to retrieve a persistent set of completion
+;;  candidates, you are similarly prompted for the candidate-set name
+;;  and the cache-file name.
+;;
+;;  In addition to saving the current set of completion candidates to
+;;  a cache file, you can add individual strings as future completion
+;;  candidates to any cache file, and you can remove candidates from a
+;;  cache file individually.  You do this using commands
+;;  `icicle-add-entry-to-saved-completion-set' and
+;;  `icicle-remove-entry-from-saved-completion-set'.
+;;
+;;  Adding an individual candidate is similar to using the Emacs
+;;  file-name cache commands that add file names to the cache, but it
+;;  adds only a single candidate.  For file names, adding a directory
+;;  name effectively provides completion for all of its files as well,
+;;  so there is no need to add each file name as well as the directory
+;;  name.  Alternatively, you can always use `C-}' to add all file
+;;  names that match your current input.
+;;
+;;(@* "Filesets and Icicles Saved Completion Sets")
+;;  ** Filesets and Icicles Saved Completion Sets **
+;;
+;;  Starting with release 22, GNU Emacs includes a filesets feature
+;;  that lets you create named sets of file names, called "filesets".
+;;  It is a powerful feature, letting you define such sets by
+;;  intension, using regexp patterns, as well as by extension, listing
+;;  file names explicitly.  You can easily use a fileset to define a
+;;  project of files.
+;;
+;;  Icicles lets you use an Emacs fileset any time you can use an
+;;  Icicles saved completion set, provided that option
+;;  `icicle-filesets-as-saved-completion-sets-flag' is non-`nil'.
+;;
+;;  That is, you can retrieve fileset file names as the current set of
+;;  completion candidates or save the current completion candidates to
+;;  a fileset.  Provided
+;;  `icicle-filesets-as-saved-completion-sets-flag' is non-`nil', you
+;;  can always choose a fileset as the set to retrieve.  To save to a
+;;  fileset, use a prefix arg with `C-}' or a zero prefix arg with
+;;  `C-M->'.  Saving candidates to a fileset gives you an alternative
+;;  to customizing option `filesets-data'.
+;;
+;;  Being able to use an Emacs fileset in place of an Icicles saved
+;;  set lets you use filesets in additional ways.  For example, it
+;;  lets you open Dired on only the files in a fileset, for easy
+;;  manipulation of the member files.  Conversely, you can save all of
+;;  the marked files in a Dired buffer as a fileset. See
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Dired Enhancements").
+;;
+;;  Beyond letting you use a fileset in place of a persistent Icicles
+;;  saved completion set, you can include filesets in such saved
+;;  Icicles sets.  That is, you can save one or more filesets of any
+;;  kind (`:files', `:tree', etc.) in an Icicles persistent saved set
+;;  (cache file).  When you then retrieve such a saved set, all of the
+;;  file names specified by all of the included filesets become
+;;  completion candidates.
+;;
+;;  For example, this could be a saved Icicles set that combines a
+;;  `:tree' fileset with an explicit `:files' fileset and with two
+;;  additional files:
+;;
+;;  ((:fileset "set1" (:tree "~/my/dir" "^ici.+\\.el$"))
+;;   (:fileset "set2" (:files "dired+.el" "c:/my/dir/buff-menu+.el"))
+;;   "c:/some/other/dir/foobar.el"
+;;   "c:/somewhere/else/toto.el")
+;;
+;;  This is a great way to put together a project of files from
+;;  different directory trees.  And even aside from the use of such a
+;;  saved set for completion, this combining of filesets is something
+;;  that you cannot do with Emacs filesets alone, as far as I know -
+;;  you cannot combine different filesets into super filesets, and a
+;;  given fileset can specify files in only one way (`:files',
+;;  `:tree', etc.).  Icicles gives you a way to associate related
+;;  filesets and use them together as a single set.
+;;
+;;  You can use commands
+;;  `icicle-remove-entry-from-saved-completion-set' and
+;;  `icicle-add-entry-to-saved-completion-set' to remove a fileset
+;;  from an Icicles saved set or add a fileset to a saved set.  To
+;;  add, use a prefix arg to tell
+;;  `icicle-add-entry-to-saved-completion-set' that you are adding a
+;;  fileset and not a single completion candidate.  To add a single
+;;  file (default: the current buffer's file) to a fileset, use
+;;  command `icicle-add-file-to-fileset'.
+;;
+;;  Note: Use the right type of saved candidates (persistent or not)
+;;  for a given command.  It is the particular command that determines
+;;  whether or not a given type of saved candidate is appropriate.
+;;  For example, you can save search hits when you use
+;;  `icicle-search-file' (same as `icicle-search' with a negative
+;;  prefix arg), and those saved search-hit candidates effectively
+;;  reference files and positions in those files.  And you can later
+;;  retrieve and reuse such saved candidates to visit the search
+;;  positions.  But those candidates are not merely file names, so
+;;  they cannot be used with a command such as `find-file' or
+;;  `icicle-file' that expects a file name.  Conversely, you cannot
+;;  use a saved set of file names with a command such as
+;;  `icicle-search-file' that expects `icicle-search' candidates.
+;;
+;;(@* "Improving Performance with Persistent Sets")
+;;  ** Improving Performance with Persistent Sets **
+;;
+;;  There are two independent reasons that using a persistent set of
+;;  file names can improve performance:
+;;
+;;  * Avoiding remote file-name completion.  You can complete your
+;;    input against remote file names without using Tramp and thus
+;;    without accessing the remote file system.  (Once you have chosen
+;;    the file you want, visiting it of course makes a remote access.)
+;;
+;;  * Avoiding generation of a large completion set.  Retrieving a
+;;    list of file names is much, much faster than generating such a
+;;    list.  So generate once and retrieve often, from a cache.
+;;
+;;  These are covered in the next two sections.
+;;
+;;(@* "Avoid Remote File-Name Completion")
+;;  *** Avoid Remote File-Name Completion ***
+;;
+;;  When you complete the name of a remote file, Tramp accesses the
+;;  remote file system to see which matching files exist.  This takes
+;;  time.  The completion itself is complicated - it involves parsing
+;;  the remote file name and calling upon various file handlers.  But
+;;  the greatest time spent is in accessing the remote machine.
+;;
+;;  When you retrieve a (persistently) saved set of file names during
+;;  completion, you are telling Emacs that these are the candidates
+;;  you want to complete against.  You are not asking Emacs (Tramp) to
+;;  tell you what the possible candidates are; you are telling it.
+;;  (Obviously you will want to save the completions in a file on the
+;;  local machine, so retrieval itself takes no time.)
+;;
+;;  After retrieving the saved candidates as the only possible ones,
+;;  you might type some input and complete it (`TAB' or `S-TAB') to
+;;  narrow your choices.  Or you might not bother with completion but
+;;  instead pick one of the candidates using `mouse-2' or by cycling
+;;  to it and using `RET'.
+;;
+;;  You can use either relative or absolute file-name completion with
+;;  remote file names.  Relative name completion as provided by
+;;  `read-file-name' (via `C-x C-f', for example) always involves
+;;  Tramp (or ange-ftp, prior to Emacs 22).  When using relative name
+;;  completion, you can save time in these ways:
+;;
+;;  * Turn off incremental completion (using `C-#'), so that Tramp is
+;;    used only when you hit `TAB' or `S-TAB', not with each character
+;;    you type or delete!
+;;
+;;  * Use `mouse-2', or cycle and use `RET', so that you avoid
+;;    completion altogether.  Tramp is then used only to access the
+;;    chosen file.
+;;
+;;  If you use absolute file-name completion as provided by
+;;  `completing-read' (via `C-u C-x C-f', for example), then you need
+;;  not worry about turning off incremental completion or avoiding
+;;  completion by cycling or using `mouse-2'.  This is because
+;;  completion is entirely local - `completing-read' has no notion of
+;;  files, let alone remote files.
+;;
+;;  In addition, if you use absolute file-name completion then you
+;;  need not bother to type the (long) remote file-name prefix to get
+;;  into the right directory for completion.  Again, `completing-read'
+;;  has no notion of files or directories - it just completes an input
+;;  pattern against string candidates.  Just type a substring or other
+;;  regexp and then hit `S-TAB'.
+;;
+;;  In general, using absolute file names (`C-u C-x C-f') is the way
+;;  to go when dealing with remote files.  There is no need to forego
+;;  the advantages of Icicles completion.  On the other hand, if you
+;;  are going to work in a directory on a remote machine for some time
+;;  using files other than those in some saved completion set, then
+;;  you might want to use relative file names (`C-x C-f').
+;;
+;;(@* "Avoid Generating A Large Completion Set")
+;;  *** Avoid Generating A Large Completion Set ***
+;;
+;;  Section (@> "File-Name Input and Locating Files Anywhere") tells
+;;  you how you can locate any file in your file system.  If you save
+;;  the set of all file names persistently, you will increase the
+;;  performance of using it - it is much faster to retrieve the list
+;;  of all file names than it is to generate it.
+;;
+;;  With 36 GB of files in my file system, my all-file-system cache
+;;  file is 20 MB, and retrieving the file-name completions from it
+;;  takes only a few seconds.  With this feature, Icicles essentially
+;;  gives you the functionality of the Unix `locate' command, but with
+;;  the addition of real-time regexp matching.  Here is all you do:
+;;
+;;    M-x icicle-locate-file RET
+;;    C-#        ; Once or twice: turn off incremental completion.
+;;    C-{        ; Retrieve all file names from your cache file.
+;;               ; You are prompted for the set name and file name.
+;;    foo.*bar   ; Regexp to match names with `foo' followed by `bar'.
+;;    S-TAB      ; Update `*Completions*' display (because of `C-#').
+;;
+;;  Of course, once you have retrieved a set of candidates from your
+;;  cache file, you can access them again without re-reading the file.
+;;  When they are retrieved from your cache they are saved in variable
+;;  `icicle-saved-completion-candidates', so the next time you want to
+;;  use them, just retrieve them from this variable with `C-M-<'.
+;;
+;;  See Also:
+;;
+;;  * (@> "File-Name Input and Locating Files Anywhere") for
+;;    information about relative vs absolute file names and about
+;;    finding files located anywhere in your file system
+;;
+;;  * (@> "Icompletion") for information about `C-#' (toggle
+;;    incremental completion)
+;;
+;;  * (@> "Sets of Completion Candidates") for information about
+;;    `C-M->' (save current candidates)
+;;
+;;  * (@> "Dealing With Large Candidate Sets")
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Icicles Bookmark Enhancements")
+;;    for information about using autofile bookmarks, which are
+;;    another form of persistent file names
+ 
+;;(@* "Dealing With Large Candidate Sets")
+;;
+;;  Dealing With Large Candidate Sets
+;;  ---------------------------------
+;;
+;;  One of the advantages Icicles provides is the ability to deal with
+;;  large sets of completion candidates with ease.  There are other
+;;  libraries that also let you cycle among various choices of
+;;  different kinds (buffers, files, and so on), but cycling quickly
+;;  loses its effectiveness as the number of candidates increases.
+;;
+;;  Icicles apropos matching lets you work with a large initial set of
+;;  candidates by filtering them, quickly reducing the number
+;;  candidates to cycle through.  Filtering by a prefix only (vanilla
+;;  Emacs) is not very potent.  Until you get used to Icicles, you
+;;  will be surprised at your ability to manipulate even humongous
+;;  sets of choices.
+;;
+;;  Nevertheless, there can be times when a candidate set is so large
+;;  that you need to use a few tricks to deal with it efficiently.
+;;  There are two main things that take time when dealing with a large
+;;  set: computing the set and displaying it (with highlighting) in
+;;  buffer `*Completions*'.  In particular, incremental completion
+;;  display is costly because it does both of these, recompute the set
+;;  and redisplay it, each time you type or delete a character in the
+;;  minibuffer.
+;;
+;;  Here are some tips to improve performance with a large set of
+;;  candidates:
+;;
+;;  * Turn off incremental completion display in buffer
+;;    `*Completions*'.  You can do this on the fly at any time by
+;;    using `C-#' in the minibuffer - use `C-#' again to turn it back
+;;    on.  See (@> "Icompletion").
+;;
+;;  * Compute a large candidate set only once, cache the result, and
+;;    reuse it later by reading the cache instead of recomputing.
+;;    This is useful, for instance, for the candidate set of all files
+;;    on your file system.  You can cache a set of candidates in
+;;    either a variable (quickest, but not persistent) or a disk file
+;;    (slower, persistent).
+;;    See (@> "Persistent Sets of Completion Candidates").
+;;
+;;  * Compute a large candidate set (and perhaps cache it or filter
+;;    it) without displaying it in `*Completions*', by using `C-M-TAB'
+;;    or `C-M-S-TAB' instead of `TAB' or `S-TAB', respectively.  These
+;;    are bound to commands `icicle-prefix-complete-no-display' and
+;;    `icicle-apropos-complete-no-display'.  For example, when
+;;    initially computing the set of all files on your file system for
+;;    `C-u M-x icicle-locate-file', use `C-M-S-TAB' to compute the
+;;    set, then use `C-}' to save it to a cache file - you need never
+;;    display it.
+;;
+;;    (The documentation refers to the keys that do this as
+;;    `C-M-S-TAB' and `C-M-TAB'.  Actually, this is only by default.
+;;    You can customize this, using options
+;;    `icicle-apropos-complete-no-display-keys' and
+;;    `icicle-prefix-complete-no-display-keys'.)
+ 
+;;(@* "History Enhancements")
+;;
+;;  History Enhancements
+;;  --------------------
+;;
+;;  This section is about accessing and reusing previous input that
+;;  you have typed in the minibuffer.
+;;
+;;(@* "What Input, What History?")
+;;  ** What Input, What History? **
+;;
+;;  First, what is meant by "input" and "input history"?  In vanilla
+;;  Emacs and in this doc, "minibuffer history" and "input history"
+;;  generally refer to input that you have typed (or cycled or
+;;  completed) in the minibuffer and then entered using `RET' (or
+;;  `S-RET').  Emacs provides different history lists for this,
+;;  depending on the kind of input.  The most general such list is the
+;;  value of variable `minibuffer-history'.
+;;
+;;  But what about input that you type in the minibuffer (e.g. during
+;;  completion) but that you do not enter with `RET'?  That is not
+;;  recorded in any standard history list, so you cannot recall it
+;;  using `M-p' and `M-n'.
+;;
+;;  The Icicles doc speaks ambiguously of "minibuffer input".  This
+;;  always refers to something that you type in the minibuffer, but
+;;  sometimes it means input that you enter with `RET' and sometimes
+;;  it does not.  The context and the use of phrases such as "entered"
+;;  and "entered with `RET'" should make clear what is meant.  Input
+;;  that you type during completion but that you do not necessarily
+;;  enter is sometimes referred to in the Icicles doc as "completion
+;;  input".
+;;
+;;  Because completion is so important to Icicles, because cycling
+;;  replaces the input you type in the minibuffer, and because you
+;;  sometimes need to retrieve such typed input that was never
+;;  entered, Icicles also records this input.  You can retrieve it
+;;  during completion using `C-l' (`icicle-retrieve-previous-input')
+;;  and `C-S-l', that is, `C-L', (`icicle-retrieve-next-input').  Use
+;;  these commands to cycle among your past completion inputs
+;;  (backward and forward, respectively).
+;;
+;;  User option `icicle-completion-history-max-length' limits the
+;;  number of completion inputs to save.
+;;
+;;  If you customize user option `icicle-C-l-uses-completion-flag' to
+;;  non-`nil', then, instead of cycling, `C-l' lets you use Icicles
+;;  completion to retrieve a past completion input (`C-L' does the
+;;  same thing).  Using completion to retrieve a past input does not
+;;  also choose that input as the candidate for the main completion;
+;;  it just replaces your current minibuffer input with it.  Because
+;;  `C-l' completion uses a recursive minibuffer, you can also use
+;;  `C-g' to cancel this completion and return to the main completion.
+;;
+;;  You can temporarily reverse the effect of
+;;  `icicle-C-l-uses-completion-flag' by using a prefix argument
+;;  (`C-u') with `C-l'.  Thus, `C-u C-l' uses completion if
+;;  `icicle-C-l-uses-completion-flag' is `nil' and cycles if it is
+;;  non-`nil'.
+;;
+;;  The other sections here describe Icicles enhancements for
+;;  minibuffer histories.  They are thus concerned only with inputs
+;;  that you enter, not with completion inputs that are not entered.
+;;
+;;(@* "Overview of Minibuffer History Enhancements")
+;;  ** Overview of Minibuffer History Enhancements **
+;;
+;;  Icicles enhances the minibuffer history in these independent ways:
+;;
+;;  1. Commands invoked using a menu-bar menu are included in the
+;;     command history for `M-x'.  This helps you quickly find again
+;;     and reuse a (possibly deep) menu item.  It lets you use
+;;     completion to access such commands.  And it helps you learn the
+;;     commands that correspond to menu items that you use, thus
+;;     providing a missing bridge between menu use and minibuffer use.
+;;
+;;     If you do not want to include menu-item commands in the command
+;;     history, then set option `icicle-menu-items-to-history-flag' to
+;;     `nil'.
+;;
+;;     Note: Non-`nil' `icicle-menu-items-to-history-flag' simply
+;;     makes Emacs handle menu items that you choose the same way that
+;;     it handles commands that you enter using `RET'.  It does not
+;;     add such menu items to your completion history, which you
+;;     access using `C-l' (see (@> "What Input, What History?"),
+;;     above).
+;;
+;;  2. Command `icicle-insert-history-element' (bound to `M-o' in the
+;;     minibuffer) lets you use (lax) completion to insert a history
+;;     element in the minibuffer.
+;;
+;;  3. Candidates displayed in `*Completions*' are highlighted using
+;;     face `icicle-historical-candidate' (blue foreground, by
+;;     default), when they have been used previously, so you can more
+;;     easily recognize them.  This highlighting is controlled by
+;;     option `icicle-highlight-historical-candidates-flag'.  You can
+;;     toggle this from the minibuffer at any time using `C-pause'.
+;;
+;;  4. Command `icicle-toggle-alternative-sorting', (`C-M-,' in the
+;;     minibuffer) re-sorts completion candidates, placing previously
+;;     used candidates first.  This is a toggle: repeat it to return
+;;     to the original order.
+;;
+;;  5. Command `icicle-keep-only-past-inputs' (`M-pause' in the
+;;     minibuffer) restricts the current set of completion candidates
+;;     to those that you have used previously.  In other words, it
+;;     keeps only those candidates that are highlighted in blue.  To
+;;     use `M-pause', you must first have used `TAB' or `S-TAB' to
+;;     establish an explicit candidate set.  If you use `C-u M-pause',
+;;     then the previously used candidates are ordered
+;;     chronologically, most recent first.  Without `C-u', the normal
+;;     sort order is used (`icicle-sort-comparer').
+;;
+;;  6. Command `icicle-history' (`M-h' in the minibuffer) matches the
+;;     current input against the minibuffer history directly.  It can
+;;     be used during completion.
+;;
+;;  7. Command `icicle-other-history' (`C-M-pause' in the minibuffer)
+;;     lets you use a different history for the current completion.
+;;     You can choose the history using completion.
+;;
+;;  8. Commands `icicle-clear-history' and
+;;     `icicle-clear-current-history' (`M-i' in the minibuffer)
+;;     provide a general way to clean up histories.
+;;
+;;  9. When you cycle among previously entered inputs using `M-p' and
+;;     `M-n', you can use `M-k' (command
+;;     `icicle-erase-minibuffer-or-history-element') to delete the
+;;     current occurrence from the history list.  This is a quick and
+;;     handy way to clean up list entries that you are no longer
+;;     interested in.  Only the occurrence that you have cycled to is
+;;     deleted; if there are identical entries elsewhere in the
+;;     history, they remain.
+;;
+;;  Some of these enhancements are described below in more detail.
+;;  Each of 1-7 lets you see the complete list of previous inputs that
+;;  match your current input.  In vanilla Emacs, the history lists are
+;;  never shown as such; you can access previous inputs only one at a
+;;  time, in order (with `M-p').  In vanilla Emacs, you can use a
+;;  regexp to search the history list (via `M-r'), but the regexp
+;;  matching is not dynamic, and the first match found is the (only)
+;;  one you get.
+;;
+;;  Displaying previous inputs that match the current input sounds
+;;  like a minor advantage, but it is actually quite helpful in
+;;  practice.  Among other things, it means that you can work with
+;;  long history lists in a practical way.
+;;
+;;(@* "Using Completion to Insert Previous Inputs: `M-o'")
+;;  ** Using Completion to Insert Previous Inputs: `M-o' **
+;;
+;;  Unlike the other minibuffer history enhancements, described below,
+;;  which are available only during minibuffer completion, you can use
+;;  `M-o' (`icicle-insert-history-element') anytime you are asked for
+;;  minibuffer input.  It provides a recursive minibuffer in which you
+;;  can match a previous input using completion.  After you hit `RET'
+;;  to accept your choice, it is inserted in the minibuffer just as if
+;;  you had typed it.  This is a form of on-demand completion
+;;  (see (@> "Completion On Demand"), and as such is always available.
+;;
+;;  This has the advantage over cycling with `M-n' or `M-p' and
+;;  searching with `M-s' or `M-r', that you can use Icicles completion
+;;  and cycling to quickly access a previous input, no matter how long
+;;  ago you entered it.
+;;
+;;  When completion is available for reading input, if you use `M-o'
+;;  to choose a previously entered input, this just inserts that input
+;;  in the minibuffer.  What is in the minibuffer after you use `M-o'
+;;  is not automatically chosen for the main completion - you can edit
+;;  the minibuffer contents before entering it with `RET'.  You can
+;;  also use `C-g' during the `M-o' completion to cancel it and return
+;;  to the main completion.
+;;
+;;(@* "Putting Previous Candidates First: `C-M-,'")
+;;  ** Putting Previous Candidates First: `C-M-,' **
+;;
+;;  At any time, two of the Icicles sort orders are immediately
+;;  available.  These are the values of user options
+;;  `icicle-sort-comparer' and `icicle-alternative-sort-comparer'.  By
+;;  default, the former usually sorts alphabetically, and the latter
+;;  puts all previously used inputs first, before the candidates you
+;;  have not yet used.  Each of these groups, used and unused
+;;  candidates, is then sorted alphabetically, separately.  So, with
+;;  the default alternative sort, you can see all matching candidates
+;;  (used and unused), but you privilege those used previously - they
+;;  are the first listed in `*Completions*' and the first available
+;;  for cycling.
+;;
+;;  If you prefer, by customizing these user options, you can use
+;;  `icicle-historical-alphabetic-p' as the main sort function (option
+;;  `icicle-sort-comparer') and some other sort function
+;;  (e.g. `icicle-case-string-less-p') as the alternative sort
+;;  function.
+;;
+;;  You can toggle at any time between normal sorting and alternative
+;;  sorting, using command `icicle-toggle-alternative-sorting'.
+;;  During completion, this is bound to `C-M-,'.  Together with
+;;  toggling between normal sorting and not sorting at all, which is a
+;;  sort-order choice available through `C-,', this gives you quite a
+;;  lot of flexibility.
+;;
+;;(@* "Matching Only Historical Candidates: `M-h' and `M-pause'")
+;;  ** Matching Only Historical Candidates: `M-h' and `M-pause' **
+;;
+;;  Both `M-h' (`icicle-history') and `M-pause'
+;;  (`icicle-keep-only-past-inputs') can be used toward the same end.
+;;  They both work for all input types.  They both use the appropriate
+;;  history list for the current command.  They both provide
+;;  completion and cycling for the minibuffer history.  Use them as
+;;  another way to search through a history list or complete to one of
+;;  its elements.
+;;
+;;  For example, If you use `C-x C-f' to find a file, and then use
+;;  `M-h' or `M-pause', the completion candidates will be the names of
+;;  files that you have previously accessed (file names you have input
+;;  in the minibuffer), and which match the current minibuffer input.
+;;
+;;  `M-h' lets you complete your input against the minibuffer input
+;;  history.  `M-pause' lets you restrict the current explicit set of
+;;  completion candidates to those that are also in the minibuffer
+;;  history.
+;;
+;;  They provide similar functionality in different ways.  The
+;;  difference is that `M-pause' takes the current set of matching
+;;  candidates into account.  It is a completion-candidates set
+;;  operation, similar to those described in section
+;;  (@> "Sets of Completion Candidates").
+;;
+;;  This means, in particular, that with `M-pause' you can first
+;;  perform set operations on the set of candidates, and then use that
+;;  result to restrict the history search.  For example, you can first
+;;  complement the candidate set using `C-~', then use `M-pause' to
+;;  restrict those candidates to matches in the history list.  In this
+;;  way, you avoid including matches from the original match set when
+;;  searching the history.
+;;
+;;  Example: You are in a directory with lots of files that have the
+;;  prefix `foo' and lots of C-language source files.  You happen to
+;;  be interested in another file, however.  One way to get to that
+;;  file is to use Dired's ability to mark files by matching a regexp
+;;  and then use Dired's ability to omit the marked files from view.
+;;  You can scan through those that remain, and pick the one you want.
+;;  However, it turns out that even then there are many files to scan.
+;;  You accessed the one you want now just the other day, but the file
+;;  date is unfortunately not significant.
+;;
+;;  In Icicles, you use regexp matching and take the set complement of
+;;  the hits, just like in Dired: `C-x C-f foo.*\.c$' defines the
+;;  candidate set as all files whose names start with `foo' and have
+;;  extension `c'.  `C-~' then defines the candidate set as all files
+;;  whose names are not like that.  Finally, you use `M-pause' to
+;;  restrict the file-name candidates to names that you have used
+;;  before.  You've accessed many, many files recently, so just
+;;  cycling through the history with `M-p' would be tedious.  You
+;;  could match a regexp against the file history, but how can you
+;;  come up with a regexp that finds anti-matches?
+;;
+;;  A consequence of this difference between `M-h' and `M-pause' is
+;;  that using `TAB' or `S-TAB' after `M-pause' abandons use of the
+;;  minibuffer history and starts a new set of completion candidates.
+;;  It simply completes the current input in the context of the
+;;  current command; `TAB' and `S-TAB' have nothing to do with the
+;;  minibuffer history in this case.  Using `TAB' or `S-TAB' after
+;;  `M-h', however, re-completes your input against the current
+;;  history list.
+;;
+;;  Another consequence is that you can use `down' or `C-down' on the
+;;  candidates displayed by `M-h', but not on those displayed by
+;;  `M-pause'.  For example, to cycle through the doc for each
+;;  variable that starts with `icicle-' which you have previously
+;;  input, you can use `C-h v icicle- M-h', then repeatedly use
+;;  `C-down'.
+;;
+;;  Also, file-name and directory-name completion works differently in
+;;  these two commands.  By default, the current directory is (as
+;;  always) inserted into the minibuffer by commands such as
+;;  `find-file', so either `M-h' or `M-pause' after `C-x C-f' will
+;;  match previously input file names from the current directory.
+;;
+;;  However, in the case of `M-h', the entire minibuffer input is
+;;  matched against the history list, which is a list of absolute file
+;;  names.  `M-pause' works only with the current candidate set,
+;;  which, if you have already used `TAB' or `S-TAB' in the current
+;;  directory, is a set of relative file names in that directory.
+;;
+;;  This difference has a consequence for apropos (regexp) completion
+;;  with `M-h'.  It means that to match a file name using a substring
+;;  you must, in the minibuffer, either not specify a directory (erase
+;;  it) or explicitly use `.*' before the file-name substring.
+;;
+;;  For example, with `M-h', `/foo/bar/lph' will not apropos-match the
+;;  previously input file name `/foo/bar/alphabet-soup.el'; you should
+;;  use either `/foo/bar/.*lph' or `lph' (no directory).
+;;
+;;  In the case of `M-pause', however, the input is matched against
+;;  the history list as restricted by the existing completion list.
+;;  And, since apropos file-name completion uses only the relative
+;;  file name, without the directory name, as a regexp, the candidate
+;;  list that is restricted has already matched the input regexp.  The
+;;  action of `M-pause' is simply to filter the list of candidates,
+;;  keeping those that are in the history list.  This means that, with
+;;  `M-pause', the input `/foo/bar/lph' will match against the
+;;  previously input file name `/foo/bar/alphabet-soup.el'.
+;;
+;;  Note that neither `M-h' nor `M-pause' uses a recursive minibuffer;
+;;  they each simply co-opt the current completion, changing it to
+;;  completion against the history.  This means that whatever
+;;  completion mode (prefix or apropos) was in effect before you use
+;;  `M-h' or `M-pause' remains in effect for the history completion as
+;;  well.
+;;
+;;  If this all sounds confusing, just give it a try; it is much
+;;  harder to describe than it is to experience.
+;;
+;;(@* "Using Other Histories; Commands Any Which Way")
+;;  ** Using Other Histories; Commands Any Which Way **
+;;
+;;  This section describes how to complete your input against a
+;;  history other than the default history provided for the current
+;;  command.  A special case of this, starting with Emacs 23, is
+;;  completing a command, abbrev, or keyboard macro name against all
+;;  such that were previously executed in any interactive way.  This
+;;  includes commands invoked using a menu.
+;;
+;;(@* "Completing Against All Interactive Commands")
+;;  *** Completing Against All Interactive Commands ***
+;;
+;;  When you execute a command using `M-x', it is added to the history
+;;  `extended-command-history'.  Likewise, when you execute a command
+;;  or abbrev using `icicle-command-abbrev-command'.  And when you
+;;  execute a keyboard macro using `C-x M-e'
+;;  (`icicle-execute-named-keyboard-macro'), it is added to history
+;;  `icicle-kmacro-history'.
+;;
+;;  However, when you execute a command, abbrev, or keyboard macro in
+;;  other ways than these, it is not added to such a history.  For
+;;  example, if you choose a menu item, the associated command is not
+;;  added to any of these histories.  Thus, although `M-o' lets you
+;;  complete against previously used commands, this does not include
+;;  commands that were called via a menu item.
+;;
+;;  To remedy this, starting with Emacs 23 Icicles can optionally add
+;;  all commands that are called using `call-interactively' to the
+;;  larger command history `icicle-interactive-history'.  This
+;;  includes commands on menus.  To enable this feature, you must
+;;  customize option `icicle-populate-interactive-history-flag', to
+;;  make it non-`nil'.  Thereafter, when you enter Icicle mode, all
+;;  interactive use of commands records them on this special history.
+;;
+;;  During completion, you can then use `C-M-pause'
+;;  (`icicle-other-history') to complete against this extended set of
+;;  previously used commands.  For example, if you use menu item `Open
+;;  File', then the corresponding command, `menu-find-file-existing',
+;;  becomes available as a completion candidate.  (Recall too that the
+;;  command associated with a given menu item is shown in the
+;;  `*Completions*' mode line whenever you cycle to it.)
+;;
+;;  Be aware that use of this feature can slow Emacs down, and the
+;;  history list can become quite large.
+;;
+;;(@* "Using an Alternative History")
+;;  *** Using an Alternative History ***
+;;
+;;  When you are completing something other than a command, abbrev, or
+;;  keyboard macro (or even when you complete one of those, if you use
+;;  a prefix argument), `C-M-pause' prompts you for an alternative
+;;  history to use - any history you like.  You can choose the history
+;;  using completion.  This does not automatically complete your
+;;  current input against the history you choose; it simply changes
+;;  the current history for the duration of the current minibuffer
+;;  completion.  (You can use `M-h', as usual, if you want to complete
+;;  against the chosen history.)
+;;
+;;(@* "Cleaning Up History Lists")
+;;  ** Cleaning Up History Lists **
+;;
+;;  Besides the use of `M-k' during history cycling (`M-p', `M-n') to
+;;  remove individual input occurrences from the current history list,
+;;  you can use commands `icicle-clear-history' and
+;;  `icicle-clear-current-history' to clean minibuffer histories
+;;  entirely of selected entries.  Command
+;;  `icicle-clear-current-history' is bound to `M-i' in the
+;;  minibuffer.  It is `icicle-clear-history' specialized to work on
+;;  just the current history list.
+;;
+;;  These commands prompt you for a history entry to delete from a
+;;  history list.  These are multi-commands, so you can delete
+;;  multiple entries.  For each entry you choose, all of its
+;;  occurrences are deleted from the history.
+;;
+;;  Command `icicle-clear-history' first prompts you for a history
+;;  list to act on.  This too is multi-command input, so you can use
+;;  `icicle-clear-history' to remove entries from multiple histories.
+;;
+;;  If you use a prefix argument with these commands, then the
+;;  histories are emptied entirely (upon confirmation).  Thus, for
+;;  instance, you can use `C-u M-i' at any time during minibuffer
+;;  input to completely empty the current history list.
+;;
+;;  See Also: (@> "More about Multi-Commands") for information about
+;;  using `S-delete' to delete objects associated with completion
+;;  candidates.
+ 
+;;(@* "Isearch Enhancements")
+;;
+;;  Isearch Enhancements
+;;  --------------------
+;;
+;;  Icicles provides two different enhancements for searching:
+;;
+;;  - Icicles search: Top-level Icicles commands that provide an
+;;    entirely new and different way for you to search.
+;;    This is described in section
+;;    (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview").
+;;
+;;  - Extensions to standard Emacs incremental search, Isearch.
+;;    These are described in this section.
+;;
+;;    * Search string completion against previous search strings.
+;;    * Occur mode interface for Isearch hits.
+;;    * Icicles search (`icicle-search') interface, reusing the
+;;      Isearch search string (by default).
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc2.el" :to "Support for Projects")
+;;    for information about using `grep' to search all of the files in
+;;    a project.
+;;
+;;(@* "Isearch Completion Against the Search History")
+;;  ** Isearch Completion Against the Search History **
+;;
+;;  When you search incrementally (`C-s'), Emacs lets you use `M-TAB'
+;;  (aka `C-M-i', aka `ESC-TAB') to complete your input to a string
+;;  that you have sought previously, that is, a string in the current
+;;  search history (`search-ring' or `regexp-search-ring').  In Icicle
+;;  mode, this feature is enhanced so that you can use all of the
+;;  completion enhancements provided by Icicles: `M-TAB' is bound to
+;;  `icicle-isearch-complete' during Isearch.
+;;
+;;  Some operating systems grab `M-TAB' for their own use, making it
+;;  unavailable for Emacs.  They normally do not grab `ESC TAB', which
+;;  in Emacs is typically the same ase `M-TAB'.  For this reason,
+;;  Icicles also binds `icicle-isearch-complete' to both `ESC TAB' and
+;;  `C-M-TAB'.  (Note: For MS Windows, you can use
+;;  (w32-register-hot-key [M-tab]) to allow Emacs to use `M-TAB'.)
+;;
+;;  Icicles users are in the habit of using `M-o' to complete the
+;;  current minibuffer input against previously entered inputs.
+;;  Because of the similarity, you can likewise use `M-o' during
+;;  Isearch to complete the current search string: `M-o' is equivalent
+;;  to `M-TAB'.
+;;
+;;  The keys bound by default to `icicle-isearch-complete' in
+;;  `isearch-mode-map' are thus `M-TAB', `ESC TAB', `C-M-TAB', and
+;;  `M-o'.  But you can change the keys to use for this by customizing
+;;  option `icicle-isearch-complete-keys'.
+;;
+;;  When you use `M-o' (or `M-TAB') while searching, Isearch exits
+;;  momentarily, giving way to Icicles completion in the minibuffer
+;;  (Isearch actually uses the echo area, not the minibuffer).  You
+;;  can then use either `S-TAB' or `TAB' to complete your search
+;;  string.  After you finish completing (e.g. by hitting `RET'),
+;;  Isearch resumes with the new, completed search string.  It's
+;;  pretty seamless, and easier to try than to describe.
+;;
+;;  Reminder: Using `S-TAB' vs `TAB' for regexp vs non-regexp
+;;  completion against previous search strings has nothing to do with
+;;  regexp vs non-regexp searching.  You can of course use either kind
+;;  of searching before or after having used either kind of
+;;  completion.  Isearch uses different search rings for regexp and
+;;  non-regexp searching.  The kind of search in progress (regexp or
+;;  not) at the moment you ask Isearch for completion determines which
+;;  search ring provides the candidates for completion.
+;;
+;;(@* "Launch Occur using the Isearch Search String")
+;;  ** Launch Occur using the Isearch Search String **
+;;
+;;  If you use library `color-moccur.el' or library
+;;  `occur-schroeder.el', then `C-o' is bound during Isearch to
+;;  `isearch-moccur', which provides an Occur buffer interface for
+;;  search hits.  This has nothing per se to do with Icicles, but you
+;;  might find it useful.  (Library `color-moccur.el' itself binds
+;;  `M-o' for this, but `M-o' is used in Icicles for search-string
+;;  completion.)
+;;
+;;(@* "Launch Icicles Search using the Isearch Search String")
+;;  ** Launch Icicles Search using the Isearch Search String **
+;;
+;;  Icicles search is described in section
+;;  (@file :file-name "icicles-doc2.el" :to "Icicles Search Commands, Overview").
+;;
+;;  You can start Icicles search from Isearch: Hit `S-TAB' to choose
+;;  the Icicles search initial regexp - the default value is the
+;;  current Isearch search string, but you can edit that.  Completion
+;;  is available for your input - completion against your previous
+;;  Isearch regexp search strings.
+;;
+;;  For example, use `C-s C-w C-w S-TAB' to pick up the next two words
+;;  at the cursor, then type `.*' before and after them and hit `RET'.
+;;  That puts you in Icicles search with the completion candidates
+;;  being all of the lines in the buffer that contain that two-word
+;;  phrase.  Type some more text to narrow the candidate lines to
+;;  those that match what you type.  Then use `C-next' to visit search
+;;  hits.
+;;
+;;  With Emacs 22 and later, and provided option
+;;  `isearch-allow-scrolling' (a misnomer) is non-`nil', you can use a
+;;  prefix argument with `S-TAB' to change the behavior.  You still
+;;  choose an Isearch search string using completion.  But in this
+;;  case the string does not define the Icicles search contexts.
+;;  Instead, you are prompted for a search-context regexp to do that.
+;;  The Isearch string is copied to the `kill-ring', so you can yank
+;;  it into your minibuffer input anytime, to search for it within
+;;  each of the search contexts.
+;;
+;;  The key to initiate Icicles search from Isearch is `S-TAB' only by
+;;  default.  You can change this key by customizing option
+;;  `icicle-search-from-isearch-keys'.
+ 
+;;  The Icicles doc is continued in file `icicles-doc2.el'.
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; You need not load this file.  It contains only documentation.
+
+(provide 'icicles-doc1)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-doc1.el ends here
diff --git a/auto-install/icicles-doc2.el b/auto-install/icicles-doc2.el
new file mode 100644
index 0000000..5786504
--- /dev/null
+++ b/auto-install/icicles-doc2.el
@@ -0,0 +1,9166 @@
+;;; icicles-doc2.el --- Minibuffer input completion and cycling.
+;;
+;; Filename: icicles-doc2.el
+;; Description: Minibuffer completion and cycling.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Tue Aug  1 14:21:16 1995
+;; Version: 22.0
+;; Last-Updated: Sat Sep 10 11:54:56 2011 (-0700)
+;;           By: dradams
+;;     Update #: 28247
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-doc2.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Icicles documentation, part 2.
+;;
+;;  Files `icicles-doc1.el' and `icicles-doc2.el' contain the doc for
+;;  Icicles, including how to install and use Icicles.  You can also
+;;  read the Icicles doc, in formatted form, on the Emacs-Wiki Web
+;;  site: http://www.emacswiki.org/cgi-bin/wiki/Icicles.  Emacs Wiki
+;;  also has a few addtional pages about Icicles.  In particular, if
+;;  you are new to Emacs, as well as Icicles, see this page:
+;;  http://www.emacswiki.org/cgi-bin/wiki/EmacsNewbieWithIcicles.
+;;
+;;  This file continues the Icicles documentation, which starts in
+;;  file `icicles-doc1.el'.
+ 
+;;(@* "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index and render it more readable.  Likewise, for
+;;  the cross-references and section headings throughout this file.
+;;  You can get `linkd.el' here:
+;;  http://www.emacswiki.org/cgi-bin/wiki/linkd.el.
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Documentation in File `icicles-doc1.el'")
+;;  -----------------------------------------------------------
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Nutshell View of Icicles")
+;;    (@file :file-name "icicles-doc1.el" :to "README for Non-Readers")
+;;    (@file :file-name "icicles-doc1.el" :to "Toggle Options on the Fly")
+;;    (@file :file-name "icicles-doc1.el" :to "Cycle Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Display Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Prefix Completion and Apropos Completion")
+;;    (@file :file-name "icicles-doc1.el" :to "Chains of Simple Match Patterns - Progressive Completion")
+;;    (@file :file-name "icicles-doc1.el" :to "Chip Away the Non-Elephant")
+;;    (@file :file-name "icicles-doc1.el" :to "Choose Before You Act")
+;;    (@file :file-name "icicles-doc1.el" :to "Help on Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Perform Multiple Operations in One Command")
+;;    (@file :file-name "icicles-doc1.el" :to "Perform Alternative Operations on the Fly")
+;;    (@file :file-name "icicles-doc1.el" :to "Completion Status Indicators")
+;;    (@file :file-name "icicles-doc1.el" :to "Icicles Search")
+;;    (@file :file-name "icicles-doc1.el" :to "Complete Key Sequences Too")
+;;    (@file :file-name "icicles-doc1.el" :to "Available for Almost Any Input")
+;;    (@file :file-name "icicles-doc1.el" :to "Component Icicles Libraries")
+;;    (@file :file-name "icicles-doc1.el" :to "If You Are an Emacs-Lisp Programmer")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Inserting Text Found Near the Cursor")
+;;    (@file :file-name "icicles-doc1.el" :to "FFAP: Find File At Point")
+;;    (@file :file-name "icicles-doc1.el" :to "Proxy Candidates, `M-.'")
+;;    (@file :file-name "icicles-doc1.el" :to "Repeat `M-.' To Grab More or Different")
+;;    (@file :file-name "icicles-doc1.el" :to "Resolve File Names")
+;;  (@file :file-name "icicles-doc1.el" :to "Background on Vanilla Emacs Input Completion")
+;;  (@file :file-name "icicles-doc1.el" :to "Cycling Completions")
+;;  (@file :file-name "icicles-doc1.el" :to "Traversing Minibuffer Histories")
+;;  (@file :file-name "icicles-doc1.el" :to "Apropos Completions")
+;;  (@file :file-name "icicles-doc1.el" :to "Expanded-Common-Match Completion")
+;;  (@file :file-name "icicles-doc1.el" :to "Progressive Completion")
+;;    (@file :file-name "icicles-doc1.el" :to "`M-*': Matching Additional Regexps")
+;;    (@file :file-name "icicles-doc1.el" :to "Successive Approximation...")
+;;    (@file :file-name "icicles-doc1.el" :to "`M-&': Satisfying Additional Predicates")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Regressive Completion")
+;;  (@file :file-name "icicles-doc1.el" :to "Completion On Demand")
+;;  (@file :file-name "icicles-doc1.el" :to "Moving Between the Minibuffer and Other Buffers")
+;;  (@file :file-name "icicles-doc1.el" :to "Inserting a Regexp from a Variable or Register")
+;;  (@file :file-name "icicles-doc1.el" :to "Special Characters in Input Patterns")
+;;  (@file :file-name "icicles-doc1.el" :to "Alternative Libraries: Other Methods of Choosing Default Values")
+;;  (@file :file-name "icicles-doc1.el" :to "Exiting the Minibuffer Without Confirmation")
+;;  (@file :file-name "icicles-doc1.el" :to "*Completions* Display")
+;;  (@file :file-name "icicles-doc1.el" :to "Icompletion")
+;;    (@file :file-name "icicles-doc1.el" :to "icomplete+.el Displays the Number of Other Prefix Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Icicles Highlights the Input that Won't Complete")
+;;    (@file :file-name "icicles-doc1.el" :to "Icompletion in *Completions*: Apropos and Prefix Completion")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Sorting Candidates and Removing Duplicates")
+;;    (@file :file-name "icicles-doc1.el" :to "Changing the Sort Order")
+;;    (@file :file-name "icicles-doc1.el" :to "Defining New Sort Orders")
+;;    (@file :file-name "icicles-doc1.el" :to "Different Sorts for Different Sorts of Uses")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Get Help on Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Use Candidate Help Like You Use Emacs Command `apropos'")
+;;    (@file :file-name "icicles-doc1.el" :to "Other Icicles Apropos Commands")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands")
+;;    (@file :file-name "icicles-doc1.el" :to "What Is a Multi-Command?")
+;;    (@file :file-name "icicles-doc1.el" :to "How Does a Multi-Command Work?")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "More about Multi-Commands")
+;;    (@file :file-name "icicles-doc1.el" :to "Alternative Actions")
+;;    (@file :file-name "icicles-doc1.el" :to "Deleting Objects")
+;;    (@file :file-name "icicles-doc1.el" :to "Option `icicle-use-C-for-actions-flag'")
+;;    (@file :file-name "icicles-doc1.el" :to "Accessing Saved Locations (Bookmarks) on the Fly")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Icicles Tripping")
+;;    (@file :file-name "icicles-doc1.el" :to "Highlighting the Destination")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Key Completion")
+;;    (@file :file-name "icicles-doc1.el" :to "Completing Keys")
+;;    (@file :file-name "icicles-doc1.el" :to "`S-TAB' Is Everywhere - Start With It")
+;;    (@file :file-name "icicles-doc1.el" :to "Completing Keys By Name")
+;;    (@file :file-name "icicles-doc1.el" :to "Completing Prefix Keys")
+;;    (@file :file-name "icicles-doc1.el" :to "Meta Key Bindings")
+;;    (@file :file-name "icicles-doc1.el" :to "Navigate the Key-Binding Hierarchy")
+;;    (@file :file-name "icicles-doc1.el" :to "Local Bindings Are Highlighted")
+;;    (@file :file-name "icicles-doc1.el" :to "Completing Keys By Just Hitting Them")
+;;    (@file :file-name "icicles-doc1.el" :to "Key and Command Help")
+;;    (@file :file-name "icicles-doc1.el" :to "`S-TAB' Is a Multi-Command")
+;;    (@file :file-name "icicles-doc1.el" :to "Possible Source of Confusion")
+;;    (@file :file-name "icicles-doc1.el" :to "Three-Key Emacs")
+;;    (@file :file-name "icicles-doc1.el" :to "Entering Special and Foreign Characters")
+;;    (@file :file-name "icicles-doc1.el" :to "Handling Keymaps That Are Inaccessible From the Global Map")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Icicles Multi `M-x'")
+;;    (@file :file-name "icicles-doc1.el" :to "Examples of Using Multi `M-x'")
+;;      (@file :file-name "icicles-doc1.el" :to "What about describe-variable and describe-function?")
+;;
+;;    (@file :file-name "icicles-doc1.el" :to "Multi `M-x' Turns Every Command into a Multi-Command")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Choose All Completion Candidates")
+;;  (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Saving and Retrieving Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Different Places for Saving and Retrieving Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Set Operations")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Google Matching")
+;;    (@file :file-name "icicles-doc1.el" :to "Domain of Discourse")
+;;    (@file :file-name "icicles-doc1.el" :to "Global Filtering")
+;;    (@file :file-name "icicles-doc1.el" :to "Word Matching and String Matching")
+;;    (@file :file-name "icicles-doc1.el" :to "AND Matching and OR Matching")
+;;    (@file :file-name "icicles-doc1.el" :to "NOT Matching")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Buffer-Name Input")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "File-Name Input and Locating Files Anywhere")
+;;    (@file :file-name "icicles-doc1.el" :to "Function `read-file-name'")
+;;    (@file :file-name "icicles-doc1.el" :to "Function `completing-read'")
+;;    (@file :file-name "icicles-doc1.el" :to "Icicles Commands that Read File Names")
+;;    (@file :file-name "icicles-doc1.el" :to "Absolute File Names and Different Directories")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Persistent Sets of Completion Candidates")
+;;    (@file :file-name "icicles-doc1.el" :to "Saving Candidates in Cache Files")
+;;    (@file :file-name "icicles-doc1.el" :to "Filesets and Icicles Saved Completion Sets")
+;;    (@file :file-name "icicles-doc1.el" :to "Improving Performance with Persistent Sets")
+;;      (@file :file-name "icicles-doc1.el" :to "Avoid Remote File-Name Completion")
+;;      (@file :file-name "icicles-doc1.el" :to "Avoid Generating A Large Completion Set")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Dealing With Large Candidate Sets")
+;;  (@file :file-name "icicles-doc1.el" :to "History Enhancements")
+;;    (@file :file-name "icicles-doc1.el" :to "What Input, What History?")
+;;    (@file :file-name "icicles-doc1.el" :to "Overview of Minibuffer History Enhancements")
+;;    (@file :file-name "icicles-doc1.el" :to "Using Completion to Insert Previous Inputs: `M-o'")
+;;    (@file :file-name "icicles-doc1.el" :to "Putting Previous Candidates First: `C-M-,'")
+;;    (@file :file-name "icicles-doc1.el" :to "Matching Only Historical Candidates: `M-h' and `M-pause'")
+;;    (@file :file-name "icicles-doc1.el" :to "Using Other Histories; Commands Any Which Way")
+;;      (@file :file-name "icicles-doc1.el" :to "Completing Against All Interactive Commands")
+;;      (@file :file-name "icicles-doc1.el" :to "Using an Alternative History")
+;;    (@file :file-name "icicles-doc1.el" :to "Cleaning Up History Lists")
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Isearch Enhancements")
+;;    (@file :file-name "icicles-doc1.el" :to "Launch Occur using the Isearch Search String")
+;;    (@file :file-name "icicles-doc1.el" :to "Launch Icicles Search using the Isearch Search String")
+;;
+;;  (@* "Documentation in File `icicles-doc2.el'")
+;;  ----------------------------------------------
+;;
+;;  (@> "Icicles Search Commands, Overview")
+;;    (@> "Introduction: On Beyond Occur...")
+;;    (@> "How Icicles Search Works")
+;;    (@> "Why Use 2 Search Patterns?")
+;;    (@> "Search Outside the Defined Search Contexts")
+;;    (@> "Search Multiple Buffers, Files, and Bookmarks")
+;;    (@> "User Options for Icicles Searching")
+;;    (@> "Using Regexps with Icicles Search")
+;;
+;;  (@> "Search and Replace")
+;;  (@> "Other Icicles Search Commands")
+;;    (@> "Icicles Imenu")
+;;      (@> "Type-Specific Imenu Commands")
+;;      (@> "Imenu Commands that Search Full Definitions")
+;;      (@> "Icicles Imenu Combines Benefits of Imenu and Emacs Tags")
+;;
+;;    (@> "Compile/Grep Search")
+;;    (@> "Input Reuse in Interactive Interpreter Modes")
+;;    (@> "Define Your Own Icicles Search Commands")
+;;
+;;  (@> "Icicles Bookmark Enhancements")
+;;    (@> "Saving Regions and Selecting Them")
+;;    (@> "Setting a Bookmark and Jumping to a Bookmark")
+;;    (@> "Jumping to a Bookmark")
+;;    (@> "Searching Bookmarked Objects")
+;;
+;;  (@> "Icicles Enhancements for Emacs Tags")
+;;    (@> "`icicle-find-tag': Find Tags in All Tags Tables")
+;;    (@> "`icicle-find-first-tag': Find First Tag in Current Table")
+;;    (@> "`icicle-tags-search': Search and Replace Using Tags")
+;;
+;;  (@> "Icicles Shell-Command Enhancements")
+;;    (@> "Shell Command Completion as File-Name Completion")
+;;    (@> "Gotcha: `$' in Shell Commands")
+;;    (@> "Known Shell Commands as Proxy Candidates")
+;;
+;;  (@> "Icicles Dired Enhancements")
+;;    (@> "Search-and-Replace Marked Files")
+;;    (@> "Save Marked Files as Completion Candidates")
+;;    (@> "Open Dired for a Set of File Names")
+;;    (@> "Marked Files as a Project")
+;;    (@> "Shell Commands on Marked Files")
+;;
+;;  (@> "Icicles Info Enhancements")
+;;    (@> "Icicles Completion for Info")
+;;      (@> "Virtual Info Books")
+;;
+;;    (@> "Using Icicle-Search With Info")
+;;
+;;  (@> "Support for Projects")
+;;    (@> "Bookmarks for Project Access and Organization")
+;;    (@> "A Tags File Can Define a Project")
+;;    (@> "Navigating Among Code Definitions")
+;;    (@> "Searching Project Files")
+;;    (@> "Defining and Saving Sets of Files or Buffers")
+;;    (@> "Retrieving and Reusing a Saved Project")
+;;    (@> "Semantics? Roll Your Own?")
+;;
+;;  (@> "Using Complex Completion Candidates")
+;;  (@> "Icicles OO: Object-Action Interaction")
+;;    (@> "Apropos Completion as OO")
+;;    (@> "M-RET")
+;;    (@> "`icicle-object-action' and `icicle-anything'")
+;;    (@> "Icicles with Anything")
+;;
+;;  (@> "Multi-Completions")
+;;    (@> "Icicles Multi-Completion Commands")
+;;    (@> "How Multi-Completions Work")
+;;    (@> "Multi-Completions vs `completing-read-multiple'")
+;;
+;;  (@> "Dot, Dot, Dot")
+;;  (@> "Fuzzy Completion")
+;;    (@> "Partial Completion")
+;;    (@> "Scatter-Match Completion")
+;;    (@> "Swank (Fuzzy Symbol) Completion")
+;;    (@> "Fuzzy-Match Completion")
+;;    (@> "Levenshtein Completion")
+;;    (@> "Jaro-Winkler Completion")
+;;
+;;  (@> "Completion in Other Buffers")
+;;    (@> "Dynamic Abbreviation")
+;;    (@> "BBDB Completion")
+;;    (@> "Thesaurus Lookup and Completion")
+;;    (@> "Completion in Comint Modes")
+;;
+;;  (@> "Customization and General Tips")
+;;    (@> "Using Icicles with Delete Selection Mode")
+;;    (@> "Icicles User Options and Faces")
+;;
+;;  (@> "File-Name and Directory-Name Completion Tips")
+;;  (@> "Key Bindings")
+;;    (@> "Global Bindings")
+;;    (@> "Icicles-Mode Bindings")
+;;    (@> "Minibuffer Bindings")
+;;
+;;  (@> "Customizing Key Bindings")
+;;    (@> "Customizing Global Bindings")
+;;    (@> "Customizing Icicle Mode Bindings")
+;;    (@> "Customizing Minibuffer Bindings")
+;;
+;;  (@> "Icicles Redefines Some Standard Functions")
+;;  (@> "Programming with Fancy Candidates")
+;;  (@> "Programming Multi-Completions")
+;;    (@> "Variable icicle-list-use-nth-parts")
+;;    (@> "Variable icicle-candidate-properties-alist")
+;;    (@> "What You See Is Not What You Get")
+;;
+;;  (@> "Candidates with Text Properties")
+;;    (@> "Using Property icicle-special-candidate")
+;;    (@> "Applying Text Properties to a Candidate String")
+;;
+;;  (@> "Defining Icicles Commands (Including Multi-Commands)")
+;;    (@> "Nothing To It!")
+;;    (@> "Multi-Commands Are Easy To Define Too")
+;;    (@> "Are Users Dependent on Icicles To Use Multi-Commands?")
+;;
+;;  (@> "Defining Icicles Tripping Commands")
+;;  (@> "Defining Multiple-Choice Menus")
+;;  (@> "Defining Icicles Multi `M-x'")
+;;    (@> "How Multi `M-x' is Defined")
+;;
+;;  (@> "Defining Multi-Commands the Hard Way")
+;;  (@> "Global Filters")
+;;  (@> "Specifying Match Functions for Commands")
+;;  (@> "Defining Buffer-Text Completion for Comint Modes")
+;;  (@> "Note to Programmers")
+;;  (@> "La Petite Histoire")
+;;  (@> "Note on Non-`nil' `pop-up-frames' on MS Windows")
+ 
+;;(@* "Icicles Search Commands, Overview")
+;;
+;;  Icicles Search Commands, Overview
+;;  ---------------------------------
+;;
+;;  This section provides an overview of Icicles search.
+;;
+;;  See Also:
+;;
+;;  * The doc string (`C-h f') of command `icicle-search'; it provides
+;;    a boatload of general information about Icicles search.
+;;
+;;  * (@> "Other Icicles Search Commands") for specialized Icicles
+;;    search commands, including search in particular buffers.
+;;
+;;  * (@> "Icicles Info Enhancements") for information about using
+;;    Icicles to search in Info mode.
+;;
+;;  * (@> "Icicles Bookmark Enhancements") for information about
+;;    searching bookmarks.
+;;
+;;  * (@> "Support for Projects") for information about using `grep'
+;;    to search all of the files in a project.
+;;
+;;(@* "Introduction: On Beyond Occur...")
+;;  ** Introduction: On Beyond Occur... **
+;;
+;;  You've no doubt used standard Emacs command `occur'.  It finds all
+;;  lines in a buffer that match a regexp that you enter.  It displays
+;;  the matching lines as links in buffer `*Occur*' - you can click a
+;;  link to navigate to the corresponding line in the original buffer.
+;;  Using buffer `*Occur*' is similar to using the output of the Emacs
+;;  `grep' command.
+;;
+;;  Command `icicle-occur' is similar to `occur', but instead of
+;;  entering a regexp (with `RET') you type a regexp and then use
+;;  `S-TAB' to show the matching lines in buffer `*Completions*'.  As
+;;  usual in Icicles, you can complete to a single candidate, or cycle
+;;  among candidates to choose one.  To navigate to a match in the
+;;  original buffer, use `C-RET', `C-mouse-2', `C-next', or `C-prior'.
+;;  One advantage of `icicle-occur' over `occur' is that you can
+;;  change the regexp on the fly to match different sets of lines.
+;;
+;;  Another, major advantage is that you can use progressive
+;;  completion to find lines that match multiple regexps.  A similar,
+;;  but less interactive, effect can be had using chained `grep'
+;;  commands, but it is otherwise not possible with other search
+;;  methods such as regexp Isearch.  A regexp simply cannot express
+;;  intersection ("and") except in the limited form of "followed by".
+;;
+;;  Command `icicle-search' is a generalization of `icicle-occur'.
+;;  You enter an initial, search-context regexp (using `RET'), which
+;;  defines a set of completion candidates: all of the matching
+;;  strings in the current buffer (by default).  These candidates are
+;;  called "search contexts".
+;;
+;;  Command `icicle-occur' is really `icicle-search' with an implicit
+;;  initial regexp of `.*' (which you do not enter, however).  That
+;;  is, the initial completion candidates for `icicle-occur' are all
+;;  of the lines of the buffer (`.' matches any character except a
+;;  newline).
+;;
+;;  With `icicle-search', the candidates need not be single, complete
+;;  lines; they can be any strings in the buffer, including multi-line
+;;  strings.  Your initial regexp is used over and over to find the
+;;  set of matching strings in the region or buffer that you search.
+;;  These strings then serve as the completion candidates.
+;;
+;;  For example, you might use a search-context regexp of
+;;  "[A-Z][^.?!]+[.?!]" to search sentences, "\\(.+\n\\)+" to search
+;;  paragraphs, or "\\([^\f]*[\f]\\|[^\f]+$\\)" to search pages.
+;;  (That's in fact how convenience commands
+;;  `icicles-search-sentences', `icicles-search-paragraphs', and
+;;  `icicles-search-pages' are defined.)
+;;
+;;  `\f' is the form-feed, or page-separator, character.  You input
+;;  `\f', `\t', and `\n' using `C-q l', `C-q TAB', and `C-j',
+;;  respectively.  See (@> "Dot, Dot, Dot") for information about
+;;  multi-line dot (`.'), which matches also newline.
+;;
+;;  Again, you can use progressive completion (`M-*' or `S-SPC') to
+;;  match several different regexps within the same page or the same
+;;  sentence.  For example, you could find all sentences that contain
+;;  `character', `delete', and `backward', in any order, as follows:
+;;
+;;    C-c ` [A-Z][^.?!]+[.?!] RET
+;;    character M-* delete M-* backward
+;;
+;;  When you visit a search context, both `icicle-occur' and
+;;  `icicle-search' highlight that hit.  For `icicle-occur', the
+;;  search context is the current line.  For `icicle-search', it is
+;;  whatever your search-context regexp matches.
+;;
+;;(@* "How Icicles Search Works")
+;;  ** How Icicles Search Works **
+;;
+;;  There are several Icicles search commands, some of which are bound
+;;  to keys in Icicle mode:
+;;
+;;  `C-c '',  `icicle-occur' (aka `icicle-search-lines') -
+;;               An `occur' with incremental completion
+;;  `C-c `'   `icicle-search'   - Seach buffer areas that match regexp
+;;            `icicle-search-buffer' (`C-1') - Search selected buffers
+;;            `icicle-search-buff-menu-marked' - BufferMenu marked
+;;            `icicle-search-ibuffer-marked'   - Search Ibuffer marked
+;;            `icicle-search-dired-marked' - Search Dired marked files
+;;            `icicle-search-file' (`C--')     - Search selected files
+;;            `icicle-search-bookmarks-together' (`C-u'),
+;;              `icicle-search-bookmark'            - Search bookmarks
+;;            `icicle-search-*-bookmark'   - Bookmarks of a given type
+;;  `C-c $'   `icicle-search-word'           - Whole words as contexts
+;;  `C-c ^'   `icicle-search-keywords'   - Search with regexp keywords
+;;  `C-c `'   `icicle-compilation-search'    - Search compilation hits
+;;                                             (e.g `grep' hits)
+;;  `C-c "'   ["] `icicle-search-text-property' -
+;;                            Search text having a given text property
+;;            `icicle-search-overlay-property' -
+;;                         Search text having a given overlay property
+;;            `icicle-search-char-property' -
+;;                    Search text having a given text/overlay property
+;;            `icicle-search-pages'               - Search Emacs pages
+;;            `icicle-search-paragraphs'     - Search Emacs paragraphs
+;;            `icicle-search-sentences' - Search sentences as contexts
+;;            `icicle-search-thing'     - Search thing-at-point things
+;;                                        optionally ignoring comments
+;;            `icicle-search-xml-element' - Search XML elements
+;;            `icicle-search-xml-element-text-node'- Search text nodes
+;;
+;;  `C-c ='   `icicle-imenu' (aka `icicle-search-defs') -
+;;               Navigate among Imenu entries.
+;;            `icicle-imenu-command' -
+;;               Navigate among Emacs command definitions.
+;;            `icicle-imenu-non-interactive-function' -
+;;               Navigate among Emacs non-interactive function
+;;               definitions.
+;;  `C-c TAB' `icicle-comint-command' - Retrieve a past shell command.
+;;
+;;  There are many `icicle-search-*-bookmark' commands, for searching
+;;  within bookmarks of various types.  And for each of the
+;;  `icicle-menu*' commands there is a `-full' version that searches
+;;  the full text of a command etc. definition.
+;;
+;;  All Icicles search commands operate in the same general way:
+;;
+;;  1. Unlike standard incremental search, Icicles search commands
+;;     search the entire buffer, not just the part that follows the
+;;     cursor.  If the region is active, however, then the search is
+;;     confined to the region.  Some Icicles search commands let you
+;;     search across multiple buffers, multiple files, or multiple
+;;     bookmarks, including region bookmarks.  Searching within one or
+;;     more such regions of text is a first way to limit the context
+;;     of a search.
+;;
+;;  2. You limit the search context in a second way, by providing some
+;;     information, such as a regexp or a character property (text or
+;;     overlay property), that defines zones of text that you want to
+;;     search.  You can use (lax) completion against previous input to
+;;     enter the regexp or the character property.  In some cases, the
+;;     information (e.g. regexp) to define the search context is
+;;     provided automatically by the search command; for example,
+;;     `icicle-occur' assumes that you want to search lines.
+;;
+;;  3. If you use a regexp to define the search context, and if that
+;;     regexp has subgroups, that is, subexpressions of the form
+;;     `\(...\)', then you are prompted for the subgroup to use to
+;;     define the search context.  0 means the entire regexp match is
+;;     used as a context.  1 means that whatever the first subgroup
+;;     matches is used as a context, and so on.
+;;
+;;     Using a subgroup thus limits the search context in a third way.
+;;     It lets you find a search match within a larger search-match
+;;     context.  For example, you might choose a Lisp argument list as
+;;     the search context, specifying that it must follow `(defun ':
+;;     `(defun [^(]*\(([^(]*)\)'.  Subgroup 1 is the argument list.
+;;     Specifying a subgroup search context helps you become more
+;;     familiar with regexps.  Icicles search highlighting (see below)
+;;     shows you the subgroup matches instantly.
+;;
+;;  4. You can limit the set of search contexts in a fourth way, by
+;;     using `M-&' to provide predicates that search-context
+;;     candidates must satisfy.  Command `icicle-search' and its
+;;     derivative functions use candidates of the form (CONTEXT
+;;     . MARKER), where CONTEXT is a string, the search hit (search
+;;     context), and MARKER is a buffer marker that locates the
+;;     CONTEXT.  Predicates you supply to the `M-&' prompt must expect
+;;     such candidates.  Only contexts that satisfy the predicate are
+;;     found.  For example, if the predicate is (lambda (x) (commandp
+;;     (intern-soft (car x)))), then only contexts that name Emacs
+;;     commands are found.  Or, if you have a predicate `verbp' that
+;;     tests whether a word is an English verb form, then you can use
+;;     that to limit word matches to verbs.  In this way, you can
+;;     combine purely syntactic searching (regexp or text-property
+;;     match) with more semantic search criteria.  After building up a
+;;     complex predicate by using `M-&', you can save it to a variable
+;;     with `C-M-&' and then reuse it later with `C-='.
+;;     See also (@file :file-name "icicles-doc1.el" :to "Progressive Completion").
+;;
+;;  5. Icicles finds all of the qualified search contexts, and
+;;     presents them to you as completion candidates.  As always for
+;;     Icicles completion, the number of search hits (matching
+;;     candidates), is displayed in the mode-line of buffer
+;;     `*Completions*' - e.g., `72 candidates'.
+;;
+;;  6. You can navigate among the source-buffer search contexts, using
+;;     the multi-command action keys (`C-next', `C-prior', `C-RET',
+;;     `C-mouse-2').  The contexts are highlighted in the source
+;;     buffer(s).  You can scroll the current search-hits buffer
+;;     forward and backward using `C-M-v' and `C-M-S-v' (aka `C-M-V').
+;;     Whenever the destination would be off-screen, user option
+;;     `icicle-recenter' is passed to `recenter' to make it visible.
+;;
+;;  7. As always in Icicles, your current minibuffer input filters the
+;;     set of current candidates - the search contexts, so that only
+;;     those that contain matches to your input remain as candidates.
+;;     This is a second level of matching: looking for a refinement
+;;     pattern within the search contexts. And this constitutes a
+;;     fifth way you can limit the set of search contexts.
+;;
+;;  8. As always in Icicles, this input can be a regexp.  This is
+;;     ordinary apropos completion, applied to searching.  You do not
+;;     type `RET' to enter this regexp, and you can change it on the
+;;     fly to change the set of search hits.  Icicles searching is
+;;     thus incremental, in the sense that changing your input
+;;     dynamically changes the set of matching search hits.  Icicles
+;;     searching is not incremental with respect to the initial,
+;;     context matching, however.
+;;
+;;  9. As always in Icicles, you can type some input and then hit
+;;     `C-~' to remove all candidates that match that input.  Then
+;;     type some other input and hit `C-~' again to remove those
+;;     matches.  Or you can use `M-&' to define a predicate, and then
+;;     hit `C-~' to remove all candidates that satisfy that predicate.
+;;     And so on.  And you can use `S-mouse-2' or the `delete' key to
+;;     remove individual search hits.  These techniques let you chip
+;;     away at the search set, removing hits that are uninteresting.
+;;     This is a very powerful technique for both searching and
+;;     search-and-replace (see next), and it constitutes a sixth way
+;;     to limit the set of search contexts.  See also
+;;     (@file :file-name "icicles-doc1.el" :to "Chip Away the Non-Elephant").
+;;
+;;  10. You can sort the search hits in various ways.  This can
+;;     facilitate navigation and comparison of hits, as well as
+;;     search-and-replace (see #11).  And you can define your own
+;;     Icicles search commands that provide custom search orders for
+;;     particular kinds of search.  It is likely that you have never
+;;     considered being able to sort search hits, but if you think
+;;     about it you will see that this can be handy.  If you are
+;;     searching across multiple buffers, files, or bookmarks, sorting
+;;     helps you compare, visit, and replace related hits from the
+;;     different sources, instead of having to handle all of the hits
+;;     from each source in turn.
+;;
+;;  11. You can replace text while you search, forward, backward, or
+;;     randomly.  You can replace entire search contexts or just the
+;;     parts that match your current input.  You can use any
+;;     replacement string that is allowed by `query-replace-regexp'.
+;;     In Emacs 22 or later, this includes `\,', to substitute the
+;;     result of a Lisp evaluation.  Use the alternative-action keys
+;;     for replacement: `C-S-RET', `C-S-mouse-2', `C-S-down',
+;;     `C-S-up', `C-S-next', `C-S-prior', `C-S-end', and `C-S-home'.
+;;     At the first use, you are prompted for the replacement string;
+;;     it is used thereafter.  You can use `M-|'
+;;     (`icicle-all-candidates-list-alt-action') to replace all
+;;     matches.  See (@> "Search and Replace").
+;;
+;;  12. When you visit a search context (using `C-mouse-2' or
+;;     `C-down', for example), the part of the candidate that matches
+;;     your input is highlighted.  An entire search context is
+;;     highlighted in face `icicle-search-main-regexp-current', and
+;;     the part that matches your input is highlighted in face
+;;     `icicle-search-current-input'.  All other search contexts are
+;;     also highlighted (in face `icicle-search-main-regexp-others').
+;;
+;;  13. User option `icicle-search-highlight-all-current-flag'
+;;     controls whether the input matches are highlighted within each
+;;     search context or only within the current context.  It,
+;;     together with `icicle-expand-input-to-common-match-flag',
+;;     controls whether the input-match highlighting covers an
+;;     expanded common match among all matches or just the exact input
+;;     match.
+;;
+;;  14. If you do not use a subgroup to define the search context (as
+;;     in #3, above), that is, if the search context corresponds to
+;;     the entire search regexp, then up to eight context levels
+;;     (subgroups) are each highlighted differently, using faces
+;;     `icicle-search-context-level-1' through
+;;     `icicle-search-context-level-8'.  This context-level
+;;     highlighting is not done if user option
+;;     `icicle-search-highlight-context-levels-flag' is `nil'.
+;;
+;;  You might have noticed that out of these 14 search features, 6
+;;  constitute independent ways in which you can narrow or limit the
+;;  set of search hits among which you can navigate.  And another one
+;;  (sorting) further facilitates your observation and selection of
+;;  search hits.  Restricting the search space and making search-hit
+;;  patterns more evident are in fact what search is all about, and
+;;  Icicles offers you some unique tools to do this.
+;;
+;;  For several Icicles search commands, including `icicle-search'
+;;  (`C-c `'), you provide an initial regexp to define the search
+;;  contexts (step 1, above).  Why use two regexps to search (steps 1
+;;  and 4, above)?  To make things simpler.  Regular expressions are
+;;  powerful for searching, but they can also be cumbersome sometimes.
+;;  Why not use one simple regexp to set up a set of candidates and
+;;  then, optionally, use a second simple regexp to filter those
+;;  candidates?
+;;
+;;  This is the same idea as that behind progressive completion.  And
+;;  speaking of which, how would you find a line that contains a given
+;;  set of words (each of them), but in an arbitrary (unknown) order?
+;;  Progressive completion.  Which lines in this doc section contain
+;;  the words `which', `you', and `how', in any order?  If you are
+;;  reading this doc in file `icicles-doc2.el', then just use
+;;  `icicle-occur' with progressive completion:
+;;
+;;    C-c ' which M-SPC you M-SPC how
+;;
+;;  That narrows things down to four lines that you can then navigate
+;;  among.  Progressive completion gives Icicles search a power boost.
+;;
+;;  Like `icicle-occur', commands `icicle-search-word' (`C-c $') and
+;;  `icicle-search-keywords' (`C-c ^') are variants of `icicle-search'
+;;  that differ only in the regexp used.  Each accepts your input and
+;;  converts it to a regexp that does the right thing.
+;;  `icicle-search-word' just adds `\b' before and after the word you
+;;  type, so that it matches at word boundaries.
+;;
+;;  `icicle-search-keywords' wraps the keywords you provide as input
+;;  with regexp grouping (`\(...\)') and alternative (`\|') syntax, so
+;;  that search looks for any of the keywords.
+;;
+;;  "Keywords" here is an understatement. Each keyword is actually a
+;;  regexp and is treated as such, unless you use `C-`' to turn on
+;;  escaping of regexp special characters.  In that case, each keyword
+;;  is matched as a substring.  At the `C-c $' prompt, you can use
+;;  completion to choose keywords that you have already entered, or
+;;  you can use `C-RET' to enter new keywords.
+;;
+;;  As a shortcut, you can use the search string during incremental
+;;  search (Isearch) as the initial regexp for `icicle-search'.  You
+;;  do this by hitting `S-TAB' during Isearch.  This ends Isearch and
+;;  passes its search string to `icicle-search'.  This can be a handy
+;;  way to start `icicle-search', picking up its search pattern by
+;;  using, say, `C-s C-w C-w...'.
+;;  See (@file :file-name "icicles-doc1.el" :to "Launch Icicles Search using the Isearch Search String")
+;;
+;;(@* "Search Outside the Defined Search Contexts")
+;;  ** Search Outside the Defined Search Contexts **
+;;
+;;  For each of the predefined Icicles search commands, including for
+;;  `icicle-search' itself, you can alternatively choose to search,
+;;  not the search contexts as you define them, but the non-contexts,
+;;  that is, the buffer text that is outside (in between) the search
+;;  contexts as defined.
+;;
+;;  For example, if you use `icicle-search-thing' and you define sexps
+;;  as the search contexts, then this feature lets you search the
+;;  zones of text that are not within a sexp.  Or if you use
+;;  `icicle-search-text-property' (`C-c "'), you can search the zones
+;;  of text that do not have a text-property value that you specify
+;;  (e.g., property `face' with faces `font-lock-comment-face' and
+;;  `font-lock-comment-delimiter-face' - which means all code outside
+;;  comments).
+;;
+;;  To turn this context-complementing feature on and off, hit `C-M-~'
+;;  (`icicle-toggle-search-complementing-domain') during completion.
+;;  This is a toggle, and it affects only future search commands, not
+;;  the current one.
+;;
+;;(@* "Search Multiple Buffers, Files, and Bookmarks")
+;;  ** Search Multiple Buffers, Files, and Bookmarks **
+;;
+;;  If you provide a prefix argument to most Icicles search functions,
+;;  then you can search multiple buffers, files, or bookmarks.
+;;
+;;  * Plain prefix argument (`C-u') - Search multiple bookmarks of
+;;    various kinds.  To use this feature, you must also use library
+;;    `bookmark+.el'.  See (@> "Icicles Bookmark Enhancements").
+;;
+;;  * Non-negative numeric prefix argument (e.g. `C-9') - Search
+;;    multiple buffers - you are prompted for the buffers to search.
+;;    If the prefix argument is 99, then only buffers that are
+;;    visiting files are candidates.  You can use `C-RET' and so on to
+;;    choose individual buffers with completion.  You can use `C-!' to
+;;    choose all buffers or all buffers that match a regexp.
+;;    (See (@file :file-name "icicles-doc1.el" :to "Multi-Commands").)
+;;
+;;    Note: You can use `M-s i' in Ibuffer or Buffer Menu to search
+;;    all marked buffers using Icicles search.  In Ibuffer, menu item
+;;    `Icicles Search (and Replace)...' does the same thing as `M-s
+;;    i'.
+;;
+;;  * Negative numeric prefix argument (e.g. `C--') - Search multiple
+;;    files in the current directory - you are prompted for the files
+;;    to search.  As for multiple-buffer searching, you can use
+;;    `C-RET' and so on.
+;;
+;;    Note: You can use `M-s i' in Dired to search all marked files
+;;    using Icicles search.  Menu item `Search (and Replace)...' is
+;;    added to the Icicles submenu of menu `Multiple' (or `Operate'),
+;;    and it does the same thing as `M-s i'.
+;;
+;;  As a convenience, some specialized Icicles commands are defined
+;;  that correspond to `icicle-search' with the various
+;;  prefix-argument cases: `icicle-search-bookmarks-together',
+;;  `icicle-search-buffer', and `icicle-search-file'.  If you often
+;;  use `C-c `' with one of the prefix argument options, then you
+;;  might want to bind one or more of these commands.  These commands
+;;  are also available in the Icicles menu-bar menu (or the Search
+;;  menu, if it exists).
+;;
+;;(@* "User Options for Icicles Searching")
+;;  ** User Options for Icicles Searching **
+;;
+;;  You can customize the following user options, to control search
+;;  and replacement behavior.
+;;
+;;  * If `icicle-show-multi-completion-flag' is non-`nil' (the default
+;;    value), then, whenever you use a prefix argument, Icicles search
+;;    functions annotate each candidate with the name of the buffer
+;;    where the search hit occurs, highlighted, to help orient you.
+;;    The buffer name is actually part of the (multi-completion)
+;;    candidate, so you can match against it.
+;;
+;;    Note that even when the value of this option is `nil', if option
+;;    `icicle-help-in-mode-line-delay' is greater than zero then you
+;;    can see the buffer name in the mode-line (as well as the
+;;    position and length of the search context in the buffer).
+;;
+;;  * Icicles search functions that use an initial regexp highlight
+;;    the first `icicle-search-highlight-threshold' matches for that
+;;    regexp at once (using face `icicle-search-main-regexp-others').
+;;    The effect is similar to the Emacs 22+ lazy search highlighting
+;;    of Isearch (except that the highlighting is not in fact lazy).
+;;
+;;  * If `icicle-search-highlight-all-current-flag' is non-`nil', then
+;;    Icicles search functions highlight your current input match
+;;    within *all* search contexts at once.  If it is non-`nil' and
+;;    `icicle-expand-input-to-common-match-flag' is also non-`nil',
+;;    then what is highlighted for each input match is the expanded
+;;    common match among all input matches throughout the search area.
+;;    If either is `nil', then only the exact input match is
+;;    highlighted.
+;;
+;;    For example
+;;    (see (@file :file-name "icicles-doc1.el" :to "Nutshell View of Icicles")),
+;;    if the initial regexp defining the search context is
+;;    `.*recursive.*', and your input is `edit', then searching file
+;;    `icicles-doc1.el' highlights not `edit' but
+;;    ``abort-recursive-edit'', which is the longest common match
+;;    among all input matches.
+;;
+;;    Gotcha: Remember that the expanded common match pertains to the
+;;            entire completion candidate.  In the context of Icicles
+;;            search, if you are interested in multiple matches of
+;;            your input within the same search context, and you want
+;;            to be sure to catch each match, then turn off
+;;            common-match expansion.
+;;
+;;            Why?  The search context as a whole is compared with the
+;;            other search contexts when looking for the expanded
+;;            common match.  Your input is matched against the entire
+;;            context (search hit), and the expanded common match is
+;;            (typically) the longest match that is common to the
+;;            other search contexts.  Do not expect the longest common
+;;            match of your input against all occurrences in the
+;;            search contexts.  What counts is the longest single
+;;            match for a given context.
+;;
+;;            For example, if your input is `then' and two of the
+;;            search hits are `But then X and then Y' and `W and then
+;;            Z', the expanded common match will be `and then', not
+;;            `then'.  The matches highlighted for your input thus do
+;;            not include each occurrence of `then' in the search
+;;            hits, but rather each occurrence of `and then'.
+;;
+;;    If `icicle-expand-input-to-common-match-flag',
+;;    `icicle-search-highlight-all-current-flag', and
+;;    `icicle-search-replace-common-match-flag' are all non-`nil',
+;;    then a search replacement replaces the expanded common match;
+;;    otherwise, it replaces only the exact match.
+;;
+;;    The default value of `icicle-search-highlight-all-current-flag'
+;;    is `nil', because non-`nil' can impact performance negatively if
+;;    there are many search contexts - the highlighting is updated
+;;    with each input change.  You can toggle the value at any time
+;;    using command `icicle-toggle-highlight-all-current', bound to
+;;    `C-^' in the minibuffer during Icicles search.
+;;
+;;  * If option `icicle-search-cleanup-flag' is non-`nil' (the default
+;;    value) then search highlighting is removed after the search.  If
+;;    you set this to `nil' then you can remove search highlighting
+;;    manually later using command `icicle-search-highlight-cleanup'.
+;;    You can toggle this search highlight removal at any time using
+;;    command `icicle-toggle-search-cleanup', which is bound to `C-.'
+;;    in the minibuffer during Icicles search.
+;;
+;;    One use of `nil' `icicle-search-cleanup-flag' is to highlight
+;;    regexp matches throughout a region or buffer (or multiple files
+;;    or...).  In that capacity, Icicles search functions act like
+;;    some of the highlighting commands in my library `highlight.el'.
+;;    Note that when `icicle-search-cleanup-flag' is `nil', *all*
+;;    Icicles search highlighting remains: last-visited search
+;;    context, other context matches, current-input matches, and even
+;;    regexp subgroups.  The faces for these are, respectively:
+;;
+;;    - `icicle-search-main-regexp-current'
+;;    - `icicle-search-main-regexp-others'
+;;    - `icicle-search-highlight-input-matches-here' (everywhere, if
+;;      `icicle-search-highlight-all-current-flag' is non-`nil')
+;;    - `icicle-search-context-level-1' through
+;;      `icicle-search-context-level-8'
+;;
+;;  * If `icicle-search-replace-whole-candidate-flag' is `nil', then
+;;    whatever matches your current input is replaced, within the
+;;    current search context, when you perform replacement
+;;    (e.g. `C-S-RET').  If the value is non-`nil' (the default
+;;    value), then the entire search context is replaced, instead.
+;;    You can use `M-_' at any time during searching and replacing, to
+;;    toggle the value.
+;;
+;;  * Command `icicle-search-word' (bound to `C-c $') always searches
+;;    for a whole word: your initial search string is matched only
+;;    against whole words.  Non-`nil' `icicle-search-whole-word-flag'
+;;    makes other Icicles search commands also perform whole-word
+;;    searching.  You can use `M-q' while searching to toggle this
+;;    option; the new value takes effect for the next complete search.
+;;
+;;    Whole-word searching here means that matches can contain
+;;    embedded strings of non word-constituent chars (they are skipped
+;;    over, when matching, included in the match), and any leading or
+;;    trailing word-constituent chars in the search string are dropped
+;;    (ignored for matching, not included in the match).  This means,
+;;    for instance, that you can match `foo-bar' as a word, even in
+;;    contexts (such as Emacs Lisp) where `-' is not a
+;;    word-constituent character.  Similarly, you can include embedded
+;;    whitespace in a "word", e.g., `foo bar'.
+;;
+;;  * You can toggle `icicle-use-C-for-actions-flag' at any time using
+;;    `M-g' in the minibuffer.  This is handy for multi-commands that
+;;    browse, such as Icicles search.  It means that you can use
+;;    `next' and so on instead of `C-next' and so on to navigate among
+;;    search hits.  See
+;;    (@file :file-name "icicles-doc1.el" :to "Option `icicle-use-C-for-actions-flag'").
+;;
+;;  * Non-`nil' option `icicle-ignore-comments-flag' means that
+;;    `icicle-search-thing' and related commands
+;;    (e.g. `icicle-search-xml-element') ignore comments.  That is,
+;;    they hide comments temporarily while they scan the region or
+;;    buffer for things of the given type to serve as search contexts
+;;    (completion candidates).  This prevents them, for example, from
+;;    presenting as a candidate a sexp or a list that is commented
+;;    out.  You can toggle this option anytime using `C-M-;' in the
+;;    minibuffer, but to see the effect you might need to invoke the
+;;    current command again.
+;;
+;;  * `icicle-search-hook': Functions run after searching and moving
+;;    to a match, whether by `RET' or `C-RET' (or `C-next' or
+;;    `C-prior').
+;;
+;;  It can sometimes be useful to highlight all regexp matches using a
+;;  large value of `icicle-search-highlight-threshold' and a `nil'
+;;  value of `icicle-search-cleanup-flag', and then set
+;;  `icicle-search-highlight-threshold' to zero and use an Icicles
+;;  search function again with a different regexp to search through
+;;  the same region or buffer.  This lets you see the relation between
+;;  the two sets of regexp matches.
+;;
+;;(@* "Using Regexps with Icicles Search")
+;;  ** Using Regexps with Icicles Search **
+;;
+;;  You can use Icicles search to find text entities of a certain kind
+;;  - sentences, paragraphs, file names, URLs, and so on.  A
+;;  convenient way to do this is to use `C-='
+;;  (`icicle-insert-string-from-variable') or `C-x r i'
+;;  (`insert-register') in the minibuffer to insert a predefined
+;;  regexp that matches a particular kind of text entity.  Which of
+;;  these you use depends on whether the regexp string is saved in a
+;;  variable (`C-=') or a register (`C-x r i').
+;;
+;;  For example, suppose you are in a mail client and you want to move
+;;  between mail headers.  If you use a regexp that matches the header
+;;  field you want (e.g. the sent date or sender) then Icicles search
+;;  highlights all such occurrences and lets you navigate among them -
+;;  instant mail browser!  Or, suppose you are in a C++ or Perl file
+;;  and you want to navigate among function definitions or other
+;;  definitions.  If you have a canned regexp that matches the start
+;;  of a definition, then you can use `C-=' to quickly turn
+;;  `icicle-search' into a code browser.  In a log file, navigate
+;;  among date or time entries or IP addresses...  Of course, most
+;;  programming modes and mail clients already provide other ways to
+;;  navigate, but you get the idea - Icicles search provides a general
+;;  way to navigate among things, as long as you can match them with
+;;  regexps, and `C-=' lets you quickly access a library of predefined
+;;  regexps.
+;;
+;;  You can find useful regexps to store in variables in the standard
+;;  Emacs Lisp libraries.  Grep for `font-lock-keywords' or `regexp'
+;;  in the Emacs `lisp' directory and its subdirectories.
+;;
+;;   See `align.el' for regexps for programming languages.
+;;   See `url-dav.el' for regexps matching ISO 8601 dates.
+;;   See `rmail.el', `sendmail.el', and `mh-show.el' for regexps
+;;   matching mail-header fields.
+;;
+;;  Imenu regexps occurring as parts of different values of
+;;  `imenu-generic-expression' for different buffer types can be used
+;;  as variable values for `C-='.  They all work fine with
+;;  `icicle-search', turning it into a navigator for the given mode.
+;;  See, for example, `generic-x.el' and `lisp-mode.el'.  Here is a
+;;  regexp for Javascript function definitions from `generic-x.el':
+;;
+;;   "^function\\s-+\\([A-Za-z0-9_]+\\)"
+;;
+;;  And `lisp-imenu-generic-expression' (in `lisp-mode.el') provides
+;;  regexps for Lisp function, variable, and type definitions.  Here
+;;  is the variable-definition regexp:
+;;
+;;   "^\\s-*(\\(def\\(c\\(onst\\(ant\\)?\\|ustom\\)\\|ine-symbol-macro
+;;   \\|parameter\\|var\\)\\)\\s-+\\(\\(\\sw\\|\\s_\\)+\\)"
+;;
+;;  You certainly do not want to type a regexp like that into the
+;;  minibuffer (and the function-definition regexp is twice as
+;;  complex)!  Put it into a variable or register once and use `C-='
+;;  or `C-x r i' from then on to retrieve it - simple.
+;;
+;;  If it's so simple, then why not let a command do it?  This is
+;;  exactly what command `icicle-imenu' (bound to `C-c =') does.  You
+;;  do not need to bother looking up Imenu regexps and assigning them
+;;  to variables for use with `C-=' and `icicle-search'-
+;;  `icicle-imenu' does that for you automatically.
+;;  See (@> "Other Icicles Search Commands").
+;;
+;;  In sum: For complete interactivity, type a regexp dynamically as
+;;  input to `icicle-search'.  For isolated special regexps that you
+;;  use, save them in variables and use `C-=' with `icicle-search'.
+;;  For well-defined sets of regexps, especially if used frequently,
+;;  define a command that uses `icicle-search'.  There is a spectrum
+;;  of use cases for `icicle-search'.
+;;
+;;  Command `icicle-search' is very general and very powerful.  It
+;;  might never replace incremental search - either regexp or literal
+;;  string search, but in some cases it can be quite handy.  Think of
+;;  it as another tool to add to your search-tool belt.  Admittedly,
+;;  it does take a little getting used to.  Remember, in particular,
+;;  that the initial, context regexp you enter (with `RET') cannot be
+;;  changed without re-executing `icicle-search'.
+;;
+;;  And remember too that `C-l' (`icicle-retrieve-previous-input') is
+;;  your friend - it clears the minibuffer during cycling, retrieving
+;;  your last real input.  Use it to modify your second and subsequent
+;;  regexps on the fly - those that filter the initial candidate list
+;;  further.  You can repeat `C-l' to retrieve older completion
+;;  inputs, and you can use `C-S-l' (that is, `C-L') to cycle previous
+;;  inputs in the other direction.  See
+;;  (@file :file-name "icicles-doc1.el" :to "History Enhancements").
+;;
+;;  Oh - And do not forget that you can do things like take the
+;;  complement of your fine-tuning regexp matches, within the context
+;;  of your coarse-tuning matches.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates").
+;;
+;;  For example, use `^.*defun.*$' as the main regexp, to find all
+;;  lines containing `defun'.  Then type `icicle' to match only the
+;;  lines with `defun' that also contain `icicle'.  Then complement
+;;  (`C-~') that set, to see the lines that contain `defun' but not
+;;  `icicle'.
+;;
+;;  And you can then save that set of matches, and then subtract it
+;;  from another set of matches in a different search...  You get the
+;;  idea.  When performing set operations combined with
+;;  `icicle-search', keep in mind that the saved set does not include
+;;  any position information - it is only a set of matching strings.
+;;  So, in particular, a set-union operation (`C-+') is not useful
+;;  with `icicle-search' (adding a saved set of strings without
+;;  positions is useless).  Still, you can do things like match lines
+;;  that contain `defun' followed somewhere by `()', and then subtract
+;;  the (saved) set of lines in the same region that contain `icicle'.
+;;  Try it in an Icicles library, using regexps `.*icicle.*$' and
+;;  `^*.defun.*().*$'.
+;;
+;;  One more reminder: When you save a set of completion candidates
+;;  (`C-M->'), make sure that you actually have a set of candidates to
+;;  save!  It is not enough to just enter a regexp at the
+;;  `icicle-search' prompt.  You must also use some Icicles command,
+;;  such as `TAB', `S-TAB', `next', or `down' to tell Icicles how to
+;;  create the candidate set - how to match the regexp.
+;;
+;;  See Also:
+;;
+;;  * The doc string (`C-h f') of command `icicle-search'; it provides
+;;    general information about Icicles search.
+;;
+;;  * (@> "Other Icicles Search Commands") for specialized Icicles
+;;    search commands `icicle-comint-search',
+;;    `icicle-compilation-search', `icicle-imenu',
+;;    `icicle-imenu-command', `icicle-imenu-non-interactive-function',
+;;    `icicle-search-char-property', `icicle-search-keywords',
+;;    `icicle-search-overlay-property', and
+;;    `icicle-search-text-property'.
+;;
+;;  * (@> "Search and Replace") for information about replacing search
+;;    hits or parts of search hits.
+;;
+;;  * (@> "Customization and General Tips") for information about the
+;;    `icicle-search-*' faces, which control Icicles search.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Progressive Completion")
+;;    for information about `M-*' and `M-&'.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Multi-Commands") for
+;;    information about `C-RET', `C-mouse-2', `C-next', and `C-prior'.
+;;
+;;  * (@> "Icicles Bookmark Enhancements") for information about
+;;    searching bookmarks.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Inserting a Regexp from a Variable or Register")
+;;    for more about inserting a saved string.
+;;
+;;  * (@> "Icicles Info Enhancements") for information about using
+;;    Icicles to search in Info mode.
+ 
+;;(@* "Search and Replace")
+;;
+;;  Search and Replace
+;;  ------------------
+;;
+;;  Replacement during Icicles search is something quite different
+;;  from anything you are used to.  There are several different ways
+;;  to replace search-hit text during Icicles search, and it can be a
+;;  bit of a challenge to understand all the possibilities.  So my
+;;  advice is to experiment, as well as to read the descriptions here.
+;;
+;;  You can replace the current search match by using any of the
+;;  alternative action keys: `C-S-RET', `C-S-mouse-2' (in
+;;  `*Completions*'), `C-S-down', `C-S-up', `C-S-next', `C-S-prior',
+;;  `C-S-end', or `C-S-home', .  You can use `M-|'
+;;  (`icicle-all-candidates-list-alt-action') to replace all matches
+;;  of your current input at once, throughout the search space.
+;;
+;;  At the first use of any of these, you are prompted for the
+;;  replacement pattern; it is used thereafter, or until you use `M-,'
+;;  (`icicle-search-define-replacement').  You can use `M-,' at any
+;;  time during searching to change the pattern for subsequent
+;;  replacements.  The replacement pattern can be anything that is
+;;  allowed as a replacement by `query-replace-regexp'.  In Emacs 22
+;;  or later, this includes Lisp sexp evaluation via `\,'.
+;;
+;;  Unlike `query-replace', you need not visit each search match - you
+;;  can visit and replace selected matches in any order.  Some other
+;;  differences from standard `query-replace' and
+;;  `query-replace-regexp':
+;;
+;;   * Replacing matches of your current input provides a contextual
+;;     replacement feature: replace `foo' by `fu', but only in zones
+;;     that match `toto.*titi'.
+;;
+;;   * Icicles search navigation (`C-next', etc.) lets you replace
+;;     individual search hits without navigating through each search
+;;     context in turn: direct access.
+;;
+;;   * In Icicles search, replace-all (`M-|') means replace all
+;;     matches of your current input, throughout the search space, not
+;;     just all matches that follow the cursor.  And remember that you
+;;     can (a) activate the region to limit the search-and-replace
+;;     space and (b) use progressive completion etc. to narrow the set
+;;     of hits.
+;;
+;;   * You can act across multiple buffers, files, or bookmarks -
+;;     see information about the `icicle-search' prefix arg.
+;;
+;;   * You can also replace matches within text-property search
+;;     contexts - just use `icicle-search-text-property' (`C-c "') ["]
+;;     as the search command.
+;;
+;;  Search matches are replaced - but just what is meant by a "search
+;;  match"?  It can be either an entire search context or each match
+;;  of your current minibuffer input within a search context.
+;;
+;;  Anytime during search and replace:
+;;
+;;   * `M-,' redefines the replacement string.
+;;
+;;   * `C-`' toggles `icicle-toggle-regexp-quote' (as always).  This
+;;     escapes regexp special characters, so that search is literal.
+;;
+;;   * `M-q' toggles `icicle-search-whole-word-flag'.  By default,
+;;     this is `nil', meaning that searching is not for whole words
+;;     (except for `icicle-search-word', bound to `C-c $').
+;;
+;;   * `C-M-`' toggles `icicle-search-replace-literally-flag'.  By
+;;      default, this is `nil', which means that `\' character
+;;      sequences in replacement text are intrepreted as for
+;;      `query-replace-regexp'.
+;;
+;;   * `M-_' toggles `icicle-search-replace-whole-candidate-flag'.  By
+;;     default, this is non-`nil', which means that the entire current
+;;     search context is replaced, that is, whatever matches the
+;;     context regexp that you entered initially using `RET'.
+;;     However, you can use `M-_' anytime during searching to toggle
+;;     between this default behavior and replacement of whatever your
+;;     current minibuffer input matches.
+;;
+;;   * `M-;' toggles `icicle-search-replace-common-match-flag'.
+;;     Together with other options, it controls whether to replace the
+;;     expanded common match or just the exact match.  See below.
+;;
+;;  REMEMBER THIS:
+;;
+;;  - If `icicle-search-replace-whole-candidate-flag' is true
+;;    (non-`nil'), then the granularity of replacement is a complete
+;;    search context.  In this case, replacement behaves similarly to
+;;    `query-replace-regexp' (except that special replacement
+;;    constructs, such as `\#', are not treated as such).  You can
+;;    still use minibuffer input to filter the set of search contexts,
+;;    but replacement is on a whole-context basis.
+;;
+;;  - If `icicle-search-replace-whole-candidate-flag' is false
+;;    (`nil'), then you can replace multiple input matches separately
+;;    within a search context (using `C-S-RET').  This behavior is
+;;    unique to Icicles.  You cannot, however skip over one input
+;;    match and replace the next one in the same context - `C-S-RET'
+;;    always replaces the first available match in the context
+;;    (repeated use changes which is first).  When
+;;    `icicle-search-replace-whole-candidate-flag' is `nil', you can
+;;    also use special replacement constructs, such as `\#'.
+;;
+;;  If `icicle-search-replace-whole-candidate-flag' is true, then you
+;;  can use the navigational alternative action keys, `C-S-down',
+;;  `C-S-up', `C-S-next', `C-S-prior', `C-S-end', and `C-S-home',
+;;  repeatedly to replace successive search contexts.  At the buffer
+;;  limits, these commands wrap around to the other buffer limit (last
+;;  search context to first, and vice versa).
+;;
+;;  Search traversal using these go-to-next-context-and-replace keys
+;;  is always by search context, not by individual input match.  This
+;;  means that you cannot use these keys to replace input matches
+;;  within a search context.
+;;
+;;  If `icicle-search-replace-whole-candidate-flag' is false, then you
+;;  can use these keys to replace the first input match.  More
+;;  importantly, you can use `C-S-RET' to replace that first match,
+;;  without moving on to the next context.  Because `C-S-RET' always
+;;  acts on the current search hit (context), using it again, after
+;;  you have used it to replace the first such match, replaces the
+;;  next one.  And so on.
+;;
+;;  Thus, if your input matches multiple parts of a search context and
+;;  you want to replace these matches, use `C-S-RET' repeatedly.
+;;  After all of the matches in the current context have been
+;;  replaced, `C-S-RET' replaces the first match in the next context.
+;;  (There is a gotcha, however, if the replacement text matches your
+;;  input - see below.)
+;;
+;;  You can thus traverse all matches of your input, in the current
+;;  sort order (by default, the order they appear in the source being
+;;  searched), by just repeating `C-S-RET'.  At the buffer limits,
+;;  repeating `C-S-RET' wraps around.
+;;
+;;  `C-S-RET' always replaces the first input match in the
+;;  current search context or, if there are no matches, then the first
+;;  input match in the next context.  This behavior has these
+;;  important consequences:
+;;
+;;  * If you repeat `C-S-RET' and the previous replacement no longer
+;;    matches your input, then `C-S-RET' moves on to the next input
+;;    match (which is now the first one) and replaces that.  This is
+;;    why you can usually just repeat `C-S-RET' to successively
+;;    replaces matches of your input, including from one context to
+;;    the next.
+;;
+;;  * If, on the other hand, after replacement the text still matches
+;;    your input, then repeating `C-S-RET' will just replace that
+;;    match.  For example, if you replace the input match `ab' by
+;;    `abcd', then repeating `C-S-RET' produces `abcd', then `abcdcd',
+;;    then `abcdcdcd',...
+;;
+;;  * You cannot replace an input match, skip the next match, and then
+;;    replace the following one, all in the same context.  You can,
+;;    however, replace some matches and then skip (e.g. `C-next') to
+;;    the next context.
+;;
+;;  What your input matches, hence what gets replaced if
+;;  `icicle-search-replace-whole-candidate-flag' is `nil', depends on
+;;  a few Icicles options:
+;;
+;;  - `icicle-regexp-quote-flag' determines whether to use regexp
+;;    matching or literal matching.
+;;
+;;  - `icicle-search-highlight-all-current-flag',
+;;    `icicle-expand-input-to-common-match-flag' and
+;;    `icicle-search-replace-common-match-flag' together determine
+;;    whether to replace exactly what your input matches in the
+;;    current search hit or the expanded common match (ECM) of your
+;;    input among all search hits.  If any of these options is `nil',
+;;    then your exact input match is replaced; otherwise, the ECM is
+;;    replaced.
+;;
+;;  The replacement string can be nearly anything that is allowed as a
+;;  replacement by `query-replace-regexp'.  In Emacs 22 or later, this
+;;  includes Emacs-Lisp sexp evaluation via `\,' and constructs such
+;;  as `\#' and `\N' (back references).  You can also use `\?', but it
+;;  is not very useful - you might as well use `M-,' instead, to
+;;  change the replacement text.
+;;
+;;  Finally, let me repeat what I said at the beginning of this page:
+;;  Icicles search-and-replace is different from what you are used to,
+;;  and there are several different ways to use it.  Experiment to get
+;;  to know how it works, and reread the description here.
+;;
+;;  It is important to understand the various user options (with their
+;;  toggle commands) and their effects.  They can radically change the
+;;  behavior of replacement.
+;;
+;;  In particular, to put Icicles search-and-replace to best advantage
+;;  you need to know what gets replaced, depending on those user
+;;  options: the whole search hit vs only input matches, an exact
+;;  input match vs the expanded common match.  Experiment with the
+;;  toggles `M-_', `C-^', `C-;', and `M-;'.  And you need to know how
+;;  repeated `C-S-RET' works vs repeated `C-S-next'.
+;;
+;;  I know it's tricky to learn.  Experimenting helps.  If something
+;;  happens that you did not expect, reread this section and try to
+;;  understand.  Have fun.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Search Commands, Overview") and the doc string of
+;;    `icicle-search' for more information about search-and-replace.
+;;
+;;  * (@> "Compile/Grep Search") for information about using
+;;    search-and-replace with `grep' buffers and compilation buffers.
+;;
+;;  * (@* "Icicles Dired Enhancements") for information about using
+;;    search-and-replace on marked files in Dired.
+ 
+;;(@* "Other Icicles Search Commands")
+;;
+;;  Other Icicles Search Commands
+;;  -----------------------------
+;;
+;;  Function `icicle-search' is very general.  As is explained in
+;;  (@> "Icicles Search Commands, Overview"), command `icicle-occur'
+;;  is defined trivially using `icicle-search' - it is basically
+;;  `icicle-search' with a regexp of `.*', to match lines.  Similarly,
+;;  `icicle-search-word' (`C-c $') uses a regexp of `\bWORD\b', where
+;;  `WORD' is the word to look for, and `icicle-search-keywords'
+;;  (`C-c ^') uses a regexp of `\(KW1\|KW2\|KW2...\|KWn\)', where the
+;;  `KWm' are the keywords (regexps) to look for.
+;;
+;;  Still other Icicles commands are available that make use of
+;;  `icicle-search'.  And you can define your own, specialized search
+;;  commands along the same lines.  To do that, it is instructive to
+;;  look at the source code of the commands described in this section;
+;;  they can serve as a model for defining your own search commands.
+;;
+;;  Two of the commands described here, `icicle-compilation-search'
+;;  and `icicle-comint-search', are specialized versions of
+;;  `icicle-search' that work only in particular buffers where there
+;;  is little need for `icicle-search' itself. For this reason, these
+;;  commands reuse the key sequence, `C-c `' (backquote), that is
+;;  normally bound to `icicle-search'.  This shadow binding occurs if
+;;  the current major mode is a compilation mode (for
+;;  `icicle-compilation-search') or an interactive interpreter mode
+;;  such as `shell-mode' or Lisp interactive mode (for
+;;  `icicle-comint-search').
+;;
+;;  [Programmer Note: Actually, the way this works is that `C-c `' is
+;;  bound to the value of internal variable `icicle-search-generic'.
+;;  You can use this mechanism to provide custom Icicles search
+;;  commands for particular buffers.]
+;;
+;;  Besides the commands described in this section, there are Icicles
+;;  search commands for navigating tags-file definitions and searching
+;;  their associated source files.  These are described in section
+;;  (@> "Icicles Enhancements for Emacs Tags").
+;;
+;;  If you use `M-g' in the minibuffer to toggle option
+;;  `icicle-use-C-for-actions-flag', then you can use just `next'
+;;  instead of `C-next' to navigate when using any Icicles search
+;;  command.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Option `icicle-use-C-for-actions-flag'").
+;;
+;;(@* "Searching Text with Properties")
+;;  ** Searching Text with Properties **
+;;
+;;  Instead of providing a context regexp, for commands
+;;  `icicle-search-char-property', `icicle-search-overlay-property',
+;;  and `icicle-search-text-property' (`C-c "') ["] you provide a
+;;  character property (e.g. `face') and its value
+;;  (e.g. `font-lock-function-name-face').  All zones of text that
+;;  have that property with that value become the completion
+;;  candidates (search hits).  As always, you can filter this set of
+;;  candidates by typing input in the minibuffer.
+;;
+;;  By a "character property" is meant either a text property or an
+;;  overlay property.  `icicle-search-char-property' searches both
+;;  kinds of character property; `icicle-search-overlay-property'
+;;  searches only overlay properties; and
+;;  `icicle-search-text-property' (`C-c "' ["]) searches only text
+;;  properties.
+;;
+;;  For example, if you use `icicle-search-char-property' with a
+;;  `face' property value `highlight', then the text searched includes
+;;  text with that overlay value and text with that text-property
+;;  value.  With a `face' property value of `font-lock-string-face',
+;;  you can browse or search doc strings, and so on.
+;;
+;;  If the property chosen is `face', then you can in fact choose
+;;  multiple faces, in multi-command fashion (e.g. `C-mouse-2'), and
+;;  the text that is searched has at least one of the faces you
+;;  choose.  If you choose no face value (empty input), then the
+;;  target is text that has any face at all.  The search hits are
+;;  zones of text that are distinguished by their `face' values.
+;;
+;;  As with other Icicles search commands, a prefix argument controls
+;;  whether these character-property commands search the current
+;;  buffer, selected bookmarks, selected files, or selected buffers.
+;;  However, keep in mind that, since in this case you are searching
+;;  character properties, you will find search hits only for buffers
+;;  that already have such properties, for example, buffers that have
+;;  been fontified.
+;;
+;;(@* "Icicles Imenu")
+;;  ** Icicles Imenu **
+;;
+;;  Command `icicle-imenu', which is bound to `C-c =', is an Imenu
+;;  browser.  It lets you use Icicles completion to navigate among or
+;;  search the content of definitions of functions, variables, macros,
+;;  keys, and so on in a programming language (any language that Imenu
+;;  handles).  As always in Icicles, your current input (e.g. a
+;;  regexp) filters the set of available candidates.  That is, you can
+;;  match against parts of an Imenu entry - any parts.  That's
+;;  particularly useful if there are many entries in the Imenu menu;
+;;  you do not need to read/scan the whole list.
+;;
+;;  If you look at the definition of `icicle-imenu' you'll see that it
+;;  simply lets you choose an Imenu submenu (`Functions', `User
+;;  Options', and so on) that is appropriate for the current buffer
+;;  type, and then it calls `icicle-search', passing it the
+;;  appropriate Imenu regexp.  You can similarly define your own
+;;  specialized search commands using `icicle-search' to browse regexp
+;;  matches.  You get all of the features of `icicle-search' when you
+;;  do that.  For example, `icicle-imenu' gives you these advantages
+;;  over a standard Imenu menu:
+;;
+;;  * You can restrict navigation (search) to a region.
+;;
+;;  * You can navigate (browse) among multiple entries, instead of
+;;    choosing them one by one from a menu.
+;;
+;;  * You can restrict the entries to browse using (regexp) pattern
+;;    matching.
+;;
+;;  * As for `icicle-search', you can search multiple bookmarks,
+;;    multiple buffers, or multiple files.
+;;
+;;(@* "Type-Specific Imenu Commands")
+;;  *** Type-Specific Imenu Commands ***
+;;
+;;  In addition, Icicles provides specializations of `icicle-imenu',
+;;  to find only definitions of particular types:
+;;
+;;  `icicle-imenu-command', `icicle-imenu-face',
+;;  `icicle-imenu-key-explicit-map', `icicle-imenu-key-implicit-map',
+;;  `icicle-imenu-macro', `icicle-imenu-non-interactive-function',
+;;  `icicle-imenu-user-option', `icicle-imenu-variable'
+;;
+;;  All of these commands use only the Imenu regexps that match
+;;  entities of different types.  Because these regexps were designed
+;;  (for Imenu) only to locate the start of a definition, they
+;;  generally do not match full definitions.  This makes them OK for
+;;  use by an Icicles multi-command as a browser, to navigate among
+;;  definitions.  But it does not make them useful for searching the
+;;  content of definitions.
+;;
+;;(@* "Imenu Commands that Search Full Definitions")
+;;  *** Imenu Commands that Search Full Definitions ***
+;;
+;;  Icicles also provides a similar set of commands, with the same
+;;  names but with suffix `-full', which do use full definitions as
+;;  the completion candidates, so you can search those bodies.  When
+;;  you only want to navigate, you will generally use the non `-full'
+;;  commands because the candidates are simpler.  When you want to
+;;  search you will generally use the `-full' commands.
+;;
+;;  Be aware that "full" really means what it says only for
+;;  definitions in languages like Lisp.  These commands in fact first
+;;  match the Imenu regexp, then use the text between the regexp match
+;;  beginning and one sexp forward.  In the case of Lisp sexps, that
+;;  means they use the full sexp for the definition.  But in the case
+;;  of other languages, such as C, the "full" definitions can in fact
+;;  be shorter than the simple regexp matches.
+;;
+;;
+;;(@* "Icicles Imenu Combines Benefits of Imenu and Emacs Tags")
+;;  *** Icicles Imenu Combines Benefits of Imenu and Emacs Tags ***
+;;
+;;  * Imenu lets you navigate among definitions in a single buffer.
+;;
+;;  * Emacs tags let you navigate among definitions in multiple files,
+;;    but you must build and update the tags file that identifies the
+;;    definitions.
+;;
+;;  Like Emacs tags, Icicles Imenu commands let you navigate among
+;;  definitions in multiple files - and also multiple bookmarks and
+;;  multiple non-file buffers.  Like Imenu, you need not build a tags
+;;  file.  Unlike Imenu, Icicles provides regexp completion that lets
+;;  you filter Imenu hits that you want to visit.
+;;
+;;  Another difference from Emacs tags, besides the need for a tags
+;;  file, is that, since Icicles locates definitions using Imenu
+;;  regexps, you can only navigate among definitions in buffers that
+;;  you are visiting.  This is both an advantage and a disadvantage:
+;;  you can narrow the search to certain files, but you must know
+;;  which files to search. And if you want to search all files, then
+;;  you must open them all (e.g. by matching a project regexp),
+;;
+;;  The differences mean that Icicles Imenu commands do not provide a
+;;  substitute for Emacs tags; they provide some similar
+;;  functionality.  They add another tool to your tool belt, handier
+;;  in some situations than using tags, and less useful in some other
+;;  situations.
+;;
+;;  See Also: (@> "Icicles Enhancements for Emacs Tags")
+;;
+;;(@* "Compile/Grep Search")
+;;  ** Compile/Grep Search **
+;;
+;;  In a compilation-results buffer, such as `*Compilation*' or
+;;  `*grep*', you can use command `icicle-compilation-search', bound
+;;  to `C-c `', to search among the result set (search hits).  This is
+;;  similar to `icicle-search', but when you use `C-RET', `C-mouse-2',
+;;  `C-down', `C-up', `C-next', `C-prior', `C-end', or `C-home', it
+;;  visits the source code that corresponds to the current line in the
+;;  compilation buffer.  Just as for `icicle-search', you can narrow
+;;  the set of search contexts by typing a regexp.
+;;
+;;  Using `icicle-compilation-search' with `grep' gives you two levels
+;;  of regexp searching: 1) the `grep' regexp and 2) your current
+;;  input regexp.  And you can of course use progressive completion
+;;  (`M-*') to add any number of additional levels.  (And, starting
+;;  with Emacs 22, you can pipe to other `grep' commands in the same
+;;  `M-x grep'.)
+;;
+;;  In Emacs 22 and later, you can also replace search-hit text.  You
+;;  can replace the entire grep regexp match or just the part of it
+;;  that matches your current input, depending on the value of option
+;;  `icicle-search-replace-whole-candidate-flag' (which you can toggle
+;;  with `M-_').  Replacement acts here just as it does for
+;;  `icicle-search'.
+;;
+;;  You can also use a non-`grep' compilation buffer to perform search
+;;  and replace.  Use it, for example, to correct errors in source
+;;  files.
+;;
+;;  Icicles thus gives you several ways to perform search-and-replace
+;;  throughout multiple files: `grep'/compilation, `icicle-occur', and
+;;  `icicle-search'.  The latter is of course not limited to
+;;  line-by-line search.
+;;
+;;  See Also: (@> "Search and Replace").
+;;
+;;(@* "Input Reuse in Interactive Interpreter Modes")
+;;  ** Input Reuse in Interactive Interpreter Modes **
+;;
+;;  In an interactive interpreter mode such as `shell-mode' or
+;;  interactive Lisp mode, you can search for and reuse a previous
+;;  input, possibly editing it first.  Command `icicle-comint-search',
+;;  bound to `C-c `', lets you use Icicles completion and cycling to
+;;  access your previous (shell or Lisp) inputs; it uses
+;;  `icicle-search', so it highlights your regexp input matches, and
+;;  so on.  You can use `C-$' at any time to toggle removal of
+;;  duplicate past inputs as completion candidates; by default,
+;;  duplicates are removed.
+;;
+;;  Being a search command, however, `icicle-comint-search' has access
+;;  only to the commands that are visible in the buffer.  It does not
+;;  use the `comint-input-ring', so it cannot, for instance, give you
+;;  access to commands used in a previous session, which might have
+;;  been recorded in a history file.
+;;
+;;  Another Icicles command, `icicle-comint-command', which is not a
+;;  search command, does use `comint-input-ring' and does give you
+;;  completion and cycling against previous inputs that might not have
+;;  come from the current session.  It is bound to `C-c TAB' in
+;;  `comint-mode' and derived modes.
+;;
+;;(@* "Define Your Own Icicles Search Commands")
+;;  ** Define Your Own Icicles Search Commands **
+;;
+;;  Function `icicle-search' is not only a useful user command; it is
+;;  also a framework for you to define your own Icicles search
+;;  commands.  Consult the source code for the commands presented
+;;  above for models.  And consult the doc string of `icicle-search'
+;;  for more information about calling it non-interactively.  In
+;;  particular, note that:
+;;
+;;  * You can pass a functional argument instead of a regexp to
+;;    `icicle-search', and it will use that function to define the
+;;    search contexts.  The function is passed, as arguments, the
+;;    buffer to search, the beginning and end of the search region in
+;;    that buffer, and any additional arguments that you pass to
+;;    `icicle-search'.
+;;
+;;  * You can pass a predicate argument to `icicle-search', in
+;;    addition to passing a regexp, and the search contexts will be
+;;    only those regexp matches that also satisfy the predicate.  The
+;;    predicate takes two arguments, the search-context string and a
+;;    marker at the end of the search context.  For information about
+;;    this, consult the doc string for function
+;;    `icicle-search-regexp-scan'.  For a model of using this feature,
+;;    see the code that defines command `icicle-imenu'.
+;;
+;;  By using your own function to define the search contexts, either
+;;  from scratch or by limiting regexp matches using a predicate, you
+;;  can perform semantic-based searching.  That is, your search
+;;  command can use information besides syntax to define search hits.
+;;  For instance, commands `icicle-imenu-command' and
+;;  `icicle-imenu-non-interactive-function' use the semantic predicate
+;;  `commandp' to distinguish Emacs-Lisp commands from non-interactive
+;;  functions.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Search Commands, Overview") for general information
+;;    about Icicles search and the commands `icicle-search' and
+;;    `icicle-occur'.
+;;
+;;  * (@> "Search and Replace") for information about replacing search
+;;    hits or parts of search hits.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Multi-Commands") for
+;;    information about using `C-RET', `C-mouse-2', `C-down', `C-up',
+;;    `C-next', `C-prior', `C-end', and `C-home'.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Progressive Completion")
+;;    for information about using any number of search regexps with
+;;    `M-*' and any number of search predicates with `M-&'.
+;;
+;;  * (@> "Icicles Info Enhancements") for information about using
+;;    Icicles with Info mode.
+ 
+;;(@* "Icicles Bookmark Enhancements")
+;;
+;;  Icicles Bookmark Enhancements
+;;  -----------------------------
+;;
+;;  Many of the enhancements described in this section are available
+;;  only if you also use library `bookmark+.el' (which I recommend).
+;;  Bookmark+ is compatible with vanilla Emacs bookmarks across
+;;  multiple Emacs versions.  It enhances the use of bookmarks in many
+;;  ways.  The explanation here does not attempt to describe the
+;;  Bookmark+ enhancements; it describes only the Icicles features
+;;  that make use of them.
+;;
+;;  One of the main Bookmark+ enhancements is support for new bookmark
+;;  types.  Icicles provides type-specific bookmark commands and
+;;  bookmark-candidate filtering.
+;;
+;;  In addition, when you complete the names of some kinds of objects,
+;;  you can use `C-x m' to choose objects of that type.  For example,
+;;  when you use `icicle-dired' (`C-x d') to complete a directory
+;;  name, you can use `C-x m' to choose among your Dired bookmarks.
+;;  See (@file :file-name "icicles-doc1.el" :to "Accessing Saved Locations (Bookmarks) on the Fly").
+
+;;  Regardless of the bookmark type, another Bookmark+ feature that
+;;  Icicles takes advantage of is the fact that a bookmark (any
+;;  bookmark) can save not only a single position but a region, that
+;;  is, two positions.  You can think of this as bookmarking, or
+;;  saving, regions.  When you jump to a region bookmark, the region
+;;  is activated (if option `bmkp-use-region' is non-`nil').
+;;
+;;  These are the main Icicles bookmarking features:
+;;
+;;  * Tagging files (a la delicious) and jumping to tagged files
+;;  * Bookmarking the region and selecting a bookmarked region
+;;  * Setting a bookmark and jumping to a bookmark
+;;  * Searching the text of a bookmark's buffer or region
+;;
+;;  Each is described in a little more detail below.  More generally,
+;;  however, the Bookmark+ doc is your friend.  See these sections of
+;;  the Bookmark+ doc:
+;;
+;;  * (@file :file-name "bookmark+-doc.el" :to "Bookmark Tags")
+;;  * (@file :file-name "bookmark+-doc.el" :to "Autofile Bookmarks")
+;;  * (@file :file-name "bookmark+-doc.el" :to "Tag Commands and Keys")
+;;  * (@file :file-name "bookmark+-doc.el" :to "Tags: Sets of Bookmarks")
+;;  * (@file :file-name "bookmark+-doc.el" :to "Bookmark Tags Can Have Values")
+;;
+;;
+;;(@* "Saving Regions and Selecting Them")
+;;  ** Saving Regions and Selecting Them **
+;;
+;;  Saving the region just means bookmarking it.  As for any bookmark,
+;;  it must have a name.  When you later jump to a region bookmark,
+;;  the region is activated (provided option `bmkp-use-region' is
+;;  non-`nil').
+;;
+;;  Icicles gives you quick ways to save a region and select
+;;  (activate) a saved region.  You can do both using `C-x C-x'.
+;;
+;;  * With no prefix arg, `C-x C-x' exchanges point and mark
+;;    (activating the region), as usual.
+;;
+;;  * With a plain prefix arg (`C-u'), `C-x C-x' jumps to a region
+;;    bookmark that you choose using completion, and activates it.
+;;
+;;  * With a numeric prefix arg, `C-x C-x' saves the region.  If the
+;;    prefix arg is negative, then you are prompted for the name to
+;;    use.  Otherwise, the bookmark is named automatically using the
+;;    buffer name plus ": " plus the first
+;;    `icicle-bookmark-name-length-max' characters of the region text.
+;;    (Newline characters are changed to spaces for the name.)
+;;
+;;    So if (a) you are visiting buffer `foo', (b) the region text
+;;    starts with "Arise, you wretched of the earth! For justice
+;;    thunders condemnation: A better world's in birth!", and (c) the
+;;    value of option `icicle-bookmark-name-length-max' is 15, then
+;;    `C-9 C-x C-x' sets the region bookmark named `foo: Arise, you'.
+;;
+;;(@* "Setting a Bookmark and Jumping to a Bookmark")
+;;  ** Setting a Bookmark and Jumping to a Bookmark **
+;;
+;;  Just as `C-x C-x' lets you either set or jump to a region
+;;  bookmark, so `C-x r m' lets you either set or jump to any
+;;  bookmark.  `C-x r m' is the vanilla Emacs key for setting a
+;;  bookmark.  In Icicle mode it is bound by default to command
+;;  `icicle-bookmark-cmd'. (By default, whatever keys are normally
+;;  bound to `bookmark-set' are remapped in Icicle mode to
+;;  `icicle-bookmark-cmd'.)
+;;
+;;  * With no prefix arg or a plain prefix arg (`C-u'), `C-x r m' acts
+;;    like `icicle-bookmark-set'.  This is similar to `bookmark-set',
+;;    but if you use Bookmark+ then you can use (lax) completion,
+;;    choosing from existing bookmarks for the same buffer.  This
+;;    makes it easy to update a nearby bookmark.
+;;
+;;    The same completion enhancements are available as for bookmark
+;;    jumping - see (@> "Jumping to a Bookmark"), below.
+;;
+;;  * With a negative prefix arg, `C-x r m' jumps to a bookmark (with
+;;    completion).  See (@> "Jumping to a Bookmark"), below.
+;;
+;;  * With a non-negative prefix arg, `C-x r m' sets a bookmark,
+;;    automatically naming it.  This is like the automatic naming for
+;;    a region bookmark, except that instead of including a prefix of
+;;    the region text, the name includes text from the current line
+;;    that starts at point.
+;;
+;;    So if the cursor in buffer `foo' is on the `y' in a line with
+;;    the text "Arise, you wretched of the earth!", then the bookmark
+;;    will automatically be named `foo: you wretch'.
+;;
+;;    If the prefix argument is 0, then the new bookmark does not
+;;    overwrite any existing bookmark with the same name.
+;;
+;;(@* "Jumping to a Bookmark")
+;;  ** Jumping to a Bookmark **
+;;
+;;  Icicles commands that jump to a bookmark are multi-commands: you
+;;  can use them to jump to any number of bookmarks in a single
+;;  invocation.  Each jump command acts as a bookmark browser.
+;;
+;;  As with most Icicles tripping commands, after you jump to a
+;;  (non-region) bookmark, the cursor position is highlighted using
+;;  cross hairs, if you also use library `crosshairs.el'.
+;;
+;;  Bookmark names are highlighted in buffer `*Completions*' to
+;;  indicate the bookmark type.  The faces used are those defined by
+;;  Bookmark+.
+;;
+;;  If option `icicle-show-multi-completion-flag' is non-`nil', then
+;;  each completion candidate is a multi-completion, with up to three
+;;  parts: the bookmark name, the bookmark file or buffer name, and
+;;  any (del.icio.us-style) tags the bookmark has.  You can toggle
+;;  option `icicle-show-multi-completion-flag' (for the next command)
+;;  using `M-m' during completion.
+;;
+;;  When using multi-completion candidates, you can match any of the
+;;  multi-completion parts.  For example, you can match all bookmarks
+;;  that have any tags by typing this when choosing a bookmark:
+;;
+;;    C-M-j . * C-M-j S-TAB
+;;
+;;  Or match all bookmarks whose names match `P42' and whose tags
+;;  match `blue':
+;;
+;;    P 4 2 . * C-M-j . * C-M-j . * b l u e S-TAB
+;;
+;;  (Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string'.)
+;;
+;;  `C-M-RET' shows detailed info about the current bookmark
+;;  completion candidate.  `C-u C-M-RET' shows the complete, internal
+;;  info for the bookmark.  Likewise, for the other candidate help
+;;  keys: `C-M-down' etc.  And the mode line always shows summary
+;;  info about the current bookmark.
+;;
+;;  During bookmark completion you can sort the candidates in various
+;;  bookmark-specific ways:
+;;
+;;  * By the current (latest) `*Bookmark List*' order
+;;  * By bookmark name
+;;  * By last access as a bookmark (date + time)
+;;  * By bookmark visit frequency (number of times visited)
+;;  * By last buffer or file access (date + time)
+;;  * With marked bookmarks before unmarked (in `*Bookmark List*')
+;;  * By file name
+;;  * By (local) file type
+;;  * By (local) file size
+;;  * By last (local) file access (date + time)
+;;  * By last (local) file update (date + time)
+;;  * By Info location (manual and node)
+;;  * By Gnus thread
+;;  * By URL
+;;  * By bookmark type
+;;
+;;  The most general Icicles jump commands are `icicle-bookmark' and
+;;  `icicle-bookmark-other-window'.  In Icicle mode these are bound to
+;;  whatever `bookmark-jump' and `bookmark-jump-other-window' are
+;;  normally bound to.  If you use Bookmark+, the default bindings are
+;;  `C-x j j' and `C-x 4 j j', respectively.
+;;
+;;  When you use these commands, you can narrow the completion
+;;  candidates to bookmarks of a specific type using these keys:
+;;
+;;  `C-M-b'   - non-file (buffer) bookmarks
+;;  `C-M-B'   - bookmark-list bookmarks
+;;  `C-M-d'   - Dired bookmarks
+;;  `C-M-f'   - file bookmarks
+;;  `C-M-F'   - local-file bookmarks
+;;  `C-M-g'   - Gnus bookmarks
+;;  `C-M-I'   - Info bookmarks
+;;  `C-M-K'   - desktop bookmarks
+;;  `C-M-m'   - `man' pages
+;;  `C-M-r'   - bookmarks with regions
+;;  `C-M-u'   - URL bookmarks
+;;  `C-M-w'   - W3M (URL) bookmarks
+;;  `C-M-@'   - remote-file bookmarks
+;;  `C-M-= b' - bookmarks for a specific buffer
+;;  `C-M-= f' - bookmarks for a specific file
+;;  `C-M-= .' - bookmarks for the current buffer
+;;
+;;  In addition, there are individual jump commands for bookmarks of
+;;  each of each type, and these commands are bound by default to keys
+;;  with the prefix `C-x 4 j' that use the same mnemonic characters as
+;;  for narrowing.  For example, `icicle-bookmark-info-other-window'
+;;  is bound to `C-x 4 j i'.
+;;
+;;  Commands `icicle-bookmark' and `icicle-bookmark-other-window' can
+;;  use a cache for the set of available bookmarks.  This improves
+;;  performance, especially if you have a lot of bookmarks.  The
+;;  downside is that the list of completion candidates is not
+;;  automatically updated when you add new bookmarks.
+;;
+;;  By default, this caching is off, so the set of possible bookmark
+;;  candidates is always up-to-date.  You can turn on this caching by
+;;  setting option `icicle-bookmark-refresh-cache-flag' to `nil'.
+;;
+;;  Alternatively, you can use a prefix argument to reverse the effect
+;;  of this option.  If you have a lot of bookmarks then I recommend
+;;  that you customize the option to `nil' and just update it
+;;  occasionally by using `C-u' for bookmark completion.  That will
+;;  temporarily turn off caching so that the current jump command
+;;  refreshes (updates) the cache.  The default value of the option is
+;;  `t' only to avoid confusion for new users.
+;;
+;;  The bookmarks cache is also used for searching bookmarks (see
+;;  next).  The type-specific bookmark jump commands
+;;  (e.g. `icicle-bookmark-info-other-window') do not use the cache,
+;;  since they typically use a smaller number of candidates.  And the
+;;  cache is automatically updated whenever you use `S-delete' to
+;;  delete a candidate bookmark.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Icicles Tripping")
+;;
+;;(@* "Searching Bookmarked Objects")
+;;  ** Searching Bookmarked Objects **
+;;
+;;  Icicles search (and replace) lets you search across multiple
+;;  buffers, files, or bookmarks.  This is true for nearly all Icicles
+;;  search commands.  You use a plain prefix argument to specify
+;;  bookmark searching.  For command `icicle-search' itself (`C-u C-c
+;;  `'), you can alternatively use the specific command
+;;  `icicle-search-bookmarks-together'.
+;;
+;;  When you do this you first choose the bookmarks to search, using
+;;  completion.  Use `C-RET' and similar multi-command actions to
+;;  choose (use `RET' for the final choice).  Once you have chosen the
+;;  bookmarks, you type a search pattern to narrow the set of
+;;  candidates.
+;;
+;;  (Multi-command `icicle-bookmark-list' similarly lets you choose
+;;  bookmark names.  It returns them as a Lisp list of strings.)
+;;
+;;  When you search the text of a region bookmark, the search is
+;;  limited to the region.
+;;
+;;  In addition to using `C-u' with the general Icicles search
+;;  commands, you can use the following Icicles search commands that
+;;  are specific to bookmarks:
+;;
+;;  * icicle-search-bookmark
+;;  * icicle-search-autofile-bookmark
+;;  * icicle-search-bookmark-list-bookmark
+;;  * icicle-search-desktop-bookmark
+;;  * icicle-search-dired-bookmark
+;;  * icicle-search-file-bookmark
+;;  * icicle-search-gnus-bookmark
+;;  * icicle-search-info-bookmark
+;;  * icicle-search-local-file-bookmark
+;;  * icicle-search-man-bookmark
+;;  * icicle-search-non-file-bookmark
+;;  * icicle-search-region-bookmark
+;;  * icicle-search-remote-file-bookmark
+;;  * icicle-search-specific-buffers-bookmark
+;;  * icicle-search-specific-files-bookmark
+;;  * icicle-search-this-buffer-bookmark
+;;  * icicle-search-url-bookmark
+;;  * icicle-search-w3m-bookmark 
+;;  * icicle-search-all-tags-bookmark
+;;  * icicle-search-all-tags-regexp-bookmark
+;;  * icicle-search-some-tags-bookmark
+;;  * icicle-search-some-tags-regexp-bookmark
+;;
+;;  `icicle-search-bookmark' is a general command; the others are each
+;;  specific to a certain kind of bookmark candidate, and they need
+;;  library `bookmark+.el'.  The last four let you search bookmarks
+;;  that have a certain set of tags.
+;;
+;;  All of these commands act the same way.  They are multi-commands,
+;;  so you can use them to search multiple bookmarks.  But unlike
+;;  `icicle-search-bookmarks-together' (`C-u C-c `'), you do not first
+;;  choose all of the bookmarks and then search them together.
+;;  Instead, you search them one at a time.
+;;
+;;  `icicle-search-bookmark' is flexible, letting you specify any set
+;;  of bookmarks to use as candidates.  The candidates are the
+;;  bookmarks last shown in the `*Bookmark List*' display (list
+;;  `bmkp-sorted-alist', to be precise).
+;;
+;;  You can use the Bookmark+ features of `*Bookmark List*' to limit
+;;  the candidates to bookmarks of a certain type (e.g., only
+;;  autofiles, using `A S'), bookmarks with certain tags (e.g., only
+;;  those with tags matching a regexp using `T m %' followed by `>'),
+;;  and so on.  Whatever set of bookmarks are shown (or were last
+;;  shown) in `*Bookmark List*' are the bookmarks to be searched.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Search Commands, Overview") for information about
+;;    command `icicle-search'.
+;;  * (@> "Jumping to a Bookmark") for information about bookmark
+;;    caching.  Caching is also used for bookmark searching.
+;;  * (@> "Support for Projects")
+ 
+;;(@* "Icicles Enhancements for Emacs Tags")
+;;
+;;  Icicles Enhancements for Emacs Tags
+;;  -----------------------------------
+;;
+;;  In Emacs and Icicles, the word "tag" is used in multiple ways.
+;;  This section is about tags as identifiers of source-code
+;;  definitions.  Emacs uses tags files, typically named `TAGS', to
+;;  index these definition locations.
+;;
+;;  What constitutes a "definition" is determined by the content of
+;;  the tags file.  Typically, definition recognition is available for
+;;  programming languages, but in fact a tags table can record any
+;;  text at all as a definition.  That is, if you create your own tags
+;;  table, you can use the Emacs tags feature to navigate among any
+;;  "definitions" of your own choosing.
+;;
+;;  If you use `M-g' in the minibuffer to toggle option
+;;  `icicle-use-C-for-actions-flag', then you can use just `next'
+;;  instead of `C-next' to navigate when using any of the Icicles tags
+;;  browsing commands described here.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Option `icicle-use-C-for-actions-flag'").
+;;
+;;  See Also:
+;;
+;;  * (@> "Support for Projects")
+;;  * (@file :file-name "icicles-doc1.el" :to "File-Name Input and Locating Files Anywhere")
+;;
+;;(@* "`icicle-find-tag': Find Tags in All Tags Tables")
+;;  ** `icicle-find-tag': Find Tags in All Tags Tables **
+;;
+;;  In vanilla Emacs, you use commands such as `find-tag' (`M-.') to
+;;  find a tag, `tags-loop-continue' (`M-,') to find another matching
+;;  tag, `tags-apropos' to list all tags that match a regexp, and
+;;  `list-tags' to show all tags (definitions) in a given source file.
+;;
+;;  In Icicles, you can use multi-command `icicle-find-tag', bound to
+;;  `M-.' in Icicle mode, to do all of this.  It is similar to the
+;;  Icicles search commands.  It is a general tags browser, just as
+;;  `icicle-imenu' is an Imenu browser.  Being a multicommand, you can
+;;  visit any number of tags, in any order, in a single `M-.'
+;;  invocation.
+;;
+;;  With `icicle-find-tag', you enter (using `RET') a regexp to match
+;;  the tags you want to visit.  By default, all tags in all tags
+;;  files are searched, and the matches become completion candidates
+;;  (which you can of course match further by typing another pattern).
+;;  As always, you can use progressive completion, chip away the
+;;  non-elephant, and so on.  Just as with Icicles search commands,
+;;  you use `C-RET', `C-mouse-2', `C-next', and so on, to visit the
+;;  search hits.  You can use `M-*' (`icicle-pop-mark') to return to
+;;  the place you invoked `M-.'.
+;;
+;;  By default, the completion candidates are multi-completions: the
+;;  source file name is included.  This is an important aid, because
+;;  there can be similar, or even identical, tags in different source
+;;  files.  Your current input can of course filter the source-file
+;;  name also, excluding certain files from the search.
+;;
+;;  A prefix argument  changes the default behavior, as follows:
+;;
+;;  * If non-negative (>= 0), then only the current tag table is used,
+;;    instead of all tag tables.
+;;
+;;  * If non-positive (<= 0), then the source file name is not part of
+;;    the completion candidate; only the tag itself is used.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Search Commands, Overview") for general information
+;;    about Icicles search commands.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Nutshell View of Icicles")
+;;    for information about progressive completion and chipping away
+;;    the non-elephant.
+;;
+;;(@* "`icicle-find-first-tag': Find First Tag in Current Table")
+;;  ** `icicle-find-first-tag': Find First Tag in Current Table **
+;;
+;;  Sometimes you do not need the full power and flexibility of
+;;  `icicle-find-tag'.  If you just want to find the first tag among
+;;  several duplicates that match your input, and you just want to use
+;;  the current tags table, then you can use `icicle-find-first-tag'
+;;  or `icicle-find-first-tag-other-window'.  These commands are like
+;;  vanilla `find-tag', but they are multi-commands, so you can visit
+;;  any number of tags in one invocation.  Unlike `find-tag', however,
+;;  you cannot follow up to find another tag that matches using `M-,'.
+;;
+;;(@* "`icicle-tags-search': Search and Replace Using Tags")
+;;  ** `icicle-tags-search': Search and Replace Using Tags **
+;;
+;;  In vanilla Emacs, you use commands `tags-search',
+;;  `tags-query-replace', and `tags-loop-continue' (`M-,') to search
+;;  and replace text in source files whose definitions are indexed in
+;;  a tags file.
+;;
+;;  In Icicles, you can use multi-command `icicle-tags-search' to
+;;  search and replace.  It is in fact just command `icicle-search'
+;;  applied to the relevant source files.
+;;
+;;  See Also (@> "Icicles Search Commands, Overview") for information
+;;  about `icicle-search.
+ 
+;;(@* "Icicles Shell-Command Enhancements")
+;;
+;;  Icicles Shell-Command Enhancements
+;;  ----------------------------------
+;;
+;;  Icicles provides completion support for shell commands in these
+;;  ways:
+;;
+;;  * In Shell mode and related modes, it enhances completion of
+;;    commands, previous inputs (commands plus their switches and
+;;    arguments), file names, and environment variables.
+;;    See (@> "Completion in Comint Modes").
+;;
+;;  * In any buffer, it provides Icicles completion for `M-!' and
+;;    `M-|'.  This is an optional feature that is not enabled by
+;;    default.
+;;
+;;  * In Dired mode, it provides Icicles completion for `!', and `&'.
+;;    See (@> "Shell Commands on Marked Files").  This is an optional
+;;    feature that is not enabled by default.
+;;
+;;  This section describes the optional Icicles completion available
+;;  for `M-!' and `M-|'.  It applies also to completion for `!', and
+;;  `&' in Dired (but those have additional enhancements).
+;;
+;;  In vanilla Emacs, when you enter a shell command at the prompt for
+;;  `M-!' or `M-|', no completion is available for Emacs prior to
+;;  Emacs 23.  In Emacs 23, no completion is available for empty
+;;  input, and non-empty input is completed only to a shell command
+;;  that is in your search path.
+;;
+;;  In Icicle mode, `M-!' and `M-|' can, like in vanilla Emacs 23,
+;;  complete using commands in your search path.  This depends on the
+;;  the value of option `icicle-guess-commands-in-path' (see below).
+;;
+;;(@* "Shell Command Completion as File-Name Completion")
+;;  ** Shell Command Completion as File-Name Completion **
+;;
+;;  The most significant thing about Icicles completion for reading a
+;;  shell command is that it is in fact *file-name* completion.
+;;  Reading a shell command means, first, reading a file name.  This
+;;  is unexpected, to say the least.
+;;
+;;  Because of this unusual behavior, this feature is optional and is
+;;  not enabled by default.  To enable it, customize option
+;;  `icicle-functions-to-redefine' to add the shell-related functions
+;;  `dired-read-shell-command' and `read-shell-command'.  If you do
+;;  that, then Icicle mode will substitute Icicles functions for these
+;;  standard functions and you will get the Icicles completion
+;;  described here.
+;;
+;;  A shell command is itself an executable file, either a binary
+;;  program or a script.  That's not so shocking.  But since Icicles
+;;  uses file-name completion for your entire shell-command input,
+;;  including any switches (options) and command arguments, all of
+;;  that input is interpreted by `read-file-name' as a file name,
+;;  before it gets passed on to the shell.
+;;
+;;  The reason for providing file-name completion for a shell command
+;;  is to let you easily invoke a program no matter where it resides,
+;;  whether or not its directory is in your search path.  You can use
+;;  completion to navigate to the command's location.
+;;
+;;  Icicles shell-command completion is lax, so you can enter any
+;;  command you want, not just a file-name completion candidate.  And
+;;  you can edit the completed input before hitting `RET', to add
+;;  command switches (options) and arguments.  The overall input
+;;  string is taken as a (pseudo) file name, but it is then passed to
+;;  the shell for execution.
+;;
+;;(@* "Gotcha: `$' in Shell Commands")
+;;  ** Gotcha: `$' in Shell Commands **
+;;
+;;  There is a gotcha, however, regarding `$' and file-name input:
+;;
+;;  When you hit `RET' to accept the input, `read-file-name' finishes
+;;  its job, as always, by trying to expand any environment variables
+;;  in the string.  Usually this is what you want, and it presents no
+;;  problem.  But in the context of a shell another `$' syntax is also
+;;  used.  For example, `$1' typically means the first argument or
+;;  first field; it does not mean a variable named `1'.
+;;
+;;  `read-file-name' knows nothing about this different `$' syntax,
+;;  and it systematically calls `substitute-in-file-name' to expand
+;;  any environment variables in the file name you enter (when you hit
+;;  `RET').  It interprets `$1' the same way it inteprets `$PATH',
+;;  treating `1' as an (unknown) environment variable.  This is not
+;;  what you want it to do.  If you input `awk '{print $1}' Emacs
+;;  raises this error:
+;;
+;;    Substituting nonexistent environment variable "1"
+;;
+;;  What can you do about this?  Three possible approaches:
+;;
+;;  * Do not use this Icicles feature at all.  The feature is turned
+;;    off, by default.
+;;
+;;  * You can escape a dollar sign by doubling it: use `$$' instead of
+;;    `$' when you want to pass a `$' to the shell and not let
+;;    `read-file-name' try to interpret it in terms of an environment
+;;    variable.
+;;
+;;  * You can turn off Icicle mode temporarily whenever you use a
+;;    complex command that involves `$': `M-x icy-mode'.
+;;
+;;(@* "Known Shell Commands as Proxy Candidates")
+;;  ** Known Shell Commands as Proxy Candidates **
+;;
+;;  If you do turn on Icicles file-name completion for reading shell
+;;  commands, then extra, known shell commands are also made available
+;;  as proxy completion candidates, provided that option
+;;  `icicle-guess-commands-in-path' is non-`nil' (it is `nil' by
+;;  default).  These extra candidates are the names of all executable
+;;  files (or of all files, if `shell-completion-execonly' is `nil')
+;;  in your search path.
+;;
+;;  The fact that these are Icicles proxy candidates means that they
+;;  are available regardless of the current default-directory - they
+;;  are not in fact treated as file-name candidates, even though they
+;;  are available during file-name completion.  You can easily
+;;  recognize Icicles proxy candidates in buffer `*Completions*': they
+;;  have face `icicle-proxy-candidates'.  See 
+;;  (@file :file-name "icicles-doc1.el" :to "Completions Display").
+;;
+;;  If `icicle-guess-commands-in-path' is non-`nil', the list of
+;;  search-path candidate commands is computed once and cached as the
+;;  value of option `icicle-shell-command-candidates-cache'.  The
+;;  particular non-`nil' value of `icicle-guess-commands-in-path'
+;;  determines when the cache is filled.
+;;
+;;  If the value of `icicle-guess-commands-in-path' is `first-use',
+;;  the cache is filled the first time you use it, and each time you
+;;  turn on Icicle mode it is updated.  If the value of
+;;  `icicle-guess-commands-in-path' is `load', then the cache is
+;;  instead filled each time you load Icicles.
+;;
+;;  Regardless of the non-`nil' value of
+;;  `icicle-guess-commands-in-path', if you save
+;;  `icicle-shell-command-candidates-cache', then that value is used
+;;  in future sessions (no delay for searching your path).
+;;
+;;  If your environment changes, you can use command
+;;  `icicle-recompute-shell-command-candidates' to update the cached
+;;  list at any time.  With a prefix argument, the updated value is
+;;  saved persistently.
+;;
+;;  In addition to the extra candidates computed by searching your
+;;  search path, in contexts such as Dired where target (e.g. marked)
+;;  files for the shell command are known, the extra candidates
+;;  include additional commands (possibly including switches) that
+;;  Icicles can guess might be appropriate for the target files.
+;;  See (@> "Shell Commands on Marked Files").
+;;
+;;  During Icicles shell-command completion, help is available for
+;;  individual candidates, using `C-M-RET', `C-M-mouse-2', and so on.
+;;  For an extra candidate, help is provided for the command by the
+;;  `apropos' shell command (if available).  For a file-name
+;;  candidate, help shows the file's properties.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Get Help on Candidates").
+;;
+;;  Remember also:
+;;
+;;  * After you have typed or completed the shell command per se
+;;    (e.g. a file name or search-path command), you can use `C-M-S-f'
+;;    (file-name completion on demand) to complete (relative) file
+;;    names to insert as shell-command arguments as part of the
+;;    command line to submit to the shell.  See
+;;    (@file :file-name "icicles-doc2.el" :to "Completion On Demand").
+;;
+;;  * You can use `M-o' anytime in the minibuffer to complete against
+;;    a previous input.  This means that if you have previously
+;;    entered some complex shell command (e.g. with various switches
+;;    or arguments), then you can use `M-o' to retrieve it for reuse
+;;    (possibly editing it).  See
+;;    (@file :file-name "icicles-doc2.el" :to "Using Completion to Insert Previous Inputs: `M-o'")
+ 
+;;(@* "Icicles Dired Enhancements")
+;;
+;;  Icicles Dired Enhancements
+;;  --------------------------
+;;
+;;  Icicles can help with Dired in these ways:
+;;
+;;  * You can use Icicles search-and-replace on the marked files.
+;;
+;;  * You can save marked file names as completion candidates for
+;;    reuse later.
+;;
+;;  * You can open Dired on saved file names, that is, names that you
+;;    previously saved as a completion candidates set or as an Emacs
+;;    fileset.  It does not matter how the file names were saved or
+;;    which directories the files are in.  The set of saved file names
+;;    can be persistent or just for the current Emacs session.
+;;
+;;  * You can use file-name completion when you use `!'  or `&' to
+;;    execute a shell command.  This is an optional feature that is
+;;    not enabled by default.  See also (@> "Icicles Shell-Command Enhancements").
+;;
+;;(@* "Search-and-Replace Marked Files")
+;;  ** Search-and-Replace Marked Files **
+;;
+;;  In Dired, `A' searches the marked files using a regexp, and `Q'
+;;  launches `query-replace-regexp' on them.  But suppose that you
+;;  want to change only a few occurrences in each file, perhaps among
+;;  the first occurrences.  Using `Q', you are forced to review each
+;;  search hit in turn - all of them; you cannot simply skip the rest
+;;  in one file and continue with the next file.
+;;
+;;  [I suggested that this feature be added to Emacs, and it has been
+;;  added in Emacs 23: you can now skip to the next file.]
+;;
+;;  One workaround is to use `M->' to go to the end of a file, and
+;;  then `M-,' to resume query-replace.  Or you can quit the command
+;;  altogether, unmark the file you're finished searching, and then
+;;  hit `Q' again, but that's not very convenient.  A similar problem
+;;  applies to searching using `A'.
+;;
+;;  In Dired with Icicles, you can use `M-s i'
+;;  (`icicle-search-dired-marked') to search the files and possibly
+;;  replace search hits.  This runs `icicle-search', so you have
+;;  available all of its features, including accessing search hits
+;;  directly, in any order.  To skip a whole file, just match its name
+;;  with your minibuffer input and then use `C-~' to remove all of its
+;;  occurrences from the set of hits.
+;;
+;;  Note: You can similarly use `M-s i' in Ibuffer or Buffer Menu to
+;;  search all marked buffers using Icicles search.
+;;
+;;(@* "Save Marked Files as Completion Candidates")
+;;  ** Save Marked Files as Completion Candidates **
+;;
+;;  In Dired with Icicles, you can use `C-M->'
+;;  (`icicle-dired-save-marked') to save the marked file names as a
+;;  set of completion candidates, for reuse later (e.g., using
+;;  `C-M-<').  Similarly, you can use `C->' to add the marked files to
+;;  an existing saved set of candidates.
+;;
+;;  These bindings act similarly to `C-M->' and `C->' in the
+;;  minibuffer: a prefix argument controls whether you save candidates
+;;  to a variable or a cache file.  Also, `C-M-}' saves to a variable
+;;  you name, and `C-}' saves to a cache file - see
+;;  (@* "Marked Files as a Project"), below.
+;;
+;;  You can use such a saved set of file names as candidates during
+;;  file-name completion.  They are saved as absolute names,
+;;  which means you can use them with, say, `C-u C-x C-f'.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Absolute File Names and Different Directories").
+;;
+;;(@* "Open Dired for a Set of File Names")
+;;  ** Open Dired for a Set of File Names **
+;;
+;;  In Dired with Icicles you can use `C-M-<'
+;;  (`icicle-dired-chosen-files-other-window') to open Dired for a set
+;;  of file or directory names that you choose interactively or that
+;;  you have previously saved (persistently or not) as completion
+;;  candidates or as an Emacs fileset.
+;;
+;;  For example, this opens Dired on all files whose names match the
+;;  regexp `.*foo.*bar' (the initial `.*' is implicit):
+;;
+;;    C-M-<  foo.*bar  S-TAB  C-!  C-g
+;;
+;;  The Dired buffer that is created is named `Icy File Set' (suffixed
+;;  with <1>, <2>, etc. as needed), and it contains only the chosen
+;;  file names.
+;;
+;;  The file names are checked to be sure they reference existing
+;;  files.  If any of the names are relative names, those files are
+;;  checked for existence in the Dired directory.  If you use a prefix
+;;  argument, then you are prompted for the directory to use.
+;;
+;;(@* "Marked Files as a Project")
+;;  ** Marked Files as a Project **
+;;
+;;  Just as `C-}' in the minibuffer is a shortcut for `C-u C-M->',
+;;  which saves the current set of completion candidates persistently,
+;;  so `C-}' in Dired saves the marked file names in a cache file or,
+;;  with a prefix arg, an Emacs fileset.  Similarly, just as `C-{' in
+;;  the minibuffer is a shortcut for `C-u C-M-<', which retrieves
+;;  candidates from a persistent set, so `C-{' in Dired retrieves a
+;;  persistent set of file names and opens them in a separate Dired
+;;  buffer.
+;;
+;;  You can think of such persistent file-name sets as projects.
+;;  `C-}' is bound to command `icicle-dired-save-marked-as-project'
+;;  (aka `icicle-dired-save-marked-persistently').  `C-{' is bound to
+;;  command `icicle-dired-project-other-window'.
+;;
+;;  Again, you can use such a project as a candidate set for file-name
+;;  completion at any time.  In addition, `C-}' and `C-{' can be handy
+;;  in Dired for working with projects even without using completion.
+;;  The files in a project can be distributed among any directories
+;;  anywhere.  This gives you an easy way to open Dired on just the
+;;  files you want and operate on them there.
+;;
+;;  And while in a project in Dired you can use `C-M-<' to mark a
+;;  project subset to work on, and then use `C-M->' to operate on that
+;;  subset using Icicles completion.  And you can have any number of
+;;  projects - you access each by its name (with completion) and need
+;;  not remember its cache file name.
+;;
+;;(@* "Shell Commands on Marked Files")
+;;  ** Shell Commands on Marked Files **
+;;
+;;  This is an optional feature that is not enabled by default.  See
+;;  also (@> "Icicles Shell-Command Enhancements").
+;;
+;;  In Icicle mode, `!' and `&' in Dired let you complete a shell
+;;  command.  You can optionally use Icicles file-name completion for
+;;  the shell command, by customizing option
+;;  `icicle-functions-to-redefine' to add the shell-related functions
+;;  `dired-read-shell-command' and `read-shell-command'.
+;;
+;;  If you do that, then Icicle mode will substitute Icicles functions
+;;  for these standard functions and you will get the Icicles
+;;  completion described here.  This is the same optional program-file
+;;  completion that is available anywhere when a shell command is read
+;;  (see (@> "Icicles Shell-Command Enhancements")), but in Dired the
+;;  extra, proxy candidates include commands that Icicles thinks might
+;;  be particularly appropriate for the marked files.
+;;
+;;  These proxy candidates are not necessarily only command names.
+;;  They can include switches (options) that specialize a command.
+;;  For example, if a PDF file (*.pdf) is marked in Dired, the
+;;  completion candidates might include `gv -safer', `pdftotext ?  -',
+;;  and `xpdf'.  The first two of these are not just command names
+;;  (`-safer' is a command switch).
+;;
+;;  Starting with Emacs 23, Icicles uses both of the following methods
+;;  to guess extra (proxy) candidates that are file type-specific:
+;;
+;;  * MIME-type associations
+;;
+;;  * The rules defined by user option `dired-guess-shell-alist-user'
+;;    and variable `dired-guess-shell-alist-default' (provided you use
+;;    Dired X, that is, standard library `dired-x.el')
+;;
+;;  Prior to Emacs 23, MIME types are not used.  In the example of a
+;;  PDF file, candidates `gv -safer' and `pdftotext ? -' are provided
+;;  by MIME-type associations, and candidate `xpdf' is provided by the
+;;  Dired X rules.  Note that you can customize the rules.
+;;
+;;  Any candidates that are specific to the marked files are Icicles
+;;  proxy candidates - see
+;;  (@file :file-name "icicles-doc1.el" :to "Completions Display").
+;;  These are available regardless of the current default-directory.
+;;  They are not treated as file-name candidates, even though they are
+;;  available during file-name completion.  Icicles proxy candidates
+;;  have face `icicle-proxy-candidates' in buffer `*Completions*'.
+;;
+;;  Again, everything that is true for shell-command completion
+;;  elsewhere is also true for shell-command completion in Dired.  See
+;;  (@> "Icicles Shell-Command Enhancements").  This includes adding
+;;  all commands from your search path as proxy candidates if option
+;;  `icicle-guess-commands-in-path' is non-`nil', and providing help
+;;  on individual candidates (shell commands or files) during
+;;  completion.
+;;
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Shell-Command Enhancements") for more information
+;;    about shell-command completion
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates")
+;;    for information about saved completion candidates
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Chip Away the Non-Elephant")
+;;    for the use of `C-~' to remove matching candidates
+;;
+;;  * (@> "Icicles Search Commands, Overview") for information about
+;;    `icicle-search'
+;;
+;;  * (@> "Search and Replace") for how to replace selected search hits
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Persistent Sets of Completion Candidates")
+;;    for more information about using persistent sets
+;;
+;;  * (@> "Support for Projects") for more information about working
+;;    with projects
+;;
+;;  * Library `dired+.el', which has related features such as `C-M-*'
+;;    to open Dired on just the marked files and `M-g' to `grep' just
+;;    the marked files.
+ 
+;;(@* "Icicles Info Enhancements")
+;;
+;;  Icicles Info Enhancements
+;;  -------------------------
+;;
+;;  Icicles can help with Info in these ways:
+;;
+;;  * Icicles completion is available for any input.
+;;
+;;  * You can use `icicle-search' on part or all of a manual, if you
+;;    flatten it first with `Info-merge-subnodes' .
+;;
+;;(@* "Icicles Completion for Info")
+;;  ** Icicles Completion for Info **
+;;
+;;  Whenever completion is available for Info commands, such as `g'
+;;  (`Info-goto-node'), `i' (`Info-index'), and `m' (`Info-menu'), you
+;;  can take advantage of Icicles completion.  For instance, if you
+;;  type `g yan', you can use `S-TAB' for apropos completion and
+;;  choose node `Isearch Yank', whose name contains `yan' but does not
+;;  start with it.  This is an obvious and standard Icicles feature.
+;;
+;;  Although vanilla Emacs also accepts a substring as input for `i',
+;;  it does not provide substring or regexp completion, and it will
+;;  not accept a regexp as final input.
+;;
+;;  Icicle mode binds `g', `i', and `m' to multi-commands
+;;  `icicle-Info-goto-node', `icicle-Info-index', and
+;;  `icicle-Info-menu', which means that you can also use `g', `i',
+;;  and `m' with `C-next', `C-RET', `C-mouse-2', and so on, to browse
+;;  among matching Info nodes.  Unlike browsing with repeated use of
+;;  `,' after `i' in vanilla Emacs, you can continue to see all of the
+;;  matching candidates, in buffer `*Completions*', and you need not
+;;  visit the index hits in sequential order.
+;;
+;;  If you use `M-g' in the minibuffer to toggle
+;;  `icicle-use-C-for-actions-flag', then you can use just `next'
+;;  instead of `C-next' to navigate.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Option `icicle-use-C-for-actions-flag'").
+;;
+;;  As usual in Icicles, you can sort completion candidates in various
+;;  ways, using `C-,' (`icicle-change-sort-order').  For `g', in
+;;  particular, although the default order is alphabetical, you can
+;;  choose `in book order', which shows the node candidates in the
+;;  same order as in the book.  In that case, using `g' and then
+;;  navigating among candidates sequentially using `C-down', `C-up',
+;;  `C-next', `C-prior', `C-end', or `C-home', visits the nodes in
+;;  their natural order.
+;;
+;;  As a special case of this, if you use a negative prefix argument
+;;  (that is, `M-- g'), then not only are the candidate nodes
+;;  presented `in book order', they are also limited to the nodes that
+;;  follow your current location in the book - that is, to the
+;;  remainder of the book.  (A non-negative numeric prefix argument
+;;  has the same meaning as for `Info-goto-node'.)
+;;
+;;  In addition, except when you are at the `Top' node, a pseudo-node
+;;  `..' is added to the set of completion candidates.  Choosing this
+;;  takes you up to the parent of the current node.  You can thus use
+;;  `g' in Info not only to explore nodes by name, but also as another
+;;  means to traverse the Info menu hierarchy.
+;;
+;;(@* "Virtual Info Books")
+;;  *** Virtual Info Books ***
+;;
+;;  You can take advantage of Icicles completion-candidate set
+;;  operations to create your own virtual Info books.  That is, you
+;;  can define and save sets of Info nodes or Info index entries, and
+;;  then reuse them later.
+;;
+;;  Both `m' and `g' in Info use nodes as candidates, so you can use
+;;  `m' or `g' or a combination of `m' and `g' to define a node set,
+;;  and you can use either `m' or `g' to reuse a node set.  A set of
+;;  index entries is different: You must use `i' to create and reuse
+;;  such a set.
+;;
+;;  Remember that you can define a candidate set incrementally, adding
+;;  more elements using `C->', `C-)', `insert', `M-S-mouse-2',
+;;  `M-mouse-3', or `mouse-1 mouse-3 mouse-3'.  And you can save a
+;;  candidate set persistently. [*]
+;;
+;;  You can even create a virtual book that includes Info nodes from
+;;  different manuals.  For example, you might want to collect
+;;  together specific nodes that deal with some particular topic, such
+;;  as faces, from both the Emacs manual and the Elisp manual.
+;;
+;;  You do this using `C-u g' (a plain prefix argument).  This
+;;  prepends the Info file name (book identifier) to each node-name
+;;  completion candidate.  For example, when you are in the Emacs
+;;  manual, each node candidate is prefixed by `(emacs)', and in the
+;;  Elisp manual each candidate is prefixed by `(elisp)'.  You define
+;;  a set of candidates in the usual Icicles ways, changing manuals as
+;;  needed to add additional nodes to the set you save.
+;;
+;;  A node name prefixed by its file name is analogous to an absolute
+;;  file name, that is, a relative file name prefixed by its
+;;  directory.  Because such a saved candidate has a book prefix,
+;;  e.g. `(emacs)', it is absolute and unambiguous.  You can use it
+;;  wherever you happen to be in Info, to go directly to that node.
+;;  This is a feature of `g' even in vanilla Emacs: you can go to a
+;;  node in a different manual from the one you are currently
+;;  visiting.
+;;
+;;  When you want to reuse a virtual book, hit `g' again, retrieve the
+;;  saved set of node candidates that defines the book, and navigate
+;;  among the saved nodes.
+;;
+;;  If you use library `info+.el', you can also take advantage of its
+;;  definition of virtual books and saved Info nodes.  That library
+;;  defines command `Info-virtual-book', which opens Info on a Table
+;;  of Contents of a virtual book of nodes that you have saved either
+;;  using command `Info-save-current-node' or by customizing user
+;;  option `Info-saved-nodes'.
+;;
+;;  Icicles command `icicle-Info-virtual-book' extends
+;;  `Info-virtual-book' by letting you define the virtual book nodes
+;;  using completion.  That is, you can use `g' to save a set of
+;;  node-name completion candidates (as the value of variable
+;;  `icicle-saved-completion-candidates'), and then use command
+;;  `icicle-Info-virtual-book' to open an Info buffer with those nodes
+;;  as a menu.
+;;
+;;  If you have not saved any node-name candidates, then
+;;  `icicle-Info-virtual-book' acts the same as `Info-virtual-book':
+;;  it opens the virtual book that is defined by `Info-saved-nodes'.
+;;  With `info+.el', the key `.' adds the current node to
+;;  `Info-saved-nodes', which gives you a convenient way to build up a
+;;  virtual book as you read.  This is like Emacs bookmarking, but it
+;;  keeps your saved Info nodes separate from your other bookmarks.
+;;
+;;  With a prefix argument, `icicle-Info-virtual-book' lets you choose
+;;  a persistently saved completion set to use instead of
+;;  `icicle-saved-completion-candidates' or `Info-saved-nodes'.  This
+;;  means that you can have any number of such saved node sets as
+;;  virtual books, to use at any time.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates")
+;;  for information about defining, saving, and reusing sets of
+;;  completion candidates.
+;;
+;;  * (@> "Icicles Bookmark Enhancements") for information about using Info bookmarks.
+;;
+;;  [* If you click `mouse-1' on a candidate and (starting with Emacs
+;;  22) `mouse-1-click-follows-link' is an integer, then you will need
+;;  to hold the mouse button depressed longer than that many seconds,
+;;  or else that candidate will simply by chosen.  If the value is
+;;  `t', then this will not work at all.  Any other value presents no
+;;  problem.  (Personally, I use `nil'.)]
+;;
+;;(@* "Using Icicle-Search With Info")
+;;  ** Using Icicle-Search With Info **
+;;
+;;  Icicles searching (`icicle-search') is not Isearch.  It searches
+;;  for all matches in the portion of text you tell it to search.
+;;  This means that you cannot use it to search an entire manual in
+;;  one operation, unless you have the entire manual available in a
+;;  single buffer to be searched.
+;;
+;;  So, when you use `icicle-search' (`C-c `') to search with Info,
+;;  you are limited to a few options:
+;;
+;;  * You can use it normally, to search within a single Info node.
+;;
+;;  * You can widen the visible portion of the Info buffer
+;;    (`C-x n w'), to use it on an entire Info file.  However:
+;;
+;;    1. It is not obvious how a given Info manual is divided into
+;;       files.  That is, you need to be aware of the point at which
+;;       the manual moves from one file to the next.
+;;
+;;    2. Only the nodes in the same file that you have already visited
+;;       are highlighted, and lots of ugly Info "plumbing" becomes
+;;       visible in the other nodes.
+;;
+;;    3. You lose all Info features, such as navigation using links.
+;;
+;;  * There is another way to search across nodes, which addresses #1
+;;    and #2, but still does not give you navigable links and such.
+;;    Think of it as a hack that can sometimes be handy.  That is what
+;;    is described below.
+;;
+;;  The idea is to flatten a subtree of Info nodes - possibly an
+;;  entire manual, but more typically a node and its children - and
+;;  then use `icicle-search' (`C-c `') over that flattened document.
+;;  What is needed is a command that flattens Info subtrees.  Library
+;;  `info+.el' provides such a command, `Info-merge-subnodes', and
+;;  binds it to `+' in Info.
+;;
+;;  You can control how you want the flattening to occur, by using
+;;  different values of prefix argument.  For searching, you probably
+;;  want complete flattening of the chosen subtree, in a single
+;;  buffer, so you use a prefix arg of zero: `C-u 0 +'.
+;;
+;;  This does not replace the `*Info*' buffer that you started with;
+;;  it creates a new buffer, named after the root node of the subtree
+;;  you flattened.  A principle use of `Info-merge-subnodes' is to
+;;  print out a manual or a portion of it.  Also, I wrote a library
+;;  (`mkhtml.el', outdated now) that lets you convert the result to
+;;  HTML.
+;;
+;;  In sum, you can use Icicles search in Info: `C-u 0 +', then
+;;  `C-c `'.
+;;
+;;  One caveat, however: You will generally want to limit your search
+;;  to a reasonably small subtree of a manual, instead of flattening
+;;  and then searching the entire manual.  Flattening a large manual
+;;  can take a while: it took me 10 minutes to flatten the Emacs
+;;  Manual.  Of course, you could flatten a large manual once, and
+;;  save the result in a file for later searches.
+;;
+;;  Obviously, flattening in order to search is less convenient than
+;;  using manual-wide incremental search (`C-s') with Info (starting
+;;  with Emacs 22), and it is often less convenient than using
+;;  `Info-search' (bound to `s' in Info).  Icicles searching is
+;;  different from both, and it has its advantages and disadvantages.
+;;  When you want the advantages of Icicles searching in Info, the
+;;  flattening hack can be useful.  When you do not need those
+;;  advantages, other search methods can sometimes be more
+;;  appropriate.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Multi-Commands") for
+;;    information on using multi-commands.
+;;
+;;  * (@> "Icicles Search Commands, Overview") for information about
+;;    command `icicle-search'.
+;;
+;;  * Library `info+.el' for information about `Info-merge-subnodes'.
+ 
+;;(@* "Support for Projects")
+;;
+;;  Icicles Support for Projects
+;;  ----------------------------
+;;
+;;  This section mainly provides pointers to other sections of the
+;;  Icicles doc that describe features that can help you work with a
+;;  project that involves multiple files, buffers, or bookmarks.
+;;
+;;
+;;(@* "Bookmarks for Project Access and Organization")
+;;  ** Bookmarks for Project Access and Organization **
+;;
+;;  If you use Bookmark+ (library `bookmark+.el'), then you can use
+;;  bookmarks of various types, including the following, to help
+;;  manage software projects:
+;;
+;;  * Dired buffers, with specific sets of files and subdirectories
+;;    that are marked or omitted, and using specific listing switches.
+;;
+;;  * `*Bookmark List*' buffers, with specific sets of bookmarks that
+;;    are marked or hidden.
+;;
+;;  * Multiple alternative bookmark files.  For example, use a
+;;    different one for each project.  Or use different ones for
+;;    subprojects and use them together for a full project.
+;;
+;;  * Desktops, which include sets of variables and visited buffers
+;;    and files.
+;;
+;;  * Composite, or sequence, bookmarks, which combine other
+;;    bookmarks.
+;;
+;;  You can also associate tags, in the del.icio.us sense, with most
+;;  types of bookmarks.  (Such tags are unrelated to the Emacs
+;;  source-code tags that use tags files.)  A bookmark can have any
+;;  number of tags, and multiple bookmarks can have the same tag,
+;;  which means you can use them to organize their target objects.
+;;  And tags can be more than just names: they can be user-defined
+;;  attributes, with Emacs-Lisp objects as their values.
+;;
+;;  These and other Bookmark+ features give you different ways to
+;;  save, restore, filter, access, and otherwise organize projects, as
+;;  collections of information about source-code components and
+;;  related software.
+;;
+;;  Icicles enhances access to such features.
+;;  See (@> "Icicles Bookmark Enhancements").
+;;
+;;(@* "A Tags File Can Define a Project")
+;;  ** A Tags File Can Define a Project **
+;;
+;;  One simple kind of a project includes the files that are in or
+;;  under a single directory.  Such a project is limited, but it can
+;;  often be useful, and it has the advantage of being supported by
+;;  several existing Emacs features.
+;;
+;;  Another simple kind of project includes the files that are listed
+;;  in a given Emacs tags file.  This is obviously more complex and
+;;  flexible than a directory listing.
+;;
+;;  Icicles provides multi-commands for visiting one or more files
+;;  that are listed in the current tags table:
+;;  `icicle-find-file-in-tags-table' and
+;;  `icicle-find-file-in-tags-table-other-window'.  See also
+;;  (@file :file-name "icicles-doc1.el" :to "Icicles Commands that Read File Names").
+;;
+;;(@* "Navigating Among Code Definitions")
+;;  ** Navigating Among Code Definitions **
+;;
+;;  For software projects, you need to be able to navigate among code
+;;  definitions.  Imenu and Emacs tags features are useful for this,
+;;  as are `grep' and compilation buffers.  Icicles improves all of
+;;  these.  (A tags file is just a saved index for project files.)
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Imenu")
+;;  * (@> "Icicles Enhancements for Emacs Tags")
+;;  * (@> "Compile/Grep Search")
+;;
+;;(@* "Searching Project Files")
+;;  ** Searching Project Files **
+;;
+;;  Searching within your project is another area where Icicles can
+;;  help.  Icicles search is both search and navigation.  Navigating
+;;  among tags definitions that match a regexp is also really
+;;  searching, and the same is true for Imenu and grep navigation.
+;;
+;;  See also (@> "Icicles Search Commands, Overview") and its
+;;  subsections for information about the many ways that you can use
+;;  Icicles search to access parts of your projects.
+;;
+;;  See also (@> "Icicles Dired Enhancements") for an easy way to
+;;  search marked files in Dired with Icicles search.
+;;
+;;  See also (@> "Searching Bookmarked Objects") for ways to search
+;;  bookmarked objects, including the files that have a given set of
+;;  del.icio.us-style tags and the bookmarks that are marked in a
+;;  given bookmark-list state.
+;;
+;;  And do not forget that all uses of Icicles search also let you do
+;;  search-and-replace on the fly.  This applies to `grep' results,
+;;  searching marked files in Dired, tags navigation, and Imenu
+;;  navigation.  You can at any time replace the current search hit or
+;;  just the part of it that matches your current input.
+;;
+;;(@* "Defining and Saving Sets of Files or Buffers")
+;;  ** Defining and Saving Sets of Files or Buffers **
+;;
+;;  Let's assume that you have one or more sets of files or buffers
+;;  that you use frequently.  For each such set of objects, you create
+;;  an Emacs option whose value is a list of the file or buffer names
+;;  (strings).
+;;
+;;  Later, you use the option value to refer to those objects by name.
+;;  This brings you back to the context of working with just those
+;;  particular files or buffers that belong to your project.  You can
+;;  search such sets or navigate among their objects.  Icicles has a
+;;  number of features that can help with these tasks.
+;;
+;;  Note: Bookmarks are also persistent references to files and
+;;  buffers, and you can use sets of bookmarks similarly.  Bookmarking
+;;  is a vanilla Emacs feature.  Being able to manipulate explicit
+;;  sets of bookmarks is a Bookmark+ feature (library `bookmark+.el').
+;;  Bookmarking features are described elsewhere, but they work in
+;;  concert with Icicles to offer very good project support.
+;;  See (@> "Icicles Bookmark Enhancements").
+;;
+;;  Before you can name and save a set of file or buffer names, you
+;;  must define its members: pick the file and buffer names that you
+;;  want to belong to a given project.  Icicles can help with this.
+;;
+;;  For buffers, use commands `icicle-add-buffer-config' and
+;;  `icicle-remove-buffer-config' to define one or more buffer
+;;  configurations.  These are named sets of buffers, sort functions,
+;;  and other parameters that control completion of buffer names.
+;;  Thereafter, you can use command `icicle-buffer-config' to choose a
+;;  configuration to be current.
+;;
+;;  To define a set of files, you use Icicles completion against file
+;;  names.  You can use progressive completion, chip away the
+;;  non-elephant, and so on, to get just the file names you want.
+;;
+;;  For this completion, you can use a command that calls
+;;  `read-file-name', and so matches relative file names using the
+;;  current `default-directory'.  Or you can use a command that calls
+;;  `completing-read', and so matches file names only as ordinary
+;;  strings, that is, with no notion that they are file names.  In the
+;;  latter case, the file names are often absolute, which means that
+;;  you can match not only file names but also directory components.
+;;
+;;  Examples of the former type are `icicle-find-file' and
+;;  `icicle-find-file-read-only' (`C-x C-r' by default).  Examples of
+;;  the latter type are `icicle-find-file-absolute',
+;;  `icicle-find-file-in-tags-table', `icicle-recent-file', and
+;;  `icicle-locate-file'.  Command `icicle-file' (bound to `C-x C-f'
+;;  by default) lets you do both, depending on the prefix argument.
+;;
+;;  You save a set of file names the same way you save any set of
+;;  completion candidates.  You can save all of the names that match
+;;  your current input.  You can add a set of names or individual
+;;  names to a set of names that you have already saved.
+;;
+;;  In addition, you can save the marked files in Dired as a set of
+;;  project files.
+;;
+;;  Your project is not only files that are all in the same directory,
+;;  of course.  You can save file names from multiple directories in
+;;  the same set.  And you can include directory names as well, for
+;;  use later with commands that operate on directories.  Finally, you
+;;  can also save file names as Emacs filesets and use those the same
+;;  way.  An Icicles set of saved file names can include Emacs
+;;  filesets - see
+;;  (@file :file-name "icicles-doc1.el" :to "Filesets and Icicles Saved Completion Sets").
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates")
+;;  * (@file :file-name "icicles-doc1.el" :to "Persistent Sets of Completion Candidates")
+;;  * (@> "Icicles Bookmark Enhancements")
+;;  * (@file :file-name "icicles-doc1.el" :to "Progressive Completion")
+;;  * (@file :file-name "icicles-doc1.el" :to "Chip Away the Non-Elephant")
+;;  * (@file :file-name "icicles-doc1.el" :to "File-Name Input and Locating Files Anywhere")
+;;  * (@> "Save Marked Files as Completion Candidates") (Dired)
+;;
+;;(@* "Retrieving and Reusing a Saved Project")
+;;  ** Retrieving and Reusing a Saved Project **
+;;
+;;  This section could also be called "Using Retrieved Saved Sets".
+;;
+;;  You retrieve a set of saved file names (a project) the same way
+;;  you retrieve any saved set of completion candidates.  That is, you
+;;  access the files defined for your project by retrieving their
+;;  names during completion, to serve as the current set of completion
+;;  candidates.  This odd feature is unique to Icicles.
+;;
+;;  There's nothing much more to say about this, except that you
+;;  should be taking advantage of it now.  Define and save a set of
+;;  project files (or buffers), and later use just those files,
+;;  staying within the bounds of your project for your navigation,
+;;  search, compilation, etc. needs.  Even if the files you use in a
+;;  given project are scattered all over your file system, Icicles
+;;  lets you access them together as a named unit.  For more
+;;  information, see
+;;  (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates").
+;;
+;;  If you use library `bookmark+.el' then you can open a project that
+;;  is defined by a set of bookmarks, by doing one of the following:
+;;
+;;  * Using a project-specific bookmark file.
+;;
+;;  * Using a bookmark-list bookmark (it records a `*Bookmark List*'
+;;    buffer state, including which bookmarks are marked or omitted).
+;;
+;;  You can also open Dired for a project or for a list of file names
+;;  saved non-persistently as completion candidates - only those files
+;;  are listed in the Dired buffer.
+;;  See (@> "Icicles Dired Enhancements").
+;;
+;;  You can also run `grep' on a saved list of file names using
+;;  command `icicle-grep-saved-file-candidates'.  If you use library
+;;  `dired+.el', then you can also `grep' the files in a project or
+;;  saved list of file names by opening it in Dired and then using
+;;  `M-g' (`diredp-do-grep').
+;;
+;;  Finally, note that among the sets of completion candidates that
+;;  you can save are Icicles search hits.  That's right.  Icicles
+;;  search lets you search multiple buffers, files, or bookmarks, and
+;;  you can save selected search hits or all matching hits for later
+;;  use.  When you save search hits, Icicles records the buffer or
+;;  file names and the hit locations within those buffers or files.
+;;  When you retrieve such a saved set to access its hits, Icicles
+;;  automatically takes you to the proper files.
+;;
+;;  A related feature is being able to filter tags definitions and
+;;  then save the filtered hit list.  This works the same way, and it
+;;  gives you the equivalent of per-project tags files: A saved hit
+;;  list acts just like a custom tags file when you reuse it.  And
+;;  unlike some of your project files, a tags file does not change
+;;  often, so saved hit sets stay accurate longer.
+;;
+;;(@* "Semantics? Roll Your Own?")
+;;  ** Semantics? Roll Your Own? **
+;;
+;;  I no longer develop software.  I just putz around with Emacs Lisp
+;;  for my own enjoyment, entertainment, and enlightenment.  So I do
+;;  not use things like ECB (Emacs Code Browser) or Semantic
+;;  (Bovinator).  I do not use any IDE that has knowledge of a
+;;  particular programming language.  The Icicles commands I've
+;;  written therefore use little or no semantic or language
+;;  information; they rely upon syntax for the most part, and they are
+;;  essentially language-agnostic (i.e. ignorant).
+;;
+;;  But you are a different story.  If you use, say, Semantic, you
+;;  could write a little Emacs-Lisp code to take advantage of Icicles
+;;  in combination with Semantic's parser information.  With complete
+;;  ignorance of Semantic, I dare say it would not be hard.  If you
+;;  can get an alist of completion candidates for something from
+;;  Semantic in some context, then you can exploit all of the Icicles
+;;  features: apropos completion, progressive completion,
+;;  multi-commands, Icicles search, and so on.  Likewise for any other
+;;  IDE that plays well with Emacs and for any other programming
+;;  language support.  Think about it.  Others would appreciate your
+;;  contribution.
+;;
+;;  Icicles provides lots of features for Emacs-Lisp programmers.  The
+;;  end-user commands I've written using some of those features are
+;;  really just a demonstration of what you can do.  Try rolling your
+;;  own Icicles commands.  See Also: (@> "Note to Programmers").
+ 
+;;(@* "Using Complex Completion Candidates")
+;;
+;;  Using Complex Completion Candidates
+;;  -----------------------------------
+;;
+;;  This section could also be called "Applying a Function
+;;  Interactively" or "Mapping over Sets".  It is about applying a
+;;  function to members of a set of completion candidates that you
+;;  select interactively.  The candidates can represent arbitrarily
+;;  complex data, and the function is applied to the associated data
+;;  as well, not just to the displayed (string) candidate that names
+;;  the data.
+;;
+;;  You already know that you can manipulate sets of candidates - see
+;;  (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates").
+;;  The elements of those sets are strings; you choose
+;;  candidate names.  Sometimes, however, you need to choose among
+;;  named items that are themselves complex, containing more
+;;  information than just the name.  That is the idea behind
+;;  multi-command `icicle-apply', which this section introduces.
+;;
+;;  You (or a command that you use) can obtain the information
+;;  associated with a name after you choose the name.  This is what
+;;  happens, for instance, when you use `find-file'; the command looks
+;;  up the file associated with the file name you choose.  Icicles
+;;  multi-commands such as `icicle-file' perform this lookup both when
+;;  you act on a candidate during completion (e.g. `C-RET') and when
+;;  you make a final candidate selection (`RET') - see
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands").
+;;
+;;  Names and their associated information can be available in Emacs
+;;  Lisp in the form of an association list (alist), that is, a list
+;;  whose items are conses (cons cells).  An alist is often used to
+;;  represent a function that maps one set of things to another.  The
+;;  conses in the alist represent the tuples (typically pairs) of
+;;  related items.  The car of each cons is called its "key"; the cdr
+;;  is called its "value".  Different alists have different kinds of
+;;  keys and values.  Typical key types include symbols and strings;
+;;  typical value types include symbols, strings, numbers, and lists.
+;;  There are quite a few standard Emacs-Lisp variables whose value is
+;;  an alist.  Most are internal variables, but some are user options.
+;;  See the Emacs-Lisp manual for more about alists.
+;;
+;;  The completion mechanism of Emacs function `completing-read' can
+;;  take an alist as input: the keys are the completion-candidate
+;;  strings that you choose from.  For Emacs completion, however, the
+;;  value (cdr) of each alist key/value entry is completely ignored.
+;;  Icicles uses `completing-read', and it works the same way.  If a
+;;  command needs to access the value associated with a key
+;;  (candidate), then it must somehow do so independently of
+;;  completion.
+;;
+;;  Command `icicle-search' offers an example of this.  The completion
+;;  alist contains key/value pairs whose car (key) is a search-hit
+;;  string that matches your search string and whose cdr (value) is
+;;  the buffer position for the hit.  When you use completion with
+;;  this command, you work only with the keys, but `icicle-search'
+;;  also keeps track of the corresponding buffer positions for you.
+;;  The logic for doing this is coded into the definition of
+;;  `icicle-search'.
+;;
+;;  It is common to want to do something interesting interactively
+;;  with the values also, not just the keys, of a completion alist.
+;;  Why lose the important value information when you choose a key?
+;;  And instead of requiring the logic of each command to deal with
+;;  this need individually, why not provide a general mechanism for
+;;  accessing this information - both by program and interactively?
+;;  This is what command `icicle-apply' is for.
+;;
+;;  To make use of completion alist values, you need to access the cdr
+;;  of a key/value cons (pair).  Different alists are structured
+;;  differently: the cdr can itself be complex (structured - a cons).
+;;  In general, you want to access not just the cdr (value) but the
+;;  key as well, the key/value pair as a whole, to do what you want
+;;  with it - that is, to apply some function to it.
+;;
+;;  Emacs-Lisp programmers sometimes map functions over lists to
+;;  obtain a different list.  For example, mapping the function `1+'
+;;  over the list (3 1 4 1 5 9) gives the list (4 2 5 2 6 10).  Or if
+;;  interested only in the side effects, they apply a function
+;;  iteratively over a list without bothering to accumulate the
+;;  results as a new list.  The command `icicle-apply' is inspired by
+;;  these common practices of mapping and iterating over a list, but
+;;  it applies only to alists.  And it lets you choose interactively
+;;  which alist elements to act on, instead of always acting on all
+;;  elements.
+;;
+;;  `icicle-apply' lets you apply a function of your choice to any
+;;  number of key/value entries in an alist.  As user of the command,
+;;  you choose the entries to act on.  The alist is used for
+;;  completion; you choose among the keys.  The function is applied to
+;;  the corresponding key/value pairs, however, not to the keys alone.
+;;
+;;  For example, given the alist `auto-mode-alist' and the function
+;;  `cdr', you can choose to apply `cdr' to selected alist entries.
+;;  This acts as a simple lookup function, because `cdr' just returns
+;;  the value associated with a chosen key.  If you choose, for
+;;  example, the candidate (key) "\.el\'", then the (value) result is
+;;  the symbol `emacs-lisp-mode'.  In this case, the chosen key/value
+;;  pair is ("\\.el\\'" . emacs-lisp-mode).  (A literal backslash must
+;;  be doubled in an Emacs-Lisp string.)
+;;
+;;  Function `cdr' returns the value, which is `emacs-lisp-mode' here.
+;;  If instead of `cdr' you use the function (lambda (x)
+;;  (describe-function (cdr x))), then the result of choosing
+;;  candidate "\.el\'" is to display the help for function
+;;  `emacs-lisp-mode'.  This function first uses `cdr' to obtain the
+;;  value (the mode) and then applies `describe-function' to that
+;;  value.
+;;
+;;  A typical use of `icicle-apply' is to define your own
+;;  multi-command that you or someone else can use to act on objects
+;;  selected by name.  The definition of command `icicle-goto-marker'
+;;  provides an example.  It uses an alist whose elements are pairs
+;;  composed of a text line (the key) and the marker (the value) in
+;;  that line.  It applies a function that moves to the marker.
+;;
+;;  If called interactively (as opposed to being used to define
+;;  another command), `icicle-apply' lets you use completion to choose
+;;  not only the objects to act on but also the function to apply to
+;;  them and the alist to choose them from.  See the doc string of
+;;  `icicle-apply' for more information.
+;;
+;;  Note that you can type in a lambda expression when prompted for
+;;  the function.  You can use any function, provided it targets a
+;;  key/value pair (a cons).  This is why you could not simply use
+;;  `describe-function' itself as the function to apply in the example
+;;  above: `describe-function' expects a symbol argument, not a cons.
+;;
+;;  So what is `icicle-apply' really for?  Anything you want.  You can
+;;  use it to simply browse an alist or to perform actions on complex
+;;  things.  The idea is to let you take advantage of Icicles features
+;;  to interactively filter and manipulate a set of completion keys,
+;;  and then apply any function you like to them - not just to the
+;;  keys, but to the keys or their values, or both.
+;;
+;;  You can use apropos (regexp) matching or prefix matching to filter
+;;  the alist, as always, during completion.  You can use `C-RET' and
+;;  so on to act on (that is, apply the function to) selected
+;;  key/value pairs that match your current input.
+;;
+;;  You can also act on *all* such pairs, by using `C-!' or `M-!'.
+;;  `C-!' corresponds to iterating over the items in a list, applying
+;;  a function to each.  `M-!' applies a function not to each chosen
+;;  pair, but to the *list* of all chosen pairs.  By default, the
+;;  completion candidates are not sorted, but you can of course sort
+;;  them in various ways, either interactively or by program.
+;;
+;;  As an Emacs-Lisp programmer, you can use function `icicle-apply'
+;;  programmatically to let users look things up in alists that you
+;;  construct or to act on selected alist entries in complex ways.
+;;  Icicles just provides the interactive completion features.
+;;
+;;  The real value of `icicle-apply' comes from what you do with it.
+;;  Use it with a database of geographical coordinates to look up
+;;  location names provided by users and draw corresponding vicinity
+;;  maps.  Use it with a list of hardware configurations to let users
+;;  perform diagnostic or maintenance operations on selected
+;;  equipment.  You get the idea - use your imagination.
+;;
+;;  Note: Although completion alists normally require string-valued
+;;  keys, `icicle-apply' is designed to work with any alist.
+ 
+;;(@* "Icicles OO: Object-Action Interaction")
+;;
+;;  Icicles OO: Object-Action Interaction
+;;  --------------------------------------
+;;
+;;  Here's another crazy Icicles feature: Instead of choosing a
+;;  function (e.g. command) and then the object to apply it to, choose
+;;  the object first and then the function.
+;;
+;;  The first thing to say about this feature is that Emacs is not
+;;  really designed for this, so it's not feasible to do this in a
+;;  entirely satisfactory way.  In particular, there is no practical
+;;  way, given an object, to find all of the functions that apply to
+;;  it, in order to allow all of those functions, and only those
+;;  functions, as completion candidates.
+;;
+;;  The second thing to say is that there are several ways that
+;;  Icicles helps you operate on an object that you have already
+;;  chosen:
+;;
+;;  * apropos completion - (1) choose an object type by name, (2)
+;;    choose a function, (3) choose the target object
+;;
+;;  * alternative action by type, during completion - (1) choose a
+;;    target object, (2) choose a function appropriate for the
+;;    object's type.
+;;
+;;  * `M-RET' during completion - (1) choose a target object, (2)
+;;    choose any function
+;;
+;;  * `icicle-object-action' and `icicle-anything' - (1) choose an
+;;    object type by name, (2) choose the target object, (3) choose a
+;;    function
+;;
+;;  As a special case, if you use library Anything (`anything.el'),
+;;  then `icicle-object-action' lets you apply one or more Anything
+;;  actions defined for the object.  See (@> "Icicles with Anything")
+;;  for more information.
+;;
+;;(@* "Apropos Completion as OO")
+;;  ** Apropos Completion as OO **
+;;
+;;  You can use apropos completion with `M-x' to narrow the set of
+;;  possible commands to those that have a given object type in their
+;;  name.  You choose the command before the individual object, but
+;;  you at least choose the object type first (which narrows the set
+;;  of possible objects).
+;;
+;;  If you use Icicles, you already use apropos completion this way,
+;;  but you might not have thought about it in these terms.  If you
+;;  want to invoke some command on a buffer, you might start by typing
+;;  `M-x buffer S-TAB' or `M-x buff S-TAB'.  This is simple, but it
+;;  really does get you most of the way toward object-action
+;;  interaction.  And you can of course then use progressive
+;;  completion (`M-*') to filter the matching commands for additional
+;;  object-type names; for example `M-* window' keeps only those
+;;  commands whose names contain both `buffer' and `window'.
+;;
+;;  Of course, this approach requires the command name to actually
+;;  advertise truthfully the object types that it operates on.  There
+;;  are false positives and true negatives, but Emacs is generally
+;;  quite helpful in this respect.
+;;
+;;(@* "Alternative Action as OO")
+;;  ** Alternative Action as OO **
+;;
+;;  As explained in
+;;  (@file :file-name "icicles-doc1.el" :to "Alternative Actions"),
+;;  many Icicles commands, as their alternative action
+;;  (e.g. `C-S-RET'), prompt you to choose an action to be applied to
+;;  the current completion candidate.  The actions you can choose are
+;;  all appropriate functions for the current type of object
+;;  (candidate).  If you use library Anything (see below), then any
+;;  actions defined for the current type by Anything are included.
+;;
+;;  See Also:
+;;  (@file :file-name "icicles-doc1.el" :to "Alternative Actions").
+;;
+;;(@* "M-RET")
+;;  ** M-RET **
+;;
+;;  `M-RET' (`icicle-candidate-read-fn-invoke') during completion
+;;  provides a typeless object-action interaction, which is always
+;;  available.  (You can also use `ESC RET' or `ESC C-m'.)
+;;
+;;  This is similar to the action choice provided for some
+;;  commands by `C-S-RET', except that there is no notion of the
+;;  current object type - you can choose from among all Emacs-Lisp
+;;  functions.
+;;
+;;  Whenever you cycle through completion candidates, `M-RET' enters a
+;;  recursive edit that prompts you for a function to apply to the
+;;  current candidate.  `M-mouse-2' does the same thing.  For example,
+;;  if the current candidate is a buffer named `foo.el', then `M-RET'
+;;  prompts you for a function to apply to it.  (Actually, the
+;;  function is applied to the candidate, which is the buffer name in
+;;  this case, but many functions accept an object name in place of
+;;  the object.)
+;;
+;;  The function you enter can be anything, including a lambda
+;;  expression that accepts an argument of the appropriate type.  The
+;;  function is read with (lax) completion.  It is up to you to choose
+;;  a function that is appropriate for the current object type.
+;;
+;;  If you use a prefix argument (`C-u M-RET' or `C-u M-mouse-2'),
+;;  then the result of the function application is pretty-printed.
+;;  Otherwise, the function is called for effect only.
+;;
+;;(@* "`icicle-object-action' and `icicle-anything'")
+;;  ** `icicle-object-action' and `icicle-anything' **
+;;
+;;  Another way that Icicles helps with object-action interaction is
+;;  provided by command `icicle-object-action'.  This reads an
+;;  object-type name ("what"), with completion; then it reads an
+;;  object of that type ("which"), with completion; then it reads a
+;;  function (name or lambda expression) to apply to the object
+;;  ("how"), with (lax) completion.  Again, use a prefix argument if
+;;  you want to pretty-print the result.
+;;
+;;  `what-which-how' is an alias for command `icicle-object-action'.
+;;  It is easy to remember, taking its name from the successive input
+;;  prompts: "What?" - a file.  "Which?" - icicles.el.  "How?" open.
+;;  Another alias for the same command is `a', because it acts on a
+;;  file, a buffer, a symbol, a process, and so on.  The first thing
+;;  it does is prompt you for the type of object, so you do `M-x a RET
+;;  buffer', `M-x a RET symbol', and so on.
+;;
+;;  The aliases `what-which-how' and `a' are just convenience
+;;  commands.  They are defined only if user option
+;;  `icicle-define-alias-commands-flag' is non-`nil'.  Two related
+;;  commands are also defined only if this option is non-`nil':
+;;
+;;  * `file'   - same as `a RET file'
+;;  * `buffer' - same as `a RET buffer'
+;;
+;;  For example: `M-x file RET'.  You are prompted for a file to act
+;;  on, and then for the action to use.
+;;
+;;  Note: If you use AUCTeX, then be aware of an AUCTeX bug that
+;;  causes problems if `icicle-define-alias-commands-flag' is
+;;  non-`nil'.  Here is the bug description, filed 2007/10/05 by Bjorn
+;;  Haagensen:
+;;  http://lists.gnu.org/archive/html/bug-auctex/2007-10/msg00006.html.
+;;  The problem is that AUCTeX mistakenly invokes the Icicles `file'
+;;  command, in an inappropriate context.  AUCTeX does not define any
+;;  function `file' when it is loaded, but it invokes one, if defined.
+;;  This appears to be a name-capture problem.  Since there is no
+;;  `file' function defined when Icicles is loaded, Icicles defines
+;;  its command.  AUCTeX developers will no doubt fix this bug.  Until
+;;  then, AUCTeX users can avoid the bug by setting
+;;  `icicle-define-alias-commands-flag' to `nil'.
+;;
+;;  The "type" of an object is one of these:
+;;
+;;  a. A type defining an entry in user option
+;;     `icicle-predicate-types-alist'.  These are type predicates,
+;;     such as `bufferp', `keywordp', or `atom'.
+;;
+;;  b. The `type' of an Anything source, or its `name' if it has no
+;;     `type'.  This is available only if you use library
+;;     `anything.el'.
+;;
+;;  c. A type defining an entry in user option
+;;     `icicle-type-actions-alist'.
+;;
+;;  Icicles completion is available for each prompt: the type, the
+;;  object, and the action to apply to the object.  Types defined by
+;;  Anything are highlighted in buffer `*Completions*' using face
+;;  `icicle-special-candidate'.  In the case of an Anything type, you
+;;  can use multi-command features to act on multiple objects in
+;;  multiple ways, all within a single `a' invocation.  See
+;;  (@> "Icicles with Anything") for more information about using
+;;  Anything types.
+;;
+;;  The objects of types (b) and (c) are easily named, and their names
+;;  serve as the completion candidates when you choose them.  So, for
+;;  instance, if you choose type `buffer', then you can act on a
+;;  buffer by choosing its name.
+;;
+;;  The objects of predicate type (type a, above) are not necessarily
+;;  named.  The completion candidates for these objects are symbols
+;;  whose values are the objects that are acted upon. The object-type
+;;  names used for these candidates are really Emacs-Lisp type
+;;  predicate names, which all end in `p', except for `atom'.
+;;
+;;  So, for instance, if you choose type `bufferp', then you can
+;;  choose a symbol whose value is a buffer, in order to act on that
+;;  buffer.  A buffer is of course always named, but an object of type
+;;  `stringp' is not.  The value of `emacs-version' is one such string
+;;  that you can act on.
+;;
+;;  Be aware that the action function you choose must accommodate the
+;;  object you choose as its only argument.  Also, completion of the
+;;  function candidate itself is lax, so you can enter a lambda
+;;  expression as the action.
+;;
+;;  Objects that are naturally associated with names are treated
+;;  differently, depending on the type.  Besides Anything types, the
+;;  following object types are used for named objects: `buffer',
+;;  `command', `face', `frame', `function', `option', `process',
+;;  `symbol', `variable', `window'.  For all of these except `window',
+;;  the name of the object is used.  For `window', the candidate
+;;  objects are the names of the buffers that are currently shown in a
+;;  window (on any frame).
+;;
+;;  You'll note that some types are treated both ways, 1) using named
+;;  objects and 2) using symbols whose values are objects.  An example
+;;  is `frame' and `framep': the completion candidates (objects) for
+;;  type `frame' are frame names; the candidates for type `framep' are
+;;  symbols whose values are frames.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles with Anything")
+;;  * (@file :file-name "icicles-doc1.el" :to "Apropos Completions").
+;;  * (@file :file-name "icicles-doc1.el" :to "Progressive Completion").
+ 
+;;(@* "Icicles with Anything")
+;;
+;;  Icicles with Anything
+;;  ---------------------
+;;
+;;  Library Anything (`anything.el') lets you define object types and
+;;  associate actions with them.  It provides command `anything',
+;;  which you can use to apply an action to an object, choosing the
+;;  object first by name.  All objects (of all types) that have a name
+;;  that matches your input are candidates.  You can use command
+;;  `anything' while in Icicle mode; it has the same behavior with
+;;  Icicles as without it.
+;;
+;;  Icicles also integrates some Anything features within its own
+;;  completion environment, so that you can use Icicles features such
+;;  as progressive completion at the same time.  In particular, you
+;;  can act on multiple Anything objects in the same command
+;;  invocation, and you can act on them using multiple Anything
+;;  actions.
+;;
+;;  Command `icicle-anything' (alias `any') is just command
+;;  `icicle-object-action' (alias `a') restricted to Anything types -
+;;  see (@> "Icicles OO: Object-Action Interaction").  It is more
+;;  convenient than `a' if you know that you want to use an Anything
+;;  type, because the set of type candidates to choose from is more
+;;  limited.
+;;
+;;  When you act on an object of an Anything type, you are not
+;;  prompted for the action ("how").  The default Anything action is
+;;  applied, or you can choose a different Anything action.
+;;
+;;  Command `any' (or command `a' when applied to an Anything type) is
+;;  a multi-command (see
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands")):
+;;
+;;  * `C-RET', `C-mouse-2', and so on perform the default Anything
+;;    action on each chosen object.
+;;
+;;  * `C-S-RET', `C-S-mouse-2', and so on, prompt you, for each chosen
+;;    object, to choose one or more Anything actions (with
+;;    completion).
+;;
+;;  You can thus act on any number of Anything objects in any number
+;;  of Anything ways, all in the same `any' command invocation.  And
+;;  you can of course use Icicles completion and cycling to choose.
+;;  User option `icicle-anything-transform-candidates-flag' determines
+;;  whether Anything function `anything-transform-candidates' is
+;;  applied to displayed Anything candidates in Icicles.
+;;
+;;  Here's an example of using command `any'.  Let's assume that you
+;;  have an `action' entry such as this in `anything-type-attributes'
+;;  for the Anything type `command':
+;;
+;;  (action ("Call interactively"
+;;           . (lambda (command-name)
+;;               (call-interactively (intern command-name))))
+;;          ("Describe command"
+;;           . (lambda (command-name)
+;;               (describe-function (intern command-name))))
+;;          ("Add command to kill ring" . kill-new)
+;;          ("Go to command's definition"
+;;           . (lambda (command-name)
+;;               (find-function (intern command-name)))))
+;;
+;;  This defines four actions for objects of type `command', the
+;;  default action being the first listed ("Call interactively").
+;;
+;;  You enter command `any', choose the Anything type `command', and
+;;  then choose the command `icicle-face-list' to act on:
+;;
+;;    M-x any RET
+;;    What (type): command RET
+;;    Which (command): icicle-face-list RET
+;;
+;;  This invokes command `icicle-face-list', because the default
+;;  Anything action for an object of type `command' is to call it.
+;;
+;;  If you use `C-RET' instead of `RET' when choosing command
+;;  `icicle-face-list', then you remain within the `any' invocation,
+;;  and you can do something with another command after
+;;  `icicle-face-list'.  If you use `C-S-RET' when choosing a command,
+;;  then you are prompted for the action to invoke for that command:
+;;
+;;    Which (command): icicle-face-list C-S-RET
+;;    How (action): Go to command's definition RET
+;;
+;;  If you choose the Anything action "Go to command's definition",
+;;  then, well, that's what happens: here, you go to the definition of
+;;  `icicle-face-list'.  Again, you could use `C-RET' instead of
+;;  `RET', to perform this action on the command and then choose and
+;;  apply (via `RET' or `C-RET') another action to the same command.
+;;
+;;  After you've stopped (via `RET' or `C-g') acting on command
+;;  `icicle-face-list', you can clear the minibuffer (using `M-k') and
+;;  type another command to act on, and so on.  Or, you can stop (via
+;;  `RET' or `C-g') and end the invocation of command `any'.
+;;
+;;  At each prompt, you can use (apropos or prefix) completion or
+;;  cycling to pick a candidate.  So, for instance, using completion,
+;;  you could simply do this to choose `command', `icicle-face-list',
+;;  and "Go to command definition":
+;;
+;;    M-x any RET c RET face-l S-TAB C-S-RET g TAB RET
+;;
+;;  Icicles enhances Anything by providing multi-command features, as
+;;  well as by providing all of the other standard Icicles features:
+;;  apropos and prefix completion, cycling, progressive completion,
+;;  help on individual candidates, and so on.  On the other hand,
+;;  Anything by itself provides some features that Icicles does not
+;;  exploit.  The aim of command `any' is to give you the basic
+;;  Anything features in an Icicles completion context.
+;;
+;;  A significant behavior difference between Anything (that is,
+;;  command `anything') and Icicles command `any' is that with
+;;  `anything' only the object name is used for filtering, whereas
+;;  with Icicles command `any' you first narrow down the potential
+;;  candidates by type, before the object name is matched (against
+;;  objects of only that type).
+;;
+;;  That is, with Anything, your input pattern is matched against
+;;  every possible object of every possible type.  You then choose
+;;  among the matches.  If you want, after that wide-net matching you
+;;  can cycle among only the matches of a given type (e.g. file), but
+;;  matching against all other types has already taken place.
+;;
+;;  This behavior of starting with typeless matching can be convenient
+;;  sometimes (you need not specify the object type), but it can also
+;;  be inconvenient (and unnecessarily slow) to match objects of types
+;;  totally unrelated to what you're after.  In such cases, it can
+;;  require either a long input pattern or cycling among more
+;;  candidates, to disambiguate among the hits.
+;;
+;;  With Icicles command `any', you have the inconvenience of needing
+;;  to specify first the type of object you want, but this has the
+;;  advantage of eliminating searching among irrelevant types.
+;;  Finally, remember that you can use both `anything' and `any' -
+;;  choose whichever is most convenient for the current task.
+ 
+;;(@* "Multi-Completions")
+;;
+;;  Multi-Completions
+;;  -----------------
+;;
+;;  This section is about using completion candidates that are
+;;  composed of more than one part: strings that you can complete
+;;  against separately and simultaneously.
+;;
+;;(@* "Icicles Multi-Completion Commands")
+;;  ** Icicles Multi-Completion Commands **
+;;
+;;  Have you ever used standard Emacs command `apropos-documentation'?
+;;  It searches the doc strings of all Emacs-Lisp symbols for matches
+;;  to an input regexp, and displays the hits.  It can be useful when
+;;  you do not remember the name of a function or variable but you can
+;;  guess at terms that might occur in its doc string.  Typically,
+;;  people resort to it only after first trying apropos commands that
+;;  match against the function or variable name.
+;;
+;;  The idea behind `apropos-documentation' also motivates Icicles
+;;  command `icicle-doc'.  This is a multi-command (see
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands")),
+;;  so you can use `C-RET' and `C-next' to browse the regexp matches,
+;;  displaying the documentation of each match in turn, and you can
+;;  change the regexp to get different matches during the same command
+;;  invocation.
+;;
+;;  Like `apropos-documentation', `icicle-doc' lets you match a regexp
+;;  against the doc strings of symbols such as functions, variables,
+;;  and faces.  You can of course use progressive completion to match
+;;  multiple regexps.  Here, for example, is a query that shows all doc
+;;  strings (functions, variables, faces - a lot! of doc strings)
+;;  that match both `mail' and `mode line', in either order,
+;;  as completion candidates:
+;;
+;;    M-x icicle-doc RET mail S-SPC mode line
+;;
+;;  You cannot do that with vanilla Emacs `apropos-documentation' or
+;;  with any other vanilla Emacs `apropos*' command.
+;;
+;;  Commands `icicle-vardoc', `icicle-fundoc', and `icicle-plist' are
+;;  similar to `icicle-doc' in the kind of functionality they provide.
+;;
+;;  Each of these commands gathers a tremendous amount of information
+;;  to construct an initial set of completion candidates based on all
+;;  existing Emacs symbols (in the standard `obarray').  This is
+;;  time-consuming.  Since the set of symbols that have property lists
+;;  or that name functions, variables, or faces changes little, you
+;;  can optionally bypass this gathering and reuse the last initial
+;;  set of candidates for that command.  You do this by invoking the
+;;  command using a prefix argument (non-negative prefix arg, for
+;;  `icicle-vardoc' and `icicle-plist').
+;;
+;;  Each of these particular commands also uses Icicles
+;;  multi-completion.  A "multi-completion" is a completion candidate
+;;  that has multiple parts.  A multi-completion command lets your
+;;  input match any or all parts individually, at the same time.
+;;
+;;  * Commands `icicle-vardoc' and `icicle-fundoc' let you match both
+;;    the function or variable name and the doc string.
+;;
+;;  * Command `icicle-doc' lets you match any combination of the
+;;    following:
+;;
+;;    - the function, variable, or face name
+;;    - the type: FUNCTION, VARIABLE, or FACE (uppercase)
+;;    - the doc string
+;;
+;;  * Command `icicle-plist' lets you match both a symbol name and its
+;;    property list.  You can use it to find symbols with certain
+;;    property-list keys or values.  By default (for Emacs 22 or
+;;    later), plists are pretty-printed (in `*Help*' and
+;;    `*Completions*'), but if you use a negative prefix argument then
+;;    pretty-printing is skipped, gaining a little time.
+;;
+;;  * Command `icicle-describe-option-of-type' (bound to `C-h C-o' in
+;;    Icicle mode) lets you match both an option name and the option's
+;;    `defcustom' type definition.  There are several ways to match
+;;    type definitions, controlled by the prefix argument - see the
+;;    command's doc string.  You can match a type directly or taking
+;;    type inheritance into account.  You can match a type as a sexp
+;;    or using a regexp.  You can match a type expression or match the
+;;    option's current value against a type.
+;;
+;;  Other Icicles commands that use multi-completion include
+;;  `icicle-locate-file', `icicle-locate-file-other-window',
+;;  `icicle-recent-file', and `icicle-recent-file-other-window'.
+;;  These commands let you match against two-part multi-completion
+;;  candidates that are composed of an absolute file name and the
+;;  file's last modification date.  This means that you can easily
+;;  find those notes you took sometime last week...
+;;
+;;  The way multi-completion commands work is a bit inelegant perhaps,
+;;  and it can take a little getting used to, but it is quite powerful
+;;  and lets you do things with completion that are otherwise
+;;  impossible.
+;;
+;;  In the case of commands that use two-part multi-completions, you
+;;  provide two regexps as input, one to match the name of a symbol
+;;  (e.g. a function or variable) and one to match some associated
+;;  information (doc string, property list, or type definition).
+;;
+;;  However, since completion candidates are not actually multipart,
+;;  you in fact type a single regexp that is the concatenation of the
+;;  two.  You join these two regexps using `icicle-list-join-string'
+;;  (a user option), which, by default, is `^G^J', that is, a
+;;  control-G character followed by a control-J (newline) character.
+;;  As always, you can input control characters using `C-q', so to
+;;  input `^G^J' you can use `C-q C-g C-q C-j'.
+;;
+;;  However, in Icicles, `C-j' (newline) is self-inserting during
+;;  completion, so you do not need to quote it with `C-q' - you can
+;;  use just `C-q C-g C-j'.  Better yet, you can use `C-M-j'
+;;  (`icicle-insert-list-join-string') to insert `^G^J'.
+;;
+;;  This has the added benefit (in Emacs 22 or later) of hiding the
+;;  `^G' - it's there, but you do not see it.  This hiding is only
+;;  cosmetic; you still match the characters `^G' and `^J'.  In the
+;;  same way, Icicles hides the `^G' part of `^G^J' in
+;;  `*Completions*', so the join string appears as a newline
+;;  character.
+;;
+;;  This hiding of `^G' happens only when option
+;;  `icicle-list-join-string' has its (ugly but useful) default value.
+;;  If not seeing the join string confuses you and you would prefer to
+;;  distinguish multi-completion part separators from ordinary newline
+;;  characters, then customize `icicle-list-join-string' - just remove
+;;  the following from the Lisp sexp that defines the default value:
+;;
+;;    (set-text-properties 0 1 '(display "") strg)
+;;
+;;  As an example of using a multi-completion command, you can use the
+;;  following to match a function name that contains `dired' and its
+;;  doc string that contains `file':
+;;
+;;    M-x icicle-fundoc dired^G^Jfile S-TAB
+;;
+;;  That is, you type this:
+;;
+;;    M-x icicle-fundoc dired C-q C-g C-j file S-TAB
+;;
+;;  or this:
+;;
+;;    M-x icicle-fundoc dired C-M-j file S-TAB
+;;
+;;  Well, almost.  The way it actually works is that the completion
+;;  candidates are themselves formed by concatenating symbol names
+;;  with their doc strings, using `icicle-list-join-string'.  Your
+;;  input regexp is matched against those candidates.  This means that
+;;  the input regexp `dired^G^Jfile' would actually match only
+;;  function names that *end* with `dired' and doc strings that
+;;  *begin* with `file'.
+;;
+;;  To match `file' against any part of the doc string, you must
+;;  explicitly link the two component regexps with a regexp that
+;;  matches anything.  If you want to search only the first lines of
+;;  doc strings, you can use `.*' to do that: `dired.*^G^J.*file' will
+;;  match all functions whose names contain `dired' and whose doc
+;;  strings' first lines contain `file'.
+;;
+;;  Why only the first lines?  Because `.' matches any character
+;;  except a newline - it does not look past the first line.  If you
+;;  want to search the entire doc strings (or property lists, for
+;;  `icicle-plist'), then you need to use a connecting regexp that
+;;  matches any character, including a newline.  That means a regexp
+;;  such as `\(.\|\n\)'.  Or you can just use the Icicles multi-line
+;;  dot feature - see (@> "Dot, Dot, Dot").
+;;
+;;  Without a multi-line dot, you would use something like this to
+;;  search whole, multi-line doc strings for `file':
+;;
+;;    M-x icicle-fundoc dired.*^G^J\(.\|\n\)*file S-TAB
+;;
+;;  That is, you would type (without the spaces):
+;;
+;;    M-x icicle-fundoc dired.* C-M-j \ ( . \ | C-j \ ) * file S-TAB
+;;
+;;  With a multi-line dot, you would type just this:
+;;
+;;    M-x icicle-fundoc dired.* C-M-j . * file S-TAB
+;;
+;;  What if you want to match, say, `file' in either the function name
+;;  or the doc string, not necessarily both?  Remember that a
+;;  multi-completion is in fact a single string, with a separator such
+;;  as `^G^J' in the middle somewhere.  Because it is a single string,
+;;  the simple minibuffer input `file' matches the substring `file'
+;;  anywhere in the multi-completion.  So the answer is just this:
+;;
+;;    M-x icicle-fundoc file S-TAB
+;;
+;;  Even this simple command expression combines the effect of Emacs
+;;  commands `apropos-function' with that of `apropos-documentation'.
+;;
+;;(@* "How Multi-Completions Work")
+;;  ** How Multi-Completions Work **
+;;
+;;  These commands that accept a multipart regexp are examples of
+;;  Icicles multi-completion.  Icicles extends standard function
+;;  `completing-read' so that it will accept, as the set of completion
+;;  candidates, an alist argument whose candidates are not only
+;;  individual strings but can also be lists of strings.  Each string
+;;  in the list is one part of a multipart completion candidate, that
+;;  is, a multi-completion.  The strings are joined together pairwise
+;;  using `icicle-list-join-string' by `completing-read'.  Commands
+;;  `icicle-fundoc' and`icicle-vardoc' each use lists of two strings
+;;  (name and doc), but a multi-completion can have any number of
+;;  strings.
+;;
+;;  Why is the default value of `icicle-list-join-string' so odd:
+;;  `^G^J'?  You can use any string you like, but here is the
+;;  rationale behind the default choice:
+;;
+;;  - ^G does not normally occur in simple strings such as doc strings
+;;  - a newline (^J) visually separates the multiple component strings
+;;  - ^G^J is not too difficult to enter: `C-M-j' or `C-q C-g C-j'
+;;
+;;  It is important that the value of `icicle-list-join-string' not be
+;;  something that is, itself, likely to match any of the candidates.
+;;  Otherwise, it would not serve its role as separator.
+;;
+;;  I find that it helps a bit (in Emacs 22 or later) to customize
+;;  face `escape-glyph', which is used for control characters such as
+;;  `^G', in such a way that it stands out a bit, especially because
+;;  control characters can be used in regexps that also use `^' as a
+;;  special character.  I use an orange background with a blue
+;;  foreground for this face.
+;;
+;;(@* "Multi-Completions Let You Match Multiple Things in Parallel")
+;;  ** Multi-Completions Let You Match Multiple Things in Parallel **
+;;
+;;  Consider the command `describe-option-of-type', defined in my
+;;  library `help-fns+.el' (or `help+.el', for Emacs 20).  This lets
+;;  you first pick a `defcustom' type using completion and then pick
+;;  an option of that type to describe.  There are two separate,
+;;  sequential acts of completion.  For each completion act, your
+;;  current input defines a set of matches.  You can see all option
+;;  types that match, say, the regexp `.*string', which means all
+;;  types that contain `string'.  After you choose one of those types,
+;;  you can see all options of that type whose names start with
+;;  `icicle' and then pick one.
+;;
+;;  You can thus tweak the type regexp to filter types, and you can
+;;  tweak the name regexp to filter option names.  And you can of
+;;  course use progressive completion to whittle down either set of
+;;  matches, piecemeal.
+;;
+;;  What you cannot do, however, using `describe-option-of-type' is
+;;  filter both sets at the same time: narrow down the set of type
+;;  matches and name matches simultaneously.  For that, you need
+;;  Icicles multi-completion.  Without it, you must commit 100% to a
+;;  type before you can choose among the options of that type.  With
+;;  it, you can change the type (or the name) part of your input
+;;  regexp on the fly, and see immediately the set of matching names
+;;  (or types) as well.
+;;
+;;(@* "Multi-Completions vs `completing-read-multiple'")
+;;  ** Multi-Completions vs `completing-read-multiple' **
+;;
+;;  Note that there is (only) a superficial similarity between Icicles
+;;  multi-completion and the functionality provided by function
+;;  `completing-read-multiple' of standard Emacs library `crm.el'.
+;;  The latter lets you complete multiple strings in the minibuffer,
+;;  one at a time.  It involves ordinary Emacs prefix completion, and
+;;  it uses the same set of completion candidates for each of the
+;;  strings in the input.
+;;
+;;  By contrast, Icicles multi-completion completes each part of your
+;;  input against a different set of completion candidates.  For
+;;  example, when you use `icicle-vardoc', it completes the
+;;  variable-name part of your input against the names of defined
+;;  variables, and the variable-description part against the doc
+;;  strings of defined variables.  Standard Emacs command
+;;  `completing-read-multiple' lets you complete several different
+;;  variable names at the same minibuffer prompt, but they each
+;;  complete against the same set of variable names.
+;;
+;;  Multi-completion matches a list of regexps in parallel.  See also
+;;  the description of `M-*', which matches a list of regexps in
+;;  series: (@file :file-name "icicles-doc1.el" :to "Progressive Completion").
+;;  You can combine these features, of course.
+;;
+;;(@* "Sorting Candidates by Their Second Part")
+;;  ** Sorting Candidates by Their Second Part **
+;;
+;;  Most multi-completions have two parts.  Typically, the first part
+;;  is the main part, that is, the part that you will most frequently
+;;  complete against.  Many candidate sort orders involve some flavor
+;;  of alphabetic order, and this means alphabetizing first with
+;;  respect to the first multi-completion part.
+;;
+;;  However, it can sometimes be convenient to sort instead by the
+;;  second part first.  That is what the Icicles sort order "by 2nd
+;;  parts alphabetically" is for.  You can use it, for example, with
+;;  command `icicle-locate-file' to sort file-name candidates first by
+;;  date, and then by file-name for the same date.  This gives you an
+;;  easy way to look up files that you modified during a given time
+;;  period.  For example, your input regexp can limit candidates to
+;;  those files last modified sometime in July, 2008, and you can then
+;;  access these chronologically (by cycling or in buffer
+;;  `*Completions*').  And do not forget that you can always reverse
+;;  the current sort order, using `C-N C-,' where N is an integer.
+;;
+;;  See Also:
+;;
+;;  * (@> "Programming Multi-Completions") for information about
+;;    changing the appearance and behavior of Icicles
+;;    multi-completions using Emacs-Lisp code.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Sorting Candidates and Removing Duplicates")
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Progressive Completion")
+ 
+;;(@* "Dot, Dot, Dot")
+;;
+;;  Dot, Dot, Dot
+;;  -------------
+;;
+;;  This section is about dot, that is, `.', and its role as a regexp
+;;  special character in apropos completion.
+;;
+;;  Since the inception of regular-expression matching, `.' has
+;;  matched any character *except* a newline character (aka `^J', aka
+;;  `C-j').  Recent languages typically have an additional mode in
+;;  which `.' can match any character, including a newline.  See, for
+;;  example, http://www.regular-expressions.info/dot.html and this
+;;  language comparison for regexp features:
+;;  http://www.regular-expressions.info/refflavors.html.
+;;
+;;  It is not unusual to manipulate multi-line completion candidates
+;;  in Icicles, in which case it can be handy to let `.' match any
+;;  character, including a newline.  For this and more general
+;;  reasons, I long ago requested such a mode for Emacs, but there was
+;;  little interest in implementing it.  In Emacs, dot never matches a
+;;  newline.  Too bad.
+;;
+;;  The regexp `\(.\|[\n]\)' is good enough, of course: it matches any
+;;  character: any character any except newline, plus newline.  But it
+;;  is a bit unwieldly, especially when used within a larger regexp,
+;;  and especially if used more than once in the same regexp.
+;;  Interactively, you input the `\n' using `C-j', and it appears in
+;;  the minibuffer as a newline character; that is, it creates another
+;;  line of input.
+;;
+;;  For convenience in multi-line matching, I added a *multi-line
+;;  dot*, or dot-matches-newline-too, hack to Icicles.  This feature
+;;  is turned off, by default.  You can toggle it on/off, using
+;;  command `icicle-toggle-dot' (aka `icicle-toggle-.'), which is
+;;  bound to `C-M-.' in the minibuffer during completion.
+;;
+;;  When this is turned on, `.' is highlighted in the minibuffer
+;;  (using face `highlight'), and it matches newlines also.  In fact,
+;;  although it appears as just a highlighted dot, the ugly regexp
+;;  `\(.\|[\n]\)' (the value of constant `icicle-anychar-regexp') is
+;;  really used, under the covers.  Icicles takes care of things so
+;;  that you can edit normally (delete and transpose characters,
+;;  etc.): A multi-line `.' acts just like a normal, single character,
+;;  even though it is really a string of ten characters.
+;;
+;;  If you prefer to see the full regexp, `\(.\|[\n]\)', but
+;;  highlighted, then set option `icicle-dot-show-regexp-flag' to
+;;  non-`nil'.  (In Emacs 20, the newline-matching dot is always shown
+;;  as that full regexp.)  If you prefer to turn on newline matching
+;;  by default, then just customize option `icicle-dot-string'.
+;;
+;;  This match-anything dot is handy, but sometimes you might want to
+;;  match anything except a newline, perhaps in the same input pattern
+;;  where you also want to match any character (possibly a newline) at
+;;  other positions.  How can you get the plain dot behavior, when
+;;  multi-line dot is turned on?
+;;
+;;  One way is just to use a regexp that matches anything except
+;;  newline: `[^\n]' (which you input using `[ ^ C-j ]').  Another way
+;;  is to use a plain prefix argument: `C-u .'.  (A numeric prefix
+;;  argument N inserts N multi-line dots, each of which matches any
+;;  single character.)
+;;
+;;  `C-u' flips the behavior of `.' when you hit it: If by default `.'
+;;  enters a multi-line dot, then `C-u .' enters a plain dot.  If by
+;;  default `.' enters a plain dot, then `C-u .' enters a multi-line
+;;  dot.  So `C-u' also gives you a way to enter a one-off multi-line
+;;  dot, if you prefer to generally have `.' not match a newline.
+;;  Either way, what you see in the minibuffer is the single character
+;;  `.', highlighted if it is a multi-line dot, unhighlighted if it is
+;;  a plain dot.
+;;
+;;  Multi-line dots are converted to plain dots automatically when you
+;;  use prefix completion.  And if you then move back to apropos
+;;  completion during the same completion operation, you get back any
+;;  multi-line dots you had before, and any plain dots that you
+;;  entered before remain plain.
+;;
+;;  So when is a multi-line dot useful?  Whenever you want to match
+;;  against multi-line candidates.  Typical use cases include
+;;  `icicle-search' and the Icicles doc commands, `icicle-vardoc',
+;;  `icicle-fundoc', and `icicle-doc'.
+;;
+;;  Note that the dot-matching behavior described here applies only to
+;;  matching minibuffer input against completion candidates.  It does
+;;  not mean that whenever you type `.' in the minibuffer it is
+;;  interpreted specially.  For example, when you input (using `RET')
+;;  a regexp as the context pattern for Icicles search, a `.'  has its
+;;  usual meaning in Emacs regexps - it does not match newlines.
+;;
+;;  If you want a regexp that you input (using `RET') to match any
+;;  character including a newline, then you can use `C-u C-=
+;;  icicle-anychar-regexp' to insert the proper string explicitly.
+;;  You can shorten this to just `C-=' if you use command
+;;  `icicle-save-string-to-variable':
+;;
+;;   M-x icicle-save-string-to-variable C-u C-= icicle-anychar-regexp
+;;
+;;  See Also:
+;;
+;;  * (@> "Using Regexps with Icicles Search")
+;;  * (@file :file-name "icicles-doc1.el" :to "Inserting a Regexp from a Variable or Register")
+ 
+;;(@* "Fuzzy Completion")
+;;
+;;  Fuzzy Completion
+;;  ----------------
+;;
+;;  There are a few different kinds of what might be called "fuzzy"
+;;  matching used in Icicles completion, in addition to apropos
+;;  (regexp) matching and prefix matching.  And if you have your own
+;;  method of matching then you can use that as well, by adding it to
+;;  option `icicle-S-TAB-completion-methods-alist'.
+;;
+;;  The following methods are predefined:
+;;
+;;  * Fuzzy - This method uses a fairly sophisticated matching
+;;    algorithm that seems to account for various typing mistakes.
+;;    This algorithm is provided by library `fuzzy-match.el', so I
+;;    call its use in Icicles `fuzzy' completion.  You must have
+;;    library `fuzzy-match.el' to use this.
+;;
+;;  * Swank - Symbols are completed using the algorithm of
+;;    `el-swank-fuzzy.el' - see that library for details.
+;;
+;;  * Scatter - This is a simple, poor man's fuzzy matching method
+;;    that I call `scatter' matching.  Ido calls it `flex' matching.
+;;    The TextMate editor has the same thing for file-name matching
+;;    (only), without naming it.
+;;
+;;  * Levenshtein - This method checks whether two strings differ by
+;;    at most a given number of character operations, the so-called
+;;    "Levenshtein distance".  You must have library `levenshtein.el'
+;;    to use this.
+;;
+;;  * Jaro-Winkler - This method gives matching weight to having both
+;;    (a) more characters that match in the right positions (Jara) and
+;;    (b) a longer exact prefix within the first four characters
+;;    (Winkler).
+;;
+;;  My opinion about the relative usefulness of the various methods:
+;;  Basic (prefix) completion and apropos completion are by far the
+;;  most useful.  They are followed, in order of decreasing
+;;  usefulness, by scatter, fuzzy, Levenshtein, vanilla, Jaro-Winkler,
+;;  and swank completion. YMMV.
+;;
+;;  Besides these methods, remember that you can get ordinary
+;;  substring matching with `S-TAB' by using `C-`' to turn off
+;;  (toggle) escaping of regexp special characters.  With special
+;;  characters escaped, `S-TAB' does literal substring completion.
+;;
+;;  The type of completion matching that is used when you hit `S-TAB'
+;;  and `TAB' is controlled by user options
+;;  `icicle-S-TAB-completion-methods-alist' and
+;;  `icicle-TAB-completion-methods', respectively.  The possible
+;;  methods for `TAB' are predefined, but you can add additional
+;;  methods for `S-TAB' by customizing
+;;  `icicle-S-TAB-completion-methods-alist'.
+;;
+;;(@* "Changing Completion Method")
+;;  ** Changing Completion Method **
+;;
+;;  You can use fuzzy or swank completion in place of prefix
+;;  completion (`TAB').  You can use scatter, Levenshtein, or
+;;  Jaro-Winkler completion in place of apropos completion (`S-TAB').
+;;  You can change completion methods easily at any time, by hitting a
+;;  key in the minibuffer:
+;;
+;;  * `C-(' (command `icicle-next-TAB-completion-method') to cycle
+;;    among `TAB' completion methods: `basic', `vanilla', `fuzzy', and
+;;    `swank' (`vanilla' only for Emacs 23 and later; `fuzzy' only if
+;;    you have library `fuzzy-match.el'; `swank' only if you have
+;;    library `el-swank-fuzzy.el').
+;;
+;;  * `M-(' (command `icicle-next-S-TAB-completion-method') to cycle
+;;    `S-TAB' completion methods: `apropos', `scatter', `Levenshtein',
+;;    `Levenshtein strict', and `Jaro-Winkler' (only if you have the
+;;    Autocomplete library `fuzzy.el').
+;;
+;;  Repeating `C-(' and `TAB' or `M-(' and `S-TAB' on the fly for the
+;;  same input can be a good way to learn the differences between the
+;;  various completion methods.
+;;
+;;  If you provide a prefix argument to `C-(' or `M-(', then the newly
+;;  chosen method is used only for the current command.  More
+;;  precisely, the previously active method is restored as soon as you
+;;  return to the top level.
+;;
+;;  The completion methods available for cycling via `C-(' or `M-('
+;;  are defined by options `icicle-TAB-completion-methods' and
+;;  `icicle-S-TAB-completion-methods-alist', respectively.  By
+;;  default, the first method in each list is used for matching.
+;;
+;;  Sometimes you might want to make a different set of completion
+;;  methods available during input.  You can use options
+;;  `icicle-TAB-completion-methods-per-command' and
+;;  `icicle-S-TAB-completion-methods-per-command' to do this.  These
+;;  define the methods to be made available during specific commands
+;;  (that read input with completion).  That is, they give you
+;;  command-specific control over `C-(' and `M-('.
+;;
+;;  The per-command control is provided by advising (`defadvice') the
+;;  particular commands.  You can also do this interactively, using
+;;  commands `icicle-set-TAB-methods-for-command' and
+;;  `icicle-set-S-TAB-methods-for-command'.  Invoking one of these
+;;  with a negative prefix argument removes the advice, restoring the
+;;  default choice of methods for the target command.
+;;
+;;  For example, this sets the available `TAB' methods for command
+;;  `icicle-read-color' to fuzzy (the default for this command) and
+;;  basic:
+;;
+;;    M-x icicle-set-TAB-methods-for-command RET
+;;    Command: icicle-read-color RET
+;;    TAB methods: fuzzy RET
+;;    TAB methods: basic RET
+;;    TAB methods: RET
+;;      
+;;  And this removes the special treatment for `C-(' during
+;;  `icicle-read-color', restoring the default `TAB' methods that are
+;;  defined by option `icicle-TAB-completion-methods':
+;;
+;;    C-- M-x icicle-set-TAB-methods-for-command RET
+;;    Command: icicle-read-color RET
+;;
+;;(@* "Partial Completion")
+;;  ** Partial Completion **
+;;
+;;  This section pertains to Emacs releases starting with Emacs 23.
+;;
+;;  If option `icicle-TAB-completion-methods' includes `vanilla'
+;;  (which it does, by default), and you choose `vanilla' completion
+;;  for `TAB' (by cycling using `C-(' or by customizing
+;;  `icicle-TAB-completion-methods' to use `vanilla' as the default),
+;;  then Icicles `TAB' completion respects the standard Emacs option
+;;  `completion-styles', so the behavior of `TAB' is similar to what
+;;  it is in vanilla Emacs.
+;;
+;;  Emacs includes `partial-completion' in the default value of
+;;  `completion-styles'.  This means that Icicles too will make use of
+;;  partial completion when you use `TAB' (with `vanilla').  Icicles
+;;  makes no use of `completion-styles' when you use `S-TAB'.
+;;
+;;  Partial completion is not really a kind of fuzzy completion, but
+;;  its effect can sometimes be similar.  In some ways, it is similar
+;;  to scatter-match completion (see next), but it requires you to
+;;  explicitly mark where to skip ahead (using `*', ` ' (space), or
+;;  `-').
+;;
+;;  Icicles does not support using the mode `partial-completion-mode',
+;;  and Emacs itself is in the process of deprecating it, now that the
+;;  partial-completion style is active by default.
+;;
+;;  I do not necessarily recommend using `vanilla' for `TAB'
+;;  completion, or, if you do, including `partial-completion' as an
+;;  entry in `completion-styles', because its effect is often
+;;  counter-intuitive or confusing.  But it is included by default in
+;;  Emacs, and Icicles supports it.  You might find it useful in
+;;  file-name completion, to be able to complete directory components,
+;;  for instance.
+;;
+;;(@* "Scatter-Match Completion")
+;;  ** Scatter-Match Completion **
+;;
+;;  The idea behind scatter-match completion is very simple: input
+;;  characters are matched in order against completion candidates, but
+;;  possibly with intervening characters.  That is, your input
+;;  scatter-matches a completion candidate if each character is also
+;;  in the candidate, and the character order is respected.
+;;
+;;  What this really amounts to is matching input `abc' as if it were
+;;  the regexp `a.*b.*c'.  That's all.
+;;
+;;  You can use Icicles scatter matching at any time in place of
+;;  apropos (regexp) matching.  Unlike the cases of swank and fuzzy
+;;  completion (see below), you can use it to complete file names
+;;  also.
+;;
+;;(@* "Swank (Fuzzy Symbol) Completion")
+;;  ** Swank (Fuzzy Symbol) Completion **
+;;
+;;  If you choose `swank' completion, what you get in Icicles is fuzzy
+;;  completion (see next), except regarding symbols.  That is, swank
+;;  completion per se applies only to symbols.  Symbols are completed
+;;  using the algorithm of `el-swank-fuzzy.el' - see that library for
+;;  details.
+;;
+;;  Icicles options `icicle-swank-timeout' and
+;;  `icicle-swank-prefix-length' give you some control over the
+;;  behavior.  When the `TAB' completion method is `swank', you can
+;;  use `C-x 1' (`icicle-doremi-increment-swank-timeout+') and `C-x 2'
+;;  (`icicle-doremi-increment-swank-prefix-length+') in the minibuffer
+;;  to increment these options on the fly using the arrow keys `up'
+;;  and `down'.
+;;
+;;  Swank symbol completion uses heuristics that relate to supposedly
+;;  typical patterns found in symbol names.  It also uses a timeout
+;;  that can limit the number of matches.  It is generally quite a bit
+;;  slower than fuzzy completion, and it sometimes does not provide
+;;  all candidates that you might think should match, even when all of
+;;  your input is a prefix (or even when it is already complete!).
+;;
+;;  If swank completion produces no match when you think it should,
+;;  remember that you can use `C-(' on the fly to change the
+;;  completion method.
+;;
+;;  I do not necessarily recommend swank symbol completion, but it is
+;;  available for those who appreciate it.
+;;
+;;  Like fuzzy completion (see next), swank completion always sorts
+;;  candidate symbols according to its own scoring, putting what it
+;;  thinks are the best matches first.  This means that using `C-,' in
+;;  the minibuffer to sort candidates differently has no effect.
+;;
+;;(@* "Fuzzy-Match Completion")
+;;  ** Fuzzy-Match Completion **
+;;
+;;  Fuzzy completion takes more explaining.  It is described in detail
+;;  in the commentary of library `fuzzy-match.el'; please refer to
+;;  that documentation.  Here are some things to keep in mind when you
+;;  use Icicles fuzzy completion:
+;;
+;;  * File-name completion is never fuzzy.  Basic prefix completion is
+;;    used for file names.
+;;  * Fuzzy completion is always case-sensitive.  This means that
+;;    `C-A' in the minibuffer has no effect on fuzzy completion.
+;;  * Fuzzy completion always takes a space prefix in your input into
+;;    account.  This means that `M-_' in the minibuffer has no effect
+;;    on fuzzy completion.
+;;  * Fuzzy completion candidates are always sorted by decreasing
+;;    match strength.  This means that using `C-,' in the minibuffer
+;;    to sort candidates differently has no effect.
+;;
+;;  Fuzzy completion is a form of prefix completion in which some
+;;  input characters might not be present in a matched candidate.
+;;  Matching finds the candidates that have the most characters in
+;;  common with your input, in the same order and with a minimum of
+;;  non-matching characters.  It can skip over non-matching
+;;  characters, as long as the number of characters skipped in the
+;;  candidate is less that those following them that match.  After the
+;;  matching candidates are found, they are sorted by skip length and
+;;  then candidate length.
+;;
+;;  Here are some examples:
+;;
+;;  Input         Completion Domain  Matches (Candidates)
+;;  -----         -----------------  --------------------
+;;
+;;  abc           {xxabcxx, xabcxxx,
+;;                          xabx}    {xabcxxx, xxabcxx}
+;;
+;;  point-mx      Emacs variables    {point-max, point-max-marker}
+;;
+;;  begining-of-l Emacs commands     {beginning-of-line,
+;;                                    beginning-of-line-text,
+;;                                    move-beginning-of-line,
+;;                                    widget-beginning-of-line}
+;;
+;;  The last example shows that although fuzzy matching is a kind of
+;;  prefix matching, your input is not necessarily a prefix of each
+;;  matching candidate.  It is prefix matching because it tries to
+;;  match your input starting at its beginning.  This input prefix is
+;;  matched against candidate substrings, not necessarily candidate
+;;  prefixes, but the non-matching part (if any) preceding the matched
+;;  substring must not be longer than the matching part.  That is,
+;;  non-matching substrings can be skipped over, but they must be no
+;;  longer than the matching substrings that follow them.  If an input
+;;  prefix does not match under these conditions, it is skipped over.
+;;
+;;  After matching an input prefix this way, the same process is
+;;  repeated, recursively, for input text following that prefix and
+;;  for match positions following the matches found.  That is, after
+;;  each such prefix match, the process starts again where it left off
+;;  in both the input and the candidates.  The resulting matches
+;;  contain one or more substrings of your input that are each at
+;;  least as long as the non-matching parts that immediately precede
+;;  them.  Only matches with the highest number of matching characters
+;;  are retained.  They are sorted by two criteria: (1) nearness of
+;;  matches to the start of the candidate and (2) candidate length.
+;;
+;;  The fuzzy-match algorithm is detailed in library `fuzzy-match.el'.
+;;  However, it is easier to get a feel for what it does by trying it
+;;  than by reading any description.  Just give it a try.  Do not
+;;  expect it to rival apropos completion in power or expressivity,
+;;  however.  Instead, think of it as prefix completion for lazy or
+;;  inaccurate typists!  If that sounds like you, then you might find
+;;  it useful.
+;;
+;;  As an example, here are some command-name candidates for the input
+;;  `fo' (there are lots more):
+;;
+;;  fortune          forms-mode       focus-frame
+;;  follow-mode      forward-sexp     forward-list
+;;  forward-word     forward-line     forward-page
+;;  ...
+;;  ifconfig         info             Info-up
+;;  Info-edit        Info-next        Info-help
+;;  ...
+;;  Info-mouse-follow-nearest-node    Info-goto-emacs-key-command-node
+;;
+;;  And here are all the command-name candidates for the input `fol':
+;;
+;;  follow-mode            follow-delete-other-windows-and-split
+;;  Info-last              info-lookup-file       info-lookup-reset
+;;  Info-last-preorder     info-lookup-symbol     Info-last-menu-item
+;;  nnfolder-generate-active-file     mh-folder-mode
+;;
+;;  The first thing to notice is the distribution of candidates for
+;;  input `fo'.  Candidates are in decreasing order of match fit:
+;;
+;;  * The nearer the match to the start of the candidate, the better
+;;    the fit.
+;;
+;;  * The greater the ratio of matched text to unmatched text, the
+;;    better the fit.
+;;
+;;  Note too the candidate `ifconfig'.  First, note that it has no
+;;  strict match for substring `fo'.  Its match is in fact in two
+;;  parts: `f', then `o'.  Second, note that it is considered a better
+;;  fuzzy match than the candidate `info'.  This is because its match
+;;  (`f') is nearer to the start of the candidate (second character,
+;;  versus third).
+;;
+;;  The second thing to notice is that when you type the third input
+;;  character, `l', the candidates are not a subset of the original
+;;  set that matches `fo'.  The candidates in the second screenshot
+;;  all match `fol' in a fuzzy way, even though one of them,
+;;  `mh-folder-mode', does not match `fo' sufficiently well to be
+;;  included as a candidate.  Why?  Because in the `fo' case, the
+;;  match is only two characters long and it starts after three
+;;  non-matching characters.
+;;
+;;  For both inputs: If all input prefixes are fair game for matching,
+;;  why doesn't `*Completions*' also include other command names that
+;;  match only the prefix `f' and nothing else?  Because there is at
+;;  least one match that matches more than that - only the best
+;;  matches are retained.  In this case, the best matches for input
+;;  `fo' match both the `f' and the `o', and the best matches for
+;;  input `fol' match all three of those characters.
+;;
+;;  Refer to `fuzzy-match.el' for a precise description of fuzzy
+;;  matching.  It refers to "matchiness" for how many characters match
+;;  and "closeness" for the ratio of number of characters matched to
+;;  candidate length.
+;;
+;;  Note: It is not practical to try to highlight the exact candidate
+;;  portions that match different parts of your input.  Because
+;;  fuzzy-match input does not function as a literal string for
+;;  matching purposes, it is more akin to substring matching than to
+;;  plain prefix matching.  For this reason, regexp-match highlighting
+;;  is used for fuzzy matching.  That is why you see the input `fo'
+;;  highlighted in `*Completions*' candidates in other than just the
+;;  prefix position.  It is also why the matching `f' and `o' in
+;;  candidate `ifconfig' are not highlighted: for highlighting
+;;  purposes, your input is treated as a regexp.
+;;
+;;  One takeaway here is that fuzzy completion is complicated.  Rather
+;;  than try to understand how it works and think ahead in those
+;;  terms, you just need to get a feel for it - learn by doing.  Have
+;;  fun!
+;;
+;;(@* "Levenshtein Completion")
+;;  ** Levenshtein Completion **
+;;
+;;  The "Levenshtein distance" is the maximum number of character
+;;  insertions, deletions, or replacements that are needed to
+;;  transform one string to another.  The more similar two strings
+;;  are, the smaller their Levenshtein distance.
+;;
+;;  When this kind of completion is used, Icicles considers your input
+;;  to match a completion candidate if their Levenshtein distance is
+;;  no greater than the value of option `icicle-levenshtein-distance'.
+;;  The default value of the option is 1, meaning that the difference
+;;  is at most one character operation.
+;;
+;;  Using a strict definition of the distance, this also requires the
+;;  length of your input to be within the Levenshtein distance of the
+;;  length of a completion candidate, for it to match.  That is quite
+;;  restrictive.
+;;
+;;  It is more flexible to consider your input to match a candidate if
+;;  it is within `icicle-levenshtein-distance' of some *substring* of
+;;  the candidate.  Because candidate substrings are tested, the
+;;  length of your input need not be nearly the same as the candidate
+;;  length.
+;;
+;;  When you cycle among `S-TAB' completion methods using `M-(', there
+;;  are thus two choices for Levenshtein completion: `Levenshtein' and
+;;  `Levenshtein strict'.  The former is generally more useful.
+;;
+;;  The larger the value of `icicle-levenshtein-distance', the slower
+;;  Levenshtein completion becomes, since it must test more
+;;  possibilities.  Also, when the value is 1 (except for `Levenshtein
+;;  strict'), Icicles uses a fast, special-case algorithm, and it
+;;  highlights the matching parts of candidates in buffer
+;;  `*Completions*'.  1 is the most useful value.
+;;
+;;  If the value is other than 1 (or if it is 1 with `Levenshtein
+;;  strict'), then you must also use library `levenshtein.el', and
+;;  Levenshtein completion can be quite slow.  In that case, you will
+;;  no doubt want to turn off incremental completion (`C-#').
+;;
+;;(@* "Jaro-Winkler Completion")
+;;  **  Jaro-Winkler Completion **
+;;
+;;  The Jaro-Winkler method was developed for comparing names for the
+;;  U.S. census.  It tends to take into account some typical spelling
+;;  mistakes, and it is best suited for use with short candidates.
+;;
+;;  When checking whether two strings match, higher matching weight
+;;  results when there are more characters in each string that are
+;;  also present in the other, and in approximately the same
+;;  positions.
+;;
+;;  Looking only at those characters that nearly match in this sense
+;;  (same character in about the same position), the more exact
+;;  matches there are (same character in exactly the same position),
+;;  the higher the matching weight.  That is, weight is reduced for
+;;  characters that nearly match but are not quite in the right
+;;  position.
+;;
+;;  So far, this describes Jaro matching.  The Jaro matching weight is
+;;  the average of three values; (a) the ratio of the first string's
+;;  near matches to its length, the same for the second string, and
+;;  (c) the ratio of exact matches to total matches (near and exact).
+;;
+;;  The Winkler part of the method comes from giving additional weight
+;;  for prefixes that match exactly.  The longer the exact prefix
+;;  match (up to 4 characters) the greater the weight.
+;;
+;;  Unlike the other matching methods, for Jaro-Winkler to complete
+;;  your input it must have the same number of characters as the
+;;  candidate to be matched, plus or minus two (actually
+;;  `fuzzy-accept-length-difference').  In particular, this means that
+;;  you cannot hit `S-TAB' with an empty minibuffer to see all of the
+;;  candidates.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Icicles Multi `M-x'")
+;;    for completion of command abbreviations
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Apropos Completions")
+;;    for completion with regexp matching
+;;
+;;  * http://en.wikipedia.org/wiki/Jaro-Winkler_distance for
+;;    information about Jaro-Winkler matching
+ 
+;;(@* "Completion in Other Buffers")
+;;
+;;  Completion in Other Buffers
+;;  ---------------------------
+;;
+;;  In addition to input completion, you can use Icicles to complete
+;;  words and symbols in other buffers, besides the minibuffer.
+;;  Icicles enhances this completion in these ways:
+;;
+;;  1. Lisp symbol completion via `M-TAB' (`lisp-complete-symbol').
+;;     (This is also `ESC-TAB' and `C-M-i'.)
+;;
+;;  2. Word completion using the dynamic abbreviation of standard
+;;     Emacs library `dabbrev.el', via `C-M-/'.
+;;
+;;  3. Mailing information completion for BBDB (Insidious Big Brother
+;;     Database).
+;;
+;;  4. Word completion using the words and phrases in a thesaurus, via
+;;     `C-c /' (requires library `synonyms.el').
+;;
+;;  5. `TAB' completion of the following in Shell mode and ESS modes
+;;     (and other, similar interpreters):
+;;
+;;     * Commands
+;;     * Previous inputs - commands plus their arguments
+;;     * File names
+;;     * Environment variables
+;;
+;;  Whenever multiple completion candidates are available, you can use
+;;  Icicles completion, with all of its features: cycling of
+;;  candidates (`TAB', `down', or `next'), apropos (regexp) completion
+;;  (`S-TAB'), progressive completion (`M-SPC'), help on individual
+;;  candidates (`C-M-RET'), and so on.
+;;
+;;(@* "Dynamic Abbreviation")
+;;  ** Dynamic Abbreviation **
+;;
+;;  Library `dabbrev.el' lets you type a few characters in a buffer
+;;  and then prefix-complete them (in the same buffer) to a full word
+;;  or symbol name.  The completion candidates come from words or
+;;  symbol names in buffers that you are editing.  This functionality
+;;  is called "dynamic abbreviation", though that is not a very good
+;;  term for it (words are completed, not abbreviated, dynamically).
+;;
+;;  In Emacs, there are two ways to "dynamically abbreviate" text:
+;;
+;;  a. `M-/' (command `dabbrev-expand') completes to a candidate word.
+;;     Repeating it replaces the completion with a different one -
+;;     that is, it cycles candidates in the text buffer (not in the
+;;     minibuffer).
+;;
+;;  b. `C-M-/' (command `dabbrev-completion') completes to the common
+;;     prefix of all matching completion candidates.  Repeating it
+;;     displays buffer `*Completions*' for you to choose a candidate.
+;;     However, in this case, there is no way to cycle among the
+;;     candidates.
+;;
+;;  If there are many candidate completions, then cycling among them
+;;  with `M-/' can be tedious.  You can use `C-M-/' to complete to a
+;;  common prefix, thus narrowing the set of candidates, but then you
+;;  lose the ability to cycle among them.
+;;
+;;  If user option `icicle-functions-to-redefine' contains an entry
+;;  for `dabbrev-completion' (which it does by default) then Icicles
+;;  redefines command `dabbrev-completion' (it does not change
+;;  `dabbrev-expand') so that it uses Icicles completion when there
+;;  are multiple completions.  You can use any Icicles features, such
+;;  as apropos completion and candidate cycling.  In addition, you can
+;;  even complete an empty prefix, starting from scratch with apropos
+;;  completion.
+;;
+;;(@* "BBDB Completion")
+;;  ** BBDB Completion **
+;;
+;;  Library `bbdb.el', available at http://bbdb.sourceforge.net/, is a
+;;  rolodex-like database program for GNU Emacs.
+;;
+;;  If user option `icicle-functions-to-redefine' contains an entry
+;;  for `bbdb-complete-name' (which it does by default) then Icicles
+;;  redefines command `bbdb-complete-name' so that it uses Icicles
+;;  completion when there are multiple completions.  You can use any
+;;  Icicles features, such as apropos completion and candidate
+;;  cycling.  For this feature to take effect, you must load BBDB
+;;  before you load Icicles.
+;;
+;;(@* "Thesaurus Lookup and Completion")
+;;  ** Thesaurus Lookup and Completion **
+;;
+;;  Library `synonyms.el' provides various features for defining a
+;;  thesaurus and looking up words and phrases in it.  Icicles
+;;  provides a multi-command version (alias `icicle-synonyms') of the
+;;  command `synonyms', which shows all of the synonyms that match a
+;;  regular expression (e.g. a word or phrase) and lets you navigate
+;;  among hyperlinked thesaurus entries.
+;;
+;;  Command `icicle-complete-thesaurus-entry' completes a word in a
+;;  text buffer to any word or phrase in the thesaurus.  With the
+;;  default value of option `icicle-top-level-key-bindings', this is
+;;  bound to `C-c /' in Icicle mode.
+;;
+;;  Tip: You can use `icicle-complete-thesaurus-entry' to quickly
+;;  check the spelling of a word.  If it is correctly spelled, then it
+;;  appears as a complete completion (is highlighted as such in the
+;;  minibuffer).
+;;
+;;  Another Icicles (multi-)command that uses the thesaurus is
+;;  `icicle-insert-thesaurus-entry'.  It lets you use Icicles
+;;  completion, cycling, and so on to insert thesaurus words and
+;;  phrases in any buffer.  It does not complete the word at point.
+;;  Within a single call to it, insert any number of thesaurus
+;;  entries, in succession.  If you wanted to, you could write an
+;;  entire book using a single call to
+;;  `icicle-insert-thesaurus-entry'!
+;;
+;;  All of these Icicles commands require that you load library
+;;  `synonyms.el'.
+;;
+;;(@* "Completion in Comint Modes")
+;;  ** Completion in Comint Modes **
+;;
+;;  `TAB' in a shell or similar buffer provides Icicles completion for
+;;  command names, file names, and environment variables that are
+;;  known to the shell (or other interpreter).
+;;
+;;  You can also complete input using your previous inputs as the set
+;;  of candidates.  Just type something at the prompt, hit `C-c `',
+;;  and pick one or more previous inputs to execute again (this uses
+;;  `icicle-search', so it is a multi-command).  You need not
+;;  re-execute the exact same shell command; you can edit your
+;;  previous input before hitting `RET' to enter the command.
+;;
+;;  These features are available for Comint mode and several modes
+;;  that inherit from it, including Shell mode, Shell Script (SH)
+;;  mode, various ESS modes (Emacs Speaks Statistics), Inferior
+;;  Emacs-Lisp mode (IELM), Grand Unified Debugger (GUD) mode, Tcl
+;;  mode, Rlogin mode, and NS Lookup mode.
+;;
+;;  See Also:
+;;
+;;  * (@> "Icicles Shell-Command Enhancements") for more information
+;;    about Icicles enhancements for Comint mode and related modes
+;;
+;;  * (@> "Other Icicles Search Commands") for information about other
+;;    Icicles search enhancements for Comint mode and related modes
+;;
+;;  * (@> "Defining Buffer-Text Completion for Comint Modes") for
+;;    information about how you can add Icicles completion to other
+;;    modes that inherit from Comint mode
+ 
+;;(@* "Customization and General Tips")
+;;
+;;  Customization and General Tips
+;;  ------------------------------
+;;
+;;  This section contains some tips on using Icicles and descriptions
+;;  of Icicles user options.
+;;
+;;  See Also:
+;;
+;;  * (@> "File-Name and Directory-Name Completion Tips") for tips on
+;;    using Icicles to complete file names.  User options related to
+;;    file-name and directory-name completion are presented there, not
+;;    here.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Dealing With Large Candidate Sets")
+;;    for tips on improving performance when dealing with a large
+;;    number of completion candidates.
+;;
+;;  * (@> "Customizing Key Bindings") for information on customizing
+;;    Icicles key bindings.
+;;
+;;(@* "Using Icicles with Delete Selection Mode")
+;;  ** Using Icicles with Delete Selection Mode **
+;;
+;;  Icicles works especially well with Delete Selection mode, which I
+;;  use and recommend.  (Likewise, for PC selection mode, which uses
+;;  Delete Selection mode.)  In Delete Selection mode, whenever the
+;;  region (selection) is active (highlighted), you can simply type to
+;;  replace text in the region, or hit `DEL' (Backspace) or `C-d'
+;;  (Delete) to delete the region.
+;;
+;;  However, library `delsel.el', which provides Delete Selection
+;;  mode, binds keys in minibuffer maps that are also bound by
+;;  Icicles.  For this reason, if you use both Icicles and Delete
+;;  Selection mode, you must turn on Icicle mode after you turn on
+;;  Delete Selection mode.  If you forget to do this, you will notice
+;;  that `C-g' does not abort minibuffer input.  The remedy is simply
+;;  to turn Icicle mode off, then on again.
+;;
+;;(@* "Icicles User Options and Faces")
+;;  ** Icicles User Options and Faces **
+;;
+;;  There are many user options (user variables) and several faces
+;;  that Icicles defines, and you can also use various standard user
+;;  options, including Icomplete options, that control various aspects
+;;  of completion.
+;;
+;;  One thing that can be important to understand is that if you
+;;  customize an option, and if the default value of that option
+;;  changes later in a more recent Icicles version, then your
+;;  customization will preclude your taking advantage of any new
+;;  features represented by that default option value.
+;;
+;;  This is important particularly for complex options such as
+;;  `icicle-top-level-key-bindings'.  Taking that option as an
+;;  example, if Icicles later adds more commands with default key
+;;  bindings then you will not see those bindings if you have a
+;;  customized value of `icicle-top-level-key-bindings'.  There is
+;;  nothing wrong with that; I just want you to be aware of it.
+;;
+;;  In general, it can be a good idea to look at the latest change-log
+;;  entry for `icicles-opt.el' in `icicles-chg.el', to see what
+;;  changes have been made.  If you then want to take advantage of
+;;  some change, you can use `M-x customize option' and visually
+;;  compare your customized value with the new default value in
+;;  `icicles-opt.el', then edit your customized value as you like.
+;;
+;;  * User option `icicle-mode-hook' is a normal hook containing
+;;    functions that are run after entering and exiting Icicle mode.
+;;    This is `nil', by default.
+;;
+;;  * User option `icicle-minibuffer-setup-hook' is a list of
+;;    functions to be run at the end of minibuffer setup for Icicle
+;;    mode.  This is `nil', by default.
+;;
+;;  * User option `icicle-update-input-hook' is a list of functions to
+;;    be run when minibuffer input is updated (typing or deleting).
+;;    This is `nil', by default.
+;;
+;;  * User option `icicle-no-match-hook' is a list of functions to be
+;;    run during completion (`TAB' or `S-TAB') when there are no
+;;    completion candidates that match the current input.  This is
+;;    `nil', by default.
+;;
+;;  * Case sensitivity: The following standard user options control
+;;    whether completion distinguishes between uppercase and lowercase
+;;    letters:
+;;
+;;    * `completion-ignore-case'
+;;    * `read-file-name-completion-ignore-case' (Emacs 22 and later)
+;;    * `read-buffer-completion-ignore-case' (Emacs 23 and later)
+;;
+;;    In addition, you can toggle case-sensitivity at any time using
+;;    `C-A' (that is, `C-S-a') in the minibuffer.  This toggles
+;;    `case-fold-search' and `completion-ignore-case'.  With a prefix
+;;    argument, it also toggles
+;;    `read-file-name-completion-ignore-case' and
+;;    `read-buffer-completion-ignore-case'.
+;;
+;;    More precisely, it toggles the default value of
+;;    `case-fold-search', and then it sets the other variables to the
+;;    value of `case-fold-search'.  Because the default value of
+;;    `case-fold-search' is changed, all buffers are affected.  Note
+;;    that because some Icicles commands bind one or more of these
+;;    variables, toggling case-sensitivity during command execution
+;;    will not necessarily toggle their global values.
+;;
+;;    You can tell whether completion is currently case-sensitive by
+;;    looking at the Icicle minor-mode lighter in the mode line, if
+;;    `icicle-highlight-lighter-flag' is non-`nil'.  If
+;;    case-sensitive, then the lighter text (with or without
+;;    multi-command symbol `+') is `Icy'; if not, it is `ICY'.
+;;
+;;  * User options `icicle-region-background',
+;;    `icicle-point-position-in-candidate',
+;;    `icicle-mark-position-in-candidate', and
+;;    `icicle-change-region-background-flag' are all used to define
+;;    the region (the selected text) when cycling completion
+;;    candidates.  They are described below individually.  The region
+;;    is active when cycling, so you can easily delete it or replace
+;;    it.
+;;
+;;  * User option `icicle-point-position-in-candidate' defines the
+;;    minibuffer cursor position (point) while cycling candidate
+;;    completions.  By default, the cursor is placed at the end of the
+;;    root being completed.  You can instead place it at the root
+;;    beginning or at the beginning or end of the complete minibuffer
+;;    input.  For file-name input, the beginning of minibuffer input
+;;    starts after the directory name (which is inserted
+;;    automatically).
+;;
+;;  * Similarly, user option `icicle-mark-position-in-candidate'
+;;    defines the position of the mark; by default, it is at the end
+;;    of the input.  Together, these two options control the size and
+;;    placement of the region in a flexible way.  You can make the
+;;    region include all of the input, only the root, from beginning
+;;    to root, or from root to end.  You can put the cursor at either
+;;    end of the region.  You can get rid of the region altogether, by
+;;    making point and mark coincide (at any of the possible
+;;    positions).
+;;
+;;  * Because the region background color is often quite different
+;;    from the frame background color (in order to have it stand out),
+;;    it can be a bit hard to read the completion candidates when the
+;;    region is highlighted during input cycling.  If user option
+;;    `icicle-change-region-background-flag' is non-`nil', however,
+;;    then the region background is changed to a color that differs
+;;    only slightly from the frame background, making it easier to
+;;    read the completion candidates.  The actual background color
+;;    used is the value of `icicle-region-background', which you can
+;;    customize.  If you make this color the same as the frame
+;;    background, then the region background is, in effect, invisible.
+;;
+;;  * The default value of `icicle-change-region-background-flag' is
+;;    determined by the current value of `delete-selection-mode', that
+;;    is, whether or not Delete Selection mode is enabled, when
+;;    Icicles is loaded.  For this reason, if you use Delete Selection
+;;    mode and you want the region background to change in the
+;;    minibuffer, you should either turn on Delete Selection mode
+;;    before loading `icicles.el' or explicitly customize
+;;    `icicle-change-region-background-flag' to non-`nil'.
+;;
+;;  * User option `icicle-default-value' controls the treatment of a
+;;    default value for minibuffer input.  This includes not only
+;;    functions that read input with completion (`completing-read',
+;;    `read-file-name'), but also other input-reading functions:
+;;    `read-from-minibuffer' and `read-string'.  The default value of
+;;    `t' gives the vanilla Emacs behavior: `completing-read' adds the
+;;    default input value to the prompt as a hint (but
+;;    `read-file-name' does not).  Non-`nil' and non-`t' means to
+;;    automatically insert the default input value into the minibuffer
+;;    as the initial value.  I prefer to have it inserted, as I often
+;;    use the default value (perhaps editing it).  A value of `nil'
+;;    neither inserts the default value nor adds it to the prompt.  If
+;;    the value is `t' or `nil', remember that you can always insert
+;;    the default value manually with `M-n'.  If the value is neither
+;;    `t' nor `nil', you can always use `M-p' to remove the default
+;;    value from the minibuffer.
+;;
+;;    A non-`nil', non-`t' value of `icicle-default-value' controls
+;;    also whether or not the initial value is preselected, and where
+;;    to leave the cursor: at the beginning or end of the value.
+;;    Preselecting the value can be useful in Delete Selection mode or
+;;    PC Selection mode, because it makes it easy to replace that
+;;    value by typing characters, or delete it by hitting `DEL'
+;;    (Backspace) or `C-d' (Delete).  However, all of the initial
+;;    input is lost if you type or hit `C-d' or `DEL', which is
+;;    inconvenient if you want to edit it only slightly.
+;;
+;;  * User options `icicle-thing-at-point-functions' and
+;;    `icicle-default-thing-insertion' control the behavior of `M-.'
+;;    in the minibuffer, which grabs text from the current buffer and
+;;    yanks it into the minibuffer.
+;;    See (@file :file-name "icicles-doc1.el" :to "Inserting Text Found Near the Cursor")
+;;    and the doc string (`C-h v') of
+;;    `icicle-thing-at-point-functions' for more information.
+;;
+;;  * User option `icicle-comint-dynamic-complete-replacements'
+;;    specifies a list of function replacements for
+;;    `icicle-comint-dynamic-complete' to replace the functions in
+;;    `comint-dynamic-complete-functions'.  You can use this to
+;;    provide Icicles completion for various modes that inherit from
+;;    Comint mode.  By default, it treats Comint mode and Shell mode.
+;;
+;;  * User option `icicle-input-string' is a regexp string that is
+;;    inserted in the minibuffer when you use `C-='.  See
+;;    (@file :file-name "icicles-doc1.el" :to "Inserting a Regexp from a Variable or Register").
+;;
+;;  * In buffer `*Completions*', face `icicle-historical-candidate' is
+;;    used to highlight completion candidates that you have used
+;;    (entered with `RET') previously.  This highlighting is
+;;    controlled by user option
+;;    `icicle-highlight-historical-candidates-flag'.  You can toggle
+;;    this option from the minibuffer at any time using `C-pause'.
+;;    See (@file :file-name "icicles-doc1.el" :to "History Enhancements").
+;;
+;;  * In buffer `*Completions*', face `icicle-saved-candidate' is used
+;;    to highlight completion candidates that you have saved (e.g.,
+;;    using `C-M->').  This highlighting is controlled by user option
+;;    `icicle-highlight-saved-candidates-flag'.  You can toggle this
+;;    option from the minibuffer at any time using `S-pause'.
+;;    See (@file :file-name "icicles-doc1.el" :to "Saving and Retrieving Completion Candidates").
+;;
+;;  * In buffer `*Completions*', face
+;;    `icicle-current-candidate-highlight' highlights the current
+;;    completion candidate, and, provided user option
+;;    `icicle-expand-input-to-common-match-flag' is non-`nil', face
+;;    `icicle-common-match-highlight-Completions' highlights the
+;;    expanded common match among all completions.  Faces
+;;    `icicle-match-highlight-Completions' and
+;;    `icicle-match-highlight-minibuffer' highlight whatever your
+;;    input matches, in buffer `*Completions*' and in the minibuffer,
+;;    respectively.  In the minibuffer, face `icicle-complete-input'
+;;    highlights your input when it is complete.
+;;
+;;  * Non-`nil' user option `icicle-touche-pas-aux-menus-flag' means
+;;    that Icicles will not add menu items to menu-bar menus, except
+;;    for the Icicles and Minibuf menus.  Default value `nil' means
+;;    that whenever an appropriate menu-bar menu exists, Icicles items
+;;    are added to it (when in Icicle mode).  For example, if `nil',
+;;    then Delete File is added to the File menu; otherwise it is
+;;    added to the Icicles menu.  The value of this option is used
+;;    only when Icicle mode is initially established, so changing it
+;;    has no effect after Icicles has been loaded.  However, you can
+;;    change it and save the new value, so it will be used next time.
+;;
+;;  * User option `icicle-functions-to-redefine' controls whether
+;;    Icicles redefines some standard functions, enhancing them to use
+;;    Icicles completion.  You can specify which functions to
+;;    redefine.  The original function definitions are restored when
+;;    you exit Icicle mode.
+;;
+;;  * Option `icicle-inhibit-advice-functions' is a list of functions
+;;    that Icicles redefines, and for which Icicle mode deactivates
+;;    the advice.  The advice for each is reactivated when you leave
+;;    Icicle mode.  Generally, it is a bad idea to use advice with
+;;    functions that Icicles redefines, in particular minibuffer
+;;    functions.  If you want to allow some such advice or prohibit
+;;    advice for additional functions, then customize this list.
+;;
+;;    Note: If you or a library you load advises one of these
+;;    functions while you are in Icicle mode, then toggle Icicle mode
+;;    twice, so that this option can have the proper effect.
+;;
+;;  * The following user options specify the keys to use for
+;;    mode-specific completion-candidate cycling.  The default
+;;    bindings are in parentheses.
+;;
+;;    `icicle-apropos-cycle-next-keys'                (`next')
+;;    `icicle-apropos-cycle-previous-keys'            (`prior')
+;;    `icicle-prefix-cycle-next-keys'                 (`end')
+;;    `icicle-prefix-cycle-previous-keys'             (`home')
+;;    `icicle-apropos-cycle-next-action-keys'         (`C-next')
+;;    `icicle-apropos-cycle-previous-action-keys'     (`C-prior')
+;;    `icicle-prefix-cycle-next-action-keys'          (`C-end')
+;;    `icicle-prefix-cycle-previous-action-keys'      (`C-home')
+;;    `icicle-apropos-cycle-next-alt-action-keys'     (`C-S-next')
+;;    `icicle-apropos-cycle-previous-alt-action-keys' (`C-S-prior')
+;;    `icicle-prefix-cycle-next-alt-action-keys'      (`C-S-end')
+;;    `icicle-prefix-cycle-previous-alt-action-keys'  (`C-S-home')
+;;    `icicle-apropos-cycle-next-help-keys'           (`C-M-next')
+;;    `icicle-apropos-cycle-previous-help-keys'       (`C-M-prior')
+;;    `icicle-prefix-cycle-next-help-keys'            (`C-M-end')
+;;    `icicle-prefix-cycle-previous-help-keys'        (`C-M-home')
+;;
+;;  * The following user options specify the keys to use for cycling
+;;    candidates according to the current completion mode.  The
+;;    default bindings are in parentheses.
+;;
+;;    `icicle-modal-cycle-down-keys'                  (`down')
+;;    `icicle-modal-cycle-up-keys'                    (`up')
+;;    `icicle-modal-cycle-down-action-keys'           (`C-down')
+;;    `icicle-modal-cycle-up-action-keys'             (`C-up')
+;;    `icicle-modal-cycle-down-alt-action-keys'       (`C-S-down')
+;;    `icicle-modal-cycle-up-alt-action-keys'         (`C-S-up')
+;;    `icicle-modal-cycle-down-help-keys'             (`C-M-down')
+;;    `icicle-modal-cycle-up-help-keys'               (`C-M-up')
+;;
+;;    The completion mode, and hence the behavior of these keys, is
+;;    changed only when you hit `TAB' or `S-TAB' during completion:
+;;    the mode is prefix completion after `TAB' and apropos completion
+;;    after `S-TAB'.
+;;
+;;    Note: If your customizations of the modal and non-modal cycling
+;;    keys conflict, the non-modal values win.  For example, if you
+;;    define both `icicle-modal-cycle-up-keys' and
+;;    `icicle-prefix-cycle-previous-keys' as the list `([up])', then
+;;    the `up' key will perform prefix cycling, not modal cycling.
+;;
+;;  * User option `icicle-default-cycling-mode' determines the
+;;    completion mode to be used before you hit `TAB' or `S-TAB'.
+;;    This affects only modal cycling - e.g. using keys such as `down'
+;;    and `C-down'.  Values:
+;;
+;;    - `prefix' (default) means cycle prefix completions
+;;    - `apropos' means cycle apropos completions
+;;    - other non-`nil' value means cycle inputs from input history
+;;    - `nil' means do not cycle: you must first hit a completion key
+;;
+;;    For example, if the value is `apropos' then you can immediately
+;;    cycle apropos completions without first hitting `S-TAB'.
+;;
+;;    Once you have used `TAB' or `S-TAB', the only way to traverse
+;;    the input history is to use `M-p' and `M-n'.
+;;
+;;  * User option `icicle-word-completion-keys' is a list of keys to
+;;    use for word completion.  By default, the only such key is
+;;    `M-SPC'.
+;;
+;;  * User option `icicle-apropos-complete-no-display-keys' is a list
+;;    of keys to bind to `icicle-apropos-complete-no-display'.  By
+;;    default, these keys are `C-M-S-tab' and `C-M-S-iso-lefttab',
+;;    which together implement `C-M-S-TAB'.  Similarly,
+;;    `icicle-prefix-complete-no-display-keys' is the list of keys for
+;;    `icicle-prefix-complete-no-display'.  By default, the only such
+;;    key is `C-M-tab'.
+;;
+;;  * Option `icicle-prefix-complete-keys' is the list of keys for
+;;    `icicle-prefix-complete'.  By default, these keys are `tab' and
+;;    `C-i', which together implement `TAB'.
+;;
+;;  * Option `icicle-apropos-complete-keys' is the list of keys to
+;;    bind to `icicle-apropos-complete'.  By default, these keys are
+;;    `S-tab' and `S-iso-lefttab', which together implement `S-TAB'.
+;;    (In Emacs 22 and later, `backtab' is the canonical key that
+;;    represents both `S-tab' and `S-iso-lefttab', so that is used in
+;;    the default value.)
+;;
+;;  * Option `icicle-key-complete-keys' is the list of keys to bind to
+;;    `icicle-complete-keys'.  By default, these keys are `S-tab' and
+;;    `S-iso-lefttab', which together implement `S-TAB'.  (In Emacs 22
+;;    and later, `backtab' is the canonical key that represents both
+;;    `S-tab' and `S-iso-lefttab', so that is used in the default
+;;    value.)
+;;
+;;  * Option `icicle-previous-candidate-keys' is the list of keys to
+;;    bind to `icicle-move-to-previous-completion', for moving among
+;;    candidates in buffer `*Completions*'.  By default, these keys
+;;    are `S-tab' and `S-iso-lefttab', which together implement
+;;    `S-TAB'.  (In Emacs 22 and later, `backtab' is the canonical key
+;;    that represents both `S-tab' and `S-iso-lefttab', so that is
+;;    used in the default value.)
+;;
+;;  * Option `icicle-isearch-complete-keys' is the list of keys for
+;;    `icicle-isearch-complete'.  By default, these keys are `M-TAB',
+;;    `ESC TAB', `C-M-TAB', and `M-o'.
+;;
+;;  * Option `icicle-read+insert-file-name-keys' is the list of keys
+;;    for invoking file-name completion on demand.  By default,
+;;    `C-M-S-f' is the only such key.  Option
+;;    `icicle-completing-read+insert-keys' is the list of keys for
+;;    invoking non file-name completion on demand.  By default,
+;;    `C-M-S-c' is the only such key.  See (@> "Completion On Demand").
+;;
+;;  * User option `icicle-act-before-cycle-flag' `nil' means that keys
+;;    such as `C-next', which combine candidate action and cycling,
+;;    cycle to the next (or previous) candidate and act on it.
+;;    Non-`nil' means they act on the current candidate and then cycle
+;;    to the next (or previous) candidate.  When the value is `nil',
+;;    you can think of `C-next' as an operation on the next candidate.
+;;    When the value is non-`nil', you can think of `C-next' as an
+;;    operation on the current candidate, which ends by making the
+;;    next candidate current.  Similarly for the other cycling keys
+;;    that act, alternative-act, or show help on a candidate.  The
+;;    default value is `nil'.  See also option
+;;    `icicle-use-C-for-actions-flag', which changes the keys affected
+;;    by `icicle-act-before-cycle-flag'.
+;;
+;;  * If option `icicle-use-C-for-actions-flag' is `nil', then the
+;;    keys that cycle candidates are swapped with the keys that both
+;;    cycle and act on a candidate.  You can then use `down', `up',
+;;    `next', `prior', `end' and `home' to both cycle and act, and
+;;    `C-down', `C-up', `C-next', `C-prior', `C-end', and `C-home' to
+;;    merely cycle, without acting (e.g. navigating).  The option has
+;;    no effect on other keys.  You can toggle this option at any time
+;;    using `M-g' (`icicle-toggle-C-for-actions') in the minibuffer.
+;;
+;;    (The keys mentioned here are the default bindings.  The actual
+;;    keys swapped are those defined by these user options:
+;;    `icicle-prefix-cycle-next-action-keys',
+;;    `icicle-prefix-cycle-previous-action-keys',
+;;    `icicle-apropos-cycle-next-action-keys',
+;;    `icicle-apropos-cycle-previous-action-keys',
+;;    `icicle-modal-cycle-down-action-keys',
+;;    `icicle-modal-cycle-up-action-keys',
+;;    `icicle-prefix-cycle-next-keys',
+;;    `icicle-prefix-cycle-previous-keys',
+;;    `icicle-apropos-cycle-next-keys',
+;;    `icicle-apropos-cycle-previous-keys',
+;;    `icicle-modal-cycle-down-keys', `icicle-modal-cycle-up-keys'.)
+;;
+;;  * Non-`nil' user option
+;;    `icicle-top-level-when-sole-completion-flag' means that whenever
+;;    there is only one completion candidate that matches your input,
+;;    that candidate is used immediately, without requiring you to hit
+;;    `RET' or `S-RET'.
+;;
+;;  * When `icicle-top-level-when-sole-completion-flag' is `nil',
+;;    option `icicle-top-level-when-sole-completion-delay' is the
+;;    number of seconds Icicles waits, before returning to top level
+;;    with the sole completion.  (It has no effect if the flag is
+;;    `nil'.)  The delay gives you a chance to forestall acceptance of
+;;    the sole completion: editing the completion (typing or deleting
+;;    a character) before the delay expires prevents its automatic
+;;    acceptance.  The default value is 0 seconds (no delay).
+;;
+;;  * Non-`nil' user option `icicle-TAB-shows-candidates-flag' means
+;;    that hitting `TAB' for prefix completion immediately shows the
+;;    completion candidates in buffer `*Completions*'.  If `nil', then
+;;    candidates are shown only after `TAB' is hit a second time,
+;;    which is the standard Emacs behavior.  The default value is `t'.
+;;    (Actually, the concerned keys are those defined by option
+;;    `icicle-prefix-complete-keys', not necessarily `TAB'.)
+;;
+;;  * Non-`nil' option `icicle-max-candidates' means truncate the list
+;;    of completion candidates to at most this many.  If you use
+;;    library `doremi.el' then you can use `C-x #' during completion
+;;    to increment or decrement the option value using the vertical
+;;    arrow keys or the mouse wheel.  A numeric prefix argument for
+;;    `C-x #' sets the increment size.  A plain prefix argument
+;;    (`C-u') resets `icicle-max-candidates' to `nil', meaning no
+;;    truncation.
+;;
+;;  * Non-`nil' user option `icicle-expand-input-to-common-match-flag'
+;;    means that completion commands `TAB' and `S-TAB' expand your
+;;    minibuffer input to (typically) the longest substring common to
+;;    all completion candidates and that matches your (complete) input
+;;    pattern.  This replaces the input you typed.  If you want to
+;;    edit your original, raw input, use `C-l'.  If your input has
+;;    been expanded, then hit `C-l' twice: once to replace a
+;;    completion candidate (from, say, `next') with the common match
+;;    string, and a second time to replace the common match string
+;;    with your original input.  The main reason you might want to set
+;;    this to `nil' is for apropos completion, if you want to always
+;;    work with a regexp in the minibuffer.  You can toggle this
+;;    option at any time using `C-;' in the minibuffer.
+;;    See (@file :file-name "icicles-doc1.el" :to "Expanded-Common-Match Completion").
+;;
+;;  * Non-`nil' user option
+;;    `icicle-hide-common-match-in-Completions-flag' hides, in buffer
+;;    `*Completions*', the common match for your current input from
+;;    each candidate.  You can toggle this anytime during completion
+;;    using `C-x .' (no prefix arg), which is bound to command
+;;    `icicle-toggle-hiding-common-match'.  The common match used is
+;;    governed by option `icicle-expand-input-to-common-match-flag'.
+;;
+;;  * Non-`nil' option `icicle-hide-non-matching-lines-flag' hides, in
+;;    buffer `*Completions*', all lines in multi-line candidates that
+;;    do not match your current minibuffer input.  In Emacs 22+,
+;;    consecutive such lines are elided as `...'.  You can toggle this
+;;    option anytime during completion using `C-u C-x .', which is
+;;    bound to command `icicle-toggle-hiding-non-matching-lines'.
+;;
+;;  * User option `icicle-show-Completions-initially-flag' controls
+;;    whether or not buffer `*Completions*' is shown initially,
+;;    without your needing to hit `TAB' or `S-TAB' to show it.
+;;    However, if you type something before
+;;    `icicle-incremental-completion-delay', then display is
+;;    inhibited.  The default value is `nil', meaning that
+;;    `*Completions*' is not shown until you hit `TAB' or `S-TAB'.
+;;    More typical than setting this option to non-`nil' globally is
+;;    to bind it to non-`nil' in Emacs-Lisp code, to display
+;;    `*Completions*' as a menu.  For example, pass a non-`nil'
+;;    binding to `icicle-define-command' to create a command that
+;;    displays a multiple-choice menu.
+;;
+;;    For an alternative but similar behavior to using non-`nil' for
+;;    `icicle-show-Completions-initially-flag', you can set option
+;;    `icicle-incremental-completion-flag' to a value that is neither
+;;    `nil' nor `t'.  That displays `*Completions*' as soon as you
+;;    type or delete input, but not initially.
+;;
+;;  * User option `icicle-incremental-completion-flag' controls
+;;    whether or not `*Completions*' is updated incrementally
+;;    (icompletion) as you type.  You can toggle incremental
+;;    completion at any time using `C-#'.  For more information, see
+;;    (@file :file-name "icicles-doc1.el" :to "Icompletion").
+;;
+;;  * User options `icicle-incremental-completion-delay' and
+;;    `icicle-incremental-completion-threshold' together cause a delay
+;;    before incremental completion takes effect.
+;;    See (@file :file-name "icicles-doc1.el" :to "Icompletion").
+;;
+;;  * User option `icicle-Completions-display-min-input-chars' is the
+;;    minimum number of input characters that allow buffer
+;;    `*Completions*' to remain displayed.  By default, this is zero
+;;    (0), meaning that any number of input characters, even none,
+;;    allows `*Completions*' to remain displayed.  If you use
+;;    incremental completion (see `icicle-incremental-completion-*'),
+;;    and you are bothered by `*Completions*' being automatically
+;;    updated when, for instance, you empty the minibuffer, then you
+;;    might want to set this option to, say, 1 or 2.  With a value of
+;;    2, for instance, whenever the minibuffer input has less than 2
+;;    characters, incremental completion will remove the
+;;    `*Completions*' window.  You can also remove the `*Completions*'
+;;    window at any time using `C-x 0' in the minibuffer.
+;;
+;;  * Non-`nil' option `icicle-show-Completions-help-flag' means
+;;    display help (instructions) at the top of the `*Completions*'
+;;    window.  These instructions are shown in faces
+;;    `icicle-Completions-instruction-1' and
+;;    `icicle-Completions-instruction-2'.
+;;
+;;  * Option `icicle-help-in-mode-line-delay' is the number of seconds
+;;    to display help on individual completion candidates in the
+;;    mode-line as you cycle or your input is completed.  The
+;;    mode-line that is used is that of buffer `*Completions*', if it
+;;    is displayed, or the current buffer, otherwise.  Typically, this
+;;    mode-line candidate help is the first line of a doc string, but
+;;    alternative help is available.
+;;
+;;    Regardless of the option value, a user event (e.g. a key press)
+;;    always interrupts (terminates) this help display.  Note too that
+;;    `post-command-hook' actions do not take place until this display
+;;    is finished.
+;;
+;;  * Face `icicle-mode-line-help' is used to highlight Icicles help
+;;    shown in the mode-line.  This includes that controlled by option
+;;    `icicle-help-in-mode-line-delay' and the indication in
+;;    `*Completions*' of the total number of matching candidates.
+;;
+;;  * User option `icicle-Completions-mouse-3-menu-entries' defines
+;;    the contextual menu that is popped up when you click `C-mouse-3'
+;;    on a candidate in `*Completions*'.  As an aid to customizing it,
+;;    refer to any of the constants `icicle-Completions-*' that define
+;;    its submenus.  The submenu definitions are easier to understand
+;;    in the source code (`icicles-opt.el'), because Customize does
+;;    not pretty-print them.
+;;
+;;  * Non-`nil' user option `icicle-move-Completions-frame' means that
+;;    `icicle-candidate-action' moves the frame showing buffer
+;;    `*Completions*' to the edge of the display, out of the way of
+;;    other frames.  The possible non-`nil' values are `right' and
+;;    `left', specifying the display edge to use.
+;;
+;;    This option can be useful if you use one-buffer-per-frame
+;;    (non-`nil' `pop-up-frames').  In that case, I recommend that you
+;;    also try my library `oneonone.el'.  See
+;;    (@> "Note on Non-`nil' `pop-up-frames' on MS Windows") for more
+;;    advice about non-`nil' `pop-up-frames'.
+;;
+;;  * User option `icicle-Completions-window-max-height' is the
+;;    maximum height of the `*Completions*' window, in lines.  The
+;;    window is fit to the buffer size, with this as maximum height.
+;;    This is not used if `*Completions*' is a special display buffer
+;;    with its own frame, and it is not used in Emacs releases prior
+;;    to 21.
+;;
+;;  * Starting with Emacs 23, you can use option
+;;    `icicle-Completions-text-scale-decrease' to change the size of
+;;    the text used in buffer `*Completions*'.
+;;
+;;  * User option `icicle-candidate-width-factor' controls how many
+;;    columns of completion candidates are displayed in
+;;    `*Completions*'.  The widest current candidate is scaled by this
+;;    percentage, and the window width is divided by that figure.
+;;    Other things are taken into account also, but this gives you a
+;;    way to tweak the number of columns: the larger this number, the
+;;    fewer the columns.
+;;
+;;    If you use Do Re Mi (library `doremi.el'), then you can modify
+;;    `icicle-candidate-width-factor' incrementally during completion,
+;;    seeing the effect as it changes.  Use `C-x w' from the
+;;    minibuffer, then use the `right' and `left' arrow keys or the
+;;    mouse wheel to increment and decrement the value.  You can at
+;;    the same time use the `up' and `down' keys to adjust the value
+;;    of `icicle-inter-candidates-min-spaces'.  WYSIWYG.
+;;
+;;  * User option `icicle-inter-candidates-min-spaces' is the minimum
+;;    number of spaces between candidates displayed in
+;;    `*Completions*'.  The default value is one space.
+;;
+;;    If you use Do Re Mi (library `doremi.el'), then you can modify
+;;    `icicle-inter-candidates-min-spaces' incrementally during
+;;    completion, seeing the effect as it changes.  Use `C-x |' from
+;;    the minibuffer, then use the `up' and `down' arrow keys or the
+;;    mouse wheel to increment and decrement the value.  You can at
+;;    the same time use the `left' and `right' keys to adjust the
+;;    value of `icicle-candidate-width-factor'.  WYSIWYG.
+;;
+;;  * Non-`nil' option `icicle-image-files-in-Completions' means that
+;;    thumbnail images are shown in `*Completions*' for candidates
+;;    that are (relative or absolute) names of image files.  The
+;;    default value is `t'.  If the value is `image-only', then only
+;;    the thumbnail images are shown.  If it is otherwise non-`nil'
+;;    then the file names are also shown.  You can cycle the option
+;;    value using `C-x t' in the minibuffer at any time during
+;;    completion.  This feature is available starting with Emacs 22.
+;;
+;;  * Option `icicle-completions-format' controls whether candidates
+;;    displayed in `*Completions*' are laid out horizontally (the
+;;    default) or vertically.  Set the value to `vertical' for the
+;;    latter.  Starting with Emacs 23.2, you can just use the vanilla
+;;    option `completions-format' for this, if you want the same type
+;;    of layout with Icicle mode turned on or off.
+;;
+;;    Icicles always displays multi-line candidates in a single
+;;    column, for readability.  When this is the case, the completions
+;;    format (horizontal or vertical) makes no difference - the effect
+;;    is the same.  (Icicles also inserts an empty line after each
+;;    multi-line candidate, for readability.)
+;;
+;;  * If option `icicle-menu-items-to-history-flag' is non-`nil' (the
+;;    default), then commands that you invoke using the menu-bar menu
+;;    are included in the command history for `M-x'.
+;;
+;;  * Non-`nil' option `icicle-populate-interactive-history-flag'
+;;    means that any interactive use of a command causes it to be
+;;    added to the history `icicle-interactive-history'.  You can
+;;    access this history by using `C-M-pause' during completion.  Be
+;;    aware that addition of all interactive invocations to this
+;;    history can slow Emacs down.  (This option is only available
+;;    starting with Emacs 23.)
+;;
+;;  * User option `icicle-sort-comparer' controls the order of
+;;    completion candidates during cycling and in buffer
+;;    `*Completions*'.  If `nil', then no sorting is done.  If
+;;    non-`nil', then the value must be a string-comparison function -
+;;    the function is passed to the standard function `sort' to do the
+;;    sorting.  The default value for `icicle-sort-comparer' is
+;;    `icicle-case-string-less-p', which sorts alphabetically,
+;;    possibly ignoring letter case.  During completion, you can
+;;    toggle sorting using `C-,'.  If you are an Emacs-Lisp programmer
+;;    and you write new commands using Icicles functionalities, you
+;;    can bind `icicle-sort-comparer' temporarily to any sort function
+;;    you need.
+;;
+;;  * User option `icicle-alternative-sort-comparer' is an alternative
+;;    to `icicle-sort-comparer, providing a different sort order.  By
+;;    default, it is `icicle-historical-alphabetic-p', a function that
+;;    sorts previously used completion candidates before candidates
+;;    that have not yet been used, and sorts alphabetically within
+;;    each of these groups of candidates.  In other words, it places
+;;    inputs that you have used previously at the top of buffer
+;;    `*Completions*' and makes them available for completion first.
+;;    During completion, you can toggle normal and alternative sorting
+;;    using `C-M-,'.  See (@> "Sorting Candidates") and
+;;    (@file :file-name "icicles-doc1.el" :to "History Enhancements").
+;;
+;;  * User option `icicle-change-sort-order-completion-flag' specifies
+;;    whether `C-,' cycles among available sort orders or lets you
+;;    choose a sort order using Icicles completion.  Non-`nil' means
+;;    to use completion; `nil' (the default value) means to cycle.
+;;    You can override the current setting at any time by using `C-u
+;;    C-,'.  See (@> "Sorting Candidates").
+;;
+;;  * User option `icicle-sort-orders-alist' is an alist of possible
+;;    sort orders for user to choose from using `C-,' or `M-,'.
+;;    See (@> "Sorting Candidates").
+;;
+;;  * The value of user option `icicle-transform-function' is a
+;;    function that is applied to the list of completion candidates,
+;;    to transform them before they are presented to the user.  If
+;;    `nil', then no transformation is done.  The default
+;;    transformation is to remove duplicate candidates, when
+;;    transformation is active, but the default value of this option
+;;    is `nil'.  You can toggle transformation at any time using
+;;    command `icicle-toggle-transforming', bound to `C-$' in the
+;;    minibuffer.  Although this is a user option, you probably do
+;;    *NOT* want to change its value by customizing it.  Icicles
+;;    commands already "do the right thing" when it comes to candidate
+;;    transformation.
+;;
+;;    The value of this option can be changed by program locally, for
+;;    use in particular contexts.  For example, when you use
+;;    `icicle-search-generic' (`C-c `') in a *shell* buffer, Icicles
+;;    uses this variable with a value of `icicle-remove-duplicates',
+;;    to remove duplicate shell commands from your input history list.
+;;    Lisp programmers can use this variable to transform the list of
+;;    candidates in any way they like.  A typical use is to remove
+;;    duplicates, by binding it to `icicle-remove-duplicates' or
+;;    `icicle-remove-dups-if-extras'.
+;;
+;;  * User options `icicle-require-match-flag',
+;;    `icicle-buffer-require-match-flag', and
+;;    `icicle-file-require-match-flag' let you override the value of
+;;    the REQUIRE-MATCH argument provided to `completing-read' or
+;;    `read-file-name'.  They are provided mainly for use (binding) in
+;;    `icicle-define-command' and `icicle-define-file-command', but
+;;    you may also use them globally, if you wish.  See
+;;    (@file :file-name "icicles-doc1.el" :to "Exiting the Minibuffer Without Confirmation").
+;;
+;;    A typical use is made in the definition of command
+;;    `icicle-buffer': `icicle-buffer-require-match-flag' is used to
+;;    bind `icicle-require-match-flag', so that you can, for example,
+;;    match only existing buffers and be able to match on partial
+;;    input without explicitly completing (hitting `TAB' or `S-TAB').
+;;    Simply set the option to `partial-match-ok' to get this
+;;    behavior.  To apropos-complete and exit the minibuffer, use
+;;    `S-RET' instead of `RET'.  See
+;;    (@file :file-name "icicles-doc1.el" :to "Exiting the Minibuffer Without Confirmation"),
+;;    for more information.
+;;
+;;  * Non-`nil' user option `icicle-ignore-space-prefix-flag' means to
+;;    ignore completion candidates that start with a space.  However,
+;;    such candidates are not ignored for prefix completion if the
+;;    input also starts with a space.  Naturally, apropos completion
+;;    is not affected by whether or not the input starts with a space.
+;;
+;;    Option `icicle-buffer-ignore-space-prefix-flag' lets you
+;;    override the value of `icicle-ignore-space-prefix-flag' for use
+;;    with buffer-name completion (the names of internal buffers start
+;;    with a space).  It is provided mainly for binding when using
+;;    `icicle-define-command' (`icicle-buffer' does this).
+;;
+;;    You can toggle `icicle-ignore-space-prefix-flag' at any time
+;;    using `M-_' in the minibuffer.  If the current command binds
+;;    this option locally, then it is the local, not the global, value
+;;    that is changed.  For example, if
+;;    `icicle-buffer-ignore-space-prefix-flag' is non-`nil', then
+;;    `M-_' toggles `icicle-ignore-space-prefix-flag' to `nil' only
+;;    for the duration of the buffer command (e.g. `icicle-buffer').
+;;
+;;  * Non-`nil' user option `icicle-test-for-remote-files-flag' means
+;;    that Icicles tests for remote file names; `nil' means that it
+;;    does not.  You can toggle this using `C-^' in the minibuffer
+;;    (except during Icicles search).  Turning off remote file-name
+;;    testing means that you cannot use remote files with Tramp; it
+;;    disables Tramp's remote file-name handling and completion.  This
+;;    can, for local files, slightly speed up incremental completion
+;;    and the highlighting of the part of your current input that does
+;;    not complete (see `icicle-highlight-input-completion-failure').
+;;
+;;  * Non-`nil' user option `icicle-regexp-quote-flag' reduces apropos
+;;    completion to simple substring completion and Icicles regexp
+;;    search to literal search.  Regexp special characters are no
+;;    longer recognized as special; they simply match themselves.  You
+;;    probably do not want to customize this option.  Instead, you can
+;;    toggle it at any time using `C-`' in the minibuffer.
+;;
+;;  * User options `icicle-command-abbrev-match-all-parts-flag',
+;;    `icicle-command-abbrev-priority-flag', and
+;;    `icicle-command-abbrev-alist' control the behavior of
+;;    multi-command `icicle-command-abbrev' (`C-x SPC').  The first
+;;    determines whether an abbreviation must match all parts of a
+;;    command name.  The second controls whether command names or
+;;    abbreviations take precedence in case of conflict.  The third is
+;;    the persistent list of your command abbreviations.
+;;
+;;  * User options `icicle-S-TAB-completion-methods-alist' and
+;;    `icicle-TAB-completion-methods' control which completion method
+;;    is used by `S-TAB' and `TAB', respectively, to complete your
+;;    input.  By default, the first method in each list is used for
+;;    matching.  You can use `M-(' and `C-(' (commands
+;;    `icicle-next-S-TAB-completion-method' and
+;;    `icicle-next-TAB-completion-method') in the minibuffer to cycle
+;;    among the `S-TAB' and `TAB' methods.
+;;
+;;    For fuzzy completion (choice `fuzzy' when cycling with `C-('),
+;;    `TAB' completes non-filename input using fuzzy prefix matching
+;;    as defined in library `fuzzy-match.el'.  See the Commentary in
+;;    `fuzzy-match.el' for details about fuzzy matching.
+;;
+;;    Fuzzy completion is not available for file-name completion; it
+;;    is always case-sensitive; leading spaces are taken into account;
+;;    and completion candidates are always sorted by decreasing fuzzy
+;;    match strength.  In other words, fuzzy completion is not
+;;    affected by `C-A', `M-_', or `C-,'.
+;;
+;;  * User options `icicle-S-TAB-completion-methods-per-command' and
+;;    `icicle-TAB-completion-methods-per-command' provide per-command
+;;    control of the completion methods available when you cycle using
+;;    `C-(' and `M-('.  Use them if you want to specify which methods
+;;    are available for particular commands that read input with
+;;    completion.
+;;
+;;  * User option `icicle-levenshtein-distance' is the Levenshtein
+;;    distance allowed for strings to be considered as matching during
+;;    N-off completion.  This means that two strings match if they
+;;    differ by at most this many character operations (insertion,
+;;    deletion, replacement).  This option is used only if you have
+;;    library `levenshtein.el'.  See (@> "Fuzzy Completion").
+;;
+;;  * Top-level command `icicle-search' uses several faces to
+;;    highlight found text that matches your input.  Faces
+;;    `icicle-search-main-regexp-current' and
+;;    `icicle-search-main-regexp-others' highlight what your
+;;    search-context regexp (entered with `RET') matches.  The former
+;;    highlights the current search context; the latter highlights all
+;;    other search contexts.
+;;
+;;    Face `icicle-search-current-input' highlights what your current
+;;    input (typically another regexp) matches; that is, it highlights
+;;    a match within a search context.  Faces
+;;    `icicle-search-context-level-1' through
+;;    `icicle-search-context-level-8' highlight the first eight regexp
+;;    subgroup matches, within a search context.  This highlighting is
+;;    done whenever `icicle-search-highlight-context-levels-flag' is
+;;    non-`nil' and the search context corresponds to the entire
+;;    regexp.
+;;
+;;  * User option `icicle-search-highlight-context-levels-flag'
+;;    controls highlighting of regexp subgroup matches within the
+;;    search context.  Non-`nil' (the default value) means highlight
+;;    them.
+;;
+;;  * User option `icicle-search-highlight-threshold' controls
+;;    highlighting with face `icicle-search-main-regexp-others': this
+;;    many matches, maximum, are highlighted.  If zero, then only the
+;;    current match is highlighted.  The effect is similar to the
+;;    Emacs 22+ lazy search highlighting of Isearch (except that the
+;;    highlighting is not in fact lazy).
+;;
+;;  * Non-`nil' user option `icicle-search-highlight-all-current-flag'
+;;    means highlight the current input match in all main search hits
+;;    at the same time.  If `icicle-expand-input-to-common-match-flag'
+;;    is also non-`nil', then what is highlighted for each input match
+;;    is the expanded common match among all input matches throughout
+;;    the search area.  If either is `nil', then only the exact input
+;;    match is highlighted.
+;;
+;;    The default value of `icicle-search-highlight-all-current-flag'
+;;    is `nil', because non-`nil' can impact performance negatively if
+;;    there are many search contexts - the highlighting is updated
+;;    with each input change.  You can toggle the value at any time
+;;    using command `icicle-toggle-highlight-all-current', bound to
+;;    `C-^' in the minibuffer (except during file-name completion).
+;;
+;;  * If, in addition to `icicle-search-highlight-all-current-flag'
+;;    and `icicle-expand-input-to-common-match-flag', option
+;;    `icicle-search-replace-common-match-flag' is also non-`nil',
+;;    then a search replacement replaces the expanded common match;
+;;    otherwise, it replaces only the exact match.  You can toggle the
+;;    value at any time using `M-;' in the minibuffer.
+;;
+;;  * Non-`nil' user option `icicle-search-cleanup-flag' means that
+;;    `icicle-search' highlighting is removed after the search.  This
+;;    is the default behavior.  If you set this to `nil' then you can
+;;    remove search highlighting manually later using command
+;;    `icicle-search-highlight-cleanup'.  You can toggle this search
+;;    highlight removal at any time using command
+;;    `icicle-toggle-search-cleanup', which is bound to `C-.' in the
+;;    minibuffer during Icicles search.
+;;
+;;    One use of `nil' `icicle-search-cleanup-flag' is to highlight
+;;    regexp matches throughout a region or buffer (or multiple files
+;;    or...).  In that capacity, Icicles search functions act like
+;;    some of the highlighting commands in my library `highlight.el'.
+;;    Note that when `icicle-search-cleanup-flag' is `nil', *all*
+;;    Icicles search highlighting remains: last-visited search
+;;    context, other context matches, current-input matches, and even
+;;    regexp subgroups.  The faces for these are, respectively:
+;;
+;;     - `icicle-search-main-regexp-current'
+;;     - `icicle-search-main-regexp-others'
+;;     - `icicle-search-highlight-input-matches-here' (everywhere, if
+;;       `icicle-search-highlight-all-current-flag' is non-`nil')
+;;     - `icicle-search-context-level-1' through
+;;       `icicle-search-context-level-8'
+;;
+;;  * Non-`nil' user option `icicle-search-whole-word-flag' means that
+;;    whole-word search is done.  You can use `M-q' while searching to
+;;    toggle this option; the new value takes effect for the next
+;;    complete search.
+;;
+;;    Whole-word searching here means that matches can contain
+;;    embedded strings of non word-constituent chars (they are skipped
+;;    over, when matching, included in the match), and any leading or
+;;    trailing word-constituent chars in the search string are dropped
+;;    (ignored for matching, not included in the match).  This means,
+;;    for instance, that you can match `foo-bar' as a word, even in
+;;    contexts (such as Emacs Lisp) where `-' is not a
+;;    word-constituent character.  Similarly, you can include embedded
+;;    whitespace in a "word", e.g., `foo bar'.
+;;
+;;    See also (@> "Icicles Search Commands, Overview").
+;;
+;;  * If user option `icicle-search-replace-whole-candidate-flag' is
+;;    `nil', then whatever matches your current input is replaced,
+;;    within the current search context, when you perform replacement
+;;    during Icicles searching (e.g. `C-S-RET').  If the value is
+;;    non-`nil' (the default value), then the entire search context is
+;;    replaced, instead.  You can use `M-_' at any time during
+;;    searching and replacing, to toggle the value.
+;;
+;;  * User option `icicle-search-replace-literally-flag' determines
+;;    whether Icicles search-and-replace replaces text literally or
+;;    interprets `\' specially in the replacement text, as in
+;;    `query-replace-regexp'.  Non-`nil' means to treat replacement
+;;    text literally.  The default value is `nil'.  You can use
+;;    `C-M-`' to toggle this at any time during Icicles search.
+;;
+;;  * Non-`nil' option `icicle-ignore-comments-flag' means that
+;;    `icicle-search-thing' and related commands
+;;    (e.g. `icicle-search-xml-element') ignore comments.  That is,
+;;    they hide comments temporarily while they scan the region or
+;;    buffer for things of the given type to serve as search contexts
+;;    (completion candidates).  This prevents them, for example, from
+;;    presenting as a candidate a sexp or a list that is commented
+;;    out.  You can toggle this option anytime using `C-M-;' in the
+;;    minibuffer, but to see the effect you might need to invoke the
+;;    current command again.
+;;
+;;  * User option `icicle-search-hook' is a list of functions to be
+;;    run after searching and moving to an `icicle-search' match,
+;;    whether you move there by `RET', `C-RET', `C-next', or
+;;    `C-prior'.
+;;
+;;  * User option `icicle-recenter' is passed as argument to
+;;    `recenter' whenever the current navigation destination would be
+;;    off-screen, to make it visible.
+;;
+;;  * User option `icicle-bookmark-name-length-max' is the maximum
+;;    number of characters to use when `icicle-bookmark-cmd' (`C-x r
+;;    m') with a non-negative numeric prefix argument automatically
+;;    names a bookmark.
+;;
+;;  * User option `icicle-bookmark-refresh-cache-flag' determines
+;;    whether commands such as `icicle-bookmark' and
+;;    `icicle-search-bookmark' refresh the bookmark-list cache.  The
+;;    default value of `t', meaning refresh, ensures that the set of
+;;    bookmark candidates is always up-to-date, but you can improve
+;;    performance for a large bookmark list if you customize it to
+;;    `nil'.
+;;
+;;    In any case, a plain prefix argument (`C-u') for these commands
+;;    overrides the default setting of the option for the duration of
+;;    the command.  Thus if the customized value is `nil', you can use
+;;    `C-u' occasionally to refresh the list on demand.  In addition,
+;;    the cache is refreshed whenever you use `S-delete' to delete a
+;;    candidate bookmark.
+;;
+;;  * Non-`nil' user option `icicle-show-multi-completion-flag' means
+;;    that for some commands additional information is shown along
+;;    with each completion candidate.  That is, a multi-completion is
+;;    used.  You can match against any parts of the multi-completion.
+;;    The default value is `t'.
+;;
+;;    For example, for command `icicle-search', the name of the buffer
+;;    associated with each completion candidate is added to the
+;;    candidate and highlighted.  You can match against the buffer
+;;    name, as well as the search hit within the buffer.
+;;
+;;    Note that even when the value of this option is `nil', you can
+;;    often see the multi-completion information in the mode-line when
+;;    you cycle candidates, and you can typically see it in the help
+;;    that is displayed by `C-M-mouse-2' and so on.
+;;
+;;  * User options `icicle-buffer-match-regexp',
+;;    `icicle-buffer-no-match-regexp', `icicle-buffer-predicate', and
+;;    `icicle-buffer-extras' determine the behavior of Icicles buffer
+;;    commands, such as `icicle-buffer' and `insert-buffer'.  They
+;;    determine the set of buffer-name candidates available for
+;;    completion.
+;;
+;;    The first three restrict this set to names that satisfy the
+;;    properties they specify.  Option `icicle-buffer-extras' lets you
+;;    add additional buffer names to the set of candidates, after
+;;    restriction by the other options.  Extra buffer-name candidates
+;;    are displayed in buffer `*Completions*' using face
+;;    `icicle-extra-candidate'.
+;;
+;;    Note that if an extra candidate is already a candidate anyway
+;;    then it will be present twice in the list of all candidates
+;;    (that is, unless `icicle-transform-function' removes duplicate
+;;    candidates).
+;;
+;;    Note that `icicle-buffer-predicate' is applied after matching
+;;    against user input.  It thus corresponds to
+;;    `icicle-must-pass-after-match-predicate', not to
+;;    `icicle-must-pass-predicate'.
+;;
+;;    Options `icicle-file-match-regexp',
+;;    `icicle-file-no-match-regexp', `icicle-file-predicate', and
+;;    `icicle-file-extras' act similarly for file-name completion.
+;;    You could use `icicle-file-no-match-regexp' or
+;;    `icicle-file-predicate', for instance, to exclude files that are
+;;    in or under the directories in `vc-directory-exclusion-list':
+;;
+;;    (defun my-locate-non-vc-file ()
+;;      "`icicle-locate-file', but excluding stuff in VC directories."
+;;      (interactive)
+;;      (let ((icicle-file-predicate  'not-excluded-vc-file-p))
+;;        (icicle-locate-file)))
+;;
+;;    (defun not-excluded-vc-file-p (file)
+;;      "nil if FILE is in a `vc-directory-exclusion-list' directory."
+;;      (or (not (boundp 'vc-directory-exclusion-list))
+;;          (not (consp vc-directory-exclusion-list))
+;;          (not (let ((case-fold-search  completion-ignore-case))
+;;                 (catch 'nevfp
+;;                   (dolist (dir  vc-directory-exclusion-list)
+;;                     (when (string-match
+;;                            (concat ".*" dir "\\(/.*\\)?")
+;;                            file)
+;;                       (throw 'nevfp t)))
+;;                   nil)))))
+;;
+;;  * Option `icicle-ignored-directories' is a list of directories
+;;    that are ignored by commands `icicle-locate-file' and
+;;    `icicle-locate-file-no-symlinks'.  By default, this is the value
+;;    of `vc-directory-exclusion-list'.
+;;
+;;  * User option `icicle-buffer-sort' is a predicate used to sort
+;;    buffer-name candidates in Icicles buffer commands such as
+;;    `icicle-buffer' and `icicle-insert-buffer'.  Option
+;;    `icicle-file-sort' acts similarly for file-name completion.  The
+;;    default value of `icicle-buffer-sort' is
+;;    `icicle-buffer-sort-*...*-last', which sorts names of buffers
+;;    that begin with `*' after other buffer names.  These options
+;;    affect only the initial sort order used for buffer and file
+;;    names, respectively, that is, the order used first in an Emacs
+;;    session.  The values are also put first in the list of possible
+;;    sort orders for cycling.
+;;
+;;  * User option `icicle-buffer-configs' is a list of named
+;;    configurations of options `icicle-buffer-match-regexp',
+;;    `icicle-buffer-no-match-regexp', `icicle-buffer-predicate',
+;;    `icicle-buffer-extras', and `icicle-buffer-sort'.  You use
+;;    command `icicle-buffer-config' to choose one of the
+;;    configurations to be current.  You can use commands
+;;    `icicle-add-buffer-config' and `icicle-remove-buffer-config' to
+;;    add and remove configurations from the list.
+;;
+;;    Example: A configuration such as the following, named "Files and
+;;    Scratch", defines `icicle-buffer-predicate' to display only file
+;;    buffers, and it defines `icicle-buffer-extras' to include the
+;;    extra buffer `*scratch*':
+;;
+;;     ("Files and Scratch" nil nil
+;;      (lambda (bufname) (buffer-file-name (get-buffer bufname)))
+;;      ("*scratch*") icicle-sort-comparer)
+;;
+;;    The idea of buffer-option configurations was borrowed from
+;;    library `bs.el', by Olaf Sylvester .
+;;
+;;  * User option `icicle-dot-string' is the regexp string inserted by
+;;    `icicle-insert-dot-command' (bound to `.' in the minibuffer
+;;    during completion).  You can set it to a regexp that matches any
+;;    character, including newline.  The default value instead matches
+;;    any character except newline.  You can toggle between these two
+;;    behaviors using command `icicle-toggle-dot', bound to `C-M-.'
+;;    during completion.
+;;
+;;  * Non-`nil' option `icicle-dot-show-regexp-flag' means show the
+;;    underlying regexp (value of constant `icicle-anychar-regexp')
+;;    explicitly for a multi-line dot (`.').  A `nil' value works only
+;;    for Emacs versions 21 and later.
+;;
+;;  * User options `icicle-list-join-string' and
+;;    `icicle-list-nth-parts-join-string' are described in sections
+;;    (@> "Multi-Completions") and (@> "Programming Multi-Completions").
+;;    Option `icicle-list-join-string' is the separator string that
+;;    joins together the parts of a multi-completion.  The end string
+;;    is appended to each multi-completion candidate.  Option
+;;    `icicle-list-nth-parts-join-string' specifies how the
+;;    multi-completion extracted parts are joined back together when a
+;;    user chooses a multi-completion.
+;;
+;;    The default value of `icicle-list-join-string' is `^G^J'.  With
+;;    Emacs 22 and later, the `^G' part is hidden when it appears in
+;;    `*Completions*', and you can hide it in the minibuffer also by
+;;    using `C-M-j' instead of typing `C-q C-g C-j'.  See the doc
+;;    string for more information.
+;;
+;;  * Face `icicle-candidate-part' highlights one or more parts of a
+;;    candidate, in buffer `*Completions*'.  The candidate is
+;;    typically a multi-completion.
+;;
+;;  * Face `icicle-special-candidate' highlights candidates, in
+;;    `*Completions*', that are considered "special".  Generally,
+;;    these are candidates that match user option
+;;    `icicle-special-candidate-regexp'.
+;;
+;;  * Similarly, face `icicle-proxy-candidate' highlights proxy
+;;    candidates.  These are placeholders for real candidates.
+;;    Non-`nil' user option `icicle-add-proxy-candidates-flag' means
+;;    include proxy candidates whenever there are any.  You can toggle
+;;    this option during completion using command
+;;    `icicle-toggle-proxy-candidates', which is bound to `C-M-_' in
+;;    the minibuffer.  For performance reasons, you will in some cases
+;;    need to re-invoke the command to make the proxy candidates
+;;    available.
+;;
+;;  * Face `icicle-extra-candidate' highlights extra candidates, that
+;;    is, members of `icicle-extra-candidates', `icicle-buffer-extras',
+;;    or `icicle-file-extras'.
+;;
+;;  * User option `icicle-kmacro-ring-max' acts as `kmacro-ring-max'
+;;    when you are in Icicle mode.  (When you exit Icicle mode,
+;;    `kmacro-ring-max' is restored.)  In Icicles, you will typically
+;;    want to use a much larger number than the default value in
+;;    vanilla Emacs.
+;;
+;;  * User options `icicle-regexp-search-ring-max' and
+;;    `icicle-search-ring-max' act as `regexp-search-ring-max' and
+;;    `search-ring-max', respectively, when you are in Icicle mode.
+;;    (When you exit Icicle mode, `regexp-search-ring-max' and
+;;    `search-ring-max' are restored.)  The reason for having these
+;;    options is that with Icicles you will likely want to use a much
+;;    longer search history.  By default, these are as large as
+;;    possible (virtually unlimited).
+;;
+;;    Suggestion: If you use library `savehist.el' (recommended),
+;;    customize `savehist-additional-variables' to include variables
+;;    `search-ring' and `regexp-search-ring', so that your search
+;;    histories will be saved between Emacs sessions.
+;;
+;;    Note: You can clear (empty) a given search history with command
+;;    `clear-option' (aka `icicle-reset-option-to-nil').  For example,
+;;    to clear the regular-expression search history, do this:
+;;
+;;      `C-u M-x clear-option RET regexp-search-ring RET'
+;;
+;;    (The `C-u' is needed because this variable is not a user
+;;    option.)  If you use my library `misc-cmds.el', you can clear
+;;    search histories easier, using commands `clear-search-history',
+;;    `clear-regexp-search-history', and `clear-search-histories'.
+;;    See (@file :file-name "icicles-doc1.el" :to "Isearch Completion").
+;;
+;;  * User option `icicle-completion-history-max-length' limits the
+;;    number of completion inputs to save.  If you customize user
+;;    option `icicle-C-l-uses-completion-flag' to non-`nil', then,
+;;    instead of cycling, `C-l' lets you use Icicles completion to
+;;    retrieve a past completion input.  (`C-L' does the same thing.)
+;;    If you use library `savehist.el', then you can save the history
+;;    of completion inputs persistently by customizing user option
+;;    `savehist-additional-variables' to include the Icicles internal
+;;    variables `icicle-previous-raw-file-name-inputs' and
+;;    `icicle-previous-raw-non-file-name-inputs'.
+;;
+;;  * Faces `icicle-completion', `icicle-multi-command-completion',
+;;    and `icicle-mustmatch-completion' indicate the status of
+;;    minibuffer completion.  During completion, Icicles uses them for
+;;    a minibuffer indicator and, if user option
+;;    `icicle-highlight-lighter-flag' is non-`nil', for the `Icy'
+;;    mode-line lighter as well.
+;;
+;;  * Non-`nil' option
+;;    `icicle-highlight-input-initial-whitespace-flag' uses face
+;;    `icicle-whitespace-highlight' to highlight any whitespace that
+;;    starts your minibuffer input.  This is done to help you
+;;    recognize accidentally typing such whitespace.  Otherwise, you
+;;    might not understand the set of matching completion candidates
+;;    (or lack thereof).  There is not necessarily anything wrong with
+;;    input that starts with whitespace - it might be what you want,
+;;    but without this highlighting it is easy to not notice the
+;;    whitespace.
+;;
+;;  * The part of your current input that does not complete can be
+;;    highlighted automatically, and you can then remove that part
+;;    using `C-M-l'.  This highlighting is controlled by options
+;;    `icicle-incremental-completion-flag',
+;;    `icicle-test-for-remote-files-flag',
+;;    `icicle-highlight-input-completion-failure',
+;;    `icicle-highlight-input-completion-failure-delay', and
+;;    `icicle-highlight-input-completion-failure-threshold'.  The
+;;    highlighting uses face `icicle-input-completion-fail' (for
+;;    strict completion) or `icicle-input-completion-fail-lax' (for
+;;    lax completion).  For details, see the option doc strings and
+;;    (@file :file-name "icicles-doc1.el" :to "Icicles Highlights the Input that Won't Complete").
+;;
+;;  * User option `icicle-top-level-key-bindings' specifies top-level
+;;    commands and their bindings for Icicle mode.  By default, this
+;;    rebinds several standard Emacs keys (in Icicle mode only).  For
+;;    example, it substitutes `icicle-kill-buffer' for `kill-buffer'
+;;    (binding it to whatever `kill-buffer' is bound to globally).
+;;    Top-level commands are commands that are not used only in the
+;;    minibuffer.  To change these bindings, customize
+;;    `icicle-top-level-key-bindings'.  If you do that, then you must
+;;    exit and re-enter Icicle mode to ensure that the change takes
+;;    effect.  This is really necessary only if your changes would
+;;    undefine a key.
+;;
+;;  * Non-`nil' option `icicle-define-alias-commands-flag' defines a
+;;    few top-level Icicles commands whose names do not begin with
+;;    `icicle-', for convenience when using `M-x'.  For example,
+;;    command `toggle' is defined as an alias for command
+;;    `icicle-toggle-option'.  In any case, no such command is ever
+;;    defined by Icicles if a function with the same name is already
+;;    defined.
+;;
+;;  * Non-`nil' option `icicle-byte-compile-eval-after-load-flag'
+;;    means byte-compile definitions made within `eval-after-load'.
+;;    Some Icicles functions (commands, in particular) work only if a
+;;    given library is loaded.  Some such functions are defined inside
+;;    an `eval-after-load' form, which means they are defined only,
+;;    and as soon as, the required library is loaded.
+;;
+;;    If this option is non-`nil' then those function definitions are
+;;    byte-compiled.  This compilation adds a bit to the load time, in
+;;    effect, but it means that the functions run faster.
+;;
+;;  * User option `icicle-color-themes' is a list of color themes to
+;;    cycle through when you use command `icicle-color-theme'.
+;;
+;;  * User option `icicle-saved-completion-sets' is a persistent list
+;;    of named sets of completion candidates.  You can switch among
+;;    such sets at any time.  See
+;;    (@file :file-name "icicles-doc1.el" :to "Persistent Sets of Completion Candidates").
+;;
+;;  * User option `icicle-filesets-as-saved-completion-sets-flag'
+;;    non-`nil' means you can use Emacs filesets to save completion
+;;    candidates persistently.  This means that you can save file-name
+;;    candidates in a persistent Icicles saved completion set (cache
+;;    file) or in in an Emacs fileset.  It also means that an Icicles
+;;    persistent completion set can contain filesets, in addition to
+;;    file names: any number of filesets, and filesets of different
+;;    type.  Available only for Emacs 22 and later, and you must load
+;;    library `filesets.el' (and enable filesets using
+;;    `(filesets-init)').
+;;
+;;  * User option `icicle-key-descriptions-use-<>-flag' determines
+;;    whether angle brackets (`<', `>') are used by Icicles for named
+;;    keys, such as function keys (`' vs `f9') and pseudo keys
+;;    (`' vs `mode-line').  Non-`nil' means to use angle
+;;    brackets.  This option does not affect Emacs key descriptions
+;;    outside of Icicles (e.g. `C-h k' or `C-h w'), and it has no
+;;    effect for versions of Emacs prior to 21, because they never use
+;;    angle brackets.  The default value is `nil', because I think
+;;    angle brackets reduce readability.
+;;
+;;  * User option `icicle-keymaps-for-key-completion' is a list of
+;;    variables that are bound to keymaps in which you want to bind
+;;    `S-TAB' (actually, each of the keys in the value of option
+;;    `icicle-key-complete-keys') to `icicle-complete-keys'.  Each
+;;    such keymap should have at least one prefix key.  `S-TAB' is
+;;    bound in each keymap, so that you can use it to complete the
+;;    prefix keys.  See also `icicle-complete-key-anyway-flag'.
+;;
+;;  * Non-`nil' option `icicle-complete-key-anyway-flag' means bind
+;;    `S-TAB' (actually, each of the keys in the value of option
+;;    `icicle-key-complete-keys') to `icicle-complete-keys' in each
+;;    keymap of option `icicle-keymaps-for-key-completion', regardless
+;;    of whether `S-TAB' already has a binding in that keymap.  A
+;;    value of `nil' means bind `S-TAB' only if there is not already a
+;;    binding.
+;;
+;;  * Non-`nil' option `icicle-complete-keys-self-insert-ranges' means
+;;    that `icicle-complete-keys' includes some self-inserting keys as
+;;    completion candidates.  You will probably want to leave this
+;;    `nil'.  This option has no effect before Emacs 22.
+;;    See (@file :file-name "icicles-doc1.el" :to "Entering Special and Foreign Characters")
+;;
+;;  * User option `icicle-yank-function' is a function to use to yank
+;;    text.  By default, it is `yank'.  Command
+;;    `icicle-yank-maybe-completing' calls this function, except when
+;;    it is called from the minibuffer or called with a negative
+;;    prefix argument.
+;;
+;;  * Non-`nil' user option `icicle-use-candidates-only-once-flag'
+;;    means that acting on a candidate removes it from the set of
+;;    available candidates, so that you do not see that it can be used
+;;    again.  (`TAB' or `S-TAB' makes it available again.)  The
+;;    default value is `nil', and you probably do not want to
+;;    customize this.  However, if you write Emacs-Lisp code that uses
+;;    completion, then you can bind this to non-`nil' in contexts
+;;    where that makes sense.
+;;
+;;  * Non-`nil' user option `icicle-deletion-action-flag' means
+;;    `S-delete' during completion deletes the current object.  More
+;;    precisely, it deletes the object named by the current completion
+;;    candidate, if a deletion action is defined for the current
+;;    command.  If no deletion action is defined, then the value of
+;;    this option has no effect for that command.
+;;
+;;  * User option `icicle-alternative-actions-alist' is an alist that
+;;    associates Emacs commands and alternative action functions.  It
+;;    overrides any alternative actions defined otherwise for the
+;;    commands.
+;;
+;;  * User option `icicle-type-actions-alist' is an alist that
+;;    associates Emacs object types, such as buffer, file, and
+;;    process, with functions that accept an object of the given type
+;;    as their only required object.  This is used by some Emacs
+;;    commands during completion to prompt for a function to apply to
+;;    the current completion candidate.  Each function can be a symbol
+;;    or a lambda expression.  At runtime, symbols that are not
+;;    functions (`functionp') are ignored.
+;;
+;;  * User option `icicle-type-actions-alist' is an alist of Emacs
+;;    object types and associated actions (functions).  Each function
+;;    must accept an object of the specified type as its only required
+;;    argument.  A function here can be a symbol or a lambda
+;;    expression.  Any symbols that do not have function definitions
+;;    when this option is used are filtered out (not used).
+;;
+;;  * Non-`nil' user option `icicle-use-anything-candidates-flag'
+;;    means Anything actions are used for candidate alternate actions
+;;    in some Icicles commands, and Anything types and actions are
+;;    used by command `icicle-object-action' (aka `what-which-how' and
+;;    `a').  The default value is `t'.  This option has no effect if
+;;    library `anything.el' cannot be loaded.
+;;
+;;  * Non-`nil' user option
+;;    `icicle-anything-transform-candidates-flag' means that Anything
+;;    function `anything-transform-candidates' is applied to displayed
+;;    Anything candidates in Icicles.
+;;
+;;    The advantage of a `nil' value is that command `icicle-anything'
+;;    then acts as a multi-command: you can act on multiple
+;;    candidates, or apply multiple actions for the same candidate,
+;;    within a single invocation of `icicle-anything' (or related
+;;    commands).  The advantage of a non-`nil' value is that some of
+;;    the displayed Anything candidates might be more readable.  The
+;;    default value is `nil'.  This option has no effect if library
+;;    `anything.el' cannot be loaded.
+;;
+;;  * User option `icicle-WYSIWYG-Completions-flag' controls how face
+;;    and color names are displayed as candidates in `*Completions*'.
+;;    If value is non-`nil', then a WYSIWYG (what you see is what you
+;;    get) sample of the face or color is shown.  If the value is a
+;;    string, then a face name is accompanied by a separate face
+;;    swatch with that string text.  If the value is `t', then the
+;;    face name itself is shown using the face it names.  You can use
+;;    command `icicle-toggle-WYSIWYG-Completions' to toggle this
+;;    option.
+;;
+;;  * Non-`nil' user option
+;;    `icicle-unpropertize-completion-result-flag' means that
+;;    `completing-read' and (starting with Emacs 23) `read-file-name'
+;;    will strip all text properties from the result they return.
+;;    Regardless of the option value, Icicles strips text properties
+;;    that it adds for its internal use.  See the doc string of
+;;    function `icicle-unpropertize' for more information about this.
+;;
+;;    The default value of the option is `nil'.  It is not likely that
+;;    you will need to change this, but you might if you use some
+;;    other library that cannot accept a propertized string as the
+;;    result of completion.
+;;
+;;    Note: This is the case if you use GNUS - it has a known bug in
+;;    this regard (reported 2008-06-21).  It blindly prints the
+;;    Emacs-Lisp string that is the result of completion into an MML
+;;    attribute value: filename=#("~/.gnus/attach.el" 0 25 (face
+;;    nil)).  GNUS should ensure that whatever it uses for an
+;;    attribute value is valid for MML (has normal "..." string
+;;    syntax, with acceptable characters).  But it simply calls a Lisp
+;;    print function, which prints #("...").
+;;
+;;  * User options `icicle-pp-eval-expression-print-length' and
+;;    `icicle-pp-eval-expression-print-level' control the Lisp sexp
+;;    print length and print level, respectively, for values printed
+;;    by `M-:' (`icicle-pp-eval-expression').
+;;
+;;  * Non-`nil' option `icicle-guess-commands-in-path' means that all
+;;    executable files (or all files, if option
+;;    `shell-completion-execonly' is `nil') in your search path are
+;;    included among the completion candidates whenever a shell
+;;    command is read.  The particular non-`nil' value determines when
+;;    this list of commands is updated from your current search path.
+;;    The default value is `nil'.
+;;    See (@> "Icicles Shell-Command Enhancements").
+;;
+;;  * Non-`nil' option `icicle-quote-shell-file-name-flag' means that
+;;    `icicle-read-shell-command-completing' double-quotes the file
+;;    name at the beginning of the shell command it reads.  This
+;;    affects several Emacs commands, such as `M-!' that read a shell
+;;    command and its arguments.
+;;
+;;    If this is `nil', then such commands will not quote a
+;;    shell-command file name such as
+;;    `c:/Program Files/My Dir/mycmd.exe'.  In that case, a shell such
+;;    as `bash' fails for a shell command such as
+;;    `c:/Program Files/My Dir/mycmd.exe arg1 arg2 &', because it
+;;    interprets only `c:/Program' as the shell command.  That is, it
+;;    interprets the space (`SPC') characters in the file name as
+;;    separators.
+;;
+;;    If this is non-`nil' (the default value), then input such as
+;;    `c:/Program Files/My Dir/mycmd.exe arg1 arg2 &' is passed to the
+;;    shell as `"c:/Program Files/My Dir/mycmd.exe" arg1 arg2 &'
+;;    (notice the double-quotes).
+;;
+;;    See the doc string of `icicle-quote-file-name-part-of-cmd' for
+;;    information about the characters that, like `SPC', lead to
+;;    file-name quoting.
+;;
+;;  * Non-`nil' user option `icicle-inhibit-ding-flag' means Icicles
+;;    never uses an audible bell (ding).
+;;
+;;  * Option `icicle-option-type-prefix-arg-list' is a list of symbols
+;;    that control prefix arguments for command
+;;    `icicle-describe-option-of-type (bound to `C-h C-o' by
+;;    default). A list of six symbols taken from this list:
+;;
+;;    `direct'            `inherit'            `inherit-or-value'
+;;    `direct-or-value'   `inherit-or-regexp'  `direct-or-regexp'
+;;
+;;    Choose the order you like. The list members map, in order from
+;;    left to right, to these prefix argument keys:
+;;
+;;      1. `C-u C-u'
+;;      2. `C-0'
+;;      3. `C-u'
+;;      4. `C-9' (positive)
+;;      5. no prefix arg
+;;      6. `C--' (negative)
+;;
+;;    For the meanings of the symbols, see the doc string of
+;;    `icicle-describe-option-of-type', which describes the default
+;;    prefix-argument bindings for the command.
+;;
+;;  * Non-`nil' user option `icicle-customize-save-flag' means that
+;;    Icicles will save the updated value of option
+;;    `icicle-command-abbrev-alist' when you quit Emacs.  This is the
+;;    normal behavior.  If you for some reason do not want your
+;;    `custom-file' or init file updated in this way, then customize
+;;    `icicle-customize-save-flag' to `nil'.
+;;
+;;  * If `icicle-buffers-ido-like-flag' is `t' then `icicle-buffer'
+;;    and similar commands act more Ido-like.  Specifically, those
+;;    commands then bind these options to `t':
+;;    `icicle-show-Completions-initially-flag',
+;;    `icicle-top-level-when-sole-completion-flag', and
+;;    `icicle-default-value'.
+;;
+;;  * If `icicle-files-ido-like-flag' is `t' then `icicle-file' and
+;;    similar commands act more Ido-like.  Specifically, those
+;;    commands then bind these options to `t':
+;;    `icicle-show-Completions-initially-flag',
+;;    `icicle-top-level-when-sole-completion-flag', and
+;;    `icicle-default-value'.
+;;
+;;  * The value of option `icicle-customize-save-variable-function' is
+;;    the function Icicles uses to automatically save user option
+;;    changes made by some commands.  I recommend that you do *NOT*
+;;    change this option value.  This is provided only for users who
+;;    might want to disable such automatic saving of option changes,
+;;    by setting this to `ignore', or users who might want to manage
+;;    such option saving using their own function instead of the
+;;    default value, `customize-save-variable'.
+ 
+;;(@* "File-Name and Directory-Name Completion Tips")
+;;
+;;  File-Name and Directory-Name Completion Tips
+;;  --------------------------------------------
+;;
+;;  This section contains some tips about completing file and
+;;  directory names.
+;;
+;;  * Functions `icicle-file-type-less-p', `icicle-dirs-first-p', and
+;;    `icicle-dirs-last-p' are provided as possible values for user
+;;    option `icicle-sort-comparer'.  When choosing a sort order using
+;;    `C-,' or `M-,', these are called `by file type', `by directories
+;;    first', and `by directories last'.  They sort directory names
+;;    (alphabetically) before non-directory names (after, for
+;;    `icicle-dirs-last-p').  Function `icicle-file-type-less-p' sorts
+;;    non-directories by file type (extension) alphabetically.  For
+;;    non-file-name input these all act like
+;;    `icicle-case-string-less-p'.
+;;
+;;  * User option `icicle-cycle-into-subdirs-flag' controls whether or
+;;    not minibuffer-input cycling explores subdirectories.  By
+;;    default, it is `nil', meaning that cycling does not descend into
+;;    subdirectories.
+;;
+;;    non-`nil' - When this option is non-nil, you might want to use a
+;;          function such as `icicle-dirs-last-p' for option
+;;          `icicle-sort-comparer', to prevent cycling depth-first
+;;          into the subdirectories.
+;;
+;;    `nil' - When this option is `nil', you can still choose to cycle
+;;          into a given directory (which is why `nil' is the default
+;;          value).  When cycling reaches a candidate directory that
+;;          you want to cycle through, just: 1) move the cursor
+;;          (e.g. `C-e'), 2) hit `TAB' or `S-TAB' to "complete" the
+;;          candidate, and then 3) use any of the cycle keys, such as
+;;          `down', to cycle within the candidate directory.
+;;
+;;          Although the candidate directory was already completed by
+;;          cycling, moving the cursor and explicitly "completing" it
+;;          tells Icicles that you want to treat the candidate in the
+;;          minibuffer as real input, just as if you had typed it, not
+;;          merely as a cycling candidate.
+;;
+;;  * You can use `..' during completion to access a parent directory,
+;;    and you can use `/' and `~/' to shadow input to the left.  There
+;;    is currently no special treatment of MS Windows drive letters
+;;    (e.g. `C:') - I use Cygwin on Windows.
+;;
+;;  * Non-`nil' user option
+;;    `icicle-hide-common-match-in-Completions-flag' hides the common
+;;    match for your current input from each candidate in
+;;    `*Completions*'.  You can toggle this at any time during
+;;    completion using `C-x .' (`icicle-toggle-hiding-common-match').
+;;    This can be especially useful when reading an absolute file name
+;;    (e.g. `C-u C-x C-f'), by removing any common directory
+;;    component.
+;;
+;;  * Standard Emacs user option `completion-ignored-extensions' is a
+;;    list of file-name extensions.  File names that match any of
+;;    these extensions are generally ignored for completion (but see
+;;    the doc string for particulars).  In Icicles, however, the
+;;    behavior is slightly different:
+;;
+;;    - In vanilla Emacs the option is itself ignored for display in
+;;      buffer `*Completions*'.  That is, even file names that are
+;;      ignored for completion are shown in `*Completions*' as
+;;      available completion candidates.
+;;
+;;    - In Icicles this is not the case. When a file name is ignored
+;;      it is ignored completely; it is not shown in `*Completions*'.
+;;      But in Icicles you can toggle this ignoring off or on at any
+;;      time during completion, using `C-.' in the minibuffer.
+;;
+;;    In addition, if you load library `completion-ignored-build.el',
+;;    by Kevin Ryde, then Icicles automatically takes advantage of
+;;    that library's dynamic adjustment of ignored extensions.  (Just
+;;    load the library - do not enable its minor mode or advice.)
+;;
+;;  * User option `icicle-use-~-for-home-dir-flag' controls whether
+;;    your home directory is written in the minibuffer using `~' or in
+;;    expanded form, during completion.  The default value is `t',
+;;    which means to use `~', saving minibuffer space.  You can toggle
+;;    this option at any time using command
+;;    `icicle-toggle-~-for-home-dir', bound to `M-~'.
+;;
+;;  * Remember that you can use a regular expression to
+;;    apropos-complete file names.  This is a powerful feature.  Do
+;;    not confuse its use with the ability to use shell wildcards
+;;    (globbing) to access multiple files at once.  For example, if
+;;    you use `C-x 4 f *.el RET', then all files with suffix `el' will
+;;    be opened.  Regexp matching is used only for apropos (not
+;;    prefix) completion and cycling.  See
+;;    (@file :file-name "icicles-doc1.el" :to "What About Special-Character Conflicts?").
+;;
+;;  * You can use `$' for both environment variables and as a regexp
+;;    special character.  For example, you can use a pattern such as
+;;    `$HOME.*t$' to match the files in your home directory (`$HOME')
+;;    whose names end in `t'.  See
+;;    (@file :file-name "icicles-doc1.el" :to "What About Special-Character Conflicts?").
+;;
+;;  * Starting with Emacs 23, and if the current `TAB' completion
+;;    method is `vanilla' (see (@* "Fuzzy Completion")), you can
+;;    complete environment variables during file-name completion,
+;;    using `TAB'.  So you can, for example, complete `$HO' to any of
+;;    the candidates `HOME', `HOMEDRIVE', `HOMEPATH'.  This is in
+;;    addition to the expansion of complete environment variables
+;;    (e.g. `$HOME' to `/my/home/dir/') when you use `S-TAB' or `RET'.
+;;
+;;  * You can use the idiom `\W$' as input to match only directories,
+;;    when a command asks for a file or directory name.  The `\W' says
+;;    to match any non word-syntax character.  The `$' says to match
+;;    this at the end of the name.  This works because directory names
+;;    appear as completion candidates with a trailing slash (`/'), and
+;;    slash (`/') is about the only non word-syntax character that is
+;;    likely to appear in file-name completions.  See
+;;    (@file :file-name "icicles-doc1.el" :to "What About Special-Character Conflicts?").
+;;
+;;  * You can use library `ffap.el', if you like, with Icicles, to
+;;    pick up the file, directory, or URL name under the cursor.  All
+;;    Icicles features are available during file-name and URL
+;;    completion.  If you like `ffap.el', you might also like to try
+;;    my extension library `ffap-.el'.   See also
+;;    (@file :file-name "icicles-doc1.el" :to "Inserting Text Found Near the Cursor").
+;;
+;;  * Many Icicles commands that target file or directory names look
+;;    only in the current directory (`default-directory').  This means
+;;    that the directory part of the name is ignored for matching
+;;    purposes.  You can thus use apropos completion to match a
+;;    substring, without needing to prefix the substring with `.*'.
+;;    For example, to match file `favorite-foo-file.bar' in directory
+;;    `/some/path/to/my/', it is sufficient to use either `foo' or
+;;    `/some/path/to/my/foo'.
+;;
+;;  * Some Icicles commands that target file names match your input
+;;    against file names as ordinary strings, that is, with no notion
+;;    that they are actually file names.  This is the case for
+;;    `icicle-locate-file', `icicle-recent-file',
+;;    `icicle-find-file-in-tags-table', and
+;;    `icicle-find-file-absolute', as well as `icicle-file' with a
+;;    prefix argument.  Such candidates are often absolute file names.
+;;    In that case, you can regexp-match against any part of the
+;;    absolute file name, including directory components.  See
+;;    (@file :file-name "icicles-doc1.el" :to "File-Name Input and Locating Files Anywhere").
+;;
+;;  * If you have symbolic links that might get in the way of
+;;    exploring directories while locating files, you can use command
+;;    `icicle-locate-file-no-symlinks' instead of
+;;    icicle-ignored-directories' - it will not follow symbolic links.
+;;
+;;    This also gives you a way to temporarily avoid descending into a
+;;    subdirectory you are not interested in: put a symbolic link in
+;;    its place temporarily.
+;;
+;;    Another, cleaner way to skip certain directories is to customize
+;;    or `let'-bind option `icicle-ignored-directories'. By default
+;;    this is the value of `vc-directory-exclusion-list', which means
+;;    that it ignores version-control directories.
+;;
+;;  See Also:
+;;
+;;  * (@> "Customization and General Tips") for general tips about
+;;    using Icicles.  Many of those tips apply also to file-name and
+;;    directory-name completion.
+;;  * (@file :file-name "icicles-doc1.el" :to "File-Name Input and Locating Files Anywhere").
+ 
+;;(@* "Key Bindings")
+;;
+;;  Key Bindings
+;;  ------------
+;;
+;;  You can customize any of the key bindings that Icicles uses - see
+;;  (@> "Customizing Key Bindings").  I recommend that you first try
+;;  using the default bindings, however.  There are many Icicles key
+;;  bindings (in particular in the minibuffer), but they are grouped
+;;  into a few natural sets, to help you remember them.
+;;
+;;(@* "Global Bindings")
+;;  ** Global Bindings **
+;;
+;;  Icicles does not change your global key bindings.  It changes some
+;;  minibuffer bindings, and it adds some bindings for Icicle mode,
+;;  but it does not change your global bindings.
+;;
+;;  There are two exceptions:
+;;
+;;  1. In Icicle mode, various Icicles commands are added to menu-bar
+;;  menus.  File commands are added to the File menu, and so on, under
+;;  an Icicles submenu.  Those items that do not belong naturally to
+;;  any existing menu-bar menu are added to a new top-level Icicles
+;;  menu and to the existing Minibuf menu.  Whatever the menu they
+;;  appear in, however, Icicles menu items are visible only when
+;;  Icicle mode is active.
+;;
+;;  If you do not want Icicles to add items to menus besides Minibuf
+;;  and Icicles, then set option `icicle-touche-pas-aux-menus' to
+;;  non-`nil'.  See (@> "Customizing Key Bindings").
+;;
+;;  2. Icicles adds the key `S-TAB' (bound to `icicle-complete-keys')
+;;  to each existing keymap.  This allows you to complete keys in any
+;;  keymap.  For technical reasons, these bindings are not part of
+;;  `icicle-mode-map'; other keymaps are enhanced to include this
+;;  binding.  However, this Icicles binding of `S-TAB' never replaces
+;;  any existing binding of `S-TAB'.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Key Completion") for more
+;;  information about this use of `S-TAB'.
+;;
+;;  (The documentation always refers to the key that performs key
+;;  completion as `S-TAB'.  Actually, it is `S-TAB' only by default.
+;;  You can customize it, using option `icicle-key-complete-keys'.)
+;;
+;;(@* "Icicle-Mode Bindings")
+;;  ** Icicle-Mode Bindings **
+;;
+;;  Most Icicle-mode bindings are in the Icicles menu-bar menu.  In
+;;  addition, option `icicle-top-level-key-bindings' causes Icicles to
+;;  bind some keyboard keys to some top-level Icicles commands.  Some
+;;  of these take the place of similar, global bindings whenever you
+;;  are in Icicle mode.  Typically, these top-level commands are
+;;  Icicles multi-command versions of the vanilla Emacs commands.
+;;  See (@file :file-name "icicles-doc1.el" :to "Multi-Commands").
+;;
+;;  You can customize option `icicle-top-level-key-bindings' to
+;;  specify the top-level commands that you want to bind in Icicle
+;;  mode, and the keys you want to bind them to.  With the default
+;;  value of `icicle-top-level-key-bindings', Icicles makes the
+;;  following Icicle-mode bindings:
+;;
+;;  * `C-c ''          - `icicle-occur'
+;;  * `C-c ='          - `icicle-imenu'
+;;  * `C-c `'          - `icicle-search'
+;;  * `C-c `'          - `icicle-compilation-search' (in *grep* etc.)
+;;  * `C-c `'          - `icicle-comint-search' (in *shell* etc.)
+;;  * `C-c TAB'        - `icicle-comint-command' (in *shell* etc.)
+;;  * `C-c /'          - `icicle-complete-thesaurus-entry'
+;;  * `C-h C-o'        - `icicle-describe-option-of-type'
+;;  * `ESC M-x'        - `lacarte-execute-command'
+;;  * `M-`', `f10'     - `lacarte-execute-menu-command'
+;;  * `M-x'            - `icicle-execute-extended-command'
+;;  * `C-x SPC'        - `icicle-command-abbrev'
+;;  * `C-x M-e'        - `icicle-execute-named-keyboard-macro'
+;;  * `S-f4'           - `icicle-kmacro'
+;;  * `pause'          - `icicle-switch-to/from-minibuffer'
+;;
+;;  `S-TAB' is bound, in effect, to `icicle-complete-keys', which
+;;  completes a key sequence.  Prefix keys followed by `S-TAB' are
+;;  also bound to `icicle-complete-keys'.  (`S-TAB' is effectively
+;;  bound to other commands in buffer `*Completions*' and in the
+;;  minibuffer.)
+;;
+;;  (The documentation always refers to the key that performs key
+;;  completion as `S-TAB'.  Actually, it is `S-TAB' only by default.
+;;  You can customize it, using option `icicle-key-complete-keys'.)
+;;
+;;  When `icicle-top-level-key-bindings' has its default value,
+;;  Icicles also substitutes all of the key bindings for some standard
+;;  Emacs commands.  For example, Icicles binds `icicle-buffer' to all
+;;  keys that are globally bound outside Icicle mode to standard
+;;  command `switch-to-buffer'.  By default, the following standard
+;;  commands have their bindings co-opted this way by Icicles
+;;  commands:
+;;
+;;  Standard Command                   Icicles Command
+;;
+;;  `abort-recursive-edit'.............`icicle-abort-recursive-edit'
+;;  `bookmark-jump'....................`icicle-bookmark'
+;;  `bookmark-jump-other-window'.......`icicle-bookmark-other-window'
+;;  `bookmark-set'.....................`icicle-bookmark-cmd'
+;;  `dabbrev-completion'...............`icicle-dabbrev-completion'
+;;  `delete-window'....................`icicle-delete-window'
+;;  `dired'............................`icicle-dired'
+;;  `dired-other-window'...............`icicle-dired-other-window'
+;;  `eval-expression'..................`icicle-pp-eval-expression'
+;;  `exchange-point-and-mark'.........`icicle-exchange-point-and-mark'
+;;  `execute-extended-command'.......`icicle-execute-extended-command'
+;;  `find-file'........................`icicle-file'
+;;  `find-file-other-window'...........`icicle-file-other-window'
+;;  `find-file-read-only'..............`icicle-find-file-read-only'
+;;  `find-file-read-only-other-window'.`...read-only-other-window'
+;;  `find-tag'.........................`icicle-find-tag'
+;;  `find-tag-other-window'.......`icicle-find-first-tag-other-window'
+;;  `Info-goto-node'...................`icicle-Info-goto-node'
+;;  `Info-index'.......................`icicle-Info-index'
+;;  `Info-menu'........................`icicle-Info-menu'
+;;  `insert-buffer'....................`icicle-insert-buffer'
+;;  `kill-buffer'......................`icicle-kill-buffer'
+;;  `lisp-complete-symbol'.............`icicle-lisp-complete-symbol'
+;;  `other-window'.....................`icicle-other-window-or-frame'
+;;  `other-frame'......................`icicle-select-frame'
+;;  `pop-global-mark'...`icicle-goto-global-marker-or-pop-global-mark'
+;;  `pop-tag-mark'.....................`icicle-pop-tag-mark'
+;;  `pp-eval-expression'...............`icicle-pp-eval-expression'
+;;  `set-mark-command'........`icicle-goto-marker-or-set-mark-command'
+;;  `switch-to-buffer'.................`icicle-buffer'
+;;  `switch-to-buffer-other-window'....`icicle-buffer-other-window'
+;;  `where-is'.........................`icicle-where-is'
+;;  `yank'.............................`icicle-yank-maybe-completing'
+;;
+;;  Actually, by default, Icicles binds `icicle-yank-maybe-completing'
+;;  to whatever the value of option `icicle-yank-function' is.  By
+;;  default, this value is `yank'.
+;;
+;;  Option `icicle-top-level-key-bindings' remaps not only these
+;;  standard Emacs commands but also some commands provided by other
+;;  libraries.  For example, if you use package `Bookmark+', then
+;;  type-specific bookmark jump commands such as
+;;  `bmkp-dired-jump-other-window' are remapped to Icicles
+;;  multi-command versions.
+;;
+;;  In addition, option `icicle-functions-to-redefine' redefines some
+;;  vanilla functions to their Icicles versions while in Icicle mode.
+;;  Any redefined functions that are bound to keys keep those
+;;  bindings.  For example, `Info-index' is by default redefined to
+;;  `icicle-Info-index' in Icicle mode, so `i' in Info mode is
+;;  effectively bound to `icicle-Info-index'.  Commands listed in
+;;  option `icicle-functions-to-redefine' are typically bound in
+;;  keymaps other than the global map.
+;;
+;;  Here are some other Icicles commands that you might want to bind
+;;  to keys in Icicle mode - they are not bound by Icicles (except to
+;;  menu items):
+;;
+;;  `clear-option' (alias) - Set value of binary option to `nil'
+;;  `icicle-add-buffer-candidate' -
+;;                          Add buffer to those always shown
+;;  `icicle-add-buffer-config' - Add to `icicle-buffer-configs'
+;;  `icicle-add-entry-to-saved-completion-set' -
+;;                          Add a completion candidate to a saved set
+;;  `icicle-add/update-saved-completion-set' - Add a set to
+;;                          `icicle-saved-completion-sets'
+;;  `icicle-apply'        - Selectively apply function to alist items
+;;  `icicle-apropos'      - `apropos', but shows matches
+;;  `icicle-apropos-command' - Enhanced `apropos-command'
+;;  `icicle-apropos-variable' - Enhanced `apropos-variable'
+;;  `icicle-apropos-zippy' - Show matching Zippy quotes
+;;  `icicle-bookmark-file-other-window' - Jump to file bookmarks
+;;  `icicle-bookmark-dired-other-window'  - Jump to Dired bookmarks
+;;  `icicle-bookmark-gnus-other-window' - Jump to Gnus bookmarks
+;;  `icicle-bookmark-info-other-window' - Jump to Info bookmarks
+;;  `icicle-bookmark-local-file-other-window' - Jump to local files
+;;  `icicle-bookmark-non-file-other-window' - Jump to buffers
+;;  `icicle-bookmark-region-other-window' - Jump to region bookmarks
+;;  `icicle-bookmark-remote-file-other-window' - Jump to remote files
+;;  `icicle-bookmark-url-other-window' - Jump to URL bookmarks
+;;  `icicle-bookmark-w3m-other-window' - Jump to W3M bookmarks
+;;  `icicle-buffer-config' - Pick options for Icicles buffer commands
+;;  `icicle-buffer-list'  - Choose a list of buffer names
+;;  `icicle-choose-faces' - Choose a list of face names
+;;  `icicle-choose-invisible-faces' - Choose invisible face names
+;;  `icicle-choose-visible-faces' - Choose visible face names
+;;  `icicle-clear-history' - Clear minibuffer histories
+;;  `icicle-color-theme'  - Change color theme
+;;  `icicle-completing-yank' - Yank text using completion
+;;  `icicle-customize-face' - Multi-command `customize-face'
+;;  `icicle-customize-icicles-group' -
+;;                          Customize Icicles options and faces
+;;  `icicle-delete-file'  - Delete a file or directory
+;;  `icicle-delete-windows' - Delete all windows for a buffer
+;;  `icicle-doc'          - Display doc of function, variable, or face
+;;  `icicle-doremi-increment-variable+' -
+;;                          Increment a variable using Do Re Mi
+;;  `icicle-face-list'    - Choose a list of face names
+;;  `icicle-file-list'    - Choose a list of file names
+;;  `icicle-font'         - Change the frame font
+;;  `icicle-frame-bg'     - Change the frame background color
+;;  `icicle-frame-fg'     - Change the frame foreground color
+;;  `icicle-fundoc'       - Display the doc of a function
+;;  `icicle-hide-faces'   - Hide a set of faces you choose
+;;  `icicle-hide-only-faces' - Hide a set of faces; show all others
+;;  `icicle-increment-option' - Increment numeric options (Do Re Mi)
+;;  `icicle-increment-variable' - Increment variables (Do Re Mi)
+;;  `icicle-Info-virtual-book' - Open Info on a virtual book
+;;  `icicle-insert-thesaurus-entry' -
+;;                          Insert a thesaurus entry
+;;  `icicle-keyword-list' - Choose a list of keywords (regexps)
+;;  `icicle-locate-file'  - Open a file located anywhere
+;;  `icicle-minibuffer-help' - Show Icicles minibuffer help
+;;  `icicle-plist'        - Show symbols, property lists
+;;  `icicle-recent-file'  - Open a recently used file
+;;  `icicle-recompute-shell-command-candidates' - Update from PATH
+;;  `icicle-remove-buffer-candidate' -
+;;                          Remove buffer from those always shown
+;;  `icicle-remove-buffer-config'- Remove from `icicle-buffer-configs'
+;;  `icicle-remove-entry-from-saved-completion-set' -
+;;                          Remove a candidate from a saved set
+;;  `icicle-remove-file-from-recentf-list' - Remove from recent files
+;;  `icicle-remove-saved-completion-set' - Remove a set from
+;;                          `icicle-saved-completion-sets'
+;;  `icicle-reset-option-to-nil' -
+;;                          Set value of binary option to `nil'
+;;  `icicle-save-string-to-variable' -
+;;                          Save text for use with `C-='
+;;  `icicle-search-all-tags-bookmark' - Search bookmarks that have all
+;;                                      of a given set of tags
+;;  `icicle-search-all-tags-regexp-bookmark' - Search bookmarks all of
+;;                                     whose tags match a given regexp
+;;  `icicle-search-autofile-bookmark' - Search autofile bookmarks only
+;;  `icicle-search-bookmark' - Search bookmarks
+;;  `icicle-search-bookmark-list-bookmark' - bookmark-list bookmarks
+;;  `icicle-search-bookmarks-together' - Search bookmarks together
+;;  `icicle-search-buff-menu-marked' - Search marked buffers, in order
+;;  `icicle-search-buffer' - Search multiple buffers
+;;  `icicle-search-char-property' - Search for character properties
+;;  `icicle-search-desktop-bookmark' -- Search desktop bookmarks
+;;  `icicle-search-dired-bookmark' - Search Dired bookmarks
+;;  `icicle-search-dired-marked' - Search the marked files in Dired
+;;  `icicle-search-file'  - Search multiple files
+;;  `icicle-search-file-bookmark' - Search file bookmarks
+;;  `icicle-search-gnus-bookmark' - Search Gnus bookmarks
+;;  `icicle-search-ibuffer-marked' - Search marked buffers in Ibuffer
+;;  `icicle-search-info-bookmark' - Search Info bookmarks
+;;  `icicle-search-local-file-bookmark' - Search local file bookmarks
+;;  `icicle-search-man-bookmark' - Search `man'-page bookmarks
+;;  `icicle-search-non-file-bookmark' - Search non-file bookmarks
+;;  `icicle-search-overlay-property' - Search for overlay properties
+;;  `icicle-search-pages' - Search Emacs pages (delimited by ^L chars)
+;;  `icicle-search-paragraphs' - Search Emacs paragraphs
+;;  `icicle-search-region-bookmark' - Search bookmarked regions
+;;  `icicle-search-remote-file-bookmark' - Search remote files
+;;  `icicle-search-sentences' - Search using sentences as contexts
+;;  `icicle-search-some-tags-bookmark' - Search bookmarks that have
+;;                                       some of a given set of tags
+;;  `icicle-search-some-tags-regexp-bookmark' - Search bookmarks some
+;;                                  of whose tags match a given regexp
+;;  `icicle-search-specific-buffers-bookmark' - Search bookmarks for a
+;;                                              given set of buffers
+;;  `icicle-search-specific-files-bookmark' - Search bookmarks for a
+;;                                            given set of files
+;;  `icicle-search-thing' - Search thing-at-point-defined things
+;;  `icicle-search-this-buffer-bookmark' - Search bookmarks in buffer
+;;  `icicle-search-url-bookmark' - Search URL bookmarks
+;;  `icicle-search-w3m-bookmark' - Search W3M bookmarks
+;;  `icicle-search-xml-element' - Search the contents of XML elements
+;;  `icicle-search-xml-element-text-node' - Search XML text nodes
+;;  `icicle-select-window' - Select a window by its buffer name
+;;  `icicle-set-option-to-t' - Set value of binary option to `t'
+;;  `icicle-show-faces'   - Show invisible faces you choose
+;;  `icicle-show-only-faces' - Show some invisible faces; hide others
+;;  `icicle-toggle-option' - Toggle the value of a binary option
+;;  `icicle-vardoc'       - Display the doc of a variable
+;;  `toggle' (alias)      - Toggle the value of a binary option
+;;
+;;(@* "Minibuffer Bindings")
+;;  ** Minibuffer Bindings **
+;;
+;;  There are many key bindings available while input is read in the
+;;  minibuffer.  Most of these keys are bound in the minibuffer
+;;  completion keymaps, but some are bound in the `*Completions*'
+;;  buffer keymap and some are bound when reading input without
+;;  completion.
+;;
+;;  In addition, clicking `C-mouse-3' on a completion candidate in
+;;  buffer `*Completions*' pops up a menu of available commands.  Some
+;;  of these menu commands are applicable to the completion you click;
+;;  others apply to the current state of completion or to the complete
+;;  set of completion candidates.  The associated key bindings are
+;;  indicated in the menu items, so this can be a good way to learn
+;;  minibuffer and `*Completions*' bindings.
+;;
+;;  The following key is helpful during any minibuffer input.  It pops
+;;  up the `*Help*' buffer with information about using the minibuffer
+;;  in Icicle mode.  During completion, this includes information
+;;  similar to what you are reading now.  It also lists toggle
+;;  commands and the current toggle values.
+;;
+;;    `C-?' - `icicle-minibuffer-help'
+;;
+;;  The following key bindings are made for the minibuffer completion
+;;  keymaps.  They are in effect whenever you are using the minibuffer
+;;  for input with completion (e.g. `completing-read',
+;;  `read-file-name', `M-x').
+;;
+;;    `down', `wheel-down' - `icicle-next-candidate-per-mode' (modal)
+;;    `up', `wheel-up' - `icicle-previous-candidate-per-mode' (modal)
+;;
+;;    `next', `prior'  - `icicle-next-apropos-candidate',
+;;                       `icicle-previous-apropos-candidate', which
+;;                       cycle candidate apropos completions.
+;;
+;;    `end', `home'    - `icicle-next-prefix-candidate',
+;;                       `icicle-previous-prefix-candidate',
+;;                       which cycle candidate prefix completions.
+;;
+;;      Whether a modal cycling key is used for prefix or apropos
+;;      completion at a given time depends on the current completion
+;;      mode, which is determined by which of `TAB' and `S-TAB' was used
+;;      last, or by option `icicle-default-cycling-mode' if neither was
+;;      used.
+;;
+;;      (The mouse wheel bindings are only for Emacs 22 and later.
+;;      The documentation refers to the keys that cycle completion
+;;      candidates as `down', `up', `next', `prior', `end', and
+;;      `home'.  Actually, these are the cycling keys only by default.
+;;      You can customize them using options
+;;      `icicle-modal-cycle-down-keys', `icicle-modal-cycle-up-keys',
+;;      `icicle-apropos-cycle-next-keys',
+;;      `icicle-apropos-cycle-previous-keys',
+;;      `icicle-prefix-cycle-next-keys', and
+;;      icicle-prefix-cycle-previous-keys'.)
+;;
+;;    Keys bound globally to commands that perform simple text
+;;    insertion, deletion, and transposition operations - commands
+;;    such as `self-insert-command' - are bound to Icicles versions of
+;;    those commands that do the same thing but also provide apropos
+;;    icompletion.  This includes keys such as `C-d', `C-k', and `C-w'
+;;    (and lots more).  See (@file :file-name "icicles-doc1.el" :to "Icompletion").
+;;
+;;    `pause'  - `icicle-switch-to/from-minibuffer': Move cursor to
+;;               the buffer from which the minibuffer was activated.
+;;
+;;    `C-insert' - `icicle-switch-to-Completions-buf': Move cursor to
+;;               the current candidate in buffer `*Completions*'.
+;;
+;;    `C-v'    - `icicle-scroll-Completions-forward': Scroll the
+;;               `*Completions*' window forward
+;;
+;;    `M-v'    - `icicle-scroll-Completions-backward': Scroll the
+;;               `*Completions*' window backward
+;;
+;;    `C-M-v'  - `icicle-scroll-forward': Scroll the current
+;;               non-minibuffer window forward
+;;
+;;    `C-M-V' (`C-M-S-v') - `icicle-scroll-backward': Scroll the
+;;               current non-minibuffer window backward
+;;
+;;    `M-*'    - `icicle-narrow-candidates': Narrow the set of
+;;               completion candidates using another input regexp.
+;;
+;;    `M-SPC'  - `icicle-prefix-word-complete': Complete current input
+;;               in minibuffer, as a prefix, a single word at a time.
+;;               This replaces `minibuffer-complete-word'.  In fact,
+;;               it is the keys in `icicle-word-completion-keys' that
+;;               are bound to this command; `M-SPC' is by default.
+;;
+;;    `S-SPC'  - `icicle-apropos-complete-and-narrow': Same as
+;;               `S-TAB' followed by `M-*'.
+;;
+;;    `TAB' -    `icicle-prefix-complete': Complete current input in
+;;               minibuffer, as a prefix.  If there is more than one
+;;               prefix-completion candidate, display them in buffer
+;;               `*Completions*', highlighting the common prefix.
+;;               This replaces `minibuffer-complete'.
+;;
+;;               (The documentation always refers to the key that does
+;;               this as `TAB'.  Actually, it is only `TAB' by
+;;               default.  You can customize it, using option
+;;               `icicle-prefix-complete-keys'.)
+;;
+;;    `S-TAB'  - In the minibuffer: `icicle-apropos-complete' - like
+;;               `TAB', but use apropos completion.  In buffer
+;;               `*Completions*': `icicle-move-to-previous-completion'
+;;               - move backwards among candidates.
+;;
+;;               (The documentation always refers to the keys that do
+;;               these things as `S-TAB'.  Actually, they are only
+;;               `S-TAB' by default.  You can customize the keys,
+;;               using options `icicle-apropos-complete-keys' and
+;;               `icicle-previous-candidate-keys'.)
+;;
+;;    `C-M-TAB' - `icicle-prefix-complete-no-display': Like `TAB', but
+;;               does not display candidates in `*Completions*'.
+;;
+;;               (The documentation always refers to the key that does
+;;               this as `C-M-TAB'.  Actually, it is only `C-M-TAB' by
+;;               default.  You can customize it, using option
+;;               `icicle-prefix-complete-no-display-keys'.)
+;;
+;;    `C-M-S-TAB' - `icicle-apropos-complete-no-display': Like
+;;               `S-TAB', but does not display candidates.
+;;
+;;               (The documentation always refers to the key that does
+;;               this as `C-M-S-TAB'.  Actually, it is only
+;;               `C-M-S-TAB' by default.  You can customize it, using
+;;               option `icicle-apropos-complete-no-display-keys'.)
+;;
+;;    `C-M-&'  - `icicle-save-predicate-to-variable': Save the current
+;;               predicate used for completion to a variable.
+;;
+;;    `delete' - `icicle-remove-candidate': Remove the current
+;;               candidate from consideration.
+;;
+;;    `S-mouse-2' - `icicle-mouse-remove-candidate': Same as `delete'.
+;;
+;;    `M-q'    - `icicle-insert-key-description': Insert the textual
+;;               representation of a key sequence, during key
+;;               completion.
+;;
+;;    `M-o'    - `icicle-insert-history-element': Invoke completion to
+;;               insert a previously entered input in the minibuffer.
+;;
+;;    `M-%'    - Regexp quote current input or its active region, then
+;;               apropos-complete.  Use this to literally match all or
+;;               some input in the context of regexp matching overall.
+;;
+;;    `C-M-F' (`C-M-S-f') - `icicle-read+insert-file-name': Invoke
+;;               completion to insert a file name in the minibuffer.
+;;
+;;    `C-M-C' (`C-M-S-c') - `icicle-completing-read+insert': Invoke
+;;               completion to insert something other than a file name
+;;               (not always available).
+;;
+;;               (`C-M-F' and `C-M-C' are the default values for
+;;               the keys that invoke completion on demand.  You can
+;;               customize the keys to use, using options
+;;               `icicle-read+insert-file-name-keys' and
+;;               `icicle-completing-read+insert-keys'.)
+;;
+;;  In Icicles, multi-line completion candidates are not uncommon.
+;;  You can move up and down minibuffer lines with `C-p' and `C-n',
+;;  and you can use the following keys to move among line beginnings
+;;  and ends:
+;;
+;;    `C-a', `C-e' - `icicle-beginning-of-line+',
+;;               `icicle-end-of-line+': Like normal `C-a', `C-e', but
+;;               repeating goes to the previous or next line.
+;;
+;;  If you use libraries `fit-frame.el' and `oneonone.el' with a
+;;  standalone minibuffer frame (non-`nil'
+;;  `1on1-minibuffer-frame-flag'), and if option
+;;  `1on1-fit-minibuffer-frame-flag' is non-`nil', then the minibuffer
+;;  frame is automatically resized to fit its content as you edit that
+;;  content.  (Options `1on1-fit-minibuffer-frame-max-height' and
+;;  `1on1-fit-minibuffer-frame-max-height-percent' define the maximum
+;;  height for this.)
+;;
+;;  If, in addition, you bind `1on1-fit-minibuffer-frame' to a key,
+;;  then you can use that key repeatedly to increase the height by one
+;;  line, even beyond the maximum.  Library `setup-keys.el' binds this
+;;  to `C-o'.
+;;
+;;  (If you do not use a separate minibuffer frame, then you will
+;;  likely want to set standard option `resize-mini-windows' to `t',
+;;  not to `grow-only', at least while in Icicle mode.)
+;;
+;;    `C-M-j' - `icicle-insert-list-join-string': Insert
+;;              `icicle-list-join-string'. See also
+;;              (@> "Multi-Completions").
+;;
+;;  You can insert a single Icicles multi-line dot using `C-u .', or
+;;  by turning on this dot magic generally, using `C-M-.':
+;;
+;;    `.'     - `icicle-insert-dot-command'
+;;    `C-M-.' - `icicle-toggle-dot'
+;;
+;;  In vanilla Emacs, the following keys have a special purpose during
+;;  input completion, but in Icicles they simply insert the character
+;;  typed - they are self-inserting.  This is because (1) there are
+;;  better ways to do what vanilla Emacs uses these keys for and (2)
+;;  it is useful to be able to insert these characters without first
+;;  typing `C-q' to quote them.
+;;
+;;    `?'   - see also
+;;            (@file :file-name "icicles-doc1.el" :to "What About Special-Character Conflicts?")
+;;
+;;    `SPC' (space)
+;;
+;;    `C-j' (newline) - see also `C-o', above, and
+;;                      (@> "Multi-Completions")
+;;
+;;  The following minibuffer bindings are made to clear minibuffer
+;;  input, making them handy for editing and removing completions
+;;  (e.g. default or initial values) in the minibuffer.
+;;
+;;    `M-k' - `icicle-erase-minibuffer-or-history-element'
+;;    `M-S-backspace', `M-S-delete' - `icicle-erase-minibuffer'
+;;
+;;  `M-k' has an alternative behavior when you are cycling minibuffer
+;;  history items: it deletes the current item from the history.
+;;
+;;  The following key is bound during completion to control the
+;;  display of thumbnail images in `*Completions*' for candidates that
+;;  name image files.  It cycles the value of option
+;;  `icicle-image-files-in-Completions' to show images and names (the
+;;  default), show only names, or show only images.
+;;
+;;    `C-x t'         - `icicle-cycle-image-file-thumbnail'
+;;
+;;  During (absolute or relative) file-name completion, the following
+;;  minibuffer bindings are also in effect:
+;;
+;;    `C-backspace'   - `icicle-up-directory':
+;;                      Navigate up the directory hierarchy.
+;;    `C-c +'         - `icicle-make-directory': Create a directory.
+;;    `C-x m'         - `icicle-bookmark-file-other-window':
+;;                      Visit a file or directory (Dired) bookmark.
+;;                      See also
+;;  (@file :file-name "icicles-doc1.el" :to "Accessing Saved Locations (Bookmarks) on the Fly").
+;;                      (Available only if you use `bookmark+.el'.)
+;;
+;;  During absolute file-name completion, you can use `C-c C-d' to
+;;  change the current directory on the fly (think UNIX command `cd').
+;;  See also
+;;  (@file :file-name "icicles-doc1.el" :to "Absolute File Names and Different Directories").
+;;
+;;  During buffer-name completion, the following minibuffer bindings
+;;  are also in effect:
+;;
+;;    `C-x m'         - `icicle-bookmark-non-file-other-window':
+;;                      Visit a buffer (non-file) bookmark.  See also
+;;  (@file :file-name "icicles-doc1.el" :to "Accessing Saved Locations (Bookmarks) on the Fly").
+;;                      (Available only if you use `bookmark+.el'.)
+;;
+;;    `C-x M'         - `icicle-filter-buffer-cands-for-mode':
+;;                      Filter the buffer candidate to keep only those
+;;                      in a given major mode (you are prompted for
+;;                      the mode).
+;;
+;;  The following minibuffer binding moves the cursor to the start of
+;;  the part of your input, if any, that is highlighted because it
+;;  does not match any completion candidate (see option
+;;  `icicle-highlight-input-completion-failure').  Repeating this
+;;  command kills the rest of the line, removing the highlighted
+;;  mismatched input.
+;;
+;;    `C-M-l'         - `icicle-goto/kill-failed-input'
+;;
+;;  The remaining input matches at least one candidate.
+;;
+;;  The following minibuffer bindings can be used to get rid of a
+;;  completion inserted during cycling, and retrieve what you last
+;;  typed during completion or any previous completion inputs:
+;;
+;;    `C-l'           - `icicle-retrieve-previous-input'
+;;    `C-S-l' (`C-L') - `icicle-retrieve-next-input'
+;;
+;;  You can use these to cycle among and reuse inputs that you typed
+;;  during completion but did not enter.  This completion input is not
+;;  recorded in the standard input histories - they record only input
+;;  that you have entered with `RET'.
+;;  See (@file :file-name "icicles-doc1.el" :to "History Enhancements").
+;;
+;;  For example, suppose that you used `C-h v hook' to examine various
+;;  hook variables, and you did this using`C-next' to display their
+;;  documentation.  If you finished the command by just typing `C-g',
+;;  then your input (`hook') was never really entered, so it is not
+;;  available via the minibuffer history (`M-p').  You can retrieve it
+;;  with `C-l', to use it again, in your next command.  User option
+;;  `icicle-C-l-uses-completion-flag' controls the behavior of `C-l'
+;;  and `C-L'; if non-`nil', then, instead of cycling inputs, these
+;;  commands let you access previous inputs using completion.
+;;
+;;  You of course have the standard access to the minibuffer history,
+;;  via `M-p', `M-n', `M-r', and `M-s'.  In addition to these, the
+;;  following minibuffer bindings let you use apropos completion on
+;;  the current minibuffer history list.  For explanation, see
+;;  (@file :file-name "icicles-doc1.el" :to "History Enhancements").
+;;
+;;    `M-h'     - `icicle-history'
+;;    `M-pause' - `icicle-keep-only-past-inputs'
+;;
+;;  Minibuffer binding `C-M-pause' lets you use a different minibuffer
+;;  history during the current input reading with completion.
+;;  Normally, you are prompted for the history to use.  Starting with
+;;  Emacs 23, if option `icicle-populate-interactive-history-flag' is
+;;  non-`nil', then during command, abbrev, and keyboard-macro
+;;  completion, `C-M-pause' completes your input against the history
+;;  of all commands that were invoked interactively in any way,
+;;  `icicle-interactive-history'.
+;;
+;;  The following minibuffer bindings let you act on candidate
+;;  completions.  For explanation, see
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands"),
+;;  (@file :file-name "icicles-doc1.el" :to "More about Multi-Commands"),
+;;  (@file :file-name "icicles-doc1.el" :to "Choose All Completion Candidates"),
+;;  and (@> "OO: Object-Action Interaction").
+;;
+;;    `C-RET'     - `icicle-candidate-action': current candidate
+;;    `C-mouse-2' - `icicle-mouse-candidate-action': clicked candidate
+;;    `C-down', `C-wheel-down'
+;;                - `icicle-next-candidate-per-mode-action' (modal)
+;;    `C-up', `C-wheel-up'
+;;                - `icicle-previous-candidate-per-mode-action'(modal)
+;;    `C-next'    - `icicle-next-apropos-candidate-action'
+;;    `C-prior'   - `icicle-previous-apropos-candidate-action'
+;;    `C-end'     - `icicle-next-prefix-candidate-action'
+;;    `C-home'    - `icicle-previous-prefix-candidate-action'
+;;    `C-!'       - `icicle-all-candidates-action': each candidate
+;;    `M-!'       - `icicle-all-candidates-list-action': all, as list
+;;    `M-RET'     - `icicle-candidate-read-fn-invoke': apply function
+;;    `M-mouse-2' - `icicle-mouse-yank-secondary' (in minibuffer)
+;;    `M-mouse-2' - `icicle-mouse-candidate-read-fn-invoke': apply fn
+;;    `S-delete'  - `icicle-delete-candidate-object': delete object
+;;
+;;  (Some of these are only default key bindings.  You can customize
+;;  the keys to use for `previous' and `next' actions, for instance.
+;;  The mouse-wheel bindings are only for Emacs 22 and later.  The
+;;  notation used here for the wheel bindings is that for Emacs on
+;;  Windows; on other platforms different key notations are used for
+;;  the wheel.  This same note applies to corresponding keys used with
+;;  modifiers `C-M-' and `C-S-' - see below.)
+;;
+;;  Except as noted, the bindings for `icicle-mouse-*' are actually in
+;;  the `*Completions*' buffer.
+;;
+;;  The following minibuffer bindings provide help on candidate
+;;  completions.  For explanation, see
+;;  (@file :file-name "icicles-doc1.el" :to "Get Help on Candidates")
+;;  and (@file :file-name "icicles-doc1.el" :to "Multi-Commands").
+;;
+;;    `C-M-RET'   - `icicle-help-on-candidate': current candidate
+;;    `C-M-mouse-2' - `icicle-mouse-help-on-candidate': clicked
+;;    `C-M-down', `C-M-wheel-down'
+;;                - `icicle-next-candidate-per-mode-help' (modal)
+;;    `C-M-up', `C-M-wheel-up'
+;;                - `icicle-previous-candidate-per-mode-help' (modal)
+;;    `C-M-next'  - `icicle-help-on-next-apropos-candidate'
+;;    `C-M-prior' - `icicle-help-on-previous-apropos-candidate'
+;;    `C-M-end'   - `icicle-help-on-next-prefix-candidate'
+;;    `C-M-home'  - `icicle-help-on-previous-prefix-candidate'
+;;
+;;  The following minibuffer bindings provide an alternative action
+;;  for individual candidates.  The alternative action is specific to
+;;  the given command.  Most commands define no alternative action.
+;;
+;;    `C-S-RET'     - `icicle-candidate-alt-action': current candidate
+;;    `C-S-mouse-2' - `icicle-mouse-candidate-alt-action': clicked
+;;    `C-S-down', `C-S-wheel-down'
+;;                  - `icicle-next-candidate-per-mode-alt-action'
+;;                    (modal)
+;;    `C-S-up', `C-S-wheel-up'
+;;                  - `icicle-previous-candidate-per-mode-alt-action'
+;;                    (modal)
+;;    `C-S-next'    - `icicle-next-apropos-candidate-alt-action'
+;;    `C-S-prior'   - `icicle-previous-apropos-candidate-alt-action'
+;;    `C-S-end'     - `icicle-next-prefix-candidate-alt-action'
+;;    `C-S-home'    - `icicle-previous-prefix-candidate-alt-action'
+;;    `C-|'         - `icicle-all-candidates-alt-action': each
+;;    `M-|'         - `icicle-all-candidates-list-alt-action': list
+;;
+;;  The following minibuffer bindings let you perform set operations
+;;  on sets of completion candidates.  For explanation, see
+;;  (@file :file-name "icicles-doc1.el" :to "Sets of Completion Candidates").
+;;
+;;    `C-~'     - `icicle-candidate-set-complement'
+;;    `C--'     - `icicle-candidate-set-difference'
+;;    `C-+'     - `icicle-candidate-set-union'
+;;    `C-*'     - `icicle-candidate-set-intersection'
+;;    `C-M-<'   - `icicle-candidate-set-retrieve': retrieve saved set
+;;    `C-M->'   - `icicle-candidate-set-save': save current set
+;;    `C-M-)'   - `icicle-candidate-set-save-selected': save selected
+;;    `C-<'     - `icicle-candidate-set-retrieve-more': add from saved
+;;    `C->'     - `icicle-candidate-set-save-more': add to saved set
+;;    `C-)'     - `icicle-candidate-set-save-more-selected': selected
+;;    `insert'  - `icicle-save/unsave-candidate': save current cand
+;;    `C-%'     - `icicle-candidate-set-swap': swap saved and current
+;;    `C-:'     - `icicle-candidate-set-define': define current (Lisp)
+;;    `M-S-mouse-2' - `icicle-mouse-save/unsave-candidate': (un)save
+;;    `M-S-mouse-3' - `icicle-mouse-candidate-set-save': save selected
+;;    `M-mouse-3'   - `icicle-mouse-candidate-set-save-more'
+;;
+;;  The following minibuffer bindings insert text in the minibuffer.
+;;
+;;    `M-.'     - `icicle-insert-string-at-point'
+;;    `C-='     - `icicle-insert-string-from-variable'
+;;    `M-:'     - `icicle-pp-eval-expression-in-minibuffer'
+;;                (with a prefix arg)
+;;
+;;  The following minibuffer bindings let you toggle Icicles options
+;;  or cycle among alternative Icicles behaviors.
+;;
+;;    `C-A' (that is, `C-S-a') - `icicle-toggle-case-sensitivity'
+;;    `C-.'     - `icicle-toggle-ignored-extensions' (file completion)
+;;    `C-.'     - `icicle-toggle-search-cleanup' (search)
+;;    `C-M-.'   - `icicle-toggle-dot'
+;;    `C-x .'   - `icicle-toggle-hiding-common-match'
+;;    `C-;'     - `icicle-toggle-expand-to-common-match'
+;;    `M-;'     - `icicle-toggle-search-replace-common-match'
+;;    `C-M-;'   - `icicle-toggle-icicle-toggle-ignoring-comments'
+;;    `C-,'     - `icicle-change-sort-order'
+;;    `M-,'     - `icicle-change-alternative-sort-order'
+;;    `C-M-,'   - `icicle-toggle-alternative-sorting'
+;;    `C-^'     - `icicle-toggle-remote-file-testing'
+;;    `C-^'     - `icicle-toggle-highlight-all-current' (search)
+;;    `C-#'     - `icicle-toggle-incremental-completion'
+;;    `C-('     - `icicle-next-TAB-completion-method'
+;;    `C-`'     - `icicle-toggle-regexp-quote'
+;;    `C-M-`'   - `icicle-toggle-literal-replacement' (search)
+;;    `C-$'     - `icicle-toggle-transforming' (removal of duplicates)
+;;    `C-pause' - `icicle-toggle-highlight-historical-candidates'
+;;    `S-pause' - `icicle-toggle-highlight-saved-candidates'
+;;    `M-g'     - `icicle-toggle-C-for-actions'
+;;    `M-q'     - `icicle-toggle-search-whole-word' (search)
+;;    `M-('     - `icicle-next-S-TAB-completion-method'
+;;    `M-~'     - `icicle-toggle-~-for-home-dir'
+;;    `M-_'     - `icicle-toggle-ignored-space-prefix'
+;;    `M-_'     - `icicle-toggle-search-replace-whole' (search)
+;;    `C-M-_'   - `icicle-toggle-proxy-candidates'
+;;
+;;  The following minibuffer bindings let you incrementally change
+;;  options that affect the `*Completions*' display columns and text
+;;  size.  To take advantage of these, you must also use Do Re Mi
+;;  (libraries `doremi.el' and `doremi-frm.el').  `C-x -' requires
+;;  Emacs 23 or later.
+;;
+;;    `C-x w'   - `icicle-doremi-candidate-width-factor+'
+;;    `C-x |'   - `icicle-doremi-inter-candidates-min-spaces+'
+;;    `C-x -'   - `icicle-doremi-zoom-Completions+'
+;;    `C-x #'   - increment/decrement option `icicle-max-candidates'
+;;
+;;  When used in the minibuffer, the following Icicles global binding
+;;  lets you remove the `*Completions*' window.
+;;
+;;    `C-x 0'   - `icicle-delete-window'
+;;
+;;  The following minibuffer bindings are in effect during Icicles
+;;  search:
+;;
+;;    `C-.'     - `icicle-toggle-search-cleanup'
+;;    `C-,'     - `icicle-change-sort-order'
+;;    `M-_'     - `icicle-toggle-search-replace-whole'
+;;    `M-,'     - `icicle-search-define-replacement'
+;;    `M-;'     - `icicle-toggle-search-replace-common-match'
+;;    `M-q'     - `icicle-toggle-search-whole-word'
+;;    `C-^'     - `icicle-toggle-highlight-all-current'
+;;    `C-M-`'   - `icicle-toggle-literal-replacement'
+;;
+;;  The following minibuffer binding lets you evaluate an Emacs-Lisp
+;;  sexp at any time, using a recursive minibuffer.  It displays the
+;;  result of evaluation in the echo area or in a pop-up buffer, `*Pp
+;;  Eval Output*'.  With a prefix arg (`C-u M-:'), it inserts the
+;;  result into the minibuffer at point.
+;;
+;;    `M-:'     - `icicle-pp-eval-expression-in-minibuffer'
+;;
+;;  Some additional bindings are made available in the minibuffer for
+;;  the duration of specific commands:
+;;
+;;  * During completion of names of some kinds of objects (files,
+;;    buffers, directories, Info nodes), `C-x m' lets you complete
+;;    against bookmarks that have the same type as those objects (file
+;;    bookmarks, buffer bookmarks, Dired bookmarks, Info bookmarks).
+;;    This feature requires use of package Bookmark+.
+;;
+;;  * During completion of file names, `C-backspace' is bound to
+;;    `icicle-up-directory', which navigates to the parent directory
+;;    and completes there instead.
+;;
+;;  * During completion of bookmark names, various keys with the
+;;    prefix `C-M-' are bound to commands that narrow the available
+;;    candidates to bookmarks of a specific type.  For example,
+;;    `C-M-d' narrows the choices to Dired bookmarks.
+;;
+;;  The following bindings are made for `completion-list-mode', that
+;;  is, for buffer `*Completions*', which shows the list of candidate
+;;  completions:
+;;
+;;    `left', `right' (`TAB')
+;;                    - `icicle-move-to-previous-completion',
+;;                      `icicle-move-to-next-completion': Navigate
+;;                      backward & forward among candidates
+;;    `up', `down'    - `icicle-previous-line', `icicle-next-line':
+;;                      Navigate up & down among candidates
+;;    `C-insert'      - `icicle-insert-completion': Move cursor to the
+;;                      minibuffer, with the current `*Completions*'
+;;                      candidate as input
+;;    `C-a', `C-e'    - `icicle-beginning-of-line+',
+;;                      `icicle-end-of-line+' (repeatable)
+;;    `C-g', `q'      - `icicle-abort-recursive-edit'
+;;    `mouse-2'       - `icicle-mouse-choose-completion'
+;;    `C-mouse-2'     - `icicle-mouse-candidate-action'
+;;    `M-mouse-2'     - `icicle-mouse-candidate-read-fn-invoke'
+;;    `C-M-mouse-2'   - `icicle-mouse-help-on-candidate'
+;;    `M-S-mouse-2'   - `icicle-mouse-save/unsave-candidate'
+;;    `C-mouse-3'     - `icicle-Completions-mouse-3-menu'
+;;    `M-mouse-3'     - `icicle-mouse-candidate-set-save-more'
+;;    `M-S-mouse-3'   - `icicle-mouse-candidate-set-save'
+;;    `wheel-down'    - `icicle-scroll-Completions-backward'
+;;    `wheel-up'      - `icicle-scroll-Completions-forward'
+ 
+;;(@* "Customizing Key Bindings")
+;;
+;;  Customizing Key Bindings
+;;  ------------------------
+;;
+;;  See (@> "Key Bindings") for a description of the key bindings
+;;  defined by Icicles.  The options mentioned here are also presented
+;;  there, in context.  You can customize all of the key-binding user
+;;  options with `M-x customize-group RET Icicles-Key-Bindings'.
+;;
+;;  Key bindings are very personal choices, and reflect preferences
+;;  and habits, as well as keyboard and other configurations.  You
+;;  might want to change some of the bindings that Icicles creates.
+;;  This section tells you how to do that.
+;;
+;;  However, before doing so, unless the default bindings present a
+;;  hardware or OS configuration problem for you, please try using the
+;;  default bindings for a while, before deciding that you want to
+;;  change them.  Habit is a powerful persuader, but its advice is not
+;;  always the best ;-).
+;;
+;;  The main user option for customizing key bindings is
+;;  `icicle-top-level-key-bindings'.  You use it to change or remove
+;;  any of the top-level bindings in Icicle mode.
+;;
+;;  There are some other user options that make it easy to customize
+;;  Icicles key bindings.  Most of these are minibuffer bindings.
+;;
+;;  * `icicle-modal-cycle-down-keys'            (`down', `wheel-down')
+;;    Cycle to the next candidate (modal).
+;;  * `icicle-modal-cycle-up-keys'                  (`up', `wheel-up')
+;;    Cycle to the previous candidate (modal).
+;;  * `icicle-apropos-cycle-next-keys'                        (`next')
+;;    Cycle to the next apropos-completion candidate.
+;;  * `icicle-apropos-cycle-previous-keys'                   (`prior')
+;;    Cycle to the previous apropos-completion candidate.
+;;  * `icicle-prefix-cycle-next-keys'                          (`end')
+;;    Cycle to the next prefix-completion candidate.
+;;  * `icicle-prefix-cycle-previous-keys'                     (`home')
+;;    Cycle to the previous prefix-completion candidate.
+;;  * `icicle-modal-cycle-down-action-keys'  (`C-down', `C-wheel-down)
+;;    Cycle to next candidate and act on it (modal).
+;;  * `icicle-modal-cycle-up-action-keys'        (`C-up', `C-wheel-up)
+;;    Cycle to previous candidate and act on it (modal).
+;;  * `icicle-apropos-cycle-next-action-keys'               (`C-next')
+;;    Cycle to next apropos-completion candidate and act on it.
+;;  * `icicle-apropos-cycle-previous-action-keys'          (`C-prior')
+;;    Cycle to previous apropos-completion candidate and act on it.
+;;  * `icicle-prefix-cycle-next-action-keys'                 (`C-end')
+;;    Cycle to next prefix-completion candidate and act on it.
+;;  * `icicle-prefix-cycle-previous-action-keys'            (`C-home')
+;;    Cycle to previous prefix-completion candidate and act on it.
+;;  * `icicle-modal-cycle-down-alt-action-keys'           (`C-S-down')
+;;    Cycle to next candidate and alternative-act on it (modal).
+;;  * `icicle-modal-cycle-up-alt-action-keys'               (`C-S-up')
+;;    Cycle to previous candidate and alternative-act on it (modal).
+;;  * `icicle-apropos-cycle-next-alt-action-keys'         (`C-S-next')
+;;    Cycle to next apropos-completion candidate and alternative-act
+;;    on it.
+;;  * `icicle-apropos-cycle-previous-alt-action-keys'    (`C-S-prior')
+;;    Cycle to previous apropos-completion candidate and
+;;    alternative-act on it.
+;;  * `icicle-prefix-cycle-next-alt-action-keys'           (`C-S-end')
+;;    Cycle to next prefix-completion candidate and alternative-act
+;;    on it.
+;;  * `icicle-prefix-cycle-previous-alt-action-keys'      (`C-S-home')
+;;    Cycle to previous prefix-completion candidate and
+;;    alternative-act on it.
+;;  * `icicle-modal-cycle-down-help-keys'                 (`C-M-down')
+;;    Cycle to next candidate and show help for it (modal).
+;;  * `icicle-modal-cycle-up-help-keys'                     (`C-M-up')
+;;    Cycle to previous candidate and show help for it (modal).
+;;  * `icicle-apropos-cycle-next-help-keys'               (`C-M-next')
+;;    Cycle to next apropos-completion candidate and show help for it.
+;;  * `icicle-apropos-cycle-previous-help-keys'          (`C-M-prior')
+;;    Cycle to previous apropos-completion candidate and show help.
+;;  * `icicle-prefix-cycle-next-help-keys'                 (`C-M-end')
+;;    Cycle to next prefix-completion candidate and show help for it.
+;;  * `icicle-prefix-cycle-previous-help-keys'            (`C-M-home')
+;;    Cycle to previous prefix-completion candidate and show help.
+;;  * `icicle-prefix-complete-keys'                            (`TAB')
+;;    Prefix-complete your input.
+;;  * `icicle-apropos-complete-keys'                         (`S-TAB')
+;;    Apropos-complete your input.
+;;  * `icicle-prefix-complete-no-display-keys'             (`C-M-TAB')
+;;    Prefix-complete without showing `*Completions*'.
+;;  * `icicle-apropos-complete-no-display-keys'          (`C-M-S-TAB')
+;;    Apropos-complete without showing `*Completions*'.
+;;  * `icicle-word-completion-keys'                          (`M-SPC')
+;;    Prefix-complete your input a word at a time.
+;;  * `icicle-key-complete-keys'                             (`S-TAB')
+;;    Complete key sequences.
+;;  * `icicle-previous-candidate-keys'                       (`S-TAB')
+;;    Move to the previous candidate in `*Completions*'.
+;;  * `icicle-completing-read+insert-keys'                 (`C-M-S-c')
+;;    Completion on demand.
+;;  * `icicle-read+insert-file-name-keys'                  (`C-M-S-f')
+;;    Completion on demand for file names.
+;;  * `icicle-search-from-isearch-keys'                      (`S-TAB')
+;;    Start `icicle-search' from Isearch.
+;;  * `icicle-isearch-complete-keys'       (`M-TAB', `C-M-TAB', `M-o')
+;;    Complete incremental search string using search ring.
+;;
+;;  These are the main kinds of Icicles key bindings:
+;;
+;;  * Global bindings
+;;    . Additions to menu-bar menus
+;;    . Key completion keys (`S-TAB' by default)
+;;  * Icicle mode bindings
+;;  * Minibuffer bindings
+;;
+;;(@* "Customizing Global Bindings")
+;;  ** Customizing Global Bindings **
+;;
+;;  Icicles normally adds items to appropriate existing menu-bar
+;;  menus, such as File and Options, as well as to menu-bar menus
+;;  Minibuf and Icicles.  These items are placed in an Icicles submenu
+;;  (e.g. Files > Icicles).  If you do not want to add an Icicles
+;;  submenu, then set option `icicle-touche-pas-aux-menus-flag' to
+;;  non-`nil' before loading Icicles.  The menu items are then added
+;;  to the Icicles menu.
+;;
+;;  Icicles binds key completion (`icicle-complete-keys') to the keys
+;;  defined in option `icicle-key-complete-keys'.  See
+;;  (@> "Key Bindings") for more information about this.
+;;
+;;(@* "Customizing Icicle Mode Bindings")
+;;  ** Customizing Icicle Mode Bindings **
+;;
+;;  In the Icicle mode keymap, several top-level commands are bound by
+;;  default.  You can use option `icicle-top-level-key-bindings' to
+;;  customize the keys that are used for these commands, or to remove
+;;  any such bindings.
+;;
+;;(@* "Customizing Minibuffer Bindings")
+;;  ** Customizing Minibuffer Bindings **
+;;
+;;  There are user options for most Icicles minibuffer bindings that
+;;  you might want to change - see above for the list.  This section
+;;  tells you how to change additional bindings.
+;;
+;;  To understand how you can modify Icicles minibuffer bindings, it
+;;  helps to know how Icicles creates the default bindings.  For that,
+;;  the best advice is to consult the Emacs-Lisp code in library
+;;  `icicle-mode.el'.  Even if you are not very familiar with
+;;  Emacs-Lisp, however, you should be able to do what you want by
+;;  adapting the example in this section.
+;;
+;;  Suppose that you want to bind `f11' and `f12' to traverse the
+;;  input history up and down whenever you are in Icicle mode.  There
+;;  are no user options for this, but you can do it by inserting this
+;;  code into your init file (~/.emacs), before the code that requires
+;;  (loads) library `icicles.el':
+;;
+;;  (add-hook 'icicle-mode-hook 'bind-my-icicles-keys)
+;;  (defun bind-my-icicles-keys ()
+;;    "Replace some default Icicles minibuffer bindings with others."
+;;    (dolist
+;;        (map
+;;          (append
+;;           (list minibuffer-local-completion-map
+;;                 minibuffer-local-must-match-map)
+;;           (and (fboundp
+;;                 'minibuffer-local-filename-completion-map)
+;;                (list minibuffer-local-filename-completion-map))))
+;;      (when icicle-mode
+;;        (define-key map [f11] 'previous-history-element)
+;;        (define-key map [f12] 'next-history-element))))
+;;
+;;  See Also:
+;;
+;;  * (@> "Key Bindings")
+;;  * (@> "Customization and General Tips") for information
+;;    about other customizations, besides key bindings.
+ 
+;;(@* "Icicles Redefines Some Standard Functions")
+;;
+;;  Icicles Redefines Some Standard Functions
+;;  -----------------------------------------
+;;
+;;  User option `icicle-functions-to-redefine' is a list of functions
+;;  (typically commands) that are automatically redefined in Icicle
+;;  mode to enhance them for Icicles completion.  The original
+;;  definitions are restored when you exit Icicle mode.  The default
+;;  value of `icicle-functions-to-redefine' contains the following
+;;  functions:
+;;
+;;    `bbdb-complete-name' (from BBDB), `comint-dynamic-complete',
+;;    `comint-dynamic-complete-filename',
+;;    `comint-replace-by-expanded-filename', `customize-apropos',
+;;    `customize-apropos-faces', `customize-apropos-groups',
+;;    `customize-apropos-options', `customize-apropos-options-of-type'
+;;    (from `cus-edit+.el'), `customize-face',
+;;    `customize-face-other-window', `dabbrev-completion',
+;;    `dired-read-shell-command', `ess-complete-object-name' (from
+;;    ESS), `gud-gdb-complete-command', `lisp-complete-symbol',
+;;    `lisp-completion-at-point',
+;;    `minibuffer-default-add-completions', `read-color',
+;;    `read-from-minibuffer', `read-shell-command', `read-string',
+;;    `recentf-make-menu-items', `repeat-complex-command'.
+;;
+;;  Icicles unconditionally redefines these standard Emacs functions
+;;  while in Icicle mode:
+;;
+;;    `choose-completion', `choose-completion-string',
+;;    `completing-read', `completing-read-multiple',
+;;    `completion-setup-function', `dired-smart-shell-command',
+;;    `display-completion-list', `exit-minibuffer',
+;;    `face-valid-attribute-values', `minibuffer-complete-and-exit',
+;;    `mouse-choose-completion', `next-history-element',
+;;    `read-face-name', `read-file-name', `read-number',
+;;    `shell-command', `shell-command-on-region', `sit-for',
+;;    `switch-to-completions'.
+;;
+;;  When you exit Icicle mode, the standard definitions are restored.
+ 
+;;(@* "Programming with Fancy Candidates")
+;;
+;;  Programming with Fancy Candidates
+;;  ---------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  Icicles lets you program with several kinds of candidates that are
+;;  not supported by vanilla Emacs.  For lack of a better word, I call
+;;  them all "fancy candidates".  Multi-completions are fancy
+;;  candidates.  So are ordinary string candidates that have text
+;;  properties such as `face'.  And there are other kinds of fancy
+;;  candidates.
+;;
+;;  Because they are not supported by vanilla Emacs, and because
+;;  Icicles uses Emacs functions such as `all-completions' to perform
+;;  the primitive completion operations, fancy candidates require some
+;;  extra processing.
+;;
+;;  All fancy candidates must first be converted to a form that such
+;;  primitives can understand.  During completion, fancy candidates
+;;  must sometimes be displayed specially, for example using
+;;  particular faces.  And after completion, the completion result
+;;  must sometimes be converted back again to retrieve some or all of
+;;  the original candidate information.
+;;
+;;  This conversion (encoding and decoding) can be costly, especially
+;;  when there are many candidates.  For this reason, it is turned
+;;  off, by default, so it that does not represent overhead during
+;;  completion of non-fancy candidates.
+;;
+;;  In order to use `completing-read' with fancy candidates, you must
+;;  do one of the following in your code:
+;;
+;;  1. Propertize at least the first character of the
+;;     `completing-read' PROMPT argument string with a non-`nil' text
+;;     property `icicle-fancy-candidates'.  This turns on processing
+;;     of fancy candidates for the duration of the `completing-read'
+;;     call.
+;;
+;;  2. Bind variable `icicle-fancy-candidates-p' to non-`nil'.
+;;
+;;  3. Bind variable `icicle-whole-candidate-as-text-prop-p' to
+;;     non-`nil'.
+;;
+;;  You use method 1 or 2 to handle multi-completion candidates or
+;;  candidates that have text properties or are otherwise to be
+;;  displayed specially.  I recommend that you generally use text
+;;  property `icicle-fancy-candidates', not variable
+;;  `icicle-fancy-candidates-p'.  The variable is provided so that you
+;;  can widen the scope of this feature beyond a given call to
+;;  `completing-read'.  You will need to do that only rarely.
+;;
+;;  A use case for variable `icicle-fancy-candidates-p' would be, for
+;;  instance, if your code calls other code that calls
+;;  `completing-read', so you have no direct access to the
+;;  `completing-read' PROMPT argument in order to propertize it.  If
+;;  you nevertheless want to use some fancy candidates, then you can
+;;  bind `icicle-fancy-candidates-p' with the scope you want.
+;;
+;;  You use method 3, `icicle-whole-candidate-as-text-prop-p', when
+;;  you need to save and later retrieve all of the information
+;;  contained in an alist COLLECTION entry.  Completion returns only a
+;;  string.  If the COLLECTION alist has only one entry with a given
+;;  string as its car, then you can simply use `assoc' to retrieve the
+;;  whole entry.
+;;
+;;  But if you use an alist that allows entries with different cdrs
+;;  for the same car, then you need some way to encode an entire alist
+;;  entry in a display string.  When you have this need, set variable
+;;  `icicle-candidates-alist' to the alist, and bind
+;;  `icicle-whole-candidate-as-text-prop-p' to non-`nil'.
+;;
+;;  This has the effect of encoding, as a text property on the
+;;  candidate display string, the entire corresponding original alist
+;;  entry.  You can then use `icicle-get-alist-candidate' to recover
+;;  that information.
+ 
+;;(@* "Programming Multi-Completions")
+;;
+;;  Programming Multi-Completions
+;;  -----------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  Multi-completions are completion candidates that are composed of
+;;  parts separated by `icicle-list-join-string'.  See
+;;  (@> "Multi-Completions") for information about how users interact
+;;  with multi-completions.
+;;
+;;  Multi-completions are examples of fancy candidates.
+;;  See (@> "Programming with Fancy Candidates").
+;;
+;;  You can define your own Icicles commands that use
+;;  multi-completions.  You can bind `icicle-list-join-string' to any
+;;  string you like, depending on your needs.  See
+;;  (@file :file-name "icicles-doc1.el" :to "Key Completion") for an
+;;  example where it is bound to " = ".  This section describes two
+;;  additional variables that you can bind to affect the appearance
+;;  and behavior of multi-completions.
+;;
+;;(@* "Variable icicle-list-use-nth-parts")
+;;  ** Variable icicle-list-use-nth-parts **
+;;
+;;  Variable `icicle-list-use-nth-parts' affects the minibuffer
+;;  behavior of multi-completions.  If you bind this to a list of
+;;  whole numbers, then multi-completion candidates are transformed
+;;  using those numbers as indexes.  During completion and cycling,
+;;  whenever a sole candidate matches the user input, if that
+;;  candidate is a multi-completion, then it is transformed by
+;;  extracting and possibly reordering its parts according to
+;;  `icicle-list-use-nth-parts'.
+;;
+;;  The actual candidate to match is still the original candidate; the
+;;  transformation takes place after matching, for final insertion in
+;;  the minibuffer.  This means that you must use this feature only
+;;  with lax (permissive) completion, since strict completion requires
+;;  an exact match against the original completion candidate, and the
+;;  transformed candidate will normally not match the original.
+;;
+;;  Variable `icicle-list-use-nth-parts' works as follows.  The
+;;  matching candidate is split at each `icicle-list-join-string' into
+;;  its component parts.  The indexes in `icicle-list-use-nth-parts'
+;;  are then used to extract parts, in the same order as the indexes
+;;  appear.  The extracted parts are joined back together in an order
+;;  that you specify, separated by the value of user option
+;;  `icicle-list-nth-parts-join-string'.  An index greater than the
+;;  number of parts means to use the last part.
+;;
+;;  For example: If the value of `icicle-list-use-nth-parts' is (1),
+;;  then only the first part of the multi-completion is used as the
+;;  completion candidate.  If the value is (2 1), then the resulting
+;;  candidate is the second part followed by the first part, the two
+;;  parts being joined by `icicle-list-nth-parts-join-string'.  If the
+;;  value is (1 99) and the multi-completion has fewer than 99 parts,
+;;  then the first and last parts are used.  If the value is (2 1 2),
+;;  then the resulting candidate is composed of the second part
+;;  followed by the first part followed by the second part again.
+;;
+;;  Thus, you can use a given part any number of times.  You can also
+;;  mix multi-completions and single-string completions, and you can
+;;  mix multi-completions composed of different numbers of strings.
+;;  For example, a set of completions might be:
+;;
+;;  ((("cmd1" "description of cmd1"))
+;;   (("cmd2" "description of cmd" "more"))
+;;   (("cmd3")))
+;;
+;;  If you use multi-completions with `icicle-list-use-nth-parts' in
+;;  your own commands, please make sure that their doc strings let
+;;  users know what to expect, and remind them of the behavior of
+;;  option `icicle-list-nth-parts-join-string'.  Let them know, in
+;;  particular, that:
+;;
+;;  * They can match any part of a candidate as it is displayed in
+;;    buffer `*Completions*'.
+;;
+;;  * The candidate choice they make will in fact have the form that
+;;    you define in your command.
+;;
+;;  * They can control how the parts are joined, using option
+;;    `icicle-list-nth-parts-join-string'.
+;;
+;;(@* "Variable icicle-candidate-properties-alist")
+;;  ** Variable icicle-candidate-properties-alist **
+;;
+;;  Whereas variable `icicle-list-nth-parts-join-string' affects the
+;;  appearance of multi-completions in the minibuffer, variable
+;;  `icicle-candidate-properties-alist' affects their appearance in
+;;  buffer `*Completions*'.  You use it to apply text properties to
+;;  individual parts of a multi-completion, where the parts are
+;;  defined in the same way as for `icicle-list-use-nth-parts'.
+;;
+;;  This feature affects all candidates the same way.  See also
+;;  (@> "Candidates with Text Properties") for ways to apply text
+;;  properties to individual candidates (which need not be
+;;  multi-completions).
+;;
+;;  The value of `icicle-candidate-properties-alist' is an alist whose
+;;  entries have either of these forms:
+;;
+;;  (NTH PROPERTIES) or (NTH PROPERTIES JOIN-TOO)
+;;
+;;  NTH is the number of the target multi-completion part.
+;;
+;;  PROPERTIES is a list of text properties to apply to the NTH part.
+;;
+;;  JOIN-TOO is optional.  If it is present and non-`nil', then the
+;;  text properties are also applied to the join string that follows
+;;  the target part.
+;;
+;;  You can use any text properties, including `invisible', `keymap',
+;;  `display', and properties that you define yourself and that have
+;;  meaning to only your code.
+;;
+;;  As an example of its use, commands `icicle-fundoc',
+;;  `icicle-vardoc', `icicle-doc', and `icicle-plist' bind
+;;  `icicle-candidate-properties-alist' to
+;;  ((1 (face 'icicle-candidate-part))), so that the first part of
+;;  each multi-completion candidate is highlighted using face
+;;  `icicle-candidate-part'.
+;;
+;;  Here is another example value of
+;;  `icicle-candidate-properties-alist':
+;;
+;;  ((3 (face 'underline))
+;;   (2 (invisible t) t))
+;;
+;;  The first entry underlines the third multi-completion part.  The
+;;  second entry makes both the second part and the join string that
+;;  follows it invisible.
+;;
+;;  One use of making a completion part invisible is so that you can
+;;  sort candidates using it, and let users match input against it,
+;;  but not have it appear explicitly.
+;;
+;;  Recall that `completing-read' displays only the car of each
+;;  element present in its COLLECTION (alist) argument.  For example,
+;;  if you pass `completing-read' an alist such as (("foo" . 2) ("bar"
+;;  . 3)), then only `foo' and `bar' are displayed as candidates.
+;;  However, the PREDICATE argument to `completing-read' applies to
+;;  the entire alist element, and your command that calls
+;;  `completing-read' might well use the chosen candidate (e.g. `foo')
+;;  to look up the entire element (e.g. ("foo" . 2)) for further
+;;  processing.  Several Icicles commands, including `icicle-search',
+;;  do that.
+;;
+;;  However, sometimes you might want the user to be able to match
+;;  against the additional information (e.g. 2 and 3), and you might
+;;  want to use it to sort candidates.  In that case, you can use the
+;;  alist (("foo 2") ("bar 3")).  In cases where the additional
+;;  information can be distracting, you can use multi-completion with
+;;  `icicle-candidate-properties-alist' to hide it: Pass the alist
+;;  ((("foo "2")) (("bar" 3"))) and use ((2 (invisible t))) for
+;;  `icicle-candidate-properties-alist'.
+;;
+;;  Keep in mind that hiding completion parts can be confusing to
+;;  users.  Do so with care, and let your users know what to expect.
+;;  Inform them that there are invisible parts that are nevertheless
+;;  taken into account for input matching and candidate sorting.  When
+;;  you hide parts, you will often want to omit them from the
+;;  minibuffer as well, using `icicle-list-use-nth-parts', to avoid
+;;  confusion.
+;;
+;;  Consider also the position of a hidden part: In some cases you
+;;  might want to place it first among the multi-completion parts, but
+;;  in many cases you will want to place it last, to minimize
+;;  interference with prefix-completion matching.
+;;
+;;  Similar considerations apply to other text properties, such as
+;;  `display' and `keymap', that change the appearance or behavior of
+;;  a completion candidate.
+;;
+;;(@* "What You See Is Not What You Get")
+;;  ** What You See Is Not What You Get **
+;;
+;;  While on the subject of confusing users, let me point out a
+;;  general drawback that is common to both
+;;  `icicle-list-use-nth-parts' and
+;;  `icicle-candidate-properties-alist': *not* WYSIWYG.  Keep this in
+;;  mind if you decide to take advantage of these variables.  Users
+;;  see one thing, choose it, and they get something different as a
+;;  result.  That promotes confusion that you will need to weigh
+;;  against the possible benefits.
+;;
+;;  Users are confused, because what they choose is not exactly what
+;;  they get.  What's more, a user's completion choice is not
+;;  reflected in the input history, leading to further confusion.  For
+;;  example, Icicles highlighting of previously used inputs in buffer
+;;  `*Completions*' does not apply to such a candidate, even though it
+;;  was previously entered using `RET'.  It is the transformed
+;;  candidate that was entered, not the candidate as it was proposed
+;;  for choosing, so when that candidate is proposed again, it is not
+;;  recognized as having been previously chosen.
+;;
+;;  The bottom line here is this: variables
+;;  `icicle-list-use-nth-parts' and
+;;  `icicle-candidate-properties-alist' are useful in certain
+;;  contexts, but be aware of the downside: confusing your users.
+;;
+;;  See Also:
+;;
+;;  * (@> "Multi-Completions")
+;;  * (@> "Programming with Fancy Candidates")
+;;  * (@> "Candidates with Text Properties")
+ 
+;;(@* "Candidates with Text Properties")
+;;
+;;  Candidates with Text Properties
+;;  -------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  Section (@> "Programming Multi-Completions") explains how to apply
+;;  text properties to specific parts of all multi-completion
+;;  candidates in buffer `*Completions*' at the same time.  This
+;;  section tells you how to apply text properties to specific
+;;  candidates in `*Completions*'.  The candidates need not be
+;;  multi-completions, but in some cases they can be.
+;;
+;;  When you use candidates with text properties such as `face' that
+;;  are visible, the display candidates in `*Completions*' show those
+;;  properties.  In addition, the candidate string that the user
+;;  finally chooses can also be propertized.
+;;
+;;  There are four different methods for providing candidates with
+;;  text properties, in addition to the way presented in section
+;;  (@> "Programming Multi-Completions"):
+;;
+;;  1. Apply face `icicle-special-candidate' to all candidates that
+;;     match a given regexp.
+;;
+;;  2. Use a set of text properties as the `icicle-special-candidate'
+;;     property of the symbol that represents the candidate.  The text
+;;     properties are transferred to the string candidate that is
+;;     displayed (and returned).
+;;
+;;  3. Use a propertized string as the `icicle-display-string'
+;;     property of the symbol that represents the candidate.  That
+;;     string replaces the candidate that would otherwise have been
+;;     displayed, completed against, and returned.
+;;
+;;  4. Start with a propertized string in the COLLECTION argument
+;;     that you pass to `completing-read'.
+;;
+;;  All four methods use fancy candidates, in the sense that they go
+;;  beyond what vanilla Emacs offers.  For methods 1-3, you must turn
+;;  on fancy-candidate handling.  See
+;;  (@> "Programming with Fancy Candidates").
+;;
+;;  But method 4 does not require any costly fancy-candidate encoding
+;;  or decoding, because the Icicles implementation of
+;;  `completing-read' handles propertized string candidates, and they
+;;  are transparent to the Emacs primitive completion operations.
+;;
+;;  The following sections explain methods 1-4 individually.
+;;
+;;(@* "Using Regexp `icicle-special-candidate-regexp'")
+;;  ** Using Regexp `icicle-special-candidate-regexp' **
+;;
+;;  If you just want several candidates to have face
+;;  `icicle-special-candidate' in `*Completions', you can simply
+;;  define (e.g. bind) option `icicle-special-candidate-regexp' to a
+;;  regexp that matches those candidates.  The original candidates can
+;;  be strings or symbols.  Unlike the other methods described here,
+;;  this one affects only the display in `*Completions'; the
+;;  completion return string does not have face
+;;  `icicle-special-candidate'.
+;;
+;;  The highlighting applies only to the part of a candidate that
+;;  matches the regexp.  This selectivity is particularly useful when
+;;  dealing with multi-completions.  Function `icicle-read-file-name'
+;;  provides an example: file names that match ".+/$", that is,
+;;  directory names, are highlighted as special candidates.  Function
+;;  `icicle-read-color' provides another example (using the similar,
+;;  but internal, variable `icicle-proxy-candidate-regexp'): proxy
+;;  color-name candidates such as `*point foreground*' and
+;;  `'icicle-region-background'' are highlighted, but not their color
+;;  swatches.
+;;
+;;(@* "Using Property icicle-special-candidate")
+;;  ** Using Property icicle-special-candidate **
+;;
+;;  In this approach, you use the desired list of text properties as
+;;  the value of property `icicle-special-candidate' for the symbol
+;;  that represents the candidate.  This method affects the candidates
+;;  that are used during completion, as well as the completion return
+;;  value.
+;;
+;;  If the candidate is a string, not a symbol, then `intern' it and
+;;  put the property on the resulting symbol.  If you want the effect
+;;  to be temporary, then set property `icicle-special-candidate' for
+;;  the candidate to `nil' when completion is finished.
+;;
+;;  As a shortcut, if you use the value `t' instead of a property list
+;;  for property `icicle-special-candidate', then face
+;;  `icicle-special-candidate' will be used as the `face' property of
+;;  the candidate.  Using a value of `t' is thus equivalent to using a
+;;  value of (face icicle-special-candidate).  This approach is used,
+;;  for instance, in the definition of command `icicle-complete-keys'
+;;  (`S-TAB').
+;;
+;;(@* "Using Property `icicle-display-string'")
+;;  ** Using Property `icicle-display-string' **
+;;
+;;  This method is similar to that of using property
+;;  `icicle-special-candidate'.  The use case for both is
+;;  propertizing, in a general way, candidates that are symbols.  Both
+;;  can be useful when you have an obarray as the COLLECTION argument
+;;  for `completing-read'.
+;;
+;;  In this method the symbol name is not used at all; the candidate
+;;  is entirely replaced by another string, which is typically
+;;  propertized.
+;;
+;;  You use a propertized string as the value of property
+;;  `icicle-display-string' for the candidate symbol.  The propertized
+;;  string is displayed in `*Completions*' and returned as the final
+;;  completion choice.
+;;
+;;  Note that multi-completion is not available when you use an
+;;  obarray.  Using property `icicle-special-candidate' or
+;;  `icicle-display-string' you can propertize candidates and parts of
+;;  candidates, but you cannot manipulate multi-completion parts and
+;;  there are no join or end strings.
+;;
+;;(@* "Applying Text Properties to a Candidate String")
+;;  ** Applying Text Properties to a Candidate String **
+;;
+;;  This is the most flexible approach, and it is explained in a bit
+;;  more detail.  It can be used with multi-completions, and it
+;;  affects the `*Completions*' display and the completion return
+;;  value.  However, it is limited to using an alist or list of
+;;  strings, not an obarray, as the COLLECTION argument to
+;;  `completing-read'.
+;;
+;;  In this approach, you simply apply the text properties to the
+;;  string(s) that represent the candidate, which you then pass to
+;;  `completing-read' in its COLLECTION parameter.
+;;
+;;  As with the other methods, you can use any text properties you
+;;  like, including these:
+;;
+;;  * `face' - to make some completion candidates stand out in
+;;    particular ways
+;;
+;;  * `icicle-mode-line-help' - candidate help shown in the mode-line
+;;    when the candidate is current, provided option
+;;    `icicle-help-in-mode-line-delay' is greater than zero (only the
+;;    first character of a candidate string is tested for this text
+;;    property)
+;;
+;;  * `help-echo' - candidate help shown in a mouseover tooltip,
+;;    provided `tooltip-mode' is on
+;;
+;;  * `keymap' and `pointer' - for individualized mouse treatment of
+;;    candidates
+;;
+;;  * `display' - to include images in candidates
+;;
+;;  * `invisible' - to hide part or all of particular candidates
+;;    (which are nevertheless available for completion)
+;;
+;;  As a convenience, you can use function
+;;  `icicle-candidate-short-help' to apply both
+;;  `icicle-mode-line-help' and `help-echo' text properties to a
+;;  candidate string.
+;;
+;;  How does this work?  Icicles redefines the standard Emacs function
+;;  `display-completion-list' so that it retains text properties.
+;;  Emacs should do the same, but it does not (yet).
+;;
+;;  Icicles command `icicle-read-color' presents an illustration,
+;;  using the `face' property.  (It also uses properties
+;;  `icicle-mode-line-help' and `help-echo', to provide RGB and HSV
+;;  information in the mode-line and via tooltip.)
+;;
+;;  In `icicle-read-color', a multi-completion candidate is used,
+;;  composed of an unpropertized string that names a color and a
+;;  propertized string that names its RGB (red, green, blue) value.
+;;  The RGB string, by default, has a background of the same color -
+;;  each completion candidate is thus accompanied by its own color
+;;  swatch.
+;;
+;;  The code that does this is function `icicle-make-color-candidate',
+;;  which is used by `icicle-read-color' and other Icicles commands
+;;  that read colors.  Here is a simplified definition:
+;;
+;;   (defun icicle-make-color-candidate (color-name)
+;;     "Return candidate of COLOR-NAME and its hex RGB string.
+;;   If `icicle-WYSIWYG-Completions-flag' is non-nil, then the hex RGB
+;;   string has the color as its background text property."
+;;     (let ((rgb-string  (hexrgb-color-name-to-hex color-name)))
+;;       (when icicle-WYSIWYG-Completions-flag
+;;         (put-text-property
+;;           0 (length rgb-string) 'face
+;;           (cons 'background-color rgb-string) rgb-string))
+;;       (list (list color-name rgb-string))))
+;;
+;;  You'll notice that the face property is added only when option
+;;  `icicle-WYSIWYG-Completions-flag' is non-`nil'.  You can toggle
+;;  this option at any time during completion to change the behavior.
+;;  (The new value takes effect for the next act of completion.)
+;;
+;;  You can match any part of the multi-completion: color name or RGB
+;;  value.  Command `icicle-read-color' defines a set of sort orders
+;;  that are pertinent to the color candidates.
+;;
+;;  You can use `C-,' to sort by color name, amount of red, blue,
+;;  green, all RGB components (in order), RGB distance from a base
+;;  color, hue, saturation, value, all HSV components (in order), or
+;;  HSV distance from a base color.
+;;
+;;  If option `icicle-add-proxy-candidates-flag' is non-`nil', then
+;;  command `icicle-read-color' includes proxy completion candidates
+;;  that are not color-name-and-RGB pairs.  As always, you can toggle
+;;  the use of proxy candidates using `C-M-_' in the minibuffer.
+;;
+;;  The proxy candidates for colors include the single-quoted names of
+;;  user options (variables) whose custom type is `color'.  So, for
+;;  example, option `icicle-region-background' appears as proxy color
+;;  candidate `'icicle-region-background''. Color proxies also include
+;;  the following:
+;;
+;;  * `*copied foreground*'  - last copied foreground, if available
+;;  * `*copied background*'  - last copied background, if available
+;;  * `*mouse-2 foreground*' - foreground where you click `mouse-2'
+;;  * `*mouse-2 background*' - background where you click `mouse-2'
+;;  * `*point foreground*'   - foreground under the text cursor
+;;  * `*point background*'   - background under the text cursor
+;;
+;;  When you choose a proxy color candidates, the color referred to is
+;;  used.  For example, `*point foreground*' means to use the
+;;  foreground color at the cursor position (point), whatever it might
+;;  be.  Choosing a `mouse-2' candidate lets you then click `mouse-2'
+;;  to pick up a color somewhere.  If you use library `palette.el' or
+;;  `eyedropper.el', and you have already copied a color, then you can
+;;  choose `*copied foreground*' (or background) to use that color.
+;;
+;;  Icicles treats reading face names similarly to reading colors, by
+;;  redefining standard function `read-face-name' when you are in
+;;  Icicle mode.  In this case, multi-completions are not used.  The
+;;  pertinent function is `icicle-make-face-candidate', which provides
+;;  a WYSIWYG face sample whenever `icicle-WYSIWYG-Completions-flag'
+;;  is non-`nil'.
+;;
+;;  A string value for `icicle-WYSIWYG-Completions-flag' presents the
+;;  face name accompanied by that string as a separate sample swatch.
+;;  A value of `t' presents the face name itself in the face it names.
+;;
+;;   (defun icicle-make-face-candidate (face)
+;;     "Return a completion candidate for FACE.
+;;   The value of option `icicle-WYSIWYG-Completions-flag' determines
+;;   the kind of candidate to use.
+;;    If nil, then the face name is used (a string).
+;;
+;;    If a string, then a multi-completion candidate is used, with the
+;;    face name followed by a sample swatch using FACE on the string's
+;;    text.
+;;
+;;    If `t', then the candidate is the face name itself, propertized
+;;    with FACE."
+;;     (if (stringp icicle-WYSIWYG-Completions-flag)
+;;         (let ((swatch  (copy-sequence
+;;                         icicle-WYSIWYG-Completions-flag)))
+;;           (put-text-property
+;;            0 (length icicle-WYSIWYG-Completions-flag)
+;;            'face face swatch)
+;;           (list (list (symbol-name face) swatch)))
+;;       (let ((face-name  (copy-sequence (symbol-name face))))
+;;         (when icicle-WYSIWYG-Completions-flag
+;;           (put-text-property 0 (length face-name)
+;;                              'face face face-name))
+;;         (list face-name))))
+;;
+;;  See Also:
+;;
+;;  * (@> "Programming with Fancy Candidates")
+;;  * (@> "Programming Multi-Completions")
+;;  * (@file :file-name "icicles-doc1.el" :to "Sorting Candidates and Removing Duplicates")
+;;    for information about changing sort orders.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "*Completions* Display") for
+;;    more about proxy candidates.
+ 
+;;(@* "Defining Icicles Commands (Including Multi-Commands)")
+;;
+;;  Defining Icicles Commands (Including Multi-Commands)
+;;  ----------------------------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;(@* "Nothing To It!")
+;;  ** Nothing To It! **
+;;
+;;  Defining a command that uses Icicles completion and cycling is
+;;  simple: just call `completing-read' or `read-file-name' to read
+;;  input, then act on that input.
+;;
+;;  Nothing could be simpler - just use `completing-read'or
+;;  `read-file-name'!  Icicles does the rest.  This is the most
+;;  important thing to learn about defining Icicles commands: you do
+;;  not need to do anything except call `completing-read' or
+;;  `read-file-name' as you would normally anyway.
+;;
+;;  Or at least as I HOPE you would normally.  I fear that many
+;;  Emacs-Lisp programmers do not take sufficient advantage of
+;;  `completing-read' when they could, using instead a function such
+;;  as (quel horreur !)  `read-string' to read user input.
+;;
+;;(@* "Multi-Commands Are Easy To Define Too")
+;;  ** Multi-Commands Are Easy To Define Too **
+;;
+;;  If defining an Icicles command is trivial, so is defining an
+;;  Icicles multi-command.  For the same effort it takes to define a
+;;  command that acts on a single input choice, you can have a command
+;;  that acts on any number of input choices.  A multi-command takes
+;;  advantage of one or more action functions when cycling candidates,
+;;  as described in sections
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands"),
+;;  (@> "More about Multi-Commands"), and
+;;  (@file :file-name "icicles-doc1.el" :to "Choose All Completion Candidates").
+;;
+;;  In fact, there is no reason NOT to define your commands as
+;;  multi-commands - you lose nothing, and you gain a lot.  Whenever
+;;  it is appropriate for a user to possibly want to act on multiple
+;;  objects, define a multi-command that does that.
+;;
+;;  An anecdote, to make the point.  An Icicles user sent me an email
+;;  saying how much he appreciated Icicles multi-commands, and asking
+;;  if I would add a multi-command version of `insert-buffer'.  I did
+;;  so, but I replied to him that the definition is trivial: it is
+;;  identical to the definition of `icicle-buffer', except that the
+;;  action function is `insert-buffer' instead of `switch-to-buffer'.
+;;
+;;  The point is to not be afraid of defining multi-commands yourself.
+;;  You do not really need to have me add a multi-command to Icicles
+;;  in most cases; you can easily define it yourself.  Here is a
+;;  simple definition of `icicle-insert-buffer'.  You will understand
+;;  it in detail after reading the next section.
+;;
+;;   (icicle-define-command icicle-insert-buffer
+;;     "Multi-command version of `insert-buffer'." ; Doc string
+;;     insert-buffer                               ;  Action function
+;;     "Buffer: "                            ; `completing-read' args
+;;     (mapcar #'(lambda (buf) (list (buffer-name buf))) (buffer-list))
+;;     nil t nil 'buffer-name-history (icicle-default-buffer-names) nil)
+;;
+;;  Macros `icicle-define-command' and `icicle-define-file-command'
+;;  make it easy to define a multi-command.  Without them, it is
+;;  sometimes not so easy, depending on the complexity of your action
+;;  functions.  See (@> "Defining Multi-Commands the Hard Way") for a
+;;  taste of what is involved.  If you read that section first, make
+;;  sure you come back here to see how easy things can be.
+;;
+;;  Here is how you might define a multi-command to delete one or more
+;;  files or directories:
+;;
+;;  1. Define the multi-command, `my-delete-file':
+;;
+;;  (icicle-define-file-command
+;;   my-delete-file                  ; Command name
+;;   "Delete a file or directory."   ; Doc string
+;;   my-delete-file-or-directory     ; Function to perform the action
+;;   "Delete file or directory: "    ; `read-file-name' arguments...
+;;   default-directory nil t)
+;;
+;;  2. Define the action function that deletes a single file:
+;;
+;;  (defun my-delete-file-or-directory (file)
+;;    "Delete file (or directory) FILE."
+;;    (condition-case i-delete-file
+;;        (if (eq t (car (file-attributes file)))
+;;            (delete-directory file)
+;;          (delete-file file))
+;;      (error (message "%s" (error-message-string i-delete-file))
+;;             (error "%s" (error-message-string i-delete-file)))))
+;;
+;;  There are two parts to the definition of `my-delete-file':
+;;
+;;  1. The definition of the command itself, using
+;;     `icicle-define-file-command'.
+;;
+;;  2. The definition of an action function,
+;;     `my-delete-file-or-directory', which deletes a single file (or
+;;     directory), given its name.
+;;
+;;  It is #1 that is of interest here, because that is essentially
+;;  what you do to define any multi-command.
+;;
+;;  The details of #2 are less interesting, even if more complex in
+;;  this case: `my-delete-file-or-directory' checks whether its
+;;  argument is a file or directory, and then tries to delete it.  If
+;;  an error occurs, it prints the error message and then returns the
+;;  message, so that the calling command can report on all deletion
+;;  errors.
+;;
+;;  In #1, the arguments to `icicle-define-file-command' are
+;;  straightforward:
+;;
+;;  * The name of the command being defined `my-delete-file'.
+;;
+;;  * Its doc string.
+;;
+;;  * The function that actually performs the action on the input file
+;;    name - `my-delete-file-or-directory'.
+;;
+;;  * The arguments that you would supply anyway to `read-file-name'
+;;    to read a single file name.
+;;
+;;  These are the SAME things you would need if you were defining a
+;;  simple command to delete a SINGLE file or directory.  The only
+;;  differences here are that you:
+;;
+;;  * Use `icicle-define-file-command' instead of `defun' with an
+;;    `interactive' spec.
+;;
+;;  * Separate the action code into a separate function (here,
+;;    `my-delete-file-or-directory') that acts on a single object
+;;    (here, a file).
+;;
+;;  When you use `icicle-define-file-command', the action function is
+;;  called on the result of `read-file-name', and it is also bound to
+;;  `icicle-candidate-action-fn', so that it will be applied to the
+;;  current candidate via `C-RET' or `C-mouse-2'.
+;;
+;;  Command `icicle-all-candidates-action' (`C-!' -- see
+;;  (@file :file-name "icicles-doc1.el" :to "Choose All Completion Candidates"))
+;;  can report in buffer `*Help*' on the objects that it did not act
+;;  upon successfully.  For this reporting to work, the function bound
+;;  to `icicle-candidate-action-fn'
+;;  (e.g. `my-delete-file-or-directory', above) should return `nil'
+;;  for "success" and non-`nil' (for example, an error message) for
+;;  "failure", whatever "success" and "failure" might mean in the
+;;  particular context of use.  This is not a requirement, except if
+;;  you want to take advantage of such reporting.  For a command that
+;;  deletes files, it is important to let the user know which
+;;  deletions failed when s?he tries to delete all matching candidates
+;;  at once.
+;;
+;;  If the command you want to define acts on objects other than
+;;  files, then use `icicle-define-command' instead of
+;;  `icicle-define-file-command' - the only difference is that you
+;;  then supply the arguments for `completing-read' instead of those
+;;  for `read-file-name'.
+;;
+;;  To let users know that a command is a multi-command, and how to
+;;  use it as such, `icicle-define-command' and
+;;  `icicle-define-file-command' automatically add this explanation to
+;;  the doc string you provide for the multi-command:
+;;
+;;  ---
+;;  Read input, then call `' to act on it.
+;;
+;;  Input-candidate completion and cycling are available.  While
+;;  cycling, these keys with prefix `C-' are active:
+;;
+;;  `C-mouse-2', `C-RET' - Act on current completion candidate only
+;;  `C-down', `C-wheel-down' - Move to next completion candidate and act
+;;  `C-up', `C-wheel-up' - Move to previous completion candidate and act
+;;  `C-next'  - Move to next apropos-completion candidate and act
+;;  `C-prior' - Move to previous apropos-completion candidate and act
+;;  `C-end'   - Move to next prefix-completion candidate and act
+;;  `C-home'  - Move to previous prefix-completion candidate and act
+;;  `C-!'    - Act on *all* candidates, successively (careful!)
+;;
+;;  When candidate action and cycling are combined (e.g. `C-next'), user
+;;  option `icicle-act-before-cycle-flag' determines which occurs first.
+;;
+;;  With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+;;  `C-M-RET', `C-M-down', and so on) provide help about candidates.
+;;
+;;  Use `mouse-2', `RET' or `S-RET' to finally choose a candidate, or
+;;  `C-g' to quit.
+;;
+;;  This is an Icicles command - see `icicle-mode'.
+;;  ---
+;;
+;;  Notice that the doc string of your new multi-command references
+;;  your action function (e.g. `my-delete-file-or-directory').  The
+;;  doc string you provide for the multi-command can thus be a little
+;;  more abstract, leaving any detailed explanation of the action to
+;;  the doc string of your action function.
+;;
+;;  To provide more flexibility, `icicle-define-command' and
+;;  `icicle-define-file-command' provide some predefined key bindings
+;;  and allow for additional arguments.
+;;
+;;  Here is a definition of a multi-command, `change-font', that reads
+;;  a font name and changes the selected frame to use that font.
+;;
+;;  1  (icicle-define-command
+;;  2   change-font "Change font of current frame."
+;;  3   (lambda (font)
+;;  4     (modify-frame-parameters orig-frame
+;;  5                              (list (cons 'font font))))
+;;  6   "Font: " (mapcar #'list (x-list-fonts "*"))
+;;  7   nil t nil nil nil nil
+;;  8   ((orig-frame  (selected-frame))
+;;  9    (orig-font   (frame-parameter nil 'font)))
+;;  10  nil
+;;  11  (modify-frame-parameters orig-frame
+;;  12                           (list (cons 'font orig-font)))
+;;  13  nil)
+;;
+;;  The arguments to `icicle-define-command' here are as follows:
+;;
+;;  Command name    (line 2)
+;;  Doc string      (line 2)
+;;  Action function (lines 3-5)
+;;  Args passed to `completing-read' (lines 6-7)
+;;  Additional bindings (lines 8-9)
+;;  Additional initialization code (line 10)
+;;  "Undo" code to run in case of error or user quit (lines 11-12)
+;;  Additional code to run at the end (line 13)
+;;
+;;  The following bindings are predefined - you can refer to them in
+;;  the command body:
+;;
+;;   `icicle-orig-buff'   is bound to (current-buffer)
+;;   `icicle-orig-window' is bound to (selected-window)
+;;
+;;  Before running any "undo" code that you supply, the original
+;;  buffer is restored, in case of error or user quit (`C-g').
+;;
+;;  Most of the arguments to `icicle-define-command' are optional.  In
+;;  this case, optional arguments were provided to save (lines 8-9)
+;;  and then restore (lines 11-12) the original font and frame.
+;;
+;;  Several top-level Icicles commands have been defined using
+;;  `icicle-define-command' and `icicle-define-file-command'.  You can
+;;  use their definitions as models for your own multi-commands.
+;;
+;;  `clear-option' (alias) - Set value of binary option to `nil'
+;;  `icicle-add-buffer-candidate' - Add buffer to those always shown
+;;  `icicle-add-buffer-config' - Add to `icicle-buffer-configs'
+;;  `icicle-bookmark'     - Jump to a bookmark
+;;  `icicle-bookmark-all-tags' - Jump: bookmark with all matching tags
+;;  `icicle-bookmark-all-tags-regexp' - ... matching a regexp
+;;  `icicle-bookmark-bookmark-list-' - Jump: bookmark-list bookmark
+;;  `icicle-bookmark-desktop' - Jump: bookmarked desktop
+;;  `icicle-bookmark-dired' - Jump: bookmarked Dired state
+;;  `icicle-bookmark-file' - Jump: bookmarked file
+;;  `icicle-bookmark-gnus' - Jump: bookmarked Gnus message
+;;  `icicle-bookmark-info' - Jump: bookmarked Info node
+;;  `icicle-bookmark-list' - Choose a list of bookmark names
+;;  `icicle-bookmark-local-file' - Jump: bookmarked local file
+;;  `icicle-bookmark-man' - Jump: bookmarked `man' page
+;;  `icicle-bookmark-non-file' - Jump: bookmarked non-file buffer
+;;  `icicle-bookmark-region' - Jump: bookmarked region
+;;  `icicle-bookmark-remote-file' - Jump: bookmarked remote file
+;;  `icicle-bookmark-some-tags'- Jump: bookmark with some matching tag
+;;  `icicle-bookmark-some-tags-regexp'- matching a regexp
+;;  `icicle-bookmark-specific-buffers'- Jump: specific-buffer bookmark
+;;  `icicle-bookmark-specific-files' - Jump: specific-file bookmark
+;;  `icicle-bookmark-this-buffer' - Jump: bookmark for this buffer
+;;  `icicle-bookmark-url' - Jump: bookmarked URL
+;;  `icicle-bookmark-w3m' - Jump: W3M bookmark
+;;  `icicle-buffer'       - Switch to another buffer
+;;  `icicle-buffer-config' - Choose a config for buffer commands
+;;  `icicle-buffer-list'  - Choose a list of buffer names
+;;  `icicle-choose-faces' - Choose a list of face names
+;;  `icicle-choose-invisible-faces' - Choose list of invisible faces
+;;  `icicle-choose-visible-faces' - Choose list of visible faces
+;;  `icicle-clear-history' - Clear entries from minibuffer histories
+;;  `icicle-clear-current-history' - Clear current history entries
+;;  `icicle-color-theme'  - Change color theme
+;;  `icicle-comint-command' - Reuse a previous command in comint mode
+;;  `icicle-command-abbrev' - Execute command or command abbreviation
+;;  `icicle-command-abbrev-command' - Execute command from abbrev
+;;  `icicle-completing-yank' - Yank text using completion
+;;  `icicle-delete-file'  - Delete a file or directory
+;;  `icicle-delete-windows' - Delete windows showing a buffer anywhere
+;;  `icicle-describe-option-of-type' - Describe option of a given type
+;;  `icicle-directory-list' - Choose a list of directory names
+;;  `icicle-dired'        - Visit a directory in Dired mode
+;;  `icicle-doc'          - Display doc of function, variable, or face
+;;  `icicle-execute-extended-command' -
+;;                          A multi-command version of `M-x'
+;;  `icicle-execute-named-keyboard-macro' - Execute named kbd macro
+;;  `icicle-face-list'    - Choose a list of face names
+;;  `icicle-file-list'    - Choose a list of file names
+;;  `icicle-file'         - Visit a file or directory
+;;  `icicle-find-file'    - Visit a file or directory (relative)
+;;  `icicle-find-file-absolute' - Visit a file (absolute)
+;;  `icicle-find-file-all-tags' - Visit a file with all matching tags
+;;  `icicle-find-file-all-tags-regexp' - ... matching a regexp
+;;  `icicle-find-file-in-tags-table' - Visit a file in a tags table
+;;  `icicle-find-file-read-only' - Visit a file in read-only mode
+;;  `icicle-find-file-some-tags'- Visit a file with some matching tags
+;;  `icicle-find-file-some-tags-regexp' - ... matching a regexp
+;;  `icicle-find-file-tagged' - Visit a file with matching tags
+;;  `icicle-find-first-tag' - Visit source-code definition with tag
+;;  `icicle-font'         - Change the frame font
+;;  `icicle-frame-bg'     - Change the frame background color
+;;  `icicle-frame-fg'     - Change the frame foreground color
+;;  `icicle-fundoc'       - Display the doc of a function
+;;  `icicle-Info-menu'    - Go to an Info menu node
+;;  `icicle-increment-option' - Increment option value using arrows
+;;  `icicle-increment-variable' - Increment variable value
+;;  `icicle-insert-buffer'- Insert a buffer
+;;  `icicle-insert-thesaurus-entry' - Insert an entry from a thesaurus
+;;  `icicle-keyword-list' - Choose a list of keywords (regexps)
+;;  `icicle-kill-buffer'  - Kill a buffer
+;;  `icicle-kmacro'       - Execute a keyboard macro (Emacs 22+)
+;;  `icicle-locate-file'  - Open a file located anywhere
+;;  `icicle-pick-color-by-name' - Set current highlighting color
+;;  `icicle-plist'        - Choose a symbol and its property list
+;;  `icicle-recent-file'  - Open a recently used file
+;;  `icicle-remove-buffer-candidate' -
+;;                          Remove buffer from those always shown
+;;  `icicle-remove-buffer-config' -
+;;                          Remove from `icicle-buffer-configs'
+;;  `icicle-remove-file-from-recentf-list' - Remove from recent files
+;;  `icicle-remove-saved-completion-set' - Remove a set from
+;;                          `icicle-saved-completion-sets'
+;;  `icicle-reset-option-to-nil' -
+;;                          Set value of binary option to `nil'
+;;  `icicle-search-all-tags-bookmark'- Search bookmark with given tags
+;;  `icicle-search-all-tags-regexp-bookmark'- ... tags matching regexp
+;;  `icicle-search-autofile-bookmark' - Search an autofile bookmark
+;;  `icicle-search-bookmark' - Search a bookmark
+;;  `icicle-search-bookmark-list-bookmark' - Search bookmark-list bmk
+;;  `icicle-search-desktop-bookmark' - Search a Desktop bookmark
+;;  `icicle-search-dired-bookmark' - Search a Dired bookmark
+;;  `icicle-search-file-bookmark' - Search a bookmarked file
+;;  `icicle-search-gnus-bookmark' - Search a bookmarked Gnus message
+;;  `icicle-search-info-bookmark' - Search a bookmarked Info node
+;;  `icicle-search-local-file-bookmark' - Search a local-file bookmark
+;;  `icicle-search-man-bookmark' - Search a bookmarked `man' page
+;;  `icicle-search-non-file-bookmark' - Search a bookmarked buffer
+;;  `icicle-search-region-bookmark' - Search a bookmarked region
+;;  `icicle-search-remote-file-bookmark' - Search a remote bookmark
+;;  `icicle-search-some-tags-bookmark'- Search bookmark with some tags
+;;  `icicle-search-some-tags-regexp-bookmark'- ... matching regexp
+;;  `icicle-search-specific-buffers-bookmark'- ...specific-buffers bmk
+;;  `icicle-search-specific-files-bookmark' - ... specific-files bmk
+;;  `icicle-search-this-buffer-bookmark' - ...bookmark for this buffer
+;;  `icicle-search-url-bookmark' - Search a bookmarked URL
+;;  `icicle-search-w3m-bookmark' - Search a W3M bookmark
+;;  `icicle-select-frame' - Select frame by name and raise it
+;;  `icicle-select-window' - Select window by its buffer name
+;;  `icicle-set-option-to-t' - Set the value of a binary option to `t'
+;;  `icicle-synonyms' - Show synonyms that match a regexp
+;;  `icicle-tag-a-file' - Add one or more tags to a file
+;;  `icicle-toggle-option' - Toggle the value of a binary option
+;;  `icicle-untag-a-file' - Remove one or more tags from a file
+;;  `icicle-vardoc'       - Display the doc of a variable
+;;  `icicle-where-is'     - Show key sequences that invoke a command
+;;
+;;  For simplicity, the descriptions of most of these commands are
+;;  singular actions (e.g. "kill a buffer"), but each of them can be
+;;  used to act on any number of items any number of times (e.g. kill
+;;  one or more buffers).  I recommend that you follow a similar
+;;  naming convention - remember that the doc string will let users
+;;  know that the command can be used on multiple objects.
+;;
+;;  Macros `icicle-define-command' and `icicle-define-file-command'
+;;  define a multi-command in a simple way.  Sometimes you will need a
+;;  little more flexibility.  In that case, you can use higher-order
+;;  functions `icicle-explore' and `icicle-apply' to define a
+;;  multi-command.  See (@> "Defining Icicles Tripping Commands").
+;;
+;;(@* "Are Users Dependent on Icicles To Use Multi-Commands?")
+;;  ** Are Users Dependent on Icicles To Use Multi-Commands? **
+;;
+;;  For users to be able to take advantage of the Icicles features
+;;  that your multi-command provides, they must load Icicles.  You can
+;;  do this for them, by adding (require 'icicles nil t) to your code.
+;;  The last two arguments mean that no error will be raised if for
+;;  some reason Icicles cannot be found or successfully loaded.
+;;
+;;  But that brings up another question: What happens to your
+;;  multi-command if Icicles is not available for a user, or s?he does
+;;  not want to load it?  No problem - your multi-command then
+;;  automatically turns into a normal, single-choice command -
+;;  graceful degradation.
+;;
+;;  Similarly, users can always turn off `icicle-mode' at any time, to
+;;  return to the standard Emacs behavior.
+;;
+;;  Users will, in any case, need to load Icicles at compile time, in
+;;  order to byte-compile your library that calls macro
+;;  `icicle-define-command' or `icicle-define-file-command' - either
+;;  that, or you can duplicate the definition of the macro in your
+;;  library.  To let users load Icicles at (only) compile time, add
+;;  this to your library that defines multi-commands:
+;;
+;;  (eval-when-compile '(require icicles))
+;;
+;;  See Also:
+;;
+;;  * (@> "Defining Icicles Tripping Commands") for how to use
+;;    `icicle-apply' and `icicle-explore' to define browsing commands.
+;;
+;;  * (@> "Defining Multiple-Choice Menus").
+;;
+;;  * (@> "Note to Programmers") for further programming guidelines.
+;;
+;;  * Library `synonyms.el', which uses `icicle-define-command' to
+;;    define command `synonyms'.  This command lets you use Icicles
+;;    completion on input regexps when you search a thesaurus.
+ 
+;;(@* "Defining Icicles Tripping Commands")
+;;
+;;  Defining Icicles Tripping Commands
+;;  ----------------------------------
+;;
+;;  Section (@file :file-name "icicles-doc1.el" :to "Icicles Tripping")
+;;  describes the use of Icicles tripping (aka navigation or browsing)
+;;  multi-commands.  This section tells you how to define your own
+;;  such commands for custom trips - it is thus for Emacs-Lisp
+;;  programmers.
+;;
+;;  The best way to learn how to do this is to look at how the
+;;  existing tripping commands are defined.  Some of them use macro
+;;  `icicle-define-command'; others do not.  Some use the
+;;  building-block functions `icicle-explore' or `icicle-apply';
+;;  others do not.  Several use `icicle-search' as a building block.
+;;
+;;(@* "Using `icicle-define-command'")
+;;  ** Using `icicle-define-command' **
+;;
+;;  Those that use `icicle-define-command' take advantage of some
+;;  extraneous way to obtain trip location information from a display
+;;  candidate, which is just a string.  For example, `icicle-bookmark'
+;;  ultimately uses the display string to look up location information
+;;  in a bookmarks file.  Those that use `icicle-explore' or
+;;  `icicle-apply' make use of location information stored in the
+;;  alist COLLECTION argument to `completing-read'.
+;;
+;;  You can also use `icicle-define-command', `icicle-explore', and
+;;  `icicle-apply' to define multi-commands other than browsing
+;;  commands - the action function can do anything you like.
+;;
+;;(@* "Using `icicle-explore'")
+;;  ** Using `icicle-explore' **
+;;
+;;  `icicle-explore' is a higher-order function that takes as
+;;  arguments the following functions, in addition to accepting
+;;  the optional `completing-read' arguments.
+;;
+;;  * A function to build a candidates alist (COLLECTION) for
+;;    completion.  It fills `icicle-candidates-alist' with the
+;;    candidates, each of which is a cons with a display candidate
+;;    string as car and (typically) location information as cdr.  For
+;;    example, `icicle-find-tag' uses the tag text as display
+;;    candidate and the standard tag-locating information as the cdr:
+;;    tag info, file path, and goto function.
+;;
+;;  * A function that acts on the candidate finally chosen (`RET'),
+;;    when completion is finished.
+;;
+;;  * A function to call if the user hits `C-g' during completion.
+;;
+;;  * A function to call if an error is raised during completion.
+;;
+;;  * A function to call after completion is finished, to clean things
+;;    up.
+;;
+;;  If you also bind `icicle-candidate-action-fn' to a function that
+;;  takes a display candidate (string) as argument and navigates to
+;;  the corresponding location, then `icicle-explore' does everything
+;;  you need for an Icicles trip.  You can use function
+;;  `icicle-get-alist-candidate' to get the location information for a
+;;  given display candidate.
+;;
+;;(@* "Using `icicle-apply'")
+;;  ** Using `icicle-apply' **
+;;
+;;  `icicle-apply' binds `icicle-candidate-action-fn' appropriately
+;;  and calls `icicle-explore'.  It applies its function argument to
+;;  completion candidates the user acts on (using `C-RET' etc.).  It
+;;  applies the function to the full alist entry, that is, the display
+;;  candidate car plus any additional information in the cdr.  For a
+;;  tripping command, the additional information provides a location
+;;  and the function applied takes you there.
+;;
+;;  This use of an alist that stores location information in the cdrs
+;;  is what makes `icicle-apply' and `icicle-explore' particularly
+;;  suitable for defining navigation multi-commands.  The Icicles
+;;  macros `icicle-define-command' and `icicle-define-file-command'
+;;  make no such provision, but with suitable arguments you can use
+;;  them too to define tripping commands.
+;;
+;;(@* "Using `icicle-search'")
+;;  ** Using `icicle-search' **
+;;
+;;  `icicle-search' is another high-level function for defining
+;;  tripping commands.  Like `icicle-apply', it calls
+;;  `icicle-explore', but it also provides features for searching
+;;  bookmarks, buffers, and files.  It takes as arguments the search
+;;  limits (region), if any, and either a regexp or a function that
+;;  determines the unfiltered search hits.  It does everything else
+;;  needed to define a trip command that uses search hits as
+;;  completion candidates.  Several predefined Icicles tripping
+;;  commands were defined using `icicle-search'.
+;;
+;;(@* "Tripping on Foot")
+;;  ** Tripping on Foot **
+;;
+;;  You should be able to define any tripping commands you need using
+;;  `icicle-explore', `icicle-apply', or `icicle-search'.
+;;
+;;  If, however, for some reason you decide to define one at a lower,
+;;  pedestrian level (that is, without using any of those building
+;;  blocks), then bind `icicle-whole-candidate-as-text-prop-p' to `t'
+;;  around the call to `completing-read'.  You can then use
+;;  `icicle-get-alist-candidate' to retrieve the candidate cdr
+;;  (e.g. location) information from the completion result.
+;;
+;;  However, if the action or alternate action function that you need
+;;  modifies the existing set of completion candidates on the fly, as
+;;  a side effect, then bind `icicle-whole-candidate-as-text-prop-p'
+;;  to `nil' in the action function.  Then modify both
+;;  `minibuffer-completion-table' and `icicle-candidates-alist' as
+;;  needed to perform the side effect.
+;;
+;;  Icicles search-and-replace provides an example of this.  When you
+;;  replace text, the original domain of search-hit candidates (with
+;;  their associated location information) is altered, so that you can
+;;  continue replacing coherently.  (See the code for
+;;  `icicle-search-action' and
+;;  `icicle-search-highlight-and-maybe-replace'.)
+;;
+;;  Because such side effects can change the meaning of cycling state
+;;  information such as the current candidate number, Icicles does not
+;;  automatically save such state information before a candidate
+;;  action and then restore it afterward.
+;;
+;;  For example, search-and-replace removes a search-hit candidate, as
+;;  a side effect, if the replacement text no longer matches your
+;;  input.  In that case, a current candidate number recorded before
+;;  the action would no longer correspond to the same candidate.
+;;
+;;  For this reason, if your action function does not perform any such
+;;  side effects on the candidates, and you want to restore the
+;;  cycling state as it was before a candidate action, then you might
+;;  want your action function to save and then restore the values of
+;;  Icicles variables such as `icicle-candidate-nb',
+;;  `icicle-last-completion-candidate', and
+;;  `icicle-completion-candidates'.
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Icicles Tripping")
+;;    for information about using Icicles Trip commands
+;;
+;;  * (@> "Defining Icicles Commands (Including Multi-Commands)")
+;;    for general information about defining multi-commands
+;;
+;;  * (@> "Programming with Fancy Candidates") for information about
+;;    `icicle-whole-candidate-as-text-prop-p'
+ 
+;;(@* "Defining Multiple-Choice Menus")
+;;
+;;  Defining Multiple-Choice Menus
+;;  ------------------------------
+;;
+;;  Icicles multi-commands (see
+;;  (@file :file-name "icicles-doc1.el" :to "Multi-Commands")) can be
+;;  used provide users with multiple-choice menus.  While the possible
+;;  choices can be accessed by minibuffer completion or cycling, a
+;;  user can also display them in buffer `*Completions*' using `TAB'
+;;  or `S-TAB', and click them there to choose them.
+;;
+;;  That is, buffer `*Completions*' can act as a multiple-choice menu.
+;;
+;;  Simple use case: Suppose that you use special characters (Greek
+;;  letters, math symbols, accented letters in another language...),
+;;  but only occasionally - you do not want to take the trouble to
+;;  learn a special input method for them or flip to a different soft
+;;  keyboard.  One simple way to handle this is to create a menu of
+;;  such special characters - Greek letters, for instance.  You only
+;;  need to create the menu once, providing the necessary completions
+;;  as, say, Unicode characters.  When you need to input such a
+;;  character, just use your command that pops up buffer
+;;  `*Completions*' with the available special characters.  Even if
+;;  you do not know how to type them on your keyboard, you can cycle
+;;  through them or use `mouse-2' to choose them.
+;;
+;;  Here's a simple example of defining a command that uses a
+;;  multiple-choice menu.  (Other examples given above, such as
+;;  `my-delete-file-or-directory' are also examples, but this one uses
+;;  menu items that look more like menu items.)
+;;
+;;  (icicle-define-command my-menu-command
+;;      "Display menu and act on choice(s)."
+;;      my-menu-action
+;;      "`TAB' for menu.  `C-mouse-2' to choose. "
+;;      my-menu-items nil t)
+;;
+;;  (defvar my-menu-items
+;;    '(("Foobar" . foobar-fn) ("Toto" . toto-fn) ("Titi" . titi-fn))
+;;    "Alist of menu items and their associated commands.")
+;;
+;;  (defun my-menu-action (item)
+;;    "Call function associated with menu-item ITEM."
+;;    (funcall (cdr (assoc item my-menu-items))))
+;;
+;;  (defun foobar-fn () (message "Foobar chosen"))
+;;  (defun toto-fn () (message "Toto chosen"))
+;;  (defun titi-fn () (message "Titi chosen"))
+;;
+;;  A user does `M-x my-menu-command' and hits `TAB' to display this
+;;  menu in the `*Completions*' buffer:
+;;
+;;  Click mouse-2 on a completion to select it.  (C-h: help)
+;;
+;;  Possible completions are:
+;;  Foobar          Titi
+;;  Toto
+;;
+;;  The user presses and holds the Control key.  S?he clicks `Foobar'
+;;  - message "Foobar chosen" appears.  S?he clicks `Toto - message
+;;  "Toto chosen" appears.
+;;
+;;  And so on - all while holding Control pressed.  Any number of menu
+;;  items can be chosen, any number of times.  The command is finally
+;;  exited with `RET' or `C-g'.
+;;
+;;  The COLLECTION argument passed to `completing-read' here is
+;;  `my-menu-items', an alist of key-value pairs, where the key is a
+;;  menu-item name and the value is the function that implements the
+;;  menu item.  For example, menu item `Foobar' is implemented by
+;;  function `foobar-fn', and the alist element is therefore ("Foobar"
+;;  . foobar-fn).
+;;
+;;  Function `my-menu-action' is executed when a user clicks
+;;  `C-mouse-2' on a menu item.  It just looks up the menu item's
+;;  function in alist `my-menu-items', and then calls that function.
+;;
+;;  What?  You think it's odd that the user must hit `TAB' to display
+;;  the menu?  Then just use this code instead:
+;;
+;;  (icicle-define-command
+;;   my-menu-command
+;;   "Display menu and act on choice(s)."
+;;   my-menu-action
+;;   "`C-mouse-2' or `C-RET' to choose menu items"
+;;   my-menu-items nil t nil nil nil nil
+;;   ((icicle-show-Completions-initially-flag t)))
+;;
+;;  This just adds a binding for
+;;  `icicle-show-Completions-initially-flag', so that `*Completions*'
+;;  is displayed initially.
+;;
+;;  Granted, the `*Completions*' display does not exactly look like
+;;  your average menu.  And the header line does not mention the
+;;  multiple-choice possibility (holding Control while clicking).  But
+;;  the header does say to use `C-h' for help, and that help does
+;;  mention `C-mouse-2' (as does the prompt).  And the menu does act
+;;  like a menu.  And the doc string of `my-menu-command' can provide
+;;  more help, as needed.
+;;
+;;  There are also some freebie advantages of using such menus,
+;;  besides the feature of multiple-choice.  These include choosing
+;;  menu items from the keyboard, with completion, and cycling among
+;;  menu items.  The additional features are all explained when the
+;;  user hits `C-?'.
+;;
+;;  One common use of a multiple-choice menu is letting the user
+;;  select a list of items from a larger list of candidates.  The list
+;;  is returned, with the items in the order selected.  Examples of
+;;  this include these multi-commands:
+;;
+;;  * `icicle-bookmark-list' - bookmark names
+;;
+;;  * `icicle-buffer-list' - buffer names, selected from `buffer-list'
+;;    (possibly after filtering)
+;;
+;;  * `icicle-directory-list' - directory names, selected from
+;;    subdirectories in the current directory and any directories you
+;;    navigate to
+;;
+;;  * `icicle-face-list' - face names, selected from `face-list'
+;;
+;;  * `icicle-file-list' - file names, selected from files in the
+;;    current directory and any directories you navigate to
+;;
+;;  * `icicle-keyword-list' - keywords (regexps), selected from those
+;;    you have previously entered
+;;
+;;  * `icicle-choose-faces', `icicle-choose-visible-faces',
+;;    `icicle-choose-invisible-faces' - face names, selected from the
+;;    (visible/invisible) highlighting faces in the buffer
+;;
+;;  Such commands can be used on their own, or they can be used in the
+;;  `interactive' specs of other commands that act on an entire list
+;;  of selected items.  And do not forget that the set of "menu items"
+;;  (completion candidates) is susceptible to sorting in various ways,
+;;  as well as filtering in the usual ways: progressive completion,
+;;  chipping away the non-elephant, and so on.
+;;
+;;  Here as an example definition is `icicle-file-list':
+;;
+;;   (icicle-define-command icicle-file-list
+;;     "Choose a list of file names.
+;;   The list of names (strings) is returned."
+;;     (lambda (name) (push name file-names))
+;;     "Choose file (`RET' when done): "
+;;     (mapcar #'list (directory-files default-directory nil
+;;                                     icicle-re-no-dot))
+;;     nil nil nil 'file-name-history nil nil
+;;     ((file-names  ()))                    ; Additional bindings
+;;     nil nil
+;;     (prog1 (setq file-names (delete "" file-names)) ; Return list
+;;       (when (interactive-p) (message "Files: %S" file-names))))
+;;
+;;  See (@file :file-name "icicles-doc1.el" :to "Nutshell View of Icicles")
+;;  for information about progressive completion and chipping away.
+ 
+;;(@* "Defining Icicles Multi `M-x'")
+;;
+;;  Defining Icicles Multi `M-x'
+;;  ----------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.  It explains how the
+;;  Icicles Multi `M-x' feature is implemented, providing an advanced
+;;  illustration of using macro `icicle-define-command'.
+;;
+;;(@* "How Multi `M-x' is Defined")
+;;  ** How Multi `M-x' is Defined **
+;;
+;;  The definition of `icicle-execute-extended-command' provides an
+;;  interesting illustration of using `icicle-define-command'.  The
+;;  candidate action function itself binds a candidate action
+;;  function, in case the candidate is a command that reads input with
+;;  completion.
+;;
+;;  (icicle-define-command
+;;    icicle-execute-extended-command   ; `M-x' in Icicle mode.
+;;    "Read command name, then read its arguments and call it."
+;;    icicle-execute-extended-command-1 ; Action function
+;;    (format "Execute command%s: "     ; `completing-read' args
+;;            (if current-prefix-arg
+;;                (format " (prefix %d)"
+;;                        (prefix-numeric-value current-prefix-arg))
+;;               ""))
+;;    obarray 'commandp t nil 'extended-command-history nil nil
+;;    ((last-cmd last-command))        ; Save the last command
+;;    nil nil                          ; First code, undo code
+;;    (setq last-command last-cmd))    ; Last: restore last command
+;;
+;;  (defun icicle-execute-extended-command-1 (cmd-name)
+;;    "Action function for `icicle-execute-extended-command'."
+;;     (set-buffer icicle-orig-buff) ; bound by `icicle-define-command'.
+;;     (select-window icicle-orig-window)
+;;     (let ((icicle-candidate-action-fn
+;;            (lambda (x) (funcall (intern cmd-name) x))))
+;;       (run-hooks 'post-command-hook)
+;;       (setq this-command cmd)
+;;       (run-hooks 'pre-command-hook)
+;;       (let ((enable-recursive-minibuffers  t))
+;;         (call-interactively (intern cmd-name) 'record-it))))
+;;
+;;  The last seven lines of this action function rebind
+;;  `icicle-candidate-action-fn' to a function that calls the
+;;  candidate `cmd-name' on a single argument that it reads.  This is
+;;  useful if `cmd-name' is a command that, itself, reads an input
+;;  argument with completion.  When that is the case, you can use
+;;  completion on that input, and if you do that, you can use `C-RET'
+;;  to use command `cmd-name' as a multi-command.  In other words,
+;;  this binding allows for two levels of multi-commands.
+;;
+;;  There are a few things wrong with this definition, however.  In
+;;  the action function, the candidate command is applied to a
+;;  candidate that is a string.  What if it is a command, such as
+;;  `describe-variable', that expects a symbol argument?  Or a number
+;;  argument?  There is no way to know what kind of command will be
+;;  used, and what kind of argument it will need.  The solution is to
+;;  first try a string candidate argument, then convert the string to
+;;  a symbol or number.  That is, bind this to
+;;  `icicle-candidate-action-fn':
+;;
+;;  (lambda (x)
+;;    (condition-case nil
+;;        (funcall cmd x)    ; Try to use a string candidate.  If that
+;;      (wrong-type-argument ; did not work, use a symbol or number.
+;;       (funcall cmd (car (read-from-string x))))))
+;;
+;;  A similar problem occurs if the action function called does not
+;;  accept a (single) argument.  The best thing to do in this case is
+;;  punt - call `icicle-help-on-candidate' to display help on the
+;;  candidate. To the code above, we add another error handler:
+;;
+;;  (wrong-number-of-arguments (funcall #'icicle-help-on-candidate))
+;;
+;;  And what if the command `cmd' does something that changes the
+;;  focus away from the minibuffer's frame?  That's the case for
+;;  `describe-variable', for instance: it selects buffer `*Help*'.  To
+;;  fix this potential problem, the action function needs to reset the
+;;  focus back to the minibuffer frame:
+;;
+;;  (lambda (x)
+;;    (condition-case nil
+;;        (funcall cmd x)
+;;      (wrong-type-argument (funcall cmd (car (read-from-string x))))
+;;      (wrong-number-of-arguments
+;;       (funcall #'icicle-help-on-candidate)))
+;;    (select-frame-set-input-focus
+;;      (window-frame (minibuffer-window))))
+;;
+;;  The actual definitions of the action function and the main command
+;;  are even more complex.  They need to take into account various
+;;  subtleties, including those associated with recursive minibuffers
+;;  and multiple invocations of `completing-read'.  Evaluate, for
+;;  example, (symbol-function 'icicle-execute-extended-command) to see
+;;  the real definition.
+;;
+;;  See Also:
+;;
+;;  (@file :file-name "icicles-doc1.el" :to "Icicles Multi `M-x'").
+ 
+;;(@* "Defining Multi-Commands the Hard Way")
+;;
+;;  Defining Multi-Commands the Hard Way
+;;  ------------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.  It gives you a taste
+;;  of what is involved behind the scene when you effortlessly use
+;;  `icicle-define-command' or `icicle-define-file-command' to define
+;;  a multi-command.
+;;  See (@> "Defining Icicles Commands (Including Multi-Commands)").
+;;
+;;  It can be good to know this, if only for the case where you need
+;;  to define a multi-command that has special behavior not provided
+;;  by `icicle-define(-file)-command' out of the box.  For example, if
+;;  you want the normal, single-choice `RET' behavior to be different
+;;  from the multiple-choice `C-RET' behavior, then you might want to
+;;  roll your own.  Likewise, if you want to define your own help on
+;;  individual candidates, to be invoked when users use `C-M-RET' and
+;;  so on.
+;;
+;;  To write your own multi-command, you must make the command do
+;;  this:
+;;
+;;  1. Call `completing-read' or `read-file-name', and perform some
+;;     action on the completed input.
+;;
+;;  2. Bind one or more of these variables to action functions, which
+;;     each take a completion candidate as argument:
+;;
+;;     a. `icicle-candidate-action-fn' - a function that performs an
+;;        action on a completion candidate - often the same action as
+;;        #1.
+;;
+;;     b. `icicle-candidates-list-action-fn' - a function that
+;;        performs an action on the list of all completion candidates.
+;;
+;;     c. `icicle-candidate-alt-action-fn' - a function that performs
+;;        an alternative action on a completion candidate.
+;;
+;;     d. `icicle-candidates-list-alt-action-fn' - a function that
+;;        performs an alternative action on the list of candidates.
+;;
+;;     e. `icicle-candidate-help-fn' - a function that displays
+;;        specialized help for a completion candidate.
+;;
+;;        (You can also provide mode-line help and tooltip help for
+;;        individual candidates.
+;;        See "Candidates with Text Properties".)
+;;
+;;     f. `icicle-delete-candidate-object' - a function that deletes
+;;        an object associated with (e.g. named by) a completion
+;;        candidate.
+;;
+;;  #1 just lets people use the command normally, to perform the #1
+;;  action on a completion candidate entered with `RET'.  Because of
+;;  #2, people can perform the #2 action(s) on any completion
+;;  candidates, while still continuing to cycle or complete
+;;  candidates.  `icicle-candidate-action-fn' is often the same as the
+;;  action for #1, but nothing prevents you from using different
+;;  actions.
+;;
+;;  When internal variable `icicle-candidate-action-fn' is not bound,
+;;  the default action is performed: display help on the current
+;;  completion candidate.  When `icicle-candidate-help-fn' is not
+;;  bound, the default help display is used.
+;;
+;;  Instead of binding `icicle-delete-candidate-object' to a deletion
+;;  action function, you can bind it to a symbol (variable) whose
+;;  value is a list of completion-candidate objects.
+;;  See (@> "More about Multi-Commands") for more information.
+;;
+;;  Here is a definition of a simple (not multi-) command that reads a
+;;  font name and then changes the selected frame to use that font.
+;;  By virtue of calling `completing-read', Icicles completion and
+;;  cycling are available, using all available font names as the pool
+;;  of candidates.
+;;
+;;  (defun change-font ()
+;;    "Change font of selected frame."
+;;    (modify-frame-parameters
+;;     (selected-frame)
+;;     (list (cons 'font (completing-read
+;;                        "Font: " (mapcar #'list (x-list-fonts "*"))
+;;                        nil t)))))
+;;
+;;  Here's a definition of a multi-command `change-font' that takes
+;;  advantage of an action function when cycling candidates:
+;;
+;;  1  (defun change-font ()
+;;  2    "Change font of current frame."
+;;  3    (interactive)
+;;  4   (let* ((orig-frame  (selected-frame))
+;;  5          (orig-font   (frame-parameter nil 'font))
+;;  6          (icicle-candidate-action-fn
+;;  7           ;; Perform the action on a candidate, without leaving
+;;  8           ;; `completing-read'.  You can do this over and over.
+;;  9           (lambda (font)
+;;  10             (modify-frame-parameters orig-frame
+;;  11                                      (list (cons 'font font))))))
+;;  12     (condition-case nil
+;;  13         (modify-frame-parameters
+;;  14          orig-frame
+;;  15          (list
+;;  16           (cons 'font
+;;  17                 ;; Perform the action on your final choice.
+;;  18                 (completing-read
+;;  19                  "Font: "
+;;  20                  (mapcar #'list (x-list-fonts "*")) nil t))))
+;;  21       ((quit error)
+;;  22        (modify-frame-parameters
+;;  23         orig-frame
+;;  24         (list (cons 'font orig-font)))))))
+;;
+;;  As you can see, there is a lot more going on here than in the
+;;  simple-command version.  These are the points to keep in mind,
+;;  when defining a multi-command by hand:
+;;
+;;  1. Save anything you need to restore, so you can, in effect, undo
+;;     the action in case of `C-g' (lines 4-5).
+;;
+;;  2. Bind `icicle-candidate-action-fn' to the action to perform
+;;     (lines 6-11).
+;;
+;;  3. Perform the action, using `completing-read' to provide the
+;;     target candidate (lines 13-20).  Do this in the body of a
+;;     `condition-case' (lines 12-24).
+;;
+;;  4. Restore the original context in the error-handling part of the
+;;     `condition-case' (lines 22-24).  Include `quit' in the
+;;     error-type list.
+;;
+;;  The above definition is not quite complete, in fact.  To let
+;;  `icicle-all-candidates' be able to report on failures, the
+;;  `icicle-candidate-action-fn' code should also trap errors and
+;;  return `nil' as a success indicator.
+;;
+;;  In fact, things can get even hairier (much hairier) still, if the
+;;  function at the core of your command does things like create a new
+;;  frame - especially on MS Windows, with its click-to-focus window
+;;  manager.  The action of `change-font' does not do that, but if it
+;;  did, you would need to redirect the focus back to the minibuffer
+;;  frame, using `select-frame-set-input-focus'.  As an illustration
+;;  of what's involved, here's a definition that would deal with such
+;;  problems.  It also traps `icicle-candidate-action-fn' errors,
+;;  returning `nil' to report success and the error message to report
+;;  failure.
+;;
+;;  (defun change-font ()
+;;    "Change font of current frame."
+;;    (interactive)
+;;    (let* ((icicle-orig-buff    (current-buffer))
+;;           (icicle-orig-window  (selected-window))
+;;           (orig-frame          (selected-frame))
+;;           (orig-font           (frame-parameter nil 'font))
+;;           (icicle-candidate-action-fn
+;;            (lambda (candidate)
+;;              (condition-case action-fn-return
+;;                  (progn
+;;                    (modify-frame-parameters
+;;                     orig-frame (list (cons 'font candidate)))
+;;                    (select-frame-set-input-focus
+;;                     (window-frame (minibuffer-window)))
+;;                    nil) ; Return nil to report success.
+;;                ;; Return error message to report error.
+;;                (error (error-message-string action-fn-return))))))
+;;      (condition-case act-on-choice
+;;          (modify-frame-parameters
+;;           orig-frame
+;;           (list (cons 'font
+;;                       (completing-read
+;;                        "Font: " (mapcar #'list (x-list-fonts "*"))
+;;                        nil t nil nil nil nil))))
+;;        (quit (switch-to-buffer icicle-orig-buff)
+;;              (modify-frame-parameters
+;;               orig-frame
+;;               (list (cons 'font orig-font))))
+;;        (error (switch-to-buffer icicle-orig-buff)
+;;               (modify-frame-parameters
+;;                orig-frame (list (cons 'font orig-font)))
+;;               (error "%s" (error-message-string act-on-choice))))))
+;;
+;;  That's a lot of (error-prone) work!  You obviously do not want to
+;;  be doing that a lot.  Whenever you can, you should use macro
+;;  `icicle-define-command' or `icicle-define-file-command' to define
+;;  your multi-commands.
+;;
+;;  See Also:
+;;
+;;  * (@> "Defining Icicles Commands (Including Multi-Commands)") for
+;;    the easy way to define `change-font'.
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Icicles Tripping")
+;;    for information about defining action functions that perform
+;;    side effects on candidates.
+ 
+;;(@* "Global Filters")
+;;
+;;  Global Filters
+;;  --------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  Which completion candidates get displayed?  To review:
+;;
+;;  1. The domain of discourse, that is, all possible candidates, is
+;;     determined by the arguments to `completing-read',
+;;     `read-file-name', or `M-x'.
+;;
+;;  2. A user types something in the minibuffer.  This narrows the
+;;     possible candidates to those that match the input.  Matching
+;;     can be prefix-matching or apropos-matching.
+;;
+;;  Wouldn't it sometimes be useful to filter #1 in a global way,
+;;  before filtering it with the user input (#2)?  Functions
+;;  `completing-read' and `read-file-name' take a predicate argument,
+;;  so that can be used for global filtering.  However, those
+;;  functions are usually called from some command, and it would also
+;;  be useful to give end users, not just programmers, some way to
+;;  globally filter candidates.
+;;
+;;  For example, if you have a command, such as `icicle-buffer', that
+;;  reads a buffer name and displays the buffer, some users might
+;;  always be interested only in buffers that are associated with
+;;  files.  They do not want to see possible candidates such as
+;;  `*scratch*' and `*Messages*'.  What they need is a way to apply a
+;;  global predicate that limits candidates to file-buffer names - but
+;;  they do not have access to the call to `completing-read' that is
+;;  inside the command definition.
+;;
+;;  For this reason, some global filtering variables are provided by
+;;  Icicles:
+;;
+;;    `icicle-must-match-regexp', `icicle-must-not-match-regexp',
+;;    `icicle-must-pass-predicate',
+;;    `icicle-must-pass-after-match-predicate',
+;;    `icicle-extra-candidates'.
+;;
+;;  The first and second of these are regexps that candidates must
+;;  match and must not match, respectively, in order for them to be
+;;  displayed.  The third and fourth are predicates that candidates
+;;  must satisfy.  The fifth is a list of extra candidates to display.
+;;  Any of the filters can be `nil', in which case it has no effect.
+;;
+;;  Each of these except `icicle-extra-candidates' filters not only
+;;  completion candidates but also the default values passed to
+;;  `completing-read' and `read-file-name'.
+;;
+;;  Variable `icicle-must-match-regexp' is similar to the standard
+;;  variable `completion-regexp-list', except:
+;;
+;;  * `completion-regexp-list' is a list of regexps, not just one.
+;;  * `icicle-must-match-regexp' is used after filtering using option
+;;    `icicle-transform-function'.
+;;
+;;  Variables `icicle-must-pass-predicate' and
+;;  `icicle-must-pass-after-match-predicate' act the same: they filter
+;;  display candidates.  The former filters before the current user
+;;  input is matched.  The latter filters after matching - it is
+;;  applied only to candidates that match.
+;;
+;;  Neither is like the PREDICATE argument to `completing-read' in
+;;  that they do not act on full candidates (e.g. alist entries) -
+;;  they apply only to display candidates (strings).
+;;
+;;  For apropos completion, the `completing-read' PREDICATE is applied
+;;  to all COLLECTION entries before matching those entries that
+;;  satisfy it against the user input.  If the PREDICATE argument uses
+;;  only the candidate name (it does not make any use of the full
+;;  candidate) then it can sometimes be more efficient to pass `nil'
+;;  as the PREDICATE and use `icicle-must-pass-after-match-predicate'
+;;  instead.
+;;
+;;  Here's a gotcha to keep in mind if you use
+;;  `icicle-must-pass-predicate' or
+;;  `icicle-must-pass-after-match-predicate' with (non-absolute)
+;;  file-name candidates: Since the candidate file names have no
+;;  directory part, in many cases you will want to test the candidate
+;;  expanded relative to the directory shown in the minibuffer.  One
+;;  way to do this is as follows:
+;;
+;;  (setq file  (expand-file-name file
+;;               (icicle-file-name-directory-w-default
+;;                 (icicle-input-from-minibuffer))))
+;;
+;;  This gotcha is nothing new - the same applies for standard Emacs
+;;  function `read-file-name', but it is still worth pointing out.
+;;
+;;  Variable `icicle-extra-candidates' is not really a "filter".  It
+;;  does not restrict the set of possible candidates - rather, it
+;;  extends that set.  The other filters do not act on the candidates
+;;  in `icicle-extra-candidates' - they are always added.  Extra
+;;  candidates are displayed in buffer `*Completions*' using face
+;;  `icicle-extra-candidate'.
+;;
+;;  Note that an extra candidate need not have anything in common with
+;;  the normal (non-extra) candidates.  In particular, because it is
+;;  provided explicitly, it does not follow the restrictions implied
+;;  by the current candidate-generation method.  
+;;
+;;  In this, extra candidates are similar to proxy candidates.  For
+;;  example, when option `icicle-guess-commands-in-path' is non-`nil',
+;;  the proxy shell-command candidates provided have no connection
+;;  with the file-name completion that is used to generate the other
+;;  candidates (see (@* "Icicles Shell-Command Enhancements")).
+;;
+;;  Note too that if an extra candidate is already a candidate anyway
+;;  then it will be present twice in the list of all candidates (that
+;;  is, unless `icicle-transform-function' removes duplicate
+;;  candidates).
+;;
+;;  These global variables are internal variables, even though they
+;;  are defined as user options - they are not really meant to be
+;;  customized.  If you are not an Emacs-Lisp programmer, you will not
+;;  use these variables, but some commands that you use might provide
+;;  corresponding global-filter user options.  Icicles provides
+;;  customizable user options for Icicles buffer commands, such as
+;;  `icicle-buffer'.  For example:
+;;
+;;    `icicle-buffer-match-regexp'    - Regexp buffer names must match
+;;    `icicle-buffer-no-match-regexp' - Regexp buffers must not match
+;;    `icicle-buffer-predicate'       - Predicate buffers must satisfy
+;;    `icicle-buffer-extras'          - Extra buffer names to display
+;;
+;;  You might, for instance, customize `icicle-buffer-no-match-regexp'
+;;  to not display file-buffers whose names end in `.elc', and
+;;  customize `icicle-buffer-predicate' to show only buffers that are
+;;  associated with files.  The former would use a value of "\\.elc$",
+;;  and the latter would use a value such as this:
+;;
+;;     (lambda (bufname) (buffer-file-name (get-buffer bufname)))
+;;
+;;  Similarly, Icicles provides user options for filtering and sorting
+;;  file names during completion:
+;;
+;;    `icicle-file-match-regexp'    - Regexp file names must match
+;;    `icicle-file-no-match-regexp' - Regexp file names must not match
+;;    `icicle-file-predicate'       - Predicate files must satisfy
+;;    `icicle-file-extras'          - Extra file names to display
+;;
+;;  Note that `icicle-buffer-predicate' and `icicle-file-predicate'
+;;  correspond to `icicle-must-pass-after-match-predicate', not to
+;;  `icicle-must-pass-predicate'.  They are applied after your current
+;;  input filters the candidates.
+;;
+;;  If you as a programmer write a command, and you want to expose
+;;  global filters to users of the command, you should:
+;;
+;;  1. Create corresponding user options that can be customized.
+;;  2. Bind the user options to the corresponding filtering variables.
+;;
+;;  If you use `icicle-define-command' or `icicle-define-file-command'
+;;  to define a command (recommended), then you can simply pass the
+;;  filter-variable bindings as part of the BINDINGS argument.
+;;
+;;  For convenience you can use macros `icicle-buffer-bindings' and
+;;  `icicle-file-bindings' to provide bindings that are appropriate
+;;  for buffer-name and file-name completion, respectively.  For
+;;  example, macro `icicle-buffer-bindings' expands to include these
+;;  bindings, among others:
+;;
+;;   (icicle-must-match-regexp             icicle-buffer-match-regexp)
+;;   (icicle-must-not-match-regexp      icicle-buffer-no-match-regexp)
+;;   (icicle-must-pass-after-match-predicate  icicle-buffer-predicate)
+;;   (icicle-require-match-flag      icicle-buffer-require-match-flag)
+;;   (icicle-extra-candidates                    icicle-buffer-extras)
+;;   (icicle-ignore-space-prefix-flag
+;;                             icicle-buffer-ignore-space-prefix-flag)
+;;   (icicle-delete-candidate-object            'icicle-kill-a-buffer)
+;;
+;;  As an example of using this macro, here is the core definition of
+;;  `icicle-buffer':
+;;
+;;   (icicle-define-command
+;;    icicle-buffer                          ; Command name
+;;    "Switch to a different buffer."        ; Doc string
+;;    switch-to-buffer                       ; Action function
+;;    "Switch to buffer: "                   ; `completing-read' args
+;;    (mapcar (lambda (buf) (list (buffer-name buf))) (buffer-list))
+;;    nil nil nil 'buffer-name-history
+;;    (icicle-default-buffer-names) nil
+;;    ;; Filter bindings
+;;    (icicle-buffer-bindings))       ; Macro provides buffer bindings
+;;
+;;  If you define a command that uses completion, but you do not use
+;;  `icicle-define-command' or `icicle-define-file-command', then you
+;;  can just bind appropriate variables individually around a call to
+;;  `completing-read' or `read-file-name'.
+;;
+;;  Another way that users can apply predicates to completion
+;;  candidates is to use `M-&' while completing.  These predicates
+;;  apply to the full alist-entry candidates that are supplied to
+;;  `completing-read' or `read-file-name', not just to the textual
+;;  candidates that are displayed in buffer `*Completions*'.
+;;  See (@file :file-name "icicles-doc1.el" :to "Progressive Completion").
+ 
+;;(@* "Specifying Match Functions for Commands")
+;;
+;;  Defining Commands that Use Specific Match Functions
+;;  ---------------------------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  By default, Icicles lets users use basic prefix completion (with
+;;  `TAB') or apropos completion (with `S-TAB'). They can
+;;  alternatively use other completion methods with `TAB' and `S-TAB':
+;;
+;;  * They can use `C-(' during completion to cycle among `TAB'
+;;    completion methods.
+;;
+;;  * They can use `M-(' to cycle among `S-TAB' completion
+;;    methods.
+;;
+;;  * They can customize options `icicle-TAB-completion-methods-alist'
+;;    and `icicle-S-TAB-completion-methods-alist', to define the
+;;    completion methods among which they can cycle.
+;;
+;;  When you define an Icicles command, you can specify which
+;;  string-matching functions the command uses during completion:
+;;
+;;  * If you want the command to use fuzzy completion for `TAB' by
+;;    default, then bind `icicle-fuzzy-completion-flag' to
+;;    non-`nil'. Users can still use `C-(' to toggle fuzzy completion
+;;    off.
+;;
+;;  * If you want the command to use a particular string-matching
+;;    function for `S-TAB' completion by default, then bind variable
+;;    `icicle-apropos-complete-match-fn' to that function. Users can
+;;    still use `M-(' to cycle among the other matching functions for
+;;    `S-TAB'.
+;;
+;;  You can bind `icicle-apropos-complete-match-fn' to any function
+;;  that matches strings.  You will probably also want to ensure that
+;;  it is available for `M-(' cycling, by adding it to
+;;  `icicle-S-TAB-completion-methods-alist' in a `let' binding.  For
+;;  example, to use matching function `my-match' in `my-cmd', you
+;;  might do this:
+;;
+;;  (defun my-cmd ()
+;;    "..."
+;;    (interactive)
+;;    (let ((icicle-apropos-complete-match-fn  'my-match)
+;;          (icicle-S-TAB-completion-methods-alist
+;;           (cons (cons "mine" 'my-match)
+;;                 icicle-S-TAB-completion-methods-alist)))
+;;        (do-something (completing-read "Choose: " ...) ...)))
+ 
+;;(@* "Defining Buffer-Text Completion for Comint Modes")
+;;
+;;  Defining Buffer-Text Completion for Comint Modes
+;;  ------------------------------------------------
+;;
+;;  This section is for Emacs-Lisp programmers.
+;;
+;;  Out of the box, Icicles provides completion for buffer text in
+;;  some contexts.  This includes Shell mode, for example.  Whenever
+;;  there are two or more candidate completions, you can use Icicles
+;;  completion, with all of its features (cycling, progressive
+;;  completion, apropos completion, and so on).
+;;  See (@> "Completion in Comint Modes").
+;;
+;;  Shell mode is an example of a mode that inherits from Comint mode.
+;;  Other libraries sometimes define modes that also extend Comint
+;;  mode in different ways.  Library ESS does so, for example.
+;;
+;;  In such modes, the top-level completion command used is typically
+;;  `comint-dynamic-complete', and it is typically bound to `TAB'.  In
+;;  Icicle mode, `TAB' in such a buffer is instead bound to the
+;;  Icicles version of this command, `icicle-comint-dynamic-complete'.
+;;
+;;  Icicles provides the infrastructure for you to take advantage of
+;;  Icicles completion with your own modes that inherit from Comint
+;;  mode.  For that, just do the following:
+;;
+;;  1. Define replacement functions for the functions that perform the
+;;     completion.  The functions to be replaced themselves typically
+;;     call a Comint completion function, such as
+;;     `comint-dynamic-complete-filename'.  You can typically use the
+;;     same definitions as the original functions, except replace the
+;;     call to a function that displays multiple matching candidates
+;;     by a call to a corresponding Icicles function that performs
+;;     completion.
+;;
+;;  2. Customize option `icicle-comint-dynamic-complete-replacements',
+;;     adding the mappings that specify which standard functions to
+;;     replace with your completion functions (from #1).  Take a look
+;;     at the default value of this option to see what I mean.
+;;
+;;  3. Use `eval-after-load' to toggle Icicle mode when the vanilla
+;;     code for your mode is loaded, to ensure that the original
+;;     definitions are picked up.  See the end of `icicles-mode.el'
+;;     for an example of this.
+;;
+;;  If you are interested in trying this, take a look at the Icicles
+;;  code for, say, `icicle-shell-dynamic-complete-command', comparing
+;;  it with the original code for `shell-dynamic-complete-command'.
+;;  You will see that the only change is to substitute a call to
+;;  `icicle-shell-dynamic-complete-as-command' for a call to
+;;  `shell-dynamic-complete-as-command'.  Likewise,
+;;  `icicle-shell-dynamic-complete-as-command' is a trivial alteration
+;;  of `shell-dynamic-complete-as-command'.
+;;
+;;  The key is to ultimately call an Icicles completion command, such
+;;  as `icicle-comint-dynamic-simple-complete', whenever there are
+;;  multiple completion candidates.  This has the effect of using
+;;  Icicles minibuffer completion instead of simply displaying the
+;;  alternatives in buffer `*Completions*'.
+;;
+;;  Icicles uses this same technique, of substituting Icicles
+;;  completion for simple display of alternatives, for all buffer-text
+;;  completion that it supports out of the box, even when there is no
+;;  relation with Comint mode.
+ 
+;;(@* "Note to Programmers")
+;;
+;;  Note to Programmers
+;;  -------------------
+;;
+;;  Here are some simple guidelines for using Icicles in Emacs-Lisp
+;;  programming:
+;;
+;;  1. *Use it*!  Even if you do not do anything else, include this in
+;;     your library:
+;;
+;;     (require 'icicles nil t)
+;;
+;;     That has absolutely no consequences if Icicles is not present
+;;     in the user's `load-path' (there is no load error).  If Icicles
+;;     is present, however, then users can take advantage of each use
+;;     you make of `completing-read' and `read-file-name' in your
+;;     code.
+;;
+;;  2. Use an input-completion read function, such as
+;;     `completing-read' or `read-file-name', when you read input!
+;;     There is almost never a reason not to use an input-completion
+;;     function when reading user input - especially considering that
+;;     you need not always provide a REQUIRE-MATCH argument.
+;;
+;;     Try also to find an appropriate PREDICATE argument, and a good
+;;     set of default values to pass to `completing-read' as its
+;;     COLLECTION argument.  Too often, I think, we use an overly
+;;     general COLLECTION argument, such as the `obarray', and we do
+;;     not provide a (good) PREDICATE.  Using an input-completion
+;;     function with an appropriate candidate completion list and
+;;     predicate can help users considerably.
+;;
+;;     If you want to also give users a way to customize a (different)
+;;     predicate that applies only to the textual candidates that are
+;;     displayed in buffer `*Completions*', as opposed to the full
+;;     alist-entry candidates that are supplied to `completing-read'
+;;     or `read-file-name', then you can define a new user option and
+;;     then bind internal variable `icicle-must-pass-predicate' to the
+;;     value of that option. See (@> "Global Filters").
+;;
+;;  3. Avoid using a literal-string `interactive' spec (e.g.
+;;     (interactive "fFile: ")) that reads input with completion.
+;;     Instead, call `completing-read' or `read-file-name' within the
+;;     `interactive' spec.  This saves Icicles users of progressive
+;;     completion the need to hit `RET' multiple times to pass their
+;;     input up through multiple levels of recursive minibuffers to
+;;     the top level.  See
+;;     (@file :file-name "icicles-doc1.el" :to "Progressive Completion").
+;;
+;;  4. In many cases, it makes sense to define a multi-command, rather
+;;     than a simple command.  People can always use a multi-command
+;;     as a simple command, but not vice versa.
+;;     See (@file :file-name "icicles-doc1.el" :to "Multi-Commands"),
+;;     (@> "Defining Icicles Commands (Including Multi-Commands)"),
+;;     and (@> "Defining Multi-Commands the Hard Way").
+;;
+;;  5. Consider using `icicle-completing-read-history' instead of
+;;     `read-from-minibuffer' or `read-string' for most purposes.
+;;     This lets users complete their input against previously entered
+;;     input.  Completion is lax, so they can also enter new input.
+;;
+;;  6. You can bind `icicle-sort-comparer' temporarily to any sort
+;;     function you need.
+;;
+;;  7. Function `icicle-next-candidate' is a general framework for
+;;     letting users cycle completions of partial input strings.  I
+;;     use it to define the cycling behavior for both prefix and
+;;     apropos completions.  You can use it to easily define other,
+;;     application-specific input matching/completion/cycling
+;;     behavior.  Just supply it with a function that takes the
+;;     current partial user input (a string) and returns a list of
+;;     candidate completions, however those might be defined.
+;;
+;;  8. If the potential number of completion candidates is enormous,
+;;     then icompletion display in `*Completions*' can be slow.  In
+;;     that case, consider turning it off for the duration of the
+;;     command, by binding `icicle-incremental-completion-flag' to
+;;     `nil'.  An alternative to turning it off is the approach taken
+;;     in Icicles (e.g. `icicle-vardoc' and
+;;     `icicle-insert-thesaurus-entry'): Just add a reminder to the
+;;     doc string to tell users that they can toggle
+;;     `icicle-incremental-completion-flag' with `C-#'.
+;;
+;;  9. Another of my libraries that can help programmers provide
+;;     default values is `thingatpt+.el'.  It provides functions for
+;;     picking up symbols, sexps, numbers, words, and other sorts of
+;;     thing near the text cursor (`point').
+;;
+;;  See Also:
+;;
+;;  * (@file :file-name "icicles-doc1.el" :to "Multi-Commands")
+;;  * (@> "Defining Icicles Commands (Including Multi-Commands)")
+;;  * (@> "Defining Multi-Commands the Hard Way")
+;;  * (@> "Defining Multiple-Choice Menus")
+;;  * (@> "Global Filters")
+;;  * (@> "Specifying Match Functions for Commands")
+;;  * (@> "Multi-Completions")
+ 
+;;(@* "La Petite Histoire")
+;;
+;;  La Petite Histoire
+;;  ------------------
+;;
+;;  1. This library started life as `elect-mbuf.el', by Hans Koomen.
+;;
+;;    Original posting:
+;;    From koomen@cs.rochester.edu Mon Jun 19 19:27:58 1989
+;;    To: info-gnu-emacs@prep.ai.mit.edu
+;;    Cc: Hans 
+;;    Subject: elect-mbuf.el
+;;    Date: Tue, 13 Jun 89 15:17:07 -0400
+;;
+;;  2. I hacked and enhanced the library in various relatively minor
+;;  ways over the years, maintaining it as `elect-mbuf.el' - see
+;;  details in file `icicles-chg.el'.
+;;
+;;  I did not change the main functionality of the library during this
+;;  period: it always cycled the COMPLETE list of (prefix) completion
+;;  candidates passed to `completing-read'; it did not update the
+;;  candidate list based on the current minibuffer contents.
+;;
+;;  So, for instance, if you had `M-x for' in the minibuffer, `down'
+;;  would cycle among ALL Emacs commands, not just those that start
+;;  with "for".  I used the library this way for fifteen years without
+;;  thinking much about this behavior or the code behind it.
+;;
+;;  3. In July 2005, Lennart Borgman gave `elect-mbuf.el' a quick try,
+;;  and intuitively expected to see behavior along the lines that you
+;;  see now for Icicles prefix completion:
+;;
+;;  a. `down' should cycle completions relative to the current input,
+;;     not all completions supplied to `completing-read'.
+;;  b. If buffer `*Completions*' is displayed, `down' should highlight
+;;     the current candidate there.
+;;
+;;  Good idea Lennart ().  So I
+;;  implemented that behavior, and renamed the library "Icicles" (for,
+;;  I suppose, "input cycles" or some such - or because it's "cool").
+;;
+;;  4. The code changes I made to implement #3 (completion cycling
+;;  relative to current input) made me realize that other completion
+;;  matchings could be implemented in a similar way.  Prefix
+;;  completion (the completion provided by Emacs) is handy, but it is
+;;  also sometimes a bit limited.  The idea of apropos completion
+;;  occurred to me, and I implemented that as well.
+;;
+;;  5. I extended the library quite a bit more, in terms of
+;;  convenience (highlighting, treatment of buffer
+;;  `*Completions*',..., but also in terms of functionality.  In
+;;  particular, it now treats file names too.  And, because Emacs 21
+;;  and later versions use `read-file-name' for `find-file' and so on,
+;;  Icicles now treats `read-file-name' the same as `completing-read'.
+;;
+;;  6. On another suggestion from LennartBorgman, I made Icicles take
+;;  advantage of Delete Selection mode.  And I implemented it as a
+;;  minor mode.
+;;
+;;  7, 8, 9,...  One thing has led to another, and I've just kept
+;;  adding features.  Feature creep, I guess.  But the more I play
+;;  with Icicles, the more I imagine new ways it might be made more
+;;  useful.
+ 
+;;(@* "Note on Non-`nil' `pop-up-frames' on MS Windows")
+;;
+;;  Note on Non-`nil' `pop-up-frames' on MS Windows
+;;  -----------------------------------------------
+;;
+;;  If you use `pop-up-frames' = `t', like I do, you might have
+;;  noticed that Emacs completion does not play well with using
+;;  separate frames for each buffer.  In particular, it does not play
+;;  well with having a separate frame for buffer `*Completions*'.
+;;  When you try to complete input using `TAB', a new frame is created
+;;  for buffer `*Completions*', and, at least on MS Windows, it is
+;;  selected, taking the input focus away from the original frame's
+;;  minibuffer!
+;;
+;;  This means that, once the `*Completions*' buffer has been
+;;  displayed in a separate frame, you cannot, for instance, cycle
+;;  completion candidates, without first reselecting the original
+;;  frame manually.  You cannot even use normal completion - you
+;;  cannot add text in the minibuffer, or delete text there, because
+;;  the minibuffer in the original frame no longer has the input
+;;  focus.  Bummer.
+;;
+;;  In general, Emacs does not play too well with one-buffer-per-frame
+;;  (`pop-up-frames' = `t'), and this is a good example of that
+;;  general problem.
+;;
+;;  I reported this Emacs bug.  I've been hoping it will be corrected
+;;  since Emacs 21...
+;;
+;;  I do not have this problem of loss of frame input focus in my own
+;;  setup, even though I use `pop-up-frames' = `t', because I use my
+;;  library `oneonone.el'.  (Try it!)  If you need a solution while
+;;  waiting for the Emacs fix, you can try doing something similar to
+;;  what I do in `oneonone.el':
+;;
+;;  1. Use dedicated frames for both `*Completions*' and the
+;;     minibuffer.
+;;
+;;  2. Display buffer `*Completions*' using a special-display function
+;;     that explicitly redirects the input focus from the
+;;     `*Completions*' frame back to the minibuffer frame.
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; You need not load this file.  It contains only documentation.
+
+(provide 'icicles-doc2)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-doc2.el ends here
diff --git a/auto-install/icicles-face.el b/auto-install/icicles-face.el
new file mode 100644
index 0000000..afe2808
--- /dev/null
+++ b/auto-install/icicles-face.el
@@ -0,0 +1,716 @@
+;;; icicles-face.el --- Faces for Icicles
+;;
+;; Filename: icicles-face.el
+;; Description: Faces for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:19:43 2006
+;; Version: 22.0
+;; Last-Updated: Tue Aug 16 16:21:58 2011 (-0700)
+;;           By: dradams
+;;     Update #: 574
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-face.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  customization groups and faces.  For Icicles documentation, see
+;;  `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Groups defined here:
+;;
+;;    `Icicles', `Icicles-Buffers', `Icicles-Completions-Display',
+;;    `Icicles-Files', `Icicles-Key-Bindings',
+;;    `Icicles-Key-Completion', `Icicles-Matching',
+;;    `Icicles-Minibuffer-Display', `Icicles-Miscellaneous',
+;;    `Icicles-Searching'.
+;;
+;;  Faces defined here:
+;;
+;;    `icicle-candidate-part',
+;;    `icicle-common-match-highlight-Completions',
+;;    `icicle-complete-input', `icicle-completion',
+;;    `icicle-Completions-instruction-1',
+;;    `icicle-Completions-instruction-2',
+;;    `icicle-current-candidate-highlight', `icicle-extra-candidate',
+;;    `icicle-historical-candidate', `icicle-input-completion-fail',
+;;    `icicle-input-completion-fail-lax',
+;;    `icicle-match-highlight-Completions',
+;;    `icicle-match-highlight-minibuffer', `icicle-mode-line-help',
+;;    `icicle-multi-command-completion',
+;;    `icicle-mustmatch-completion', `icicle-proxy-candidate',
+;;    `icicle-saved-candidate', `icicle-search-context-level-1',
+;;    `icicle-search-context-level-2',
+;;    `icicle-search-context-level-3',
+;;    `icicle-search-context-level-4',
+;;    `icicle-search-context-level-5',
+;;    `icicle-search-context-level-6',
+;;    `icicle-search-context-level-7',
+;;    `icicle-search-context-level-8', `icicle-search-current-input',
+;;    `icicle-search-main-regexp-current',
+;;    `icicle-search-main-regexp-others', `icicle-special-candidate',
+;;    `icicle-whitespace-highlight', `minibuffer-prompt'.
+;;
+;;  Functions defined here:
+;;
+;;    `icicle-increment-color-hue',
+;;    `icicle-increment-color-saturation'
+;;    `icicle-increment-color-value'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Groups, organized alphabetically")
+;;  (@> "Faces, organized alphabetically")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; ;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'hexrgb nil t)) ;; (no error if not found):
+  ;; hexrgb-color-values-to-hex, hexrgb-hsv-to-rgb, hexrgb-rgb-to-hsv.
+
+(require 'icicles-mac) ;; icicle-maybe-byte-compile-after-load
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Groups, organized alphabetically")
+
+;;; Groups, organized alphabetically ---------------------------------
+
+;;;###autoload
+(defgroup Icicles nil
+  "Minibuffer input completion and cycling of completion candidates."
+  :prefix "icicle-"
+  :group 'completion :group 'convenience :group 'help :group 'apropos
+  :group 'dabbrev :group 'matching :group 'minibuffer :group 'recentf
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Buffers nil
+  "Icicles preferences related to buffers."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Files nil
+  "Icicles preferences related to files."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Completions-Display nil
+  "Icicles preferences related to display of completion candidates."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Key-Bindings nil
+  "Icicles preferences related to key bindings."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Key-Completion nil
+  "Icicles preferences related to key completion (`icicle-complete-keys')."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Matching nil
+  "Icicles preferences related to matching input for completion."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Minibuffer-Display nil
+  "Icicles preferences related to minibuffer display during completion."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Miscellaneous nil
+  "Miscellaneous Icicles preferences."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+
+;;;###autoload
+(defgroup Icicles-Searching nil
+  "Icicles preferences related to searching."
+  :prefix "icicle-" :group 'Icicles
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle"
+                   ".com?subject=icicles.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and Icicles library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icicles.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/Icicles")
+  :link '(emacs-commentary-link :tag "Doc-Part2" "icicles-doc2")
+  :link '(emacs-commentary-link :tag "Doc-Part1" "icicles-doc1")
+  )
+ 
+;;(@* "Faces, organized alphabetically")
+
+;;; Faces, organized alphabetically ----------------------------------
+
+;;;###autoload
+(defface icicle-candidate-part
+    '((((background dark)) (:background "#451700143197")) ; a very dark magenta
+      (t (:background "#EF84FFEAF427"))) ; A light green.
+  "*Face used to highlight part(s) of a candidate in `*Completions*'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-common-match-highlight-Completions
+    '((((background dark)) (:foreground "#2017A71F2017")) ; a dark green
+      (t (:foreground "magenta3")))
+  "*Face used to highlight candidates common match, in `*Completions*'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-complete-input
+  '((((background dark)) (:foreground "#B19E6A64B19E")) ; a dark magenta
+    (t (:foreground "DarkGreen")))
+  "*Face used to highlight input when it is complete."
+  :group 'Icicles-Minibuffer-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-completion
+    '((((background dark)) (:foreground "#0000D53CD53C")) ; a dark cyan
+      (t (:foreground "Red")))                            ; red
+  "*Face used to indicate minibuffer completion.
+It highlights the minibuffer indicator and the `Icy' minor-mode
+lighter during completion.
+Not used for versions of Emacs before version 21."
+  :group 'Icicles-Minibuffer-Display :group 'Icicles-Miscellaneous :group 'faces)
+
+;;;###autoload
+(defface icicle-Completions-instruction-1
+  '((((background dark)) (:foreground "#AC4AAC4A0000")) ; a dark yellow
+    (t (:foreground "Blue")))
+  "*Face used to highlight first line of `*Completions*' buffer."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-Completions-instruction-2
+    '((((background dark)) (:foreground "#0000D53CD53C")) ; a dark cyan
+      (t (:foreground "Red")))
+  "*Face used to highlight second line of `*Completions*' buffer."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-current-candidate-highlight
+  '((((background dark)) (:background "#69D40A460000")) ; a red brown
+    (t (:background "CadetBlue1")))
+  "*Face used to highlight the current candidate, in `*Completions*'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-extra-candidate
+    '((((background dark)) (:background "#4517305D0000")) ; a dark brown
+      (t (:background "#C847D8FEFFFF"))) ; a light blue
+  "*Face used to highlight `*Completions*' candidates that are extra.
+This means that they belong to list `icicle-extra-candidates'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-historical-candidate
+  '((((background dark)) (:foreground "#DBD599DF0000")) ; a dark orange
+    (t (:foreground "Blue")))
+  "*Face used to highlight `*Completions*' candidates that have been used."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-input-completion-fail
+    '((((background dark)) (:background "#22225F5F2222")) ; a dark green
+      (t (:foreground "Black" :background "Plum")))
+  "*Face for highlighting failed part of input during strict completion."
+  :group 'Icicles-Minibuffer-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-input-completion-fail-lax
+    '((((background dark)) (:background "#00005E3B5A8D")) ; a dark cyan
+      (t (:foreground "Black" :background "#FFFFB8C4BB87")))
+  "*Face for highlighting failed part of input during lax completion."
+  :group 'Icicles-Minibuffer-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-match-highlight-Completions
+    '((((background dark)) (:foreground "#1F1FA21CA21C")) ; a very dark cyan
+      (t (:foreground "Red3")))
+  "*Face used to highlight root that was completed, in `*Completions*'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-match-highlight-minibuffer '((t (:underline t)))
+  "*Face used to highlight root that was completed, in minibuffer."
+  :group 'Icicles-Minibuffer-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-mode-line-help
+  '((((background dark)) (:foreground "#AC4AAC4A0000")) ; a dark yellow
+    (t (:foreground "Blue")))
+  "*Face used to highlight help shown in the mode-line."
+  :group 'Icicles-Completions-Display :group 'Icicles-Miscellaneous :group 'faces)
+
+;;;###autoload
+(defface icicle-multi-command-completion
+    '((((background dark)) ; a dark cyan on a dark magenta
+       (:foreground "#0000D53CD53C" :background "#8B3500007533"))
+      (t (:foreground "Red" :background "#78F6FFFF8E4F"))) ; red on a light green
+  "*Face used to indicate Icicles multi-command completion.
+It highlights the minibuffer indicator and the `Icy+' minor-mode
+lighter during multi-command completion.
+Not used for versions of Emacs before version 21."
+  :group 'Icicles-Minibuffer-Display :group 'Icicles-Miscellaneous :group 'faces)
+
+;;;###autoload
+(defface icicle-mustmatch-completion
+    '((((type x w32 mac graphic) (class color))
+       (:box (:line-width -2 :color "Blue"))) ; blue box
+      (t (:inverse-video t)))
+  "*Face used to indicate strict minibuffer completion.
+It highlights the minibuffer indicator and the `Icy' or `Icy+'
+minor-mode lighter during strict completion.
+Not used for versions of Emacs before version 21."
+  :group 'Icicles-Minibuffer-Display :group 'Icicles-Miscellaneous :group 'faces)
+
+;;;###autoload
+(defface icicle-proxy-candidate
+    '((((background dark)) (:background "#316B22970000")) ; a very dark brown
+      (t (:background "#E1E1EAEAFFFF"   ; A light blue.
+          :box (:line-width 2 :color "White" :style released-button))))
+  "*Face used to highlight proxy candidates in `*Completions*'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-saved-candidate
+    '((((background dark)) (:background "gray20"))   ; a dark gray
+      (t (:background "gray80"))) ; a light gray
+  "*Face used to highlight `*Completions*' candidates that have been saved."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-search-main-regexp-current
+  '((((background dark)) (:background "#00004AA652F1")) ; a dark cyan
+    (t (:background "misty rose")))
+  "*Face used to highlight current match of your search context regexp.
+This highlighting is done during Icicles searching."
+  :group 'Icicles-Searching :group 'faces)
+
+(eval-after-load "hexrgb"
+  '(progn
+
+    ;; Essentially a version of `doremi-increment-color-component' for hue only.
+    ;; Must be before `icicle-search-context-level-1'.
+    (defun icicle-increment-color-hue (color increment)
+      "Increase hue component of COLOR by INCREMENT."
+      (unless (string-match "#" color)  ; Convert color name to #hhh...
+        (setq color  (hexrgb-color-values-to-hex (x-color-values color))))
+      ;; Convert RGB to HSV
+      (let* ((rgb         (x-color-values color))
+             (red         (/ (float (nth 0 rgb)) 65535.0)) ; Convert from 0-65535 to 0.0-1.0
+             (green       (/ (float (nth 1 rgb)) 65535.0))
+             (blue        (/ (float (nth 2 rgb)) 65535.0))
+             (hsv         (hexrgb-rgb-to-hsv red green blue))
+             (hue         (nth 0 hsv))
+             (saturation  (nth 1 hsv))
+             (value       (nth 2 hsv)))
+        (setq hue  (+ hue (/ increment 100.0)))
+        (when (> hue 1.0) (setq hue  (1- hue)))
+        (hexrgb-color-values-to-hex (mapcar (lambda (x) (floor (* x 65535.0)))
+                                            (hexrgb-hsv-to-rgb hue saturation value)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-increment-color-hue)
+
+
+    ;; Essentially a version of `doremi-increment-color-component' for saturation only.
+    ;; Must be before `icicle-search-context-level-1'.
+    (defun icicle-increment-color-saturation (color increment)
+      "Increase saturation component of COLOR by INCREMENT."
+      (unless (string-match "#" color)  ; Convert color name to #hhh...
+        (setq color  (hexrgb-color-values-to-hex (x-color-values color))))
+      ;; Convert RGB to HSV
+      (let* ((rgb         (x-color-values color))
+             (red         (/ (float (nth 0 rgb)) 65535.0)) ; Convert from 0-65535 to 0.0-1.0
+             (green       (/ (float (nth 1 rgb)) 65535.0))
+             (blue        (/ (float (nth 2 rgb)) 65535.0))
+             (hsv         (hexrgb-rgb-to-hsv red green blue))
+             (hue         (nth 0 hsv))
+             (saturation  (nth 1 hsv))
+             (value       (nth 2 hsv)))
+        (setq saturation  (+ saturation (/ increment 100.0)))
+        (when (> saturation 1.0) (setq saturation  (1- saturation)))
+        (hexrgb-color-values-to-hex (mapcar (lambda (x) (floor (* x 65535.0)))
+                                            (hexrgb-hsv-to-rgb hue saturation value)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-increment-color-saturation)
+
+
+    ;; Essentially a version of `doremi-increment-color-component' for value only.
+    ;; Must be before `icicle-region-background'.
+    (defun icicle-increment-color-value (color increment)
+      "Increase value component (brightness) of COLOR by INCREMENT."
+      (unless (string-match "#" color)  ; Convert color name to #hhh...
+        (setq color  (hexrgb-color-values-to-hex (x-color-values color))))
+      ;; Convert RGB to HSV
+      (let* ((rgb         (x-color-values color))
+             (red         (/ (float (nth 0 rgb)) 65535.0)) ; Convert from 0-65535 to 0.0-1.0
+             (green       (/ (float (nth 1 rgb)) 65535.0))
+             (blue        (/ (float (nth 2 rgb)) 65535.0))
+             (hsv         (hexrgb-rgb-to-hsv red green blue))
+             (hue         (nth 0 hsv))
+             (saturation  (nth 1 hsv))
+             (value       (nth 2 hsv)))
+        (setq value  (+ value (/ increment 100.0)))
+        (when (> value 1.0) (setq value  (1- value)))
+        (hexrgb-color-values-to-hex (mapcar (lambda (x) (floor (* x 65535.0)))
+                                            (hexrgb-hsv-to-rgb hue saturation value)))))
+
+    (icicle-maybe-byte-compile-after-load icicle-increment-color-value)
+
+    ))
+
+;;;###autoload
+(defface icicle-search-context-level-1
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-saturation
+                            (icicle-increment-color-hue context-bg 80) 10)
+                           "#071F473A0000"))) ; a dark green
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-saturation
+                              (icicle-increment-color-hue context-bg 80) 10)
+                             "#FA6CC847FFFF"))))) ; a light magenta
+  "*Face used to highlight level (subgroup match) 1 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-2
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-saturation
+                            (icicle-increment-color-hue context-bg 40) 10)
+                           "#507400002839"))) ; a dark red
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-saturation
+                              (icicle-increment-color-hue context-bg 40) 10)
+                             "#C847FFFFE423"))))) ; a light cyan
+  "*Face used to highlight level (subgroup match) 2 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-3
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-saturation
+                            (icicle-increment-color-hue context-bg 60) 10)
+                           "#4517305D0000"))) ; a dark brown
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-saturation
+                              (icicle-increment-color-hue context-bg 60) 10)
+                             "#C847D8FEFFFF"))))) ; a light blue
+  "*Face used to highlight level (subgroup match) 3 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-4
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-saturation
+                            (icicle-increment-color-hue context-bg 20) 10)
+                           "#176900004E0A"))) ; a dark blue
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-saturation
+                              (icicle-increment-color-hue context-bg 20) 10)
+                             "#EF47FFFFC847"))))) ; a light yellow
+  "*Face used to highlight level (subgroup match) 4 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-5
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-hue context-bg 80)
+                           "#04602BC00000"))) ; a very dark green
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-hue context-bg 80)
+                             "#FCFCE1E1FFFF"))))) ; a light magenta
+  "*Face used to highlight level (subgroup match) 5 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-6
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-hue context-bg 40)
+                           "#32F200001979"))) ; a very dark red
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-hue context-bg 40)
+                             "#E1E1FFFFF0F0"))))) ; a light cyan
+  "*Face used to highlight level (subgroup match) 6 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-7
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-hue context-bg 60)
+                           "#316B22970000"))) ; a very dark brown
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-hue context-bg 60)
+                             "#E1E1EAEAFFFF"))))) ; a light blue
+  "*Face used to highlight level (subgroup match) 7 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-context-level-8
+    (let ((context-bg  (face-background 'icicle-search-main-regexp-current)))
+      `((((background dark))
+         (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                           (icicle-increment-color-hue context-bg 20)
+                           "#12EC00003F0E"))) ; a very dark blue
+        (t (:background ,(if (fboundp 'icicle-increment-color-saturation)
+                             (icicle-increment-color-hue context-bg 20)
+                             "#F6F5FFFFE1E1"))))) ; a light yellow
+  "*Face used to highlight level (subgroup match) 8 of your search context.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-current-input
+    '((((background dark))
+       (:foreground "White" :background "#7F0D00007F0D")) ; a dark magenta
+      (t (:foreground "Black" :background "Green")))
+  "*Face used to highlight what your current input matches.
+This highlighting is done during Icicles searching whenever
+`icicle-search-highlight-context-levels-flag' is non-nil and the
+search context corresponds to the entire regexp."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-search-main-regexp-others
+  '((((background dark)) (:background "#348608690000")) ; a very dark brown
+    (t (:background "CadetBlue1")))
+  "*Face used to highlight other matches of your search context regexp.
+If user option `icicle-search-highlight-threshold' is less than one,
+then this face is not used.
+This highlighting is done during Icicles searching."
+  :group 'Icicles-Searching :group 'faces)
+
+;;;###autoload
+(defface icicle-special-candidate
+    '((((background dark)) (:background "#176900004E0A")) ; a dark blue
+      (t (:background "#EF47FFFFC847")))   ; A light yellow.
+  "*Face used to highlight `*Completions*' candidates that are special.
+The meaning of special is that their names match
+`icicle-special-candidate-regexp'."
+  :group 'Icicles-Completions-Display :group 'faces)
+
+;;;###autoload
+(defface icicle-whitespace-highlight
+    '((((background dark)) (:background "#000093F402A2")) ; a medium green
+      (t (:background "Magenta")))
+  "*Face used to highlight initial whitespace in minibuffer input."
+  :group 'Icicles-Minibuffer-Display :group 'faces)
+
+;; This is defined in `faces.el', Emacs 22.  This is for Emacs < 22.  This is used
+;; only for versions of Emacs that have `propertize' but don't have this face.
+(unless (facep 'minibuffer-prompt)
+  (defface minibuffer-prompt '((((background dark)) (:foreground "cyan"))
+                               (t (:foreground "dark blue")))
+    "*Face for minibuffer prompts."
+    :group 'basic-faces))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-face)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-face.el ends here
diff --git a/auto-install/icicles-fn.el b/auto-install/icicles-fn.el
new file mode 100644
index 0000000..de65379
--- /dev/null
+++ b/auto-install/icicles-fn.el
@@ -0,0 +1,6331 @@
+;;; icicles-fn.el --- Non-interactive functions for Icicles
+;;
+;; Filename: icicles-fn.el
+;; Description: Non-interactive functions for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:25:53 2006
+;; Version: 22.0
+;; Last-Updated: Mon Sep  5 12:44:24 2011 (-0700)
+;;           By: dradams
+;;     Update #: 12563
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-fn.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos-fn+var', `backquote', `bytecomp', `cl',
+;;   `el-swank-fuzzy', `ffap', `ffap-', `fuzzy', `fuzzy-match',
+;;   `hexrgb', `icicles-face', `icicles-mac', `icicles-opt',
+;;   `icicles-var', `kmacro', `levenshtein', `regexp-opt',
+;;   `thingatpt', `thingatpt+', `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  non-interactive functions.  For Icicles documentation, see
+;;  `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Macros defined here:
+;;
+;;    `icicle-maybe-cached-action'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `assq-delete-all', `icicle-2nd-part-string-less-p',
+;;    `icicle-abbreviate-or-expand-file-name',
+;;    `icicle-all-completions', `icicle-alpha-p',
+;;    `icicle-alt-act-fn-for-type', `icicle-any-candidates-p',
+;;    `icicle-apropos-any-candidates-p',
+;;    `icicle-apropos-any-file-name-candidates-p',
+;;    `icicle-apropos-candidates',
+;;    `icicle-barf-if-outside-Completions',
+;;    `icicle-barf-if-outside-Completions-and-minibuffer',
+;;    `icicle-barf-if-outside-minibuffer',
+;;    `icicle-buffer-file/process-name-less-p',
+;;    `icicle-buffer-smaller-p',
+;;    `icicle-call-then-update-Completions', `icicle-candidate-set-1',
+;;    `icicle-candidate-short-help',
+;;    `icicle-case-insensitive-string-less-p',
+;;    `icicle-case-string-less-p', `icicle-cdr-lessp',
+;;    `icicle-choose-completion-string', `icicle-clear-lighter',
+;;    `icicle-clear-minibuffer', `icicle-color-name-w-bg',
+;;    `icicle-color-rgb-lessp', `icicle-command-abbrev-save',
+;;    `icicle-command-abbrev-used-more-p',
+;;    `icicle-command-names-alphabetic-p',
+;;    `icicle-complete-again-update', `icicle-completing-p',
+;;    `icicle-completing-read', `icicle-completing-read-multiple',
+;;    `icicle-completing-read-history',
+;;    `icicle-completion-all-completions',
+;;    `icicle-completion-setup-function',
+;;    `icicle-completion-try-completion', `icicle-current-TAB-method',
+;;    `icicle-custom-type', `icicle-define-crm-completion-map',
+;;    `icicle-delete-count', `icicle-delete-dups',
+;;    `icicle-delete-whitespace-from-string',
+;;    `icicle-dired-read-shell-command',
+;;    `icicle-dired-smart-shell-command',
+;;    `icicle-dir-prefix-wo-wildcards', `icicle-dirs-first-p',
+;;    `icicle-dirs-last-p', `icicle-displayable-cand-from-saved-set',
+;;    `icicle-display-cand-from-full-cand',
+;;    `icicle-display-completion-list', `icicle-display-Completions',
+;;    `icicle-display-candidates-in-Completions',
+;;    `icicle-expanded-common-match',
+;;    `icicle-expanded-common-match-1', `icicle-expand-file-name-20',
+;;    `icicle-expand-file-or-dir-name',
+;;    `icicle-explicit-saved-completion-candidates',
+;;    `icicle-extra-candidates-first-p',
+;;    `icicle-face-valid-attribute-values', `icicle-file-directory-p',
+;;    `icicle-file-name-apropos-candidates',
+;;    `icicle-file-name-directory',
+;;    `icicle-file-name-directory-w-default',
+;;    `icicle-file-name-input-p', `icicle-file-name-nondirectory',
+;;    `icicle-file-name-prefix-candidates', `icicle-file-readable-p',
+;;    `icicle-file-remote-p', `icicle-file-type-less-p',
+;;    `icicle-file-writable-p', `icicle-filesets-files-under',
+;;    `icicle-files-within', `icicle-files-within-1',
+;;    `icicle-filter-alist', `icicle-filter-wo-input',
+;;    `icicle-first-matching-candidate', `icicle-first-N',
+;;    `icicle-fit-completions-window', `icicle-fix-default-directory',
+;;    `icicle-frames-on', `icicle-fuzzy-candidates',
+;;    `icicle-get-alist-candidate',
+;;    `icicle-get-candidates-from-saved-set',
+;;    `icicle-dired-guess-shell-command', `icicle-help-line-buffer',
+;;    `icicle-help-line-file',
+;;    `icicle-highlight-candidate-in-Completions',
+;;    `icicle-highlight-complete-input',
+;;    `icicle-highlight-initial-whitespace',
+;;    `icicle-highlight-input-noncompletion',
+;;    `icicle-highlight-input-noncompletion-rest',
+;;    `icicle-highlight-lighter', `icicle-historical-alphabetic-p',
+;;    `icicle-increment-cand-nb+signal-end',
+;;    `icicle-input-from-minibuffer', `icicle-insert-candidates',
+;;    `icicle-insert-cand-in-minibuffer',
+;;    `icicle-insert-Completions-help-string',
+;;    `icicle-isearch-complete-past-string', `icicle-join-nth-parts',
+;;    `icicle-key-description', `icicle-kill-a-buffer',
+;;    `icicle-last-modified-first-p', `icicle-levenshtein-match',
+;;    `icicle-levenshtein-one-match', `icicle-levenshtein-one-regexp',
+;;    `icicle-levenshtein-strict-match',
+;;    `icicle-lisp-vanilla-completing-read',
+;;    `icicle-local-keys-first-p', `icicle-make-plain-predicate',
+;;    `icicle-major-mode-name-less-p', `icicle-make-face-candidate',
+;;    `icicle-maybe-sort-and-strip-candidates',
+;;    `icicle-maybe-sort-maybe-truncate', `icicle-mctize-all',
+;;    `icicle-mctized-display-candidate',
+;;    `icicle-mctized-full-candidate',
+;;    `icicle-merge-saved-order-less-p',
+;;    `icicle-minibuffer-default-add-completions',
+;;    `icicle-minibuf-input', `icicle-minibuf-input-sans-dir',
+;;    `icicle-minibuffer-default-add-dired-shell-commands',
+;;    `icicle-minibuffer-prompt-end', `icicle-mode-line-name-less-p',
+;;    `icicle-most-recent-first-p', `icicle-msg-maybe-in-minibuffer',
+;;    `icicle-ms-windows-NET-USE', `icicle-multi-sort',
+;;    `icicle-next-candidate', `icicle-not-basic-prefix-completion-p',
+;;    `icicle-part-1-cdr-lessp', `icicle-part-1-lessp',
+;;    `icicle-part-2-lessp', `icicle-part-3-lessp',
+;;    `icicle-part-4-lessp', `icicle-part-N-lessp',
+;;    `icicle-place-cursor', `icicle-place-overlay',
+;;    `icicle-position', `icicle-prefix-any-candidates-p',
+;;    `icicle-prefix-any-file-name-candidates-p',
+;;    `icicle-prefix-candidates', `icicle-prefix-keys-first-p',
+;;    `icicle-proxy-candidate-first-p', `icicle-put-at-head',
+;;    `icicle-put-whole-cand-prop',
+;;    `icicle-quote-file-name-part-of-cmd',
+;;    `icicle-readable-to-markers', `icicle-read-char-exclusive',
+;;    `icicle-read-face-name', `icicle-read-file-name',
+;;    `icicle-read-from-minibuffer',
+;;    `icicle-read-from-minibuf-nil-default', `icicle-read-number',
+;;    `icicle-read-shell-command',
+;;    `icicle-read-shell-command-completing', `icicle-read-string',
+;;    `icicle-read-string-completing',
+;;    `icicle-recentf-make-menu-items', `icicle-recompute-candidates',
+;;    `icicle-redefine-standard-options',
+;;    `icicle-redefine-std-completion-fns',
+;;    `icicle-remove-color-duplicates', `icicle-remove-dots',
+;;    `icicle-remove-duplicates', `icicle-remove-dups-if-extras',
+;;    `icicle-remove-if', `icicle-remove-if-not',
+;;    `icicle-remove-property', `icicle-replace-mct-cand-in-mct',
+;;    `icicle-require-match-p', `icicle-restore-standard-commands',
+;;    `icicle-restore-standard-options',
+;;    `icicle-restore-std-completion-fns', `icicle-reversible-sort',
+;;    `icicle-saved-fileset-p', `icicle-save-or-restore-input',
+;;    `icicle-save-raw-input', `icicle-scatter',
+;;    `icicle-scatter-match', `icicle-scroll-or-update-Completions',
+;;    `icicle-set-difference', `icicle-set-intersection',
+;;    `icicle-set-union', `icicle-shell-command',
+;;    `icicle-shell-command-on-region',
+;;    `icicle-show-help-in-mode-line', `icicle-show-in-mode-line',
+;;    `icicle-special-candidates-first-p',
+;;    `icicle-start-of-candidates-in-Completions',
+;;    `icicle-strip-ignored-files-and-sort',
+;;    `icicle-subst-envvar-in-file-name',
+;;    `icicle-substring-no-properties', `icicle-substrings-of-length',
+;;    `icicle-take', `icicle-toggle-icicle-mode-twice',
+;;    `icicle-transform-candidates',
+;;    `icicle-transform-multi-completion',
+;;    `icicle-unhighlight-lighter', `icicle-unpropertize',
+;;    `icicle-unsorted-apropos-candidates',
+;;    `icicle-unsorted-file-name-apropos-candidates',
+;;    `icicle-unsorted-file-name-prefix-candidates',
+;;    `icicle-unsorted-prefix-candidates', `icicle-upcase',
+;;    `icicle-value-satisfies-type-p', `icicle-var-inherits-type-p',
+;;    `icicle-var-is-of-type-p', `icicle-var-matches-type-p',
+;;    `icicle-var-val-satisfies-type-p',
+;;    `old-choose-completion-string', `old-completing-read',
+;;    `old-completing-read-multiple', `old-completion-setup-function',
+;;    `old-dired-smart-shell-command', `old-display-completion-list',
+;;    `old-face-valid-attribute-values',
+;;    `old-minibuffer-default-add-completions', `old-read-face-name',
+;;    `old-read-from-minibuffer', `old-read-number',
+;;    `old-read-string', `old-shell-command',
+;;    `old-shell-command-on-region'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `icicle-crm-local-completion-map',
+;;    `icicle-crm-local-must-match-map', `icicle-dirs-done',
+;;    `icicle-files', `old-crm-local-completion-map',
+;;    `old-crm-local-must-match-map'.
+;;
+;;
+;;  ***** NOTE: These EMACS PRIMITIVES have been REDEFINED HERE:
+;;
+;;  `completing-read'              - (See below and doc string.)
+;;  `display-completion-list'      - (See below and doc string.)
+;;  `face-valid-attribute-values'  - (See below and doc string.)
+;;  `read-file-name' Emacs 20, 21 only - (See below and doc string.)
+;;  `read-from-minibuffer'         - (See below and doc string.)
+;;  `read-string'                  - (See below and doc string.)
+;;
+;;
+;;  ***** NOTE: The following functions defined in `simple.el' have
+;;              been REDEFINED HERE:
+;;
+;;  `choose-completion-string' -
+;;     Don't exit minibuffer after `lisp-complete-symbol' completion.
+;;  `completion-setup-function' - 1. Put faces on inserted string(s).
+;;                                2. Help on help.
+;;  `repeat-complex-command' - Use `completing-read' to read command.
+;;
+;;
+;;  ***** NOTE: The following function defined in `filesets.el' has
+;;              been REDEFINED HERE:
+;;
+;;  `filesets-get-filelist' - Fix.  Bug #976 reported to Emacs devel.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+  
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Redefined standard functions")
+;;  (@> "Icicles functions - completion display (not cycling)")
+;;  (@> "Icicles functions - TAB completion cycling")
+;;  (@> "Icicles functions - S-TAB completion cycling")
+;;  (@> "Icicles functions - common helper functions")
+;;  (@> "Icicles functions - sort functions")
+  
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;; case, lexical-let, loop
+                                  ;; plus, for Emacs < 21: dolist, push, pop
+
+(require 'hexrgb nil t) ;; (no error if not found): hexrgb-color-name-to-hex
+(require 'wid-edit+ nil t) ;; (no error if not found):
+                           ;; redefined color widget (for icicle-var-is-of-type-p)
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "icicles-mac")   ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'icicles-mac)))           ; Require, so can load separately if not on `load-path'.
+  ;; icicle-with-selected-window
+(require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
+  ;; icicle-Completions-display-min-input-chars, icicle-cycle-into-subdirs-flag,
+  ;; icicle-expand-input-to-common-match-flag, icicle-hide-common-match-in-Completions-flag,
+  ;; icicle-hide-non-matching-lines-flag, icicle-highlight-historical-candidates-flag,
+  ;; icicle-highlight-input-initial-whitespace-flag, icicle-ignore-space-prefix-flag,
+  ;; icicle-incremental-completion-delay, icicle-incremental-completion-flag,
+  ;; icicle-incremental-completion-threshold, icicle-default-value, icicle-list-join-string,
+  ;; icicle-mark-position-in-candidate, icicle-point-position-in-candidate, icicle-regexp-quote-flag,
+  ;; icicle-require-match-flag, 
+  ;; icicle-show-Completions-help-flag, icicle-sort-comparer, icicle-special-candidate-regexp,
+  ;; icicle-transform-function, icicle-use-~-for-home-dir-flag
+(require 'icicles-var)
+  ;; icicle-candidate-nb, icicle-candidate-action-fn, icicle-candidate-properties-alist,
+  ;; icicle-cmd-calling-for-completion, icicle-common-match-string, icicle-complete-input-overlay,
+  ;; icicle-completing-p, icicle-completion-candidates, icicle-current-completion-mode,
+  ;; icicle-current-input, icicle-current-raw-input, icicle-default-directory, icicle-edit-update-p,
+  ;; icicle-extra-candidates, icicle-ignored-extensions-regexp, icicle-incremental-completion-p,
+  ;; icicle-initial-value, icicle-last-completion-candidate, icicle-last-input,
+  ;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-predicate,
+  ;; icicle-must-pass-after-match-predicate, icicle-nb-of-other-cycle-candidates, icicle-re-no-dot,
+  ;; icicle-reverse-sort-p, icicle-saved-completion-candidates
+
+;; This requirement is real, but leads to recursion.
+;; You should, in any case, just load everything by loading `icicles.el'.
+;; (require 'icicles-mode) ;; icicle-mode
+
+
+;; Byte-compiling this file, you will likely get some error or warning
+;; messages due to differences between different versions of Emacs.
+
+
+;;; Defvars to quiet the byte-compiler:
+
+(when (< emacs-major-version 22)
+  (defvar completion-common-substring)
+  (defvar completion-root-regexp)
+  (defvar minibuffer-completing-symbol)
+  (defvar minibuffer-prompt-properties)
+  (defvar partial-completion-mode)
+  (defvar read-file-name-completion-ignore-case)
+  (defvar minibuffer-local-filename-completion-map)
+  (defvar minibuffer-local-must-match-filename-map)
+  (defvar minibuffer-local-filename-must-match-map)
+  (defvar read-file-name-predicate)
+  (defvar tooltip-mode))
+
+(when (< emacs-major-version 23)
+  (defvar completion-styles)            ; In `minibuffer.el'
+  (defvar icicle-Completions-text-scale-decrease)) ; In `icicles-opt.el' (for Emacs 23)
+
+(defvar completion-root-regexp)         ; In `simple.el' (for Emacs 22 and 23.1)
+(defvar doremi-boost-down-keys)         ; In `doremi.el'
+(defvar doremi-boost-up-keys)           ; In `doremi.el'
+(defvar doremi-down-keys)               ; In `doremi.el'
+(defvar doremi-up-keys)                 ; In `doremi.el'
+(defvar eyedrop-picked-background)      ; In `eyedrop.el' and `palette.el'
+(defvar eyedrop-picked-foreground)      ; In `eyedrop.el' and `palette.el'
+(defvar filesets-data)                  ; In `filesets.el'
+(defvar font-width-table)               ; In C code.
+(defvar font-weight-table)              ; In C code.
+(defvar font-slant-table)               ; In C code.
+(defvar list-colors-sort)               ; In `facemenu.el'
+(defvar 1on1-*Completions*-frame-flag)  ; In `oneonone.el'
+(defvar shell-completion-execonly)      ; In `shell.el'
+(defvar recentf-list)                   ; In `recentf.el'
+(defvar recentf-menu-filter-commands)
+(defvar recentf-menu-filter)
+(defvar recentf-max-menu-items)
+(defvar recentf-menu-open-all-flag)
+(defvar recentf-menu-filter-commands)
+(defvar recentf-menu-items-for-commands)
+
+;; The name changed during development of Emacs 23.  They aliased it for 23.1, but removed it for 23.2.
+;; Use the new name and alias the old, but don't declare old obsolete (let Emacs 23 do that.)
+(when (and (boundp 'minibuffer-local-must-match-filename-map) (fboundp 'defvaralias)) ; Emacs 22
+  (defvar minibuffer-local-filename-must-match-map minibuffer-local-must-match-filename-map
+    "Local keymap for minibuffer input with completion for filenames with exact match.")
+  (defvaralias 'minibuffer-local-must-match-filename-map 'minibuffer-local-filename-must-match-map))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+  
+;;(@* "Redefined standard functions")
+
+;;; Redefined standard functions -------------------------------------
+
+
+;; REPLACE ORIGINAL `choose-completion-string' in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Don't exit minibuffer if this is just a `lisp-complete-symbol' completion.
+;; Go to point-max before insert choice.  Respect `icicle-dir-candidate-can-exit-p'.
+;;
+;; Free variable `completion-reference-buffer' is defined in `simple.el'.
+;;
+(unless (fboundp 'old-choose-completion-string)
+  (defalias 'old-choose-completion-string (symbol-function 'choose-completion-string)))
+
+(cond ((> emacs-major-version 21)       ; Emacs 22+
+       (defun icicle-choose-completion-string (choice &optional buffer base-size)
+         "Switch to BUFFER and insert the completion choice CHOICE.
+BASE-SIZE, if non-nil, says how many characters of BUFFER's text
+to keep.  If it is nil, we call `choose-completion-delete-max-match'
+to decide what to delete.
+If BUFFER is the minibuffer, then exit the minibuffer, unless one of
+the following is true:
+   - it is reading a file name, CHOICE is a directory, and
+     `icicle-dir-candidate-can-exit-p' is nil
+   - `completion-no-auto-exit' is non-nil
+   - this is just a `lisp-complete-symbol' completion."
+         (let* ((buffer  (or buffer completion-reference-buffer))
+                (mini-p  (minibufferp buffer)))
+           ;; If BUFFER is a minibuffer, barf unless it's currently active.
+           (if (and mini-p (or (not (active-minibuffer-window))
+                               (not (equal buffer (window-buffer (active-minibuffer-window))))))
+               (error "Minibuffer is not active for completion")
+             ;; Set buffer so buffer-local `choose-completion-string-functions' works.
+             (set-buffer buffer)
+             (unless (run-hook-with-args-until-success 'choose-completion-string-functions
+                                                       choice buffer mini-p base-size)
+;;; $$$$$$ Removed this because it led to an error in Emacs 24, since base-size is nil there.
+;;;        Anyway, Icicles doesn't really need or use base-size or `choose-completion-delete-max-match'.
+;;;                ;; Insert the completion into the buffer where completion was requested.
+;;;                (if base-size
+;;;                    (delete-region (+ base-size (if mini-p (minibuffer-prompt-end) (point-min)))
+;;;                                   (if mini-p (point-max) (point)))
+;;;                  (choose-completion-delete-max-match choice))
+
+               ;; Forget about base-size altogether.  Replace the whole input always.
+               (delete-region (+ (or base-size 0) (if mini-p (minibuffer-prompt-end) (point-min)))
+                              (if mini-p (point-max) (point)))
+               (when mini-p (goto-char (point-max))) ; $$$$$ (was unconditional)
+               (insert choice)
+               (remove-text-properties (- (point) (length choice)) (point) '(mouse-face nil))
+               ;; Update point in the window that BUFFER is showing in.
+               (let ((window  (get-buffer-window buffer 0))) (set-window-point window (point)))
+               ;; If completing for the minibuffer, exit it with this choice,
+               ;; unless this was a `lisp-complete-symbol' completion.
+               (and (not completion-no-auto-exit)
+                    (equal buffer (window-buffer (minibuffer-window)))
+                    (or minibuffer-completion-table
+                        (and icicle-mode (or icicle-extra-candidates icicle-proxy-candidates)))
+                    (not (eq 'lisp-complete-symbol icicle-cmd-calling-for-completion))
+                    ;; Exit the minibuffer if `icicle-dir-candidate-can-exit-p',
+                    ;; or not reading a file name, or chosen file is not a directory.
+                    (if (or icicle-dir-candidate-can-exit-p
+                            (not (eq minibuffer-completion-table 'read-file-name-internal))
+                            (not (file-directory-p (field-string (point-max)))))
+                        (exit-minibuffer)
+                      (let ((mini  (active-minibuffer-window)))
+                        (select-window mini)
+                        (when minibuffer-auto-raise (raise-frame (window-frame mini)))))))))))
+
+      ((> emacs-major-version 20)       ; Emacs 21
+       (defun icicle-choose-completion-string (choice &optional buffer base-size)
+         "Switch to BUFFER and insert the completion choice CHOICE.
+BASE-SIZE, if non-nil, says how many characters of BUFFER's text
+to keep.  If it is nil, we call `choose-completion-delete-max-match'
+to decide what to delete.
+If BUFFER is the minibuffer, then exit the minibuffer, unless one of
+the following is true:
+   - it is reading a file name, CHOICE is a directory, and
+     `icicle-dir-candidate-can-exit-p' is nil
+   - `completion-no-auto-exit' is non-nil
+   - this is just a `lisp-complete-symbol' completion."
+         (let ((buffer  (or buffer completion-reference-buffer))
+               (mini-p  (save-match-data (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
+                                                       (buffer-name buffer)))))
+           ;; If BUFFER is a minibuffer, barf unless it's currently active.
+           (if (and mini-p (or (not (active-minibuffer-window))
+                               (not (equal buffer (window-buffer (active-minibuffer-window))))))
+               (error "Minibuffer is not active for completion")
+             ;; Insert the completion into the buffer where completion was requested.
+             (set-buffer buffer)
+             (if base-size
+                 (delete-region (+ base-size (if mini-p (icicle-minibuffer-prompt-end) (point-min)))
+                                (if mini-p (point-max) (point)))
+               (choose-completion-delete-max-match choice))
+             (when mini-p (goto-char (point-max))) ; $$$$$ (was unconditional)
+             (insert choice)
+             (remove-text-properties (- (point) (length choice)) (point) '(mouse-face nil))
+             ;; Update point in the window that BUFFER is showing in.
+             (let ((window  (get-buffer-window buffer 0))) (set-window-point window (point)))
+             ;; If completing for the minibuffer, exit it with this choice,
+             ;; unless this was a `lisp-complete-symbol' completion.
+             (and (not completion-no-auto-exit)
+                  (equal buffer (window-buffer (minibuffer-window)))
+                  (or minibuffer-completion-table
+                      (and icicle-mode (or icicle-extra-candidates icicle-proxy-candidates)))
+                  (not (eq 'lisp-complete-symbol icicle-cmd-calling-for-completion))
+                  ;; Exit the minibuffer if `icicle-dir-candidate-can-exit-p',
+                  ;; or not reading a file name, or chosen file is not a directory.
+                  (if (or icicle-dir-candidate-can-exit-p
+                          (not (eq minibuffer-completion-table 'read-file-name-internal))
+                          (not (file-directory-p (field-string (point-max)))))
+                      (exit-minibuffer)
+                    (let ((mini  (active-minibuffer-window)))
+                      (select-window mini)
+                      (when minibuffer-auto-raise (raise-frame (window-frame mini))))))))))
+
+      (t                                ; Emacs 20
+       (defun icicle-choose-completion-string (choice &optional buffer base-size)
+         "Switch to BUFFER and insert the completion choice CHOICE.
+ BASE-SIZE, if non-nil, says how many characters of BUFFER's text
+ to keep.  If it is nil, we call `choose-completion-delete-max-match'
+ to decide what to delete.
+ If BUFFER is the minibuffer, then exit the minibuffer, unless one of
+ the following is true:
+    - it is reading a file name, CHOICE is a directory, and
+      `icicle-dir-candidate-can-exit-p' is nil
+    - `completion-no-auto-exit' is non-nil
+    - this is just a `lisp-complete-symbol' completion."
+         (let ((buffer  (or buffer completion-reference-buffer))
+               (mini-p  (save-match-data (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
+                                                       (buffer-name buffer)))))
+           ;; If BUFFER is a minibuffer, barf unless it's currently active.
+           (when (and mini-p (or (not (active-minibuffer-window))
+                                 (not (equal buffer (window-buffer (active-minibuffer-window))))))
+             (error "Minibuffer is not active for completion"))
+           ;; Insert the completion into the buffer where completion was requested.
+           (set-buffer buffer)
+           (if base-size
+               (delete-region (+ base-size (point-min)) (if mini-p (point-max) (point)))
+             (choose-completion-delete-max-match choice))
+           (when mini-p (goto-char (point-max))) ; $$$$$ (was unconditional)
+           (insert choice)
+           (remove-text-properties (- (point) (length choice)) (point) '(mouse-face nil))
+           ;; Update point in the window that BUFFER is showing in.
+           (let ((window  (get-buffer-window buffer 0))) (set-window-point window (point)))
+           ;; If completing for the minibuffer, exit it with this choice,
+           ;; unless this was a `lisp-complete-symbol' completion.
+           (and (not completion-no-auto-exit)
+                (equal buffer (window-buffer (minibuffer-window)))
+                (or minibuffer-completion-table
+                    (and icicle-mode (or icicle-extra-candidates icicle-proxy-candidates)))
+                (not (eq 'lisp-complete-symbol icicle-cmd-calling-for-completion))
+                ;; Exit the minibuffer if `icicle-dir-candidate-can-exit-p',
+                ;; or not reading a file name, or chosen file is not a directory.
+                (if (or icicle-dir-candidate-can-exit-p
+                        (not (eq minibuffer-completion-table 'read-file-name-internal))
+                        (not (file-directory-p (buffer-string))))
+                    (exit-minibuffer)
+                  (select-window (active-minibuffer-window))))))))
+
+
+;; REPLACE ORIGINAL `completion-setup-function' in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Don't print the help lines here.  Do that in `icicle-display-completion-list' instead.
+;; That's so we can fit the `*Completions*' window to the buffer, including the help lines.
+;;
+(unless (fboundp 'old-completion-setup-function)
+  (defalias 'old-completion-setup-function (symbol-function 'completion-setup-function)))
+
+(when (< emacs-major-version 22)
+  (defun icicle-completion-setup-function ()
+    "Set up for completion.  This goes in `completion-setup-hook'
+so it is called after completion-list buffer text is written."
+    (save-excursion
+      (let* ((mainbuf        (current-buffer))
+             (mbuf-contents  (icicle-input-from-minibuffer))
+             ;; $$$$$ Should we `expand-file-name' mbuf-contents first?
+             (dir-of-input   (and minibuffer-completing-file-name
+                                  (icicle-file-name-directory mbuf-contents))))
+        ;; If reading file name and either `icicle-comp-base-is-default-dir-p' is nil or this is a
+        ;; completion command, then set `default-directory' so it will be copied into `*Completions*'.
+        (when (and dir-of-input
+                   (or (and (symbolp this-command) (get this-command 'icicle-completing-command))
+                       (not icicle-comp-base-is-default-dir-p)))
+          (with-current-buffer mainbuf (setq default-directory  dir-of-input)))
+        (with-current-buffer standard-output
+          (completion-list-mode)
+          (set (make-local-variable 'completion-reference-buffer) mainbuf)
+          (setq completion-base-size
+                (cond ((and (eq minibuffer-completion-table 'read-file-name-internal)
+                            icicle-comp-base-is-default-dir-p
+                            (length default-directory)))
+                      ((eq minibuffer-completion-table 'read-file-name-internal)
+                       ;; For file name completion, use the number of chars before
+                       ;; the start of the file name component at point.
+                       (with-current-buffer mainbuf
+                         (save-excursion (skip-chars-backward "^/")
+                                         (- (point) (icicle-minibuffer-prompt-end)))))
+                      ((save-match-data (string-match "\\` \\*Minibuf-[0-9]+\\*\\'"
+                                                      (buffer-name mainbuf)))
+                       ;; Otherwise, in minibuffer, the whole input is being completed.
+                       0))))))))
+
+(when (or (= emacs-major-version 22)    ; Emacs 22 or 23.1
+          (and (= emacs-major-version 23) (= emacs-minor-version 1)))
+  (defun icicle-completion-setup-function ()
+    "Set up for completion.  This goes in `completion-setup-hook'
+so it is called after completion-list buffer text is written."
+    (save-excursion
+      (let* ((mainbuf        (current-buffer))
+             (mbuf-contents  (minibuffer-completion-contents)) ; Get contents only up to point.
+             ;; $$$$$ Should we `expand-file-name' mbuf-contents first?  Vanilla Emacs does that.
+             (dir-of-input   (and minibuffer-completing-file-name
+                                  (icicle-file-name-directory mbuf-contents)))
+             common-string-length)
+        ;; If reading file name and either `icicle-comp-base-is-default-dir-p' is nil or this is a
+        ;; completion command, then set `default-directory' so it will be copied into `*Completions*'.
+        (when (and dir-of-input
+                   (or (and (symbolp this-command) (get this-command 'icicle-completing-command))
+                       (not icicle-comp-base-is-default-dir-p)))
+          (with-current-buffer mainbuf (setq default-directory  dir-of-input)))
+        (with-current-buffer standard-output
+          (completion-list-mode)
+          (set (make-local-variable 'completion-reference-buffer) mainbuf)
+          (setq completion-base-size
+                (cond ((and minibuffer-completing-file-name icicle-comp-base-is-default-dir-p
+                            (length default-directory)))
+                      ((and (symbolp minibuffer-completion-table)
+                            (get minibuffer-completion-table 'completion-base-size-function))
+                       ;; To compute base size, a function can use the global value of
+                       ;; `completion-common-substring' or `minibuffer-completion-contents'.
+                       (with-current-buffer mainbuf
+                         (funcall (get minibuffer-completion-table 'completion-base-size-function))))
+                      (minibuffer-completing-file-name
+                       ;; For file name completion, use the number of chars before
+                       ;; the start of the file name component at point.
+                       (with-current-buffer mainbuf
+                         (save-excursion (skip-chars-backward completion-root-regexp)
+                                         (- (point) (minibuffer-prompt-end)))))
+                      ((and (boundp 'minibuffer-completing-symbol) minibuffer-completing-symbol) nil)
+                      ;; Otherwise, in minibuffer, the base size is 0.
+                      ((minibufferp mainbuf) 0)))
+          (setq common-string-length
+                (cond (completion-common-substring (length completion-common-substring))
+                      (completion-base-size (- (length mbuf-contents) completion-base-size))))
+          ;; Put faces on first uncommon characters and common parts.
+          (when (and (integerp common-string-length) (>= common-string-length 0))
+            (let ((element-start  (point-min))
+                  (maxp           (point-max))
+                  element-common-end)
+              (while (and (setq element-start  (next-single-property-change element-start 'mouse-face))
+                          (< (setq element-common-end  (+ element-start common-string-length))
+                             maxp))
+                (when (get-char-property element-start 'mouse-face)
+                  (if (and (> common-string-length 0)
+                           (get-char-property (1- element-common-end) 'mouse-face))
+                      (put-text-property element-start element-common-end
+                                         'font-lock-face 'completions-common-part))
+                  (if (get-char-property element-common-end 'mouse-face)
+                      (put-text-property element-common-end (1+ element-common-end)
+                                         'font-lock-face 'completions-first-difference)))))))))))
+
+(when (or (> emacs-major-version 23)    ; Emacs 23.2+
+          (and (= emacs-major-version 23) (>= emacs-minor-version 2)))
+  (defun icicle-completion-setup-function ()
+    "Set up for completion.  This goes in `completion-setup-hook'
+so it is called after completion-list buffer text is written."
+    ;; I could probably get rid of even more of the vanilla vestiges here...
+    (save-excursion
+      (let* ((mainbuf        (current-buffer))
+             (mbuf-contents  (minibuffer-completion-contents)) ; Get contents only up to point.
+             ;; $$$$$ Should we `expand-file-name' mbuf-contents first?  Vanilla Emacs does that.
+             (dir-of-input   (and minibuffer-completing-file-name
+                                  (icicle-file-name-directory mbuf-contents))))
+        ;; If reading file name and either `icicle-comp-base-is-default-dir-p' is nil or this is a
+        ;; completion command, then set `default-directory' so it will be copied into `*Completions*'.
+        (when (and dir-of-input
+                   (or (and (symbolp this-command) (get this-command 'icicle-completing-command))
+                       (not icicle-comp-base-is-default-dir-p)))
+          (with-current-buffer mainbuf (setq default-directory  dir-of-input)))
+        (with-current-buffer standard-output
+          (completion-list-mode)
+          (set (make-local-variable 'completion-reference-buffer) mainbuf))))))
+
+(defun icicle-insert-Completions-help-string ()
+  "Add or remove help in `*Completions*'.
+This is controlled by `icicle-show-Completions-help-flag'.  If that
+option is nil, remove help; else, add it."
+  (if icicle-show-Completions-help-flag
+      (let ((instruction2  (or (and icicle-mode (substitute-command-keys
+                                                 (concat "(\\"
+                                                         "\\[icicle-minibuffer-help]: help) ")))
+                               ""))
+            instruction1)
+        (cond ((< emacs-major-version 22)
+               (setq instruction1  (if window-system ; We have a mouse.
+                                       (substitute-command-keys "Click \\\
+\\[mouse-choose-completion] on a completion to select it.  ")
+                                     (substitute-command-keys ; No mouse.
+                                      "In this buffer, type \\\
+\\[choose-completion] to select the completion near point.  "))))
+              ((>= emacs-major-version 22)
+               (setq instruction1  (if (display-mouse-p) ; We have a mouse.
+                                       (substitute-command-keys
+                                        "Click \\\
+\\[mouse-choose-completion] or type \\[choose-completion] on a completion to select it.  ")
+                                     (substitute-command-keys ; No mouse.
+                                      "In this buffer, type \\\
+\\[choose-completion] to select the completion near point.  ")))))
+        (goto-char (point-min))
+        (put-text-property 0 (length instruction1) 'face 'icicle-Completions-instruction-1
+                           instruction1)
+        (put-text-property 0 (length instruction2) 'face 'icicle-Completions-instruction-2
+                           instruction2)
+        (insert instruction1 instruction2 "\n"))
+
+    ;; Not showing help.  Remove standard Emacs help string.
+    (goto-char (point-min))
+    (re-search-forward "Possible completions are:\n")
+    (delete-region (point-min) (point))))
+
+(defun icicle-read-from-minibuf-nil-default (prompt &optional initial-contents keymap read hist
+                                             default-value inherit-input-method)
+  "Like `read-from-minibuffer', but return nil for empty input.
+Args are as for `read-from-minibuffer'.
+If nothing is input, then nil is returned."
+  (let ((input  (read-from-minibuffer prompt initial-contents keymap nil hist default-value
+                                      inherit-input-method)))
+    (if (string= "" input) nil (if read (car (read-from-string input)) input))))
+
+(defun icicle-completing-read-history (prompt &optional hist pred init-input def inherit-i-m)
+  "Lax `completing-read' against entries in history HIST.
+Arguments are as for `completing-read'.  HIST is a symbol that is a
+history variable.  It defaults to `minibuffer-history'.  Completion is
+lax: a match is not required."
+  (setq hist  (or hist 'minibuffer-history))
+  (let ((hist-val  (icicle-remove-duplicates (symbol-value hist))))
+    (when (and (consp hist-val) (not (stringp (car hist-val)))) ; Convert, e.g. `comand-history'.
+      (setq hist-val  (mapcar (lambda (v) (format "%s" v)) hist-val)))
+    (completing-read prompt (mapcar #'list hist-val) pred nil init-input hist def inherit-i-m)))
+
+;; Based on the Emacs 22 C code that defined `completing-read'.
+(defun icicle-lisp-vanilla-completing-read (prompt collection &optional predicate require-match
+                                            initial-input hist def inherit-input-method)
+  "Lisp version of vanilla Emacs `completing-read'."
+  (let ((pos  0)  val  histvar  histpos  position  init)
+    (setq init                             initial-input
+          minibuffer-completion-table      collection
+          minibuffer-completion-predicate  predicate
+          minibuffer-completion-confirm    (if (eq require-match t) nil require-match))
+    (setq position  nil)
+    (when init
+      (when (consp init) (setq position  (cdr init)
+                               init      (car init)))
+      (unless (stringp init)
+        (error "icicle-lisp-vanilla-completing-read, INIT must be a string: %S" init))
+      (if (not position)
+          (setq pos  (1+ (length init))) ; Default is to put cursor at end of INITIAL-INPUT.
+        (unless (integerp position)
+          (error "icicle-lisp-vanilla-completing-read, POSITION must be an integer: %S" position))
+        (setq pos  (1+ position))))     ; Convert zero-based to one-based.
+    (if (symbolp hist)
+        (setq histvar  hist
+              histpos  nil)
+      (setq histvar  (car-safe hist)
+            histpos  (cdr-safe hist)))
+    (unless histvar (setq histvar  'minibuffer-history))
+    (unless histpos (setq histpos  0))
+    ;; $$$$$$
+    ;;     (setq val  (read-from-minibuffer
+    ;;                 prompt
+    ;;                 (cons init pos)          ; initial-contents
+    ;;                 (if (not require-match)  ; key map
+    ;;                     (if (or (not minibuffer-completing-file-name)
+    ;;                             (eq minibuffer-completing-file-name 'lambda)
+    ;;                             (not (boundp 'minibuffer-local-filename-completion-map)))
+    ;;                         minibuffer-local-completion-map
+    ;;                       minibuffer-local-filename-completion-map)
+    ;;                   (if (or (not minibuffer-completing-file-name)
+    ;;                           (eq minibuffer-completing-file-name 'lambda)
+    ;;                           (not (boundp 'minibuffer-local-filename-must-match-map)))
+    ;;                       minibuffer-local-must-match-map
+    ;;                     minibuffer-local-filename-must-match-map))
+    ;;                 nil histvar def inherit-input-method))
+    (setq val  (read-from-minibuffer
+                prompt
+                (cons init pos)         ; initial-contents
+                (if (not require-match) ; keymap
+                    (if (or (not minibuffer-completing-file-name)
+                            (eq minibuffer-completing-file-name 'lambda)
+                            (not (boundp 'minibuffer-local-filename-completion-map)))
+                        minibuffer-local-completion-map
+                      (if (fboundp 'make-composed-keymap) ; Emacs 24, starting July 2011.
+                          (make-composed-keymap
+                           minibuffer-local-filename-completion-map
+                           minibuffer-local-completion-map)
+                        minibuffer-local-filename-completion-map))
+                  (if (or (not minibuffer-completing-file-name)
+                          (eq minibuffer-completing-file-name 'lambda)
+                          (and (not (fboundp 'make-composed-keymap)) ; Emacs 24, starting July 2011.
+                               (not (boundp 'minibuffer-local-filename-must-match-map))))
+                      minibuffer-local-must-match-map
+                    (if (fboundp 'make-composed-keymap) ; Emacs 24, starting July 2011.
+                        (make-composed-keymap
+                         minibuffer-local-filename-completion-map
+                         minibuffer-local-must-match-map)
+                      minibuffer-local-filename-must-match-map)))
+                nil histvar def inherit-input-method))
+    ;; Use `icicle-filtered-default-value', not DEF, because `read-from-minibuffer' filters it.
+    (when (consp icicle-filtered-default-value) ; Emacs 23 lets DEF be a list of strings - use first.
+      (setq icicle-filtered-default-value  (car icicle-filtered-default-value)))
+    (when (and (stringp val) (string= val "") icicle-filtered-default-value)
+      (setq val  icicle-filtered-default-value))
+    val))
+
+
+;; REPLACE ORIGINAL `completing-read' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Allows for completion candidates that are lists of strings.
+;; Allows for reading and returning completion candidates that are strings with properties.
+;; Adds completion status indicator to minibuffer and mode-line lighter.
+;; Removes `*Completions*' window.
+;;
+;; We use HIST-m@%=!$+&^*z instead of HIST, to avoid name capture by `minibuffer-history-variable's
+;; value.  If we didn't need to be Emacs 20-compatible, then we could employ
+;; `#1=#:hist'...`#1#'...`#1' read syntax to use an uninterned symbol.
+;;
+(unless (fboundp 'old-completing-read)
+  (defalias 'old-completing-read (symbol-function 'completing-read)))
+
+(defun icicle-completing-read (prompt collection &optional predicate require-match
+                               initial-input hist-m@%=!$+&^*z def inherit-input-method)
+  "Read string in minibuffer, with completion and cycling of completions.
+Prefix completion via \\\
+`\\[icicle-prefix-word-complete]' (word) and `\\[icicle-prefix-complete]' (full).
+Apropos (regexp) completion via `\\[icicle-apropos-complete]'.
+
+Prefix cycling of candidate completions via `\\[icicle-previous-prefix-candidate]' and \
+`\\[icicle-next-prefix-candidate]'.
+Apropos cycling of candidate completions via `\\[icicle-previous-apropos-candidate]' and \
+`\\[icicle-next-apropos-candidate]'.
+
+Cycling of past minibuffer inputs via `\\[previous-history-element]' and \
+`\\[next-history-element]'.
+Searching through input history via `\\[previous-matching-history-element]' \
+and `\\[next-matching-history-element]'.
+
+Case is ignored if `completion-ignore-case' is non-nil.
+Position of the cursor (point) and the mark during completion cycling
+  is determined by `icicle-point-position-in-candidate' and
+  `icicle-mark-position-in-candidate', respectively.
+Highlighting of the matched part of completion candidates during
+  cycling is determined by `icicle-match-highlight-minibuffer',
+  `icicle-match-highlight-Completions', and
+  `icicle-common-match-highlight-Completions'.
+
+Use `\\[icicle-minibuffer-help]' during completion for more information on completion and key
+bindings in Icicle mode.
+
+PROMPT is a string to prompt with. It normally ends in a colon and a
+space.  If PROMPT has non-nil text property `icicle-fancy-candidates'
+on its first character, then completion candidates can be fancy - they
+can have properties.  However, if all of the candidates would be
+acceptable to vanilla Emacs, then PROMPT need not use property
+`icicle-fancy-candidates', even for candidates that have text
+properties.  Property `icicle-fancy-candidates' is needed only for
+candidates that require encoding and decoding to store and retrieve
+properties.  See the Icicles doc, section `Programming with Fancy
+Candidates'.
+
+COLLECTION is an obarray or an alist whose elements' cars are strings.
+It can also be a function that performs the completion itself.
+In Emacs 22 or later, it can also be a hash table or list of strings.
+
+In Icicle mode, the car of an alist entry can also be a list of
+strings.  In this case, the completion candidate is a
+multi-completion.  The strings are joined pairwise with
+`icicle-list-join-string' to form the completion candidate seen by the
+user.  You can use variable `icicle-candidate-properties-alist' to
+control the appearance of multi-completions in buffer `*Completions*'.
+You can use variables `icicle-list-use-nth-parts' and
+`icicle-list-nth-parts-join-string' to control the minibuffer behavior
+of multi-completions.  See the Icicles documentation for more
+information.
+
+PREDICATE limits completion to a subset of COLLECTION.
+
+See `try-completion' and `all-completions' for more details on
+completion, COLLECTION, and PREDICATE.
+
+REQUIRE-MATCH can take any of these values:
+* nil means the user can exit using any input.
+* t means the user can exit only if the input is (or completes to) an
+  element of COLLECTION or is null.
+* In Emacs 23 or later:
+  - `confirm' means the user can exit with any input, but if the input
+    is not an element of COLLECTION then confirmation is needed.
+  - `confirm-after-completion' is similar, except that with
+    non-matching input exit is allowed only just after completing.
+* Anything else behaves like t, except that hitting `\\[exit-minibuffer]' does not
+  exit if it performs non-null completion.
+
+Regardless of the value of REQUIRE-MATCH, if the user input is empty,
+then `completing-read' returns DEF or, if DEF is nil, an empty string.
+
+If option `icicle-require-match-flag' is non-nil, it overrides the
+value of REQUIRE-MATCH.
+
+If INITIAL-INPUT is non-nil, insert it in the minibuffer initially,
+with point positioned at the end.  If it is (STRING . POSITION), the
+initial input is STRING, but point is placed at zero-indexed position
+POSITION in STRING.  (This is different from `read-from-minibuffer'
+and related functions, which use one-indexing for POSITION.)
+
+INITIAL-INPUT is considered deprecated by vanilla Emacs, but not by
+Icicles.  If INITIAL-INPUT is nil and DEF is non-nil, the user can use
+`next-history-element' to yank DEF into the minibuffer.
+
+HIST, if non-nil, specifies a history list and optionally the initial
+position in the list.  It can be a symbol, which is the history list
+variable to use, or it can be a cons cell (HISTVAR . HISTPOS).  If a
+cons cell, HISTVAR is the history list variable to use, and HISTPOS is
+the initial position (the position in the list used by the minibuffer
+history commands).  For consistency, you should also specify that
+element of the history as the value of INITIAL-INPUT.  Positions are
+counted starting from 1 at the beginning of the list.  The variable
+`history-length' controls the maximum length of a history list.
+
+DEF, if non-nil, is the default value or (Emacs 23+ only) the list of
+default values.  Option `icicle-default-value' controls the treatment
+of the default value (or the first default value, if DEF is a list):
+whether it is shown in the prompt, substituted for an empty
+INITIAL-INPUT, and so on.
+
+If INHERIT-INPUT-METHOD is non-nil, the minibuffer inherits the
+current input method and the setting of `enable-multibyte-characters'.
+
+Both completion candidates and DEF are filtered using these Icicles
+variables:
+  `icicle-must-match-regexp'
+  `icicle-must-not-match-regexp'
+  `icicle-must-pass-predicate'
+
+Completion ignores case when `completion-ignore-case' is non-nil."
+  (unless (stringp icicle-initial-value) (setq icicle-initial-value  "")) ; Convert nil to "".
+  (unless initial-input (setq initial-input  icicle-initial-value))
+  (if (consp initial-input)
+      (setq icicle-initial-value  (car initial-input))
+    (setq initial-input         (format "%s" initial-input) ; Convert symbol to string
+          icicle-initial-value  initial-input))
+  (setq icicle-nb-of-other-cycle-candidates  0)
+
+  ;; Use DEF for INITIAL-INPUT also, if `icicle-default-value' says so.
+  (when (and def icicle-default-value (not (eq icicle-default-value t))
+             (stringp initial-input) (string= "" initial-input))
+    ;; Filter DEF using `icicle-filter-wo-input'.  Done in `read-from-minibuffer' anyway, but we
+    ;; must also do it here, to reuse the correct default value for the init value.
+    (if (atom def)
+        (setq initial-input  (or (icicle-filter-wo-input def) "")) ; Ensure that it is non-nil.
+      (let ((found  nil)
+            (def1   def))
+        (while (and (not found) def1)
+          (setq found  (icicle-filter-wo-input (car def1))
+                def1   (cdr def1)))
+        (setq initial-input  (or found ""))))
+    (when (memq icicle-default-value '(insert-start preselect-start))
+      (setq initial-input  (cons initial-input 0))))
+
+  ;; Override REQUIRE-MATCH as needed.
+  (setq require-match           (case icicle-require-match-flag
+                                  ((nil)               require-match)
+                                  (no-match-required   nil)
+                                  (partial-match-ok    t)
+                                  (full-match-required 'full-match-required))
+        icicle-require-match-p  require-match)
+  (icicle-highlight-lighter)
+  (let* ((minibuffer-history-variable       minibuffer-history-variable)
+         ;; $$$$$$$$$$ `minibuffer-completion-table' binding needed?  `setq' in `*-lisp-vanilla-*'.
+         (minibuffer-allow-text-properties  t) ; This is nil for completion in vanilla Emacs.
+         (minibuffer-completion-table       collection)
+         (icicle-fancy-cands-internal-p     (or icicle-whole-candidate-as-text-prop-p
+                                                icicle-fancy-candidates-p
+                                                (get-text-property
+                                                 0 'icicle-fancy-candidates prompt)))
+         result)
+    ;; Transform a cons collection to what is expected for `minibuffer-completion-table'.
+    (when icicle-fancy-cands-internal-p
+      (let ((c+p  (icicle-mctize-all collection predicate)))
+        (setq collection  (car c+p)     ; After banalizing for vanilla Emacs.
+              predicate   (cadr c+p))))
+    ;; $$$$$$$$$$$$$ (setq minibuffer-completion-table  collection)
+    (cond ((not icicle-mode)
+           (setq result  (icicle-lisp-vanilla-completing-read
+                          prompt collection predicate require-match initial-input
+                          hist-m@%=!$+&^*z def inherit-input-method)))
+          (t
+           (let ((minibuffer-prompt-properties
+                  (and (boundp 'minibuffer-prompt-properties) ; Emacs 21+ only
+                       (icicle-remove-property 'face minibuffer-prompt-properties)))
+                 (minibuffer-completing-file-name
+                  ;; Can't be file-name completion unless it's a function.
+                  (and (functionp collection) minibuffer-completing-file-name)))
+             (when (< emacs-major-version 21)
+               (setq prompt  (concat (and icicle-candidate-action-fn "+ ") prompt)))
+             (setq result  (catch 'icicle-read-top
+                             (icicle-lisp-vanilla-completing-read
+                              prompt collection predicate require-match initial-input
+                              hist-m@%=!$+&^*z def inherit-input-method)))
+             (icicle-unpropertize result))))
+    ;; HACK.  Without this, when REQUIRE-MATCH is non-nil, `*Completions*' window
+    ;; does not disappear.
+    (when require-match (icicle-remove-Completions-window))
+    result))
+
+(defun icicle-mctize-all (coll pred)
+  "Transform collection COLL and predicate PRED for vanilla completion.
+COLL is an Icicles collection argument acceptable to
+  `icicle-completing-read' but not necessarily to vanilla
+  `completing-read': COLL can contain multi-completions.
+PRED is a predicate.
+
+Returns a new two-element list of the new collection and predicate:
+\(MCT NEWPRED), where MCT is COLL transformed and NEWPRED is PRED
+transformed.  MCT is a collection suitable for vanilla
+`completing-read'.
+
+COLL is transformed to MCT by applying `icicle-mctized-full-candidate'
+to each of its elements.
+
+If PRED is non-nil, then NEWPRED is a predicate that applies PRED to
+the cdr of an MCT entry.  If PRED is nil, so is NEWPRED."
+  (when (consp coll)
+    ;; Copy alist collection COLL, so we don't change the original alist in any way.
+    ;; Change each entry in COLL using `icicle-mctized-full-candidate'.
+    (setq coll  (mapcar #'icicle-mctized-full-candidate coll))
+    ;; Convert non-nil PRED so that, for a cons entry with a string car, PRED uses the cdr
+    ;; (which is the original entry) instead.
+    (and pred (lexical-let ((new-pred  pred))
+                (setq pred  (lambda (x)
+                              (funcall new-pred (if (and (consp x) (stringp (car x))) (cdr x) x)))))))
+  (list coll pred))
+
+(defun icicle-mctized-full-candidate (cand)
+  "Return MCT candidate that corresponds to full candidate CAND.
+See the source code for details."
+  ;; If neither `icicle-fancy-cands-internal-p' nor `icicle-whole-candidate-as-text-prop-p' is
+  ;;   non-nil, then just return CAND.
+  ;; Otherwise:
+  ;;   If CAND is a string A, we change it to (A) and then treat that (as follows).
+  ;;   If CAND is (A . B), where A is a string, then we change it to (S A . B), where S is a copy
+  ;;     of A.  This way, the cdr of each MCT candidate is the original alist candidate, (A . B).
+  ;;   If CAND is (M . B), where M is a multi-completion (X Y Z...), then we change it to
+  ;;     (M' A . B), where M' is the display string for the multi-completion M.
+  ;;   Otherwise, we make no change to CAND.
+  ;;   If `icicle-whole-candidate-as-text-prop-p' is non-nil and the MCT candidate is a cons (X A . B)
+  ;;     with a string car X, then we put the cdr, (A . B), as a text property on the car X, so
+  ;;     we can get back the original (A . B) from the car.
+  (if (not (or icicle-fancy-cands-internal-p icicle-whole-candidate-as-text-prop-p))
+      cand
+    (let ((new-cand
+           (cond ((and (consp cand)     ; Multi-completion: (("aa" "bb") . cc) ->
+                       (consp (car cand)) ; ("aa^G\nbb\n\n" ("aa" "bb") . cc)
+                       (stringp (caar cand)))
+                  ;; $$$$$$
+                  ;; (when (string-match "\n" icicle-list-join-string)
+                  ;;   (setq icicle-completions-format-internal  'horizontal)) ; Override
+                  ;; $$$$$$ (cons (concat (mapconcat #'identity (car cand) icicle-list-join-string)
+                  ;;                      icicle-list-end-string) ; $$$$$$
+                  (cons (mapconcat #'identity (car cand) icicle-list-join-string) cand))
+                 ((and (consp cand) (stringp (car cand))) ; ("aa" . cc) -> ("aa" "aa" . cc)
+                  (cons (copy-sequence (car cand)) cand))
+                 ((stringp cand)        ; "aa" -> ("aa" "aa")
+                  (list (copy-sequence cand) cand)) 
+                 (t                     ; Anything else: (aa), aa -> no change
+                  cand))))
+      ;; Put original alist candidates on display candidates (strings), as a text property.
+      (when (and icicle-whole-candidate-as-text-prop-p (consp new-cand) (stringp (car new-cand)))
+        (icicle-put-whole-cand-prop new-cand))
+      new-cand)))
+
+(defun icicle-put-whole-cand-prop (cand)
+  "Put cdr of CAND on its car, as text property `icicle-whole-candidate'.
+This has no side effects.
+Returns a new propertized string corresponding to (car CAND)."
+  (let ((text-cand  (copy-sequence (car cand))))
+    (put-text-property 0 (length text-cand) 'icicle-whole-candidate (cdr cand) text-cand)
+    (setcar cand text-cand)
+    text-cand))
+
+(defun icicle-mctized-display-candidate (cand)
+  "Return MCT candidate that corresponds to display candidate CAND."
+  (let ((full-cand  (or (funcall icicle-get-alist-candidate-function cand) (list cand))))
+    (cons cand full-cand)))
+
+(defun icicle-replace-mct-cand-in-mct (old new)
+  "Replace OLD candidate with NEW in `minibuffer-completion-table'.
+Both OLD and NEW have been mctized.  That is, they are ready for
+`minibuffer-completion-table'."
+  (let ((newlist  minibuffer-completion-table))
+    (catch 'icicle-replace-cand-in-mct
+      (while newlist
+        (when (equal (car newlist) old)
+          (setcar newlist new)
+          (throw 'icicle-replace-cand-in-mct nil))
+        (setq newlist  (cdr newlist))))
+    minibuffer-completion-table))
+
+(defun icicle-read-file-name (prompt &optional dir default-filename
+                              require-match initial-input predicate)
+  "Read file name, prompting with PROMPT and completing in directory DIR.
+Value is not expanded---you must call `expand-file-name' yourself.
+DIR should be an absolute directory name.  It defaults to the value of
+ `default-directory'.
+Default the name to DEFAULT-FILENAME if user exits the minibuffer with
+the same non-empty string that was inserted by this function.
+ (If DEFAULT-FILENAME is omitted, the visited file name is used,
+  but if INITIAL-INPUT is specified, that combined with DIR is used.)
+If the user exits with an empty minibuffer, this function returns
+an empty string.  (This can only happen if the user erased the
+pre-inserted contents or if `insert-default-directory' is nil.)
+Fourth arg REQUIRE-MATCH non-nil means require existing file's name.
+ Non-nil and non-t means also require confirmation after completion.
+Fifth arg INITIAL-INPUT specifies text to start with.
+If optional sixth arg PREDICATE is non-nil, possible completions and
+ the resulting file name must satisfy `(funcall predicate NAME)'.
+ This argument is only available starting with Emacs 22.
+
+Both completion candidates and DEFAULT-FILENAME are filtered using
+these Icicles variables:
+  `icicle-must-match-regexp'
+  `icicle-must-not-match-regexp'
+  `icicle-must-pass-predicate'
+
+Directory names are highlighted in `*Completions*' using face
+`icicle-special-candidate'.
+
+If option `icicle-require-match-flag' is non-nil, it overrides the
+value of REQUIRE-MATCH.
+
+Cycling into subdirectories is determined by option
+`icicle-cycle-into-subdirs-flag'.  Case is ignored if
+`read-file-name-completion-ignore-case' is non-nil.  See also
+`read-file-name-function'.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, then the
+following proxy file-name candidates are included.  (This inclusion
+can be toggled at any time from the minibuffer, using `C-M-_'.)
+
+* `*mouse-2 file name*' - Click `mouse-2' on a file name to choose it.
+* `*point file name*'   - Use the file name at point (cursor).
+* Single-quoted file-name variables - Use the variable's value.
+
+Candidates `*mouse-2 file name*' and `*point file name*' are available
+only if library `ffap.el' can be loaded.  A file-name variable has
+custom type `file' or (file :must-match t).
+
+If this command was invoked with the mouse, use a file dialog box if
+`use-dialog-box' is non-nil, and the window system or X toolkit in use
+provides a file dialog box.
+
+See also `read-file-name-completion-ignore-case' (Emacs version > 21)
+and `read-file-name-function'."
+  (unwind-protect
+       (let* ((mouse-file                       "*mouse-2 file name*")
+              (icicle-special-candidate-regexp  (or icicle-special-candidate-regexp ".+/$"))
+              (minibuffer-completing-file-name  t)
+              (read-file-name-predicate         (and (boundp 'read-file-name-predicate)
+                                                     read-file-name-predicate))
+              (ffap-available-p                 (or (require 'ffap- nil t) (require 'ffap nil t)))
+              ;; The next four prevent slowing down `ffap-guesser'.
+              (ffap-alist nil)                  (ffap-machine-p-known 'accept)
+              (ffap-url-regexp nil)             (ffap-shell-prompt-regexp nil) 
+              (fap
+               (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit))
+                   (condition-case nil
+                       (abbreviate-file-name (dired-get-file-for-visit))
+                     (error nil))
+                 (and ffap-available-p (ffap-guesser))))
+              (icicle-proxy-candidates
+               (append 
+                (and icicle-add-proxy-candidates-flag
+                     (append (and fap (list "*point file name*"))
+                             (and ffap-available-p (list mouse-file))
+                             (let ((ipc  ()))
+                               (mapatoms
+                                (lambda (cand)
+                                  (when (and (user-variable-p cand)
+                                             (condition-case nil
+                                                 (icicle-var-is-of-type-p cand
+                                                                          '(file (file :must-match t)))
+                                               (error nil)))
+                                    (push (concat "'" (symbol-name cand) "'") ipc))))
+                               ipc)))
+                icicle-proxy-candidates))
+              result)
+
+         ;;  ;; $$$$$$ Does Emacs 23+ need explicit directory? If so, add these three lines
+         ;;  (unless dir (setq dir  default-directory))
+         ;;  (unless (file-name-absolute-p dir) (setq dir  (expand-file-name dir)))
+         ;;  (setq dir  (abbreviate-file-name dir)) ; Use `~' for home directory.
+
+         (setq result  (icicle-read-file-name-1 prompt dir default-filename
+                                                require-match initial-input predicate))
+         (when ffap-available-p
+           (cond ((save-match-data (string-match "*point file name\\*$" result))
+                  (setq result  fap))
+                 ((save-match-data (string-match "*mouse-2 file name\\*$" result))
+                  (setq result
+                        (progn (let ((e  (read-event "Click `mouse-2' on file name")))
+                                 (read-event) ; Get rid of mouse up event.
+                                 (save-excursion
+                                   (mouse-set-point e)
+                                   (if (and (eq major-mode 'dired-mode)
+                                            (fboundp 'dired-get-file-for-visit)) ; In `dired+.el'.
+                                       (condition-case nil ; E.g. error: not on file line (ignore)
+                                           (abbreviate-file-name (dired-get-file-for-visit))
+                                         (error "No such file"))
+                                     (or (ffap-guesser) (error "No such file"))))))))))
+         (icicle-unpropertize result)
+         (let* ((temp  (member (file-name-nondirectory result) icicle-proxy-candidates))
+                (symb  (and temp (intern (substring (car temp) 1 (1- (length (car temp))))))))
+           (when (and symb (boundp symb)) (setq result  (symbol-value symb))))
+         result)
+    (setq icicle-proxy-candidates  ())))
+
+(defun icicle-read-file-name-1 (prompt &optional dir default-filename
+                                require-match initial-input predicate)
+  "Helper function for `icicle-read-file-name'."
+  (setq icicle-nb-of-other-cycle-candidates  0
+        icicle-initial-value                 (or initial-input (if (stringp icicle-initial-value)
+                                                                   icicle-initial-value
+                                                                 "")))
+  (icicle-fix-default-directory)        ; Make sure there are no backslashes in it.
+  (unless (string= "" icicle-initial-value) (setq initial-input  icicle-initial-value))
+
+  ;; Use DEFAULT-FILENAME for INITIAL-INPUT also, if `icicle-default-value' says so.
+  ;; But if so, remove the directory part first.
+  ;; Note that if DEFAULT-FILENAME is null, then we let INITIAL-INPUT remain null too.
+  (when (and default-filename icicle-default-value (not (eq icicle-default-value t))
+             ;; We don't use the same test as for `completing-read':
+             ;; (stringp initial-input) (string= "" initial-input))
+             (string= "" icicle-initial-value))
+    ;; Filter DEFAULT-FILENAME using `icicle-filter-wo-input'.  Done in `read-from-minibuffer'
+    ;; anyway, but we must also do it here, to reuse the correct default value for the init value.
+    (if (atom default-filename)
+        (setq initial-input  (icicle-filter-wo-input (file-name-nondirectory default-filename)))
+      (let ((found  nil)
+            (def1   default-filename))
+        (while (and (not found) def1)
+          (setq found  (icicle-filter-wo-input (file-name-nondirectory (car def1)))
+                def1   (cdr def1)))
+        (setq initial-input  (or found "")))))
+
+  ;; Override REQUIRE-MATCH as needed.
+  (setq require-match           (case icicle-require-match-flag
+                                  ((nil) require-match)
+                                  (no-match-required nil)
+                                  (partial-match-ok t)
+                                  (full-match-required 'full-match-required))
+        icicle-require-match-p  require-match)
+  (icicle-highlight-lighter)
+  (let ((read-file-name-function      nil)
+        (minibuffer-history-variable  minibuffer-history-variable)
+        result)
+    (let ((minibuffer-prompt-properties
+           (and (boundp 'minibuffer-prompt-properties) ; Emacs 21+ only
+                (icicle-remove-property 'face minibuffer-prompt-properties))))
+      (when (< emacs-major-version 21)
+        (setq prompt  (concat (and icicle-candidate-action-fn "+ ") prompt)))
+      (condition-case nil               ; If Emacs 22+, use predicate arg.
+          (setq result  (catch 'icicle-read-top
+                          (funcall (or icicle-old-read-file-name-fn 'read-file-name) prompt dir
+                                   default-filename require-match initial-input predicate)))
+        (wrong-number-of-arguments
+         (setq result  (catch 'icicle-read-top
+                         (funcall (or icicle-old-read-file-name-fn 'read-file-name) prompt dir
+                                  default-filename require-match initial-input))))))
+    ;; HACK.  Without this, when REQUIRE-MATCH is non-nil, `*Completions*' window
+    ;; does not disappear.
+    (when require-match (icicle-remove-Completions-window))
+    result))
+
+(defun icicle-fix-default-directory ()
+  "Convert backslashes in `default-directory' to slashes."
+  ;; This is a hack.  If you do `C-x 4 f' from a standalone minibuffer
+  ;; frame, `default-directory' on MS Windows has this form:
+  ;; `C:\some-dir/'.  There is a backslash character in the string.  This
+  ;; is not a problem for standard Emacs, but it is a problem for Icicles,
+  ;; because we interpret backslashes using regexp syntax - they are not
+  ;; file separators for Icicles.  So, we call `substitute-in-file-name' to
+  ;; change all backslashes in `default-directory' to slashes.  This
+  ;; shouldn't hurt, because `default-directory' is an absolute directory
+  ;; name - it doesn't contain environment variables.  For example, we
+  ;; convert `C:\some-dir/' to `c:/some-directory/'."
+  (setq default-directory  (icicle-abbreviate-or-expand-file-name
+                            (substitute-in-file-name default-directory))))
+
+(defun icicle-remove-property (prop plist)
+  "Remove property PROP from property-list PLIST, non-destructively.
+Returns the modified copy of PLIST."
+  (let ((cpy     plist)
+        (result  ()))
+    (while cpy
+      (unless (eq prop (car cpy)) (setq result  `(,(cadr cpy) ,(car cpy) ,@result)))
+      (setq cpy  (cddr cpy)))
+    (nreverse result)))
+
+
+;; REPLACE ORIGINAL `read-from-minibuffer' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Respect `icicle-default-value'.
+;;
+;; We use HIST-m@%=!$+&^*z instead of HIST, to avoid name capture by `minibuffer-history-variable's
+;; value.  If we didn't need to be Emacs 20-compatible, then we could employ
+;; `#1=#:hist'...`#1#'...`#1' read syntax to use an uninterned symbol.
+;;
+(unless (fboundp 'old-read-from-minibuffer)
+  (defalias 'old-read-from-minibuffer (symbol-function 'read-from-minibuffer)))
+
+(defun icicle-read-from-minibuffer (prompt &optional initial-contents keymap read
+                                    hist-m@%=!$+&^*z default-value inherit-input-method)
+  "Read a string from the minibuffer, prompting with string PROMPT.
+The optional second arg INITIAL-CONTENTS is an alternative to
+  DEFAULT-VALUE.  Vanilla Emacs considers it to be obsolete, but
+  Icicles does not.  It is discussed in more detail below.
+Third arg KEYMAP is a keymap to use while reading;
+  if omitted or nil, the default is `minibuffer-local-map'.
+If fourth arg READ is non-nil, then interpret the result as a Lisp object
+  and return that object:
+  in other words, do `(car (read-from-string INPUT-STRING))'
+Fifth arg HIST, if non-nil, specifies a history list and optionally
+  the initial position in the list.  It can be a symbol, which is the
+  history list variable to use, or it can be a cons cell
+  (HISTVAR . HISTPOS).  In that case, HISTVAR is the history list variable
+  to use, and HISTPOS is the initial position for use by the minibuffer
+  history commands.  For consistency, you should also specify that
+  element of the history as the value of INITIAL-CONTENTS.  Positions
+  are counted starting from 1 at the beginning of the list.
+Sixth arg DEFAULT-VALUE is the default value.  If non-nil, it is available
+  for history commands; but, unless READ is non-nil, `read-from-minibuffer'
+  does NOT return DEFAULT-VALUE if the user enters empty input!  It returns
+  the empty string.  DEFAULT-VALUE can be a string or a list of strings.
+  These  become the minibuffer's future history, available using `M-n'.
+Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
+ the current input method and the setting of `enable-multibyte-characters'.
+Eighth arg KEEP-ALL, if non-nil, says to put all inputs in the history list,
+ even empty or duplicate inputs.  This is available starting with Emacs 22.
+If the variable `minibuffer-allow-text-properties' is non-nil,
+ then the string which is returned includes whatever text properties
+ were present in the minibuffer.  Otherwise the value has no text properties.
+
+Option `icicle-default-value' controls how the default value,
+DEFAULT-VALUE, is treated.
+
+The remainder of this documentation string describes the
+INITIAL-CONTENTS argument in more detail.  If non-nil,
+INITIAL-CONTENTS is a string to be inserted into the minibuffer before
+reading input.  Normally, point is put at the end of that string.
+However, if INITIAL-CONTENTS is (STRING . POSITION), the initial input
+is STRING, but point is placed at one-indexed position POSITION in the
+minibuffer.  Any integer value less than or equal to one puts point at
+the beginning of the string.  *Note* that this behavior differs from
+the way such arguments are used in `completing-read' and some related
+functions, which use zero-indexing for POSITION."
+  (unless initial-contents (setq initial-contents  ""))
+
+  ;; Filter DEFAULT-VALUE using `icicle-filter-wo-input'.
+  (when default-value
+    (setq default-value
+          (if (atom default-value)
+              (icicle-filter-wo-input default-value)
+            (delq nil (mapcar #'icicle-filter-wo-input default-value))))) ; Emacs 23 accepts a list.
+  ;; Save new default value for caller (e.g. `icicle-lisp-vanilla-completing-read'.
+  (setq icicle-filtered-default-value  default-value)
+
+  ;; If a list of strings, use the first one for prompt etc.
+  (let ((def-value  (if (consp default-value) (car default-value) default-value)))
+    ;; Maybe use DEFAULT-VALUE for INITIAL-CONTENTS also.
+    (when (and icicle-default-value  (not (eq icicle-default-value t))
+               def-value  (stringp initial-contents)  (string= "" initial-contents))
+      (setq initial-contents  (if (integerp def-value) ; Character
+                                  (char-to-string def-value)
+                                def-value)))
+    (when (and def-value (eq icicle-default-value t)) ; Add DEFAULT-VALUE to PROMPT.
+      (when (icicle-file-name-input-p) (setq def-value  (file-name-nondirectory def-value)))
+      (setq prompt  (if (string-match "\\(.*\\)\\(: *\\)$" prompt)
+                        (concat (substring prompt (match-beginning 1) (match-end 1)) " (" def-value
+                                ")" (substring prompt (match-beginning 2) (match-end 2)))
+                      (concat prompt def-value)))))
+  (old-read-from-minibuffer
+   prompt initial-contents keymap read hist-m@%=!$+&^*z default-value inherit-input-method))
+
+
+;; REPLACE ORIGINAL `minibuffer-default-add-completions' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Respect Icicles global filters, so you don't see, as defaults, candidates that were filtered out.
+;;
+(when (fboundp 'minibuffer-default-add-completions) ; Emacs 23+.
+  (unless (fboundp 'old-minibuffer-default-add-completions)
+    (defalias 'old-minibuffer-default-add-completions
+        (symbol-function 'minibuffer-default-add-completions)))
+
+  ;; Use this as `minibuffer-default-add-function'.
+  (defun icicle-minibuffer-default-add-completions ()
+    "Like `old-minibuffer-default-add-completions', but respect global filters."
+    (let ((def  minibuffer-default)
+          (all  (icicle-all-completions "" minibuffer-completion-table
+                                        minibuffer-completion-predicate 'HIDE-SPACES)))
+      (setq all  (icicle-remove-if-not (lambda (cand)
+                                         (let ((case-fold-search  completion-ignore-case))
+                                           (icicle-filter-wo-input cand)))
+                                       all))
+      (if (listp def)
+          (append def all)
+        (cons def (delete def all))))))
+
+
+;; REPLACE ORIGINAL `read-number' defined in `subr.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; 1. Let user enter a numeric variable name, for its value.  Allow completion.
+;; 2. Allow for error reading input.
+;; 3. Call `ding' if not a number, and don't redisplay for `sit-for'.
+;;
+(when (fboundp 'read-number)            ; Emacs 22+
+  (unless (fboundp 'old-read-number)
+    (defalias 'old-read-number (symbol-function 'read-number)))
+
+  (defun icicle-read-number (prompt &optional default)
+    "Read a number in the minibuffer, prompting with PROMPT (a string).
+DEFAULT is returned if the user hits `RET' without typing anything.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, the user can
+also enter the name of a numeric variable - its value is returned.
+Completion is available for this.  A numeric variable is a variable
+whose value or whose custom type is compatible with type `integer',
+`number', or `float'."
+    (unwind-protect
+         (let ((num  nil)
+               (icicle-proxy-candidates
+                (and icicle-add-proxy-candidates-flag
+                     (let ((ipc  ()))
+                       (mapatoms
+                        (lambda (cand)
+                          (when (and (user-variable-p cand)
+                                     (condition-case nil
+                                         (icicle-var-is-of-type-p cand (if (>= emacs-major-version 22)
+                                                                           '(number integer float)
+                                                                         '(number integer)))
+                                       (error nil)))
+                            (push (symbol-name cand) ipc))))
+                       ipc)))
+             
+               ;; Emacs 23 allows DEFAULT to be a list of strings - use the first one for prompt etc.
+               (default1  (if (consp default) (car default) default)))
+           (when default
+             (save-match-data
+               (setq prompt  (if (string-match "\\(\\):[ \t]*\\'" prompt)
+                                 (replace-match (format " (default %s)" default1) t t prompt 1)
+                               (replace-regexp-in-string
+                                "[ \t]*\\'" (format " (default %s) " default1) prompt t t)))))
+           (when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+           (while (progn
+                    (let ((str  (completing-read prompt nil nil nil nil nil
+                                                 (if (consp default)
+                                                     (mapcar #'number-to-string default)
+                                                   (and default1 (number-to-string default1)))))
+                          temp)
+                      (setq num  (cond ((zerop (length str)) default1)
+                                       ((setq temp  (member str icicle-proxy-candidates))
+                                        (symbol-value (intern (car temp))))
+                                       ((stringp str) (condition-case nil (read str) (error nil))))))
+                    (unless (numberp num)
+                      (icicle-ding) (message "Not a number.  Try again.") (sit-for 0.5 nil t)
+                      t)))
+           num)
+      (setq icicle-proxy-candidates  ()))))
+
+;; Can't replace standard `read-char-exclusive' with this, because, starting with Emacs 22, it has
+;; an optional SECONDS arg that cannot be simulated using `completing-read'.
+(defun icicle-read-char-exclusive (prompt &optional inherit-input-method)
+  "Read a character in the minibuffer, prompting with PROMPT (a string).
+It is returned as a number.
+Optional arg INHERIT-INPUT-METHOD is as for `completing-read'.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, the user can
+also enter the name of a character variable - its value is returned.
+Completion is available for this.  A character variable is a variable
+whose value is compatible with type `character'."
+  (unwind-protect
+       (let* ((char  nil)
+              (icicle-proxy-candidates
+               (and icicle-add-proxy-candidates-flag
+                    (let ((ipc  ()))
+                      (mapatoms (lambda (cand)
+                                  (when (and (user-variable-p cand)
+                                             (condition-case nil
+                                                 (icicle-var-is-of-type-p cand '(character))
+                                               (error nil)))
+                                    (push (symbol-name cand) ipc))))
+                      ipc)))
+              str temp)
+         (when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+         (setq str   (completing-read prompt nil nil nil nil nil nil inherit-input-method)
+               char  (cond ((zerop (length str)) (error "No character read"))
+                           ((setq temp  (member str icicle-proxy-candidates))
+                            (symbol-value (intern (car temp))))
+                           ((stringp str) (condition-case nil
+                                              (progn (when (> (length str) 1)
+                                                       (message "First char is used: `%c'"
+                                                                (elt str 0)) (sit-for 2))
+                                                     (elt str 0))
+                                            (error nil)))))
+         char)
+    (setq icicle-proxy-candidates  ())))
+
+(defun icicle-read-string-completing (prompt &optional default pred hist)
+  "Read a string in the minibuffer, prompting with PROMPT (a string).
+If the user hits `RET' without typing anything, return DEFAULT, or \"\"
+  if DEFAULT is nil.
+PRED is a predicate that filters the variables available for completion.
+HIST is the history list to use, as for `completing-read'.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, the user can
+also enter the name of a string variable - its value is returned.
+Completion is available for this.  A string variable is a variable
+whose value or whose custom type is compatible with type `string'."
+  (unwind-protect
+       (let ((strg  nil)
+             (icicle-proxy-candidates
+              (and icicle-add-proxy-candidates-flag
+                   (let ((ipc  ()))
+                     (mapatoms (lambda (cand)
+                                 (when (and (user-variable-p cand)
+                                            (condition-case nil
+                                                (icicle-var-is-of-type-p cand '(string color regexp))
+                                              (error nil)))
+                                   (push (symbol-name cand) ipc))))
+                     ipc)))
+             ;; Emacs 23 allows DEFAULT to be a list of strings - use the first one for prompt etc.
+             (default1  (if (consp default) (car default) default)))
+         (when default
+           (save-match-data 
+             (setq prompt  (if (string-match "\\(\\):[ \t]*\\'" prompt)
+                               (replace-match (format " (default %s)" default1) t t prompt 1)
+                             (replace-regexp-in-string
+                              "[ \t]*\\'" (format " (default %s) " default1) prompt t t)))))
+         (when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+         (let ((strg-read  (completing-read prompt nil pred nil
+                                            (and (consp hist)
+                                                 (nth (cdr hist) (symbol-value (car hist))))
+                                            hist default))
+               temp)
+           (setq strg  (cond ((zerop (length strg-read)) (or default1 ""))
+                             ((setq temp  (member strg-read icicle-proxy-candidates))
+                              (setq temp  (symbol-value (intern (car temp))))
+                              (cond ((and (symbolp hist) (consp (symbol-value hist)))
+                                     (setcar (symbol-value hist) temp))
+                                    ((and (consp hist) (symbolp (car hist))
+                                          (consp (symbol-value (car hist))))
+                                     (setcar (symbol-value (car hist)) temp)))
+                              temp)
+                             (t strg-read))))
+         strg)
+    (setq icicle-proxy-candidates  ())))
+
+;; Same as `help-var-is-of-type-p'.
+(defun icicle-var-is-of-type-p (variable types &optional mode)
+  "Return non-nil if VARIABLE satisfies one of the custom types in TYPES.
+TYPES is a list of `defcustom' type sexps or a list of regexp strings.
+TYPES are matched, in order, against VARIABLE's type definition or
+VARIABLE's current value, until one is satisfied or all are tried.
+
+If TYPES is a list of regexps, then each is regexp-matched against
+VARIABLE's custom type.
+
+Otherwise, TYPES is a list of type sexps, each of which is a
+definition acceptable for `defcustom' :type or the first symbol of
+such a definition (e.g. `choice').  In this case, two kinds of type
+comparison are possible:
+
+1. VARIABLE's custom type, or its first symbol, is matched using
+  `equal' against each type in TYPES.
+
+2. VARIABLE's current value is checked against each type in TYPES to
+   see if it satisfies one of them.  In this case, VARIABLE's own type
+   is not used; VARIABLE might not even be typed - it could be a
+   variable not defined using `defcustom'.
+
+For any of the comparisons against VARIABLE's type, either that type
+can be checked directly or its supertypes (inherited types) can also
+be checked.
+
+These different type-checking possibilities depend on the value of
+argument MODE, as follows, and they determine the meaning of the
+returned value:
+
+`direct':   VARIABLE's type matches a member of list TYPES
+`inherit':  VARIABLE's type matches or is a subtype of a TYPES member
+`value':    VARIABLE is bound, and its value satisfies a type in TYPES
+`inherit-or-value': `inherit' or `value', tested in that order
+`direct-or-value':  `direct' or `value', tested in that order
+anything else (default): `inherit'
+
+VARIABLE's current value cannot satisfy a regexp type: it is
+impossible to know which concrete types a value must match."
+  (case mode
+    ((nil inherit)     (icicle-var-inherits-type-p variable types))
+    (inherit-or-value  (or (icicle-var-inherits-type-p variable types)
+                           (icicle-var-val-satisfies-type-p variable types)))
+    (value             (icicle-var-val-satisfies-type-p variable types))
+    (direct            (icicle-var-matches-type-p variable types))
+    (direct-or-value   (or (member (get variable 'custom-type) types)
+                           (icicle-var-val-satisfies-type-p variable types)))
+    (otherwise         (icicle-var-inherits-type-p variable types))))
+
+(defun icicle-var-matches-type-p (variable types)
+  "VARIABLE's type matches a member of TYPES."
+  (catch 'icicle-type-matches
+    (let ((var-type  (get variable 'custom-type)))
+      (dolist (type types)
+        (when (if (stringp type)
+                  (save-match-data (string-match type (format "%s" (format "%S" var-type))))
+                (equal var-type type))
+          (throw 'icicle-type-matches t))))
+    nil))
+
+(defun icicle-var-inherits-type-p (variable types)
+  "VARIABLE's type matches or is a subtype of a member of list TYPES."
+  (catch 'icicle-type-inherits
+    (let ((var-type  (get variable 'custom-type)))
+      (dolist (type types)
+        (while var-type
+          (when (or (and (stringp type)
+                         (save-match-data (string-match type (format "%s" (format "%S" var-type)))))
+                    (equal type var-type))
+            (throw 'icicle-type-inherits t))
+          (when (consp var-type) (setq var-type  (car var-type)))
+          (when (or (and (stringp type)
+                         (save-match-data (string-match type (format "%s" (format "%S" var-type)))))
+                    (equal type var-type))
+            (throw 'icicle-type-inherits t))
+          (setq var-type  (car (get var-type 'widget-type))))
+        (setq var-type  (get variable 'custom-type))))
+    nil))
+
+(defun icicle-var-val-satisfies-type-p (variable types)
+  "VARIABLE is bound, and its value satisfies a type in the list TYPES."
+  (and (boundp variable)
+       (let ((val  (symbol-value variable)))
+         (and (widget-convert (get variable 'custom-type))
+              (icicle-value-satisfies-type-p val types)))))
+
+(defun icicle-value-satisfies-type-p (value types)
+  "Return non-nil if VALUE satisfies a type in the list TYPES."
+  (catch 'icicle-type-value-satisfies
+    (dolist (type types)
+      (unless (stringp type)            ; Skip, for regexp type.
+        (setq type  (widget-convert type))
+        ;; Satisfies if either :match or :validate.
+        (when (condition-case nil
+                  (progn (when (and (widget-get type :match) (widget-apply type :match value))
+                           (throw 'icicle-type-value-satisfies t))
+                         (when (and (widget-get type :validate)
+                                    (progn (widget-put type :value value)
+                                           (not (widget-apply type :validate))))
+                           (throw 'icicle-type-value-satisfies t)))
+                (error nil))
+          (throw 'icicle-type-value-satisfies t))))
+    nil))
+
+(defun icicle-custom-type (variable)
+  "Returns the `defcustom' type of VARIABLE.
+Returns nil if VARIABLE is not a user option.
+
+Note: If the library that defines VARIABLE has not yet been loaded,
+then `icicle-custom-type' loads it.  Be sure you want to do that
+before you call this function."
+  (and (custom-variable-p variable)
+       (or (get variable 'custom-type)
+           (progn (custom-load-symbol variable) (get variable 'custom-type)))))
+
+
+;; REPLACE ORIGINAL `read-string' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Respect `icicle-default-value' (via use of `read-from-minibuffer').
+;;
+;; We use HIST-m@%=!$+&^*z instead of HISTORY, to avoid name capture by `minibuffer-history-variable's
+;; value.  If we didn't need to be Emacs 20-compatible, then we could employ
+;; `#1=#:hist'...`#1#'...`#1' read syntax to use an uninterned symbol.
+;;
+(unless (fboundp 'old-read-string)
+  (defalias 'old-read-string (symbol-function 'read-string)))
+
+(defun icicle-read-string (prompt &optional initial-input hist-m@%=!$+&^*z
+                           default-value inherit-input-method)
+  "Read a string from the minibuffer, prompting with string PROMPT.
+If non-nil, second arg INITIAL-INPUT is a string to insert before reading.
+  Vanilla Emacs considers it to be obsolete, but Icicles does not.  It
+  behaves like argument INITIAL-CONTENTS in `read-from-minibuffer'.
+  See the documentation string of `read-from-minibuffer' for details.
+The third arg HISTORY, if non-nil, specifies a history list
+  and optionally the initial position in the list.
+  See `read-from-minibuffer' for details of HISTORY argument.
+Fourth arg DEFAULT-VALUE is the default value.  If non-nil, it is used
+ for history commands, and as the value to return if the user enters
+ the empty string.
+Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
+ the current input method and the setting of enable-multibyte-characters."
+  (let ((value  (read-from-minibuffer prompt initial-input nil nil hist-m@%=!$+&^*z
+                                      default-value inherit-input-method)))
+    (when (and default-value (equal value ""))
+      (setq value (if (consp default-value) (car default-value) default-value)))
+    value))
+
+
+;; REPLACE ORIGINAL `read-face-name' in `faces.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Show face names in `*Completions*' with the faces they name.
+;;
+(unless (fboundp 'old-read-face-name)
+  (defalias 'old-read-face-name (symbol-function 'read-face-name)))
+
+(cond ((< emacs-major-version 21)
+       (defun icicle-read-face-name (prompt) ; Emacs 20
+         "Read a face name with completion and return its face symbol.
+PROMPT is the prompt.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, then you can
+also enter the name of a face-name variable - its value is returned.
+A face-name variable is a variable with custom-type `face'.
+
+If library `eyedropper.el' is used, then you can also choose proxy
+candidate `*point face name*' to use the face at point."
+         (require 'eyedropper nil t)
+         (let ((icicle-list-nth-parts-join-string  ": ")
+               (icicle-list-join-string            ": ")
+               ;; $$$$$$ (icicle-list-end-string             "")
+               (icicle-list-use-nth-parts          '(1))
+               (icicle-proxy-candidates
+                (and icicle-add-proxy-candidates-flag
+                     (append (and (fboundp 'eyedrop-face-at-point) (list "*point face name*"))
+                             (let ((ipc  ()))
+                               (mapatoms
+                                (lambda (cand)
+                                  (when (and (user-variable-p cand) (eq (get cand 'custom-type) 'face))
+                                    (push `,(concat "'" (symbol-name cand) "'") ipc))))
+                               ipc))))
+               face)
+           (setq prompt  (copy-sequence prompt)) ; So we can modify it by adding property.
+           (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+           (while (= (length face) 0)
+             (setq face  (icicle-transform-multi-completion
+                          (completing-read prompt (mapcar #'icicle-make-face-candidate (face-list))
+                                           nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+                                           (if (boundp 'face-name-history)
+                                               'face-name-history
+                                             'icicle-face-name-history)))))
+           (let ((proxy  (car (member face icicle-proxy-candidates))))
+             (cond ((save-match-data (string-match "*point face name\\*$" face))
+                    (eyedrop-face-at-point))
+                   (proxy (symbol-value (intern (substring proxy 1 (1- (length proxy))))))
+                   (t (intern face)))))))
+      ((= emacs-major-version 21)       ; Emacs 21
+       (defun icicle-read-face-name (prompt)
+         "Read a face name with completion and return its face symbol.
+PROMPT is the prompt.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, then you can
+also enter the name of a face-name variable - its value is returned.
+A face-name variable is a variable with custom-type `face'.
+
+If library `eyedropper.el' is used, then you can also choose proxy
+candidate `*point face name*' to use the face at point."
+         (require 'eyedropper nil t)
+         (let ((icicle-list-nth-parts-join-string  ": ")
+               (icicle-list-join-string            ": ")
+               ;; $$$$$$ (icicle-list-end-string             "")
+               (icicle-list-use-nth-parts          '(1))
+               (icicle-proxy-candidates
+                (and icicle-add-proxy-candidates-flag
+                     (append (and (fboundp 'eyedrop-face-at-point) (list "*point face name*"))
+                             (let ((ipc ()))
+                               (mapatoms
+                                (lambda (cand)
+                                  (when (and (user-variable-p cand) (eq (get cand 'custom-type) 'face))
+                                    (push `,(concat "'" (symbol-name cand) "'") ipc))))
+                               ipc))))
+               (face-list  (face-list))
+               (def        (thing-at-point 'symbol))
+               face)
+           (cond ((assoc def face-list) (setq prompt  (concat prompt " (default " def "): ")))
+                 (t (setq def     nil
+                          prompt  (concat prompt ": "))))
+           (setq prompt  (copy-sequence prompt)) ; So we can modify it by adding property.
+           (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+           (while (equal "" (setq face  (icicle-transform-multi-completion
+                                         (completing-read
+                                          prompt (mapcar #'icicle-make-face-candidate face-list) nil
+                                          (not (stringp icicle-WYSIWYG-Completions-flag)) nil
+                                          (if (boundp 'face-name-history)
+                                              'face-name-history
+                                            'icicle-face-name-history)
+                                          def)))))
+           (let ((proxy  (car (member face icicle-proxy-candidates))))
+             (cond ((save-match-data (string-match "*point face name\\*$" face))
+                    (eyedrop-face-at-point))
+                   (proxy (symbol-value (intern (substring proxy 1 (1- (length proxy))))))
+                   (t (intern face)))))))
+      ((< emacs-major-version 24)       ; Emacs 22-23
+       (defun icicle-read-face-name (prompt &optional string-describing-default multiple)
+         "Read a face name with completion and return its face symbol
+By default, use the face(s) on the character after point.  If that
+character has the property `read-face-name', that overrides the `face'
+property.
+
+PROMPT should be a string that describes what the caller will do with the face;
+  it should not end in a space.
+STRING-DESCRIBING-DEFAULT should describe what default the caller will use if
+  the user just types RET; you can omit it.
+If MULTIPLE is non-nil, return a list of faces (possibly only one).
+Otherwise, return a single face.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, then you can
+also enter the name of a face-name variable - its value is returned.
+A face-name variable is a variable with custom-type `face'.
+
+If library `palette.el' or `eyedropper.el' is used, then you can also
+choose proxy candidate `*point face name*' to use the face at point."
+         (or (require 'palette nil t) (require 'eyedropper nil t))
+         (let ((faceprop       (or (get-char-property (point) 'read-face-name)
+                                   (get-char-property (point) 'face)))
+               (aliasfaces     ())
+               (nonaliasfaces  ())
+               (icicle-proxy-candidates
+                (and icicle-add-proxy-candidates-flag
+                     (let ((ipc  ()))
+                       (mapatoms
+                        (lambda (cand)
+                          (when (and (user-variable-p cand) (eq (get cand 'custom-type) 'face))
+                            (push `,(concat "'" (symbol-name cand) "'") ipc))))
+                       ipc)))
+               faces)
+           ;; Undo Emacs 22 brain-dead treatment of PROMPT arg.
+           (when (save-match-data (string-match ": $" prompt))
+             (setq prompt  (substring prompt 0 -2)))
+           ;; Try to get a face name from the buffer.
+           (when (memq (intern-soft (thing-at-point 'symbol)) (face-list))
+             (setq faces  (list (intern-soft (thing-at-point 'symbol)))))
+           ;; Add the named faces that the `face' property uses.
+           (if (and (consp faceprop)
+                    ;; Don't treat an attribute spec as a list of faces.
+                    (not (keywordp (car faceprop)))
+                    (not (memq (car faceprop) '(foreground-color background-color))))
+               (dolist (f faceprop) (when (symbolp f) (push f faces)))
+             (when (and faceprop (symbolp faceprop)) (push faceprop faces)))
+           (delete-dups faces)
+           (cond (multiple
+                  ;; We leave this branch as it is.  Icicles does nothing special with
+                  ;; `completing-read-multiple'.
+                  (require 'crm)
+                  (mapatoms (lambda (s) (when (custom-facep s) ; Build up the completion tables.
+                                          (if (get s 'face-alias)
+                                              (push (symbol-name s) aliasfaces)
+                                            (push (symbol-name s) nonaliasfaces)))))
+                  (let* ((input   (completing-read-multiple ; Read the input.
+                                   (if (or faces string-describing-default)
+                                       (format "%s (default %s): "
+                                               prompt (if faces
+                                                          (mapconcat 'symbol-name faces ",")
+                                                        string-describing-default))
+                                     (format "%s: " prompt))
+                                   ;; This lambda expression is the expansion of Emacs 22 macro
+                                   ;; (complete-in-turn nonaliasfaces aliasfaces).  We expand it so
+                                   ;; this can be compiled also in Emacs < 22 to work for Emacs 22.
+                                   (lambda (string predicate mode)
+                                     (cond ((eq mode t)
+                                            (or (all-completions string nonaliasfaces predicate)
+                                                (all-completions string aliasfaces predicate)))
+                                           ((eq mode nil)
+                                            (or (try-completion string nonaliasfaces predicate)
+                                                (try-completion string aliasfaces predicate)))
+                                           (t
+                                            (or (test-completion string nonaliasfaces predicate)
+                                                (test-completion string aliasfaces predicate)))))
+                                   nil t nil (if (boundp 'face-name-history)
+                                                 'face-name-history
+                                               'icicle-face-name-history)
+                                   (and faces (mapconcat 'symbol-name faces ","))))
+                         (output  (cond ((or (equal input "") (equal input '(""))) ; Canonicalize.
+                                         faces)
+                                        ((stringp input)
+                                         (mapcar 'intern (split-string input ", *" t)))
+                                        ((listp input)
+                                         (mapcar 'intern input))
+                                        (input))))
+                    output))            ; Return the list of faces
+                 (t
+                  (when (consp faces) (setq faces  (list (car faces))))
+                  (let ((icicle-list-nth-parts-join-string  ": ")
+                        (icicle-list-join-string            ": ")
+                        ;; $$$$$$ (icicle-list-end-string             "")
+                        (icicle-list-use-nth-parts          '(1))
+                        (face-list                          (face-list))
+                        (def                                (if faces
+                                                                (mapconcat 'symbol-name faces ",")
+                                                              string-describing-default))
+                        face)
+                    (setq prompt  (copy-sequence prompt)) ; So we can modify it by adding property.
+                    (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+                    (while (equal "" (setq face  (icicle-transform-multi-completion
+                                                  (completing-read
+                                                   (if def
+                                                       (format "%s (default %s): " prompt def)
+                                                     (format "%s: " prompt))
+                                                   (mapcar #'icicle-make-face-candidate face-list)
+                                                   nil (not (stringp icicle-WYSIWYG-Completions-flag))
+                                                   nil (if (boundp 'face-name-history)
+                                                           'face-name-history
+                                                         'icicle-face-name-history)
+                                                   def)))))
+                    (let ((proxy  (car (member face icicle-proxy-candidates))))
+                      (if proxy
+                          (symbol-value (intern (substring proxy 1 (1- (length proxy)))))
+                        (intern face)))))))))
+      (t
+       (defun icicle-read-face-name (prompt &optional default multiple)
+         "Read a face name with completion and return its face symbol.
+By default, use the face(s) on the character after point.  If that
+character has the property `read-face-name', that overrides the `face'
+property.
+
+PROMPT should be a string that describes what the caller will do with the face;
+  it should not end in a space.
+Optional arg DEFAULT provides the value to display in the minibuffer
+prompt.  If not a string then it is also what is returned if the user
+just hits `RET' (empty input).  If a string then `nil' is returned.
+
+If MULTIPLE is non-nil, return a list of faces (possibly only one).
+Otherwise, return a single face.
+
+If option `icicle-add-proxy-candidates-flag' is non-nil, then you can
+also enter the name of a face-name variable - its value is returned.
+A face-name variable is a variable with custom-type `face'.
+
+If library `palette.el' or `eyedropper.el' is used, then you can also
+choose proxy candidate `*point face name*' to use the face at point."
+         (or (require 'palette nil t) (require 'eyedropper nil t))
+         (let ((faceprop       (or (get-char-property (point) 'read-face-name)
+                                   (get-char-property (point) 'face)))
+               (aliasfaces     ())
+               (nonaliasfaces  ())
+               (icicle-proxy-candidates
+                (and icicle-add-proxy-candidates-flag
+                     (let ((ipc  ()))
+                       (mapatoms
+                        (lambda (cand)
+                          (when (and (user-variable-p cand) (eq (get cand 'custom-type) 'face))
+                            (push `,(concat "'" (symbol-name cand) "'") ipc))))
+                       ipc)))
+               faces)
+           ;; Undo vanilla Emacs brain-dead treatment of PROMPT arg.
+           (when (save-match-data (string-match ": $" prompt))
+             (setq prompt  (substring prompt 0 -2)))
+           ;; Try to get a face name from the buffer.
+           (when (memq (intern-soft (thing-at-point 'symbol)) (face-list))
+             (setq faces  (list (intern-soft (thing-at-point 'symbol)))))
+           ;; Add the named faces that the `face' property uses.
+           (if (and (consp faceprop)
+                    ;; Don't treat an attribute spec as a list of faces.
+                    (not (keywordp (car faceprop)))
+                    (not (memq (car faceprop) '(foreground-color background-color))))
+               (dolist (f faceprop) (when (symbolp f) (push f faces)))
+             (when (and faceprop (symbolp faceprop)) (push faceprop faces)))
+           (delete-dups faces)
+           (cond (multiple
+                  ;; We leave this branch as it is.  Icicles does nothing special with
+                  ;; `completing-read-multiple'.
+                  (require 'crm)
+                  (mapatoms (lambda (s) (when (custom-facep s) ; Build up the completion tables.
+                                          (if (get s 'face-alias)
+                                              (push (symbol-name s) aliasfaces)
+                                            (push (symbol-name s) nonaliasfaces)))))
+                  (let* ((input   (completing-read-multiple ; Read the input.
+                                   (if (or faces default)
+                                       (format "%s (default `%s'): "
+                                               prompt (if faces
+                                                          (mapconcat 'symbol-name faces ",")
+                                                        default))
+                                     (format "%s: " prompt))
+                                   (completion-table-in-turn nonaliasfaces aliasfaces)
+                                   nil t nil (if (boundp 'face-name-history)
+                                                 'face-name-history
+                                               'icicle-face-name-history)
+                                   (and faces (mapconcat 'symbol-name faces ","))))
+                         (output  (cond ((or (equal input "") (equal input '(""))) ; Canonicalize.
+                                         (or faces (and (not (stringp default)) default)))
+                                        ((stringp input)
+                                         (mapcar 'intern (split-string input ", *" t)))
+                                        ((listp input)
+                                         (mapcar 'intern input))
+                                        (input))))
+                    output))            ; Return the list of faces
+                 (t
+                  (when (consp faces) (setq faces  (list (car faces))))
+                  (let ((icicle-list-nth-parts-join-string  ": ")
+                        (icicle-list-join-string            ": ")
+                        ;; $$$$$$ (icicle-list-end-string             "")
+                        (icicle-list-use-nth-parts          '(1))
+                        (face-list                          (face-list))
+                        (def                                (if faces
+                                                                (mapconcat 'symbol-name faces ",")
+                                                              (and (not (stringp default)) default)))
+                        face)
+                    (setq prompt  (copy-sequence prompt)) ; So we can modify it by adding property.
+                    (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+                    (while (equal "" (setq face  (icicle-transform-multi-completion
+                                                  (completing-read
+                                                   (if def
+                                                       (format "%s (default `%s'): " prompt def)
+                                                     (format "%s: " prompt))
+                                                   (mapcar #'icicle-make-face-candidate face-list)
+                                                   nil (not (stringp icicle-WYSIWYG-Completions-flag))
+                                                   nil (if (boundp 'face-name-history)
+                                                           'face-name-history
+                                                         'icicle-face-name-history)
+                                                   def)))))
+                    (let ((proxy  (car (member face icicle-proxy-candidates))))
+                      (if proxy
+                          (symbol-value (intern (substring proxy 1 (1- (length proxy)))))
+                        (intern face))))))
+           ))))
+
+(defun icicle-make-face-candidate (face)
+  "Return a completion candidate for FACE.
+The value of option `icicle-WYSIWYG-Completions-flag' determines the
+kind of candidate to use.
+ If nil, then the face name is used (a string).
+
+ If a string, then a multi-completion candidate is used, with the face
+ name followed by a sample swatch using FACE on the string's text.
+
+ If t, then the candidate is the face name itself, propertized with
+FACE."
+  (if (stringp icicle-WYSIWYG-Completions-flag)
+      (let ((swatch  (copy-sequence icicle-WYSIWYG-Completions-flag)))
+        (put-text-property 0 (length icicle-WYSIWYG-Completions-flag) 'face face swatch)
+        (list (list (symbol-name face) swatch)))
+    (let ((face-name  (copy-sequence (symbol-name face))))
+      (when icicle-WYSIWYG-Completions-flag
+        (put-text-property 0 (length face-name) 'face face face-name))
+      (list face-name))))
+
+
+;; REPLACE ORIGINAL `face-valid-attribute-values' in `faces.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Show color names in `*Completions*' with the (background) colors they name.
+;; This is really so that commands such as `modify-face' take advantage of colored candidates.
+;; We don't bother to try the same thing for Emacs 20, but the fix (directly to `modify-face') is
+;; similar and trivial.
+;;
+(when (fboundp 'face-valid-attribute-values) ; Emacs 21+.
+  (unless (fboundp 'old-face-valid-attribute-values)
+    (defalias 'old-face-valid-attribute-values (symbol-function 'face-valid-attribute-values)))
+
+  (if (fboundp 'window-system)          ; Emacs 23+
+      ;; Emacs 23+ `font-family-list' is strings, not conses of strings like older `x-font-family-list'.
+      (defun icicle-face-valid-attribute-values (attribute &optional frame)
+        "Return valid values for face attribute ATTRIBUTE.
+The optional argument FRAME is used to determine available fonts
+and colors.  If it is nil or not specified, the selected frame is
+used.  Value is an alist of (NAME . VALUE) if ATTRIBUTE expects a value
+out of a set of discrete values.  Value is `integerp' if ATTRIBUTE expects
+an integer value."
+        (let ((valid
+               (case attribute
+                 (:family (if (window-system frame)
+                              (mapcar (lambda (x) (cons x x)) ; Just strings, so don't take car.
+                                      (font-family-list))
+                            ;; Only one font on TTYs.
+                            (list (cons "default" "default"))))
+                 (:foundry
+                  (list nil))
+                 (:width
+                  (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+                          font-width-table))
+                 (:weight
+                  (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+                          font-weight-table))
+                 (:slant
+                  (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
+                          font-slant-table))
+                 (:inverse-video
+                  (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                          (internal-lisp-face-attribute-values attribute)))
+                 ((:underline :overline :strike-through :box)
+                  (if (window-system frame)
+                      (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                                     (internal-lisp-face-attribute-values attribute))
+                             (mapcar #'(lambda (c) (cons c c))
+                                     (mapcar #'icicle-color-name-w-bg (defined-colors frame))))
+                    (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                            (internal-lisp-face-attribute-values attribute))))
+                 ((:foreground :background)
+                  (mapcar #'(lambda (c) (cons c c))
+                          (mapcar #'icicle-color-name-w-bg (defined-colors frame))))
+                 ((:height) 'integerp)
+                 (:stipple (and (memq (window-system frame) '(x ns)) ; No stipple on w32
+                                (mapcar #'list (apply #'nconc (mapcar (lambda (dir)
+                                                                        (and (file-readable-p dir)
+                                                                             (file-directory-p dir)
+                                                                             (directory-files dir)))
+                                                                      x-bitmap-file-path)))))
+                 (:inherit (cons '("none" . nil)
+                                 (mapcar #'(lambda (c) (cons (symbol-name c) c)) (face-list))))
+                 (t
+                  (error "Internal error")))))
+          (if (and (listp valid) (not (memq attribute '(:inherit))))
+              (nconc (list (cons "unspecified" 'unspecified)) valid)
+            valid)))
+    (defun icicle-face-valid-attribute-values (attribute &optional frame) ; Emacs 21-22.
+      "Return valid values for face attribute ATTRIBUTE.
+The optional argument FRAME is used to determine available fonts
+and colors.  If it is nil or not specified, the selected frame is
+used.  Value is an alist of (NAME . VALUE) if ATTRIBUTE expects a value
+out of a set of discrete values.  Value is `integerp' if ATTRIBUTE expects
+an integer value."
+      (let ((valid
+             (case attribute
+               (:family (if window-system
+                            (mapcar #'(lambda (x) (cons (car x) (car x)))
+                                    (if (fboundp 'font-family-list)
+                                        (font-family-list)
+                                      (x-font-family-list)))
+                          ;; Only one font on TTYs.
+                          (list (cons "default" "default"))))
+               ((:width :weight :slant :inverse-video)
+                (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                        (internal-lisp-face-attribute-values attribute)))
+               ((:underline :overline :strike-through :box)
+                (if window-system
+                    (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                                   (internal-lisp-face-attribute-values attribute))
+                           (mapcar #'(lambda (c) (cons c c))
+                                   (mapcar #'icicle-color-name-w-bg (x-defined-colors frame))))
+                  (mapcar #'(lambda (x) (cons (symbol-name x) x))
+                          (internal-lisp-face-attribute-values attribute))))
+               ((:foreground :background)
+                (mapcar #'(lambda (c) (cons c c))
+                        (mapcar #'icicle-color-name-w-bg (x-defined-colors frame))))
+               ((:height) 'integerp)
+               (:stipple (and (memq window-system '(x w32 mac))
+                              (mapcar #'list (apply #'nconc (mapcar (lambda (dir)
+                                                                      (and (file-readable-p dir)
+                                                                           (file-directory-p dir)
+                                                                           (directory-files dir)))
+                                                                    x-bitmap-file-path)))))
+               (:inherit (cons '("none" . nil)
+                               (mapcar #'(lambda (c) (cons (symbol-name c) c)) (face-list))))
+               (t
+                (error "Internal error")))))
+        (if (and (listp valid) (not (memq attribute '(:inherit))))
+            (nconc (list (cons "unspecified" 'unspecified)) valid)
+          valid))))
+
+  (defun icicle-color-name-w-bg (color-name)
+    "Return copy of string COLOR-NAME with its background of that color.
+If `hexrgb.el' is not loaded, then just return COLOR-NAME."
+    (if (featurep 'hexrgb)
+        (let ((propertized-name  (copy-sequence color-name)))
+          (put-text-property 0 (length propertized-name)
+                             'face (cons 'background-color (hexrgb-color-name-to-hex color-name))
+                             propertized-name)
+          propertized-name)
+      color-name)))
+
+
+;; REPLACE ORIGINAL `completing-read-multiple' stuff in `crm.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Essentially, we just inhibit Icicles features for Icicle mode.
+;;
+(eval-after-load "crm"
+  '(progn
+    (when (fboundp 'crm-init-keymaps) (crm-init-keymaps)) ; Emacs 22, but not 23.
+    ;; Save vanilla CRM stuff as `old-' stuff.
+    (unless (fboundp 'old-completing-read-multiple)
+      (defalias 'old-completing-read-multiple (symbol-function 'completing-read-multiple)))
+    (defvar old-crm-local-completion-map crm-local-completion-map "Original CRM completion map.")
+    (defvar old-crm-local-must-match-map crm-local-must-match-map "Original CRM must-match map.")
+
+    ;; Define CRM stuff to use in Icicle mode.  Basically, just inhibit Icicles features.
+    (defun icicle-completing-read-multiple (prompt collection &optional predicate require-match
+                                            initial-input hist def inherit-input-method)
+      "Read multiple strings in the minibuffer, with completion.
+By using this functionality, a user may specify multiple strings at a
+single prompt, optionally using completion.
+
+Multiple strings are specified by separating each of the strings with
+a prespecified separator character.  For example, if the separator
+character is a comma, the strings 'alice', 'bob', and 'eve' would be
+specified as 'alice,bob,eve'.
+
+The default value for the separator character is the value of
+`crm-default-separator' (comma).  The separator character may be
+changed by modifying the value of `crm-separator'.
+
+Contiguous strings of non-separator-characters are referred to as
+'elements'.  In the aforementioned example, the elements are: 'alice',
+'bob', and 'eve'.
+
+Completion is available on a per-element basis.  For example, if the
+contents of the minibuffer are 'alice,bob,eve' and point is between
+'l' and 'i', pressing TAB operates on the element 'alice'.
+
+The return value of this function is a list of the read strings.
+
+See the documentation for `completing-read' for details on the
+arguments: PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH,
+INITIAL-INPUT, HIST, DEF, and INHERIT-INPUT-METHOD."
+      (let ((icicle-highlight-input-completion-failure  nil))
+        (old-completing-read-multiple prompt collection predicate require-match
+                                      initial-input hist def inherit-input-method)))
+
+    ;; Helper function - workaround because of a lack of multiple inheritance for keymaps.
+    (defun icicle-define-crm-completion-map (map)
+      "Make basic bindings for keymap MAP, a crm completion map."
+      (set-keymap-parent map minibuffer-local-completion-map)
+      (define-key map [remap minibuffer-complete] ; Emacs 22, 23.
+        (if (fboundp 'crm-complete) #'crm-complete #'crm-minibuffer-complete))
+      (when (fboundp 'crm-complete-word)
+        (define-key map [remap minibuffer-complete-word] #'crm-complete-word))
+      (when (and (boundp 'icicle-word-completion-keys) (fboundp 'crm-complete-word))
+        (dolist (key icicle-word-completion-keys) (define-key map key #'crm-complete-word)))
+      (define-key map [remap minibuffer-completion-help] ; Emacs 22, 23.
+        (if (fboundp 'crm-completion-help) #'crm-completion-help #'crm-minibuffer-completion-help))
+      (define-key map "?" #'crm-completion-help) ; Put back `?' as help (self-insert for Icicles).
+      (when (boundp 'icicle-prefix-complete-keys) ; Don't use Icicles completion.
+        (dolist (key icicle-prefix-complete-keys)
+          (define-key map key           ; Emacs 22, 23.
+            (if (fboundp 'crm-complete) #'crm-complete #'crm-minibuffer-complete)))))
+
+    (defvar icicle-crm-local-completion-map
+      (let ((map  (make-sparse-keymap)))
+        (icicle-define-crm-completion-map map)
+        map)
+      "Local keymap for minibuffer multiple input with completion.
+Analog of `minibuffer-local-completion-map'.")
+
+    (defvar icicle-crm-local-must-match-map
+      (let ((map  (make-sparse-keymap)))
+        (icicle-define-crm-completion-map map)
+        (define-key map [remap minibuffer-complete-and-exit]
+          (if (fboundp 'crm-complete-and-exit)
+              #'crm-complete-and-exit
+            #'crm-minibuffer-complete-and-exit))
+        map)
+      "Local keymap for minibuffer multiple input with exact match completion.
+Analog of `minibuffer-local-must-match-map' for crm.")
+
+    ;; Now, toggle Icicle mode, to take into account loading `crm.el' and redefining its stuff.
+    (eval-after-load "icicles-mode" '(icicle-toggle-icicle-mode-twice))))
+
+
+;; REPLACE ORIGINAL `read-shell-command' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Uses Icicles completion.
+;;
+(defun icicle-read-shell-command (prompt &optional initial-contents hist default-value
+                                  inherit-input-method)
+  "Read a shell command.
+Use file-name completion, unless INITIAL-CONTENTS is non-nil.
+For completion, pass args to `icicle-read-shell-command-completing'."
+  (if initial-contents
+      (if (fboundp 'old-read-shell-command) ; Emacs 23+.
+          (old-read-shell-command prompt initial-contents hist default-value inherit-input-method)
+        (error "icicle-read-shell-command: YOU SHOULD NOT SEE THIS; use`M-x icicle-send-bug-report'"))
+    (if (fboundp 'minibuffer-with-setup-hook)
+        (minibuffer-with-setup-hook
+         (lambda ()
+           (set (make-local-variable 'minibuffer-default-add-function)
+                'minibuffer-default-add-shell-commands))
+         (icicle-read-shell-command-completing prompt initial-contents (or hist 'shell-command-history)
+                                               default-value inherit-input-method))
+      (icicle-read-shell-command-completing prompt initial-contents (or hist 'shell-command-history)
+                                            default-value inherit-input-method))))
+
+
+;; REPLACE ORIGINAL `shell-command' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Uses Icicles completion.
+;; Not needed for Emacs 23+ - Icicles completion is automatic via `icicle-read-shell-command'.
+;;
+(unless (fboundp 'read-shell-command)   ; Emacs 23
+  (defun icicle-dired-smart-shell-command (command &optional output-buffer error-buffer)
+    "Like `icicle-shell-command', but in the current Virtual Dired directory.
+Uses Icicles completion - see `icicle-read-shell-command-completing'."
+    (interactive
+     (list (icicle-read-shell-command "Shell command: " nil nil
+                                      (cond (buffer-file-name (file-relative-name buffer-file-name))
+                                            ((eq major-mode 'dired-mode) (dired-get-filename t t))))
+           current-prefix-arg
+           shell-command-default-error-buffer))
+    (let ((default-directory  (if (fboundp 'dired-default-directory) ; Emacs 21+.
+                                  (dired-default-directory)
+                                (default-directory))))
+      (icicle-shell-command command output-buffer error-buffer))))
+
+
+;; REPLACE ORIGINAL `shell-command' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Uses Icicles completion.
+;; Not needed for Emacs 23+ - Icicles completion is automatic via `icicle-read-shell-command'.
+;;
+(unless (fboundp 'read-shell-command)   ; Emacs 23.
+  (unless (fboundp 'old-shell-command)
+    (defalias 'old-shell-command (symbol-function 'shell-command)))
+
+  (defun icicle-shell-command (command &optional output-buffer error-buffer)
+    "Execute string COMMAND in inferior shell; display output, if any.
+Uses Icicles completion - see `icicle-read-shell-command-completing'.
+
+With prefix argument, insert the COMMAND's output at point.
+
+If COMMAND ends in ampersand, execute it asynchronously.
+The output appears in the buffer `*Async Shell Command*'.
+That buffer is in shell mode.
+
+Otherwise, COMMAND is executed synchronously.  The output appears in
+the buffer `*Shell Command Output*'.  If the output is short enough to
+display in the echo area (which is determined by the variables
+`resize-mini-windows' and `max-mini-window-height'), it is shown
+there, but it is nonetheless available in buffer `*Shell Command
+Output*' even though that buffer is not automatically displayed.
+
+To specify a coding system for converting non-ASCII characters
+in the shell command output, use \\[universal-coding-system-argument] \
+before this command.
+
+Noninteractive callers can specify coding systems by binding
+`coding-system-for-read' and `coding-system-for-write'.
+
+The optional second argument OUTPUT-BUFFER, if non-nil,
+says to put the output in some other buffer.
+If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
+If OUTPUT-BUFFER is not a buffer and not nil,
+insert output in current buffer.  (This cannot be done asynchronously.)
+In either case, the output is inserted after point (leaving mark after it).
+
+If the command terminates without error, but generates output,
+and you did not specify \"insert it in the current buffer\",
+the output can be displayed in the echo area or in its buffer.
+If the output is short enough to display in the echo area
+\(determined by the variable `max-mini-window-height' if
+`resize-mini-windows' is non-nil), it is shown there.
+Otherwise,the buffer containing the output is displayed.
+
+If there is output and an error, and you did not specify \"insert it
+in the current buffer\", a message about the error goes at the end
+of the output.
+
+If there is no output, or if output is inserted in the current buffer,
+then `*Shell Command Output*' is deleted.
+
+If the optional third argument ERROR-BUFFER is non-nil, it is a buffer
+or buffer name to which to direct the command's standard error output.
+If it is nil, error output is mingled with regular output.
+In an interactive call, the variable `shell-command-default-error-buffer'
+specifies the value of ERROR-BUFFER."
+    (interactive
+     (list (icicle-read-shell-command "Shell command: " nil nil
+                                      (and buffer-file-name (file-relative-name buffer-file-name)))
+           current-prefix-arg
+           shell-command-default-error-buffer))
+    (old-shell-command command output-buffer error-buffer)))
+
+
+;; REPLACE ORIGINAL `shell-command-on-region' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Uses Icicles completion.
+;; Not needed for Emacs 23+ - Icicles completion is automatic via `icicle-read-shell-command'.
+;;
+(unless (fboundp 'read-shell-command)   ; Emacs 23.
+  (unless (fboundp 'old-shell-command-on-region)
+    (defalias 'old-shell-command-on-region (symbol-function 'shell-command-on-region)))
+
+  (defun icicle-shell-command-on-region (start end command &optional output-buffer replace
+                                         error-buffer display-error-buffer)
+    "Execute string COMMAND in inferior shell with region as input.
+Uses Icicles completion - see `icicle-read-shell-command-completing'.
+
+Normally, display any output in temp buffer `*Shell Command Output*';
+Prefix arg means replace the region with it.  Return the exit code of
+COMMAND.
+
+To specify a coding system for converting non-ASCII characters
+in the input and output to the shell command, use \\[universal-coding-system-argument]
+before this command.  By default, the input (from the current buffer)
+is encoded in the same coding system that will be used to save the file,
+`buffer-file-coding-system'.  If the output is going to replace the region,
+then it is decoded from that same coding system.
+
+The noninteractive arguments are START, END, COMMAND,
+OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
+Noninteractive callers can specify coding systems by binding
+`coding-system-for-read' and `coding-system-for-write'.
+
+If the command generates output, the output may be displayed
+in the echo area or in a buffer.
+If the output is short enough to display in the echo area
+\(determined by the variable `max-mini-window-height' if
+`resize-mini-windows' is non-nil), it is shown there.  Otherwise
+it is displayed in the buffer `*Shell Command Output*'.  The output
+is available in that buffer in both cases.
+
+If there is output and an error, a message about the error
+appears at the end of the output.
+
+If there is no output, or if output is inserted in the current buffer,
+then `*Shell Command Output*' is deleted.
+
+If the optional fourth argument OUTPUT-BUFFER is non-nil,
+that says to put the output in some other buffer.
+If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
+If OUTPUT-BUFFER is not a buffer and not nil,
+insert output in the current buffer.
+In either case, the output is inserted after point (leaving mark after it).
+
+If REPLACE, the optional fifth argument, is non-nil, that means insert
+the output in place of text from START to END, putting point and mark
+around it.
+
+If optional sixth argument ERROR-BUFFER is non-nil, it is a buffer
+or buffer name to which to direct the command's standard error output.
+If it is nil, error output is mingled with regular output.
+If DISPLAY-ERROR-BUFFER is non-nil, display the error buffer if there
+were any errors.  (This is always t, interactively.)  This argument is
+not available before Emacs 22.
+In an interactive call, the variable `shell-command-default-error-buffer'
+specifies the value of ERROR-BUFFER."
+    (interactive (let (string)
+                   (unless (mark) (error "The mark is not set now, so there is no region"))
+                   ;; Do this before calling region-beginning and region-end, in case subprocess
+                   ;; output relocates them while we are in the minibuffer.
+                   (setq string  (icicle-read-shell-command "Shell command on region: "))
+                   ;; call-interactively recognizes region-beginning and region-end specially,
+                   ;; leaving them in the history.
+                   (list (region-beginning) (region-end) string current-prefix-arg current-prefix-arg
+                         shell-command-default-error-buffer (= emacs-major-version 22))))
+    (if (= emacs-major-version 22)      ; `icicle-shell-command-on-region' not defined for Emacs 23+.
+        (old-shell-command-on-region start end command output-buffer replace error-buffer
+                                     display-error-buffer)
+      (old-shell-command-on-region start end command output-buffer replace error-buffer))))
+
+(defvar icicle-files () "A files list")
+
+
+;; REPLACE ORIGINAL `dired-read-shell-command' defined in `dired-aux.el'
+;; and redefined in `dired-x.el', saving it for restoration when you toggle `icicle-mode'.
+;; Uses Icicles completion.
+;; Uses `icicle-minibuffer-default-add-dired-shell-commands', not
+;; `minibuffer-default-add-dired-shell-commands'.
+;; Binds `icicle-files' for use as free var elsewhere.
+;;
+(defun icicle-dired-read-shell-command (prompt arg files)
+  "Read a shell command for FILES using file-name completion.
+Uses Icicles completion - see `icicle-read-shell-command-completing'.
+ARG is passed to `dired-mark-prompt' as its first arg, for the prompt.
+FILES are the files for which the shell command should be appropriate."
+  (let ((icicle-files  files))
+    (if (fboundp 'minibuffer-with-setup-hook)
+        (minibuffer-with-setup-hook
+         (lambda ()
+           (set (make-local-variable 'minibuffer-default-add-function)
+                'icicle-minibuffer-default-add-dired-shell-commands))
+         (dired-mark-pop-up  nil 'shell files 'icicle-dired-guess-shell-command
+                             (format prompt (dired-mark-prompt arg files)) files))
+      (dired-mark-pop-up  nil 'shell files 'icicle-dired-guess-shell-command
+                          (format prompt (dired-mark-prompt arg files)) files))))
+
+(defun icicle-dired-guess-shell-command (prompt files)
+  "Read a shell command for FILES using file-name completion.
+Call `icicle-read-shell-command-completing', passing PROMPT and FILES."
+  (icicle-read-shell-command-completing prompt nil nil nil nil files))
+
+;; Similar to `minibuffer-default-add-dired-shell-commands', but if Dired-X is available
+;; we include also the commands from `dired-guess-default'.
+;;
+;; Free var here: `icicle-files' is bound in `icicle-dired-read-shell-command'.
+;;;###autoload
+(defun icicle-minibuffer-default-add-dired-shell-commands ()
+  "Return a list of all commands associated with current dired files.
+The commands are from `minibuffer-default-add-dired-shell-commands',
+and if `dired-x.el' is used, `dired-guess-default'."
+  (interactive)
+  (let ((dired-guess-cmds  (and (boundp 'icicle-files) (fboundp 'dired-guess-default)
+                                (dired-guess-default icicle-files)))
+        (mailcap-cmds      (and (boundp 'icicle-files) (require 'mailcap nil t)
+                                (mailcap-file-default-commands icicle-files))))
+    (when (stringp dired-guess-cmds) (setq dired-guess-cmds  (list dired-guess-cmds)))
+    (if (listp minibuffer-default)
+        (append minibuffer-default dired-guess-cmds mailcap-cmds)
+      (cons minibuffer-default (append dired-guess-cmds mailcap-cmds)))))
+
+(defun icicle-read-shell-command-completing (prompt &optional initial-contents hist default-value
+                                             inherit-input-method files)
+  "Read a shell command using file-name completion.
+FILES name some files for which the command might be appropriate.
+The other arguments are the same as those for `read-from-minibuffer',
+except that READ and KEYMAP are missing, and HIST defaults to
+`shell-command-history'.
+
+Completion is lax, so you can use any shell command you want, not
+just a completion candidate, and you can edit the completed input to
+add options and arguments etc.
+
+In addition to file-name candidates, the following are combined to
+produce extra completion candidates (which are indicated using face
+`icicle-extra-candidates' in buffer `*Completions*'):
+
+* If you use Dired X, then the rules defined by user option
+  `dired-guess-shell-alist-user' and variable
+  `dired-guess-shell-alist-default' provide candidates appropriate for
+  the marked files in Dired.
+
+* Starting with Emacs 23, MIME-type associations provide candidates
+  appropriate for the marked files.
+
+* If option `icicle-guess-commands-in-path' is non-nil, then
+  executable files (or all files, if `shell-completion-execonly' is
+  nil) in your search path provide candidates.
+
+In addition, if `icicle-extra-candidates' is non-nil, its elements are
+also included as extra candidates.
+
+Help is available for individual candidates, using `C-M-RET',
+`C-M-mouse-2', and so on.  For an extra candidate (that is, for a
+shell command guessed to be appropriate), help is provided by the
+`apropos' shell command (if available).  For a file name, help shows
+the file's properties."
+  (let* ((dired-guess-files                           (and files (fboundp 'dired-guess-default)
+                                                           (dired-guess-default files)))
+         (icicle-sort-comparer                        'icicle-extra-candidates-first-p)
+         (completion-ignore-case                      (memq system-type '(ms-dos windows-nt cygwin)))
+         (insert-default-directory                    nil)
+         (icicle-extra-candidates-dir-insert-p        nil)
+         (icicle-point-position-in-candidate          'input-end)
+         (icicle-candidate-help-fn                    (lambda (cand)
+                                                        (if (member cand icicle-extra-candidates)
+                                                            (shell-command
+                                                             (concat "apropos " (shell-quote-argument
+                                                                                 cand))
+                                                             "*Help*")
+                                                          (icicle-describe-file cand))))
+         (icicle-extra-candidates                     icicle-extra-candidates)
+         (icicle-must-match-regexp                    icicle-file-match-regexp)
+         (icicle-must-not-match-regexp                icicle-file-no-match-regexp)
+         (icicle-must-pass-after-match-predicate      icicle-file-predicate)
+         (icicle-transform-function                   'icicle-remove-dups-if-extras)
+         ;; (icicle-sort-comparer                        (or icicle-file-sort icicle-sort-comparer))
+         (icicle-require-match-flag                   icicle-file-require-match-flag)
+         (icicle-default-value          ; Let user get default via `M-n', but don't insert it.
+          (and (memq icicle-default-value '(t nil)) icicle-default-value)))
+    (when (and dired-guess-files (atom dired-guess-files))
+      (setq dired-guess-files  (list dired-guess-files)))
+    ;; Add dired-guess guesses and mailcap guesses to `icicle-extra-candidates'.
+    (setq icicle-extra-candidates  (append dired-guess-files
+                                           (and files (require 'mailcap nil t) ; Emacs 23.
+                                                (fboundp 'mailcap-file-default-commands)
+                                                (mailcap-file-default-commands files))
+                                           icicle-extra-candidates))
+    (when icicle-guess-commands-in-path ; Add commands available from user's search path.
+      (setq icicle-extra-candidates  (append icicle-extra-candidates
+                                             (or icicle-shell-command-candidates-cache
+                                                 (icicle-recompute-shell-command-candidates)))))
+    (when icicle-extra-candidates
+      (setq prompt  (copy-sequence prompt)) ; So we can modify it by adding property.
+      (put-text-property 0 1 'icicle-fancy-candidates t prompt))
+    (let ((cmd  (icicle-read-file-name prompt nil default-value nil initial-contents)))
+      (when icicle-quote-shell-file-name-flag (setq cmd (icicle-quote-file-name-part-of-cmd cmd)))
+      cmd)))
+     
+(defun icicle-quote-file-name-part-of-cmd (strg)
+  "Double-quote the file name that starts string STRG, for the shell.
+This assumes a UNIX-style shell, for which the following characters
+normally need to be escaped in file names: [ \t\n;<>&|()'\"#$].
+This is appropriate, for example, if you use Cygwin with MS Windows.
+
+STRG is assumed to be a shell command, possibly including arguments
+and possibly ending with `&' to indicate asynchronous execution.
+
+The beginning of STRG is assumed to be a file name, possibly including
+the characters [ \t\n;<>&|()'\"#$].  This function double-quotes the
+file name only, not the rest of STRG.
+
+Example: If STRG is `c:/Program Files/My Dir/mycmd.exe arg1 arg2 &',
+and file c:/Program Files/My Dir/mycmd.exe exists, then this returns
+`\"c:/Program Files/My Dir/mycmd.exe\" arg1 arg2 &'."
+  (save-match-data
+    (if (not (string-match "[ \t\n;<>&|()'\"#$]" strg))
+        strg
+      (let ((indx         0)
+            (compl        "")
+            (filename     "")
+            (quoted-strg  strg)
+            prefix)
+        (while (and indx                ; Find longest prefix that matches a file name.
+                    (setq indx    (1+ (length compl)))
+                    (<= indx (length strg))
+                    (setq prefix  (substring strg 0 indx))
+                    (setq compl   (try-completion prefix 'read-file-name-internal
+                                                  (if (> emacs-major-version 22)
+                                                      minibuffer-completion-predicate
+                                                    default-directory))))
+          (when (and (<= (length compl) (length strg)) (string-match compl strg 0)
+                     (file-exists-p compl))
+            (setq filename compl)))
+        (if (or (string= "" filename)  (not (file-exists-p filename)))
+            strg
+          (setq quoted-strg  (concat "\"" filename "\""))
+          (setq quoted-strg  (concat quoted-strg (substring strg (length filename)))))))))
+
+
+;; REPLACE ORIGINAL `recentf-make-menu-items' defined in `recentf.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;; Adds Icicles submenu to Open Recent menu.
+;;
+(defun icicle-recentf-make-menu-items (&optional menu)
+  "Make menu items from the recent list.
+This is a menu filter function which ignores the MENU argument."
+  (setq recentf-menu-filter-commands nil)
+  (let* ((recentf-menu-shortcuts 0)
+         (file-items  (icicle-condition-case-no-debug err
+                          (mapcar 'recentf-make-menu-item
+                                  (recentf-apply-menu-filter recentf-menu-filter
+                                                             (recentf-menu-elements
+                                                              recentf-max-menu-items)))
+                        (error (message "recentf update menu failed: %s" (error-message-string err))))))
+    (append (or file-items '(["No files" t :help "No recent file to open" :active nil]))
+            (if recentf-menu-open-all-flag
+                '(["All..." recentf-open-files :help "Open recent files through a dialog" :active t])
+              (and (< recentf-max-menu-items (length recentf-list)) ; `recentf-list' is free here.
+                   '(["More..." recentf-open-more-files
+                      :help "Open files not in the menu through a dialog" :active t])))
+            (and recentf-menu-filter-commands '("---")) recentf-menu-filter-commands
+            (and recentf-menu-items-for-commands '("---")) recentf-menu-items-for-commands
+            (and icicle-mode
+                 '(("Icicles"
+                    ["+ Open Recent File..." icicle-recent-file]
+                    ["+ Open Recent File (Other Window)..." icicle-recent-file-other-window]
+                    ["+ Remove from Recent Files List..." icicle-remove-file-from-recentf-list]))))))
+ 
+;;(@* "Icicles functions - completion display (not cycling)")
+
+;;; Icicles functions - completion display (not cycling) -------------
+
+(defun icicle-display-candidates-in-Completions (&optional reverse-p no-display-p)
+  "Refresh the current set of completion candidates in `*Completions*'.
+REVERSE-P non-nil means display the candidates in reverse order.
+NO-DISPLAY-P non-nil means do not display the candidates; just
+  recompute them.  If the value is `no-msg', then do not show a
+  minibuffer message indicating that candidates were updated."
+  ;;$$   ;; Pred is special if `minibuffer-completion-table' is a function.
+  ;;   (when (and (not (functionp minibuffer-completion-table))
+  ;;              (functionp minibuffer-completion-predicate))
+  ;;     (setq icicle-completion-candidates
+  ;;           (icicle-remove-if-not
+  ;;            (lambda (cand)
+  ;;              (funcall minibuffer-completion-predicate
+  ;;                       (if (arrayp minibuffer-completion-table) (intern cand) (list cand))))
+  ;;            icicle-completion-candidates)))
+
+  ;; $$$  (case icicle-incremental-completion-flag
+  ;;     ((t always) (setq icicle-incremental-completion-p  'always))
+  ;;     ((nil) (setq icicle-incremental-completion-p  nil)))
+
+  ;; $$$$$ (unless (input-pending-p)             ; Do nothing if user hit a key.
+
+  ;; Upgrade `icicle-incremental-completion-p' if we are redisplaying, so that completions will
+  ;; be updated by `icicle-call-then-update-Completions' when you edit.
+  (setq icicle-incremental-completion-p  icicle-incremental-completion-flag)
+  (when (and (eq t icicle-incremental-completion-p) (get-buffer-window "*Completions*" 0))
+    (setq icicle-incremental-completion-p  'always))
+  (let ((nb-cands             (length icicle-completion-candidates)))
+    ;; $$$$$$ Could use this binding to prevent frame fitting, to allow room for images.
+    ;; But that is not really the solution.  Really should fit the frame or window in such a way
+    ;; that it takes image sizes into account.  Might need to wait for a fix to Emacs bug #7822.
+    ;; (autofit-frames-flag  (not icicle-image-files-in-Completions)))
+    (cond ((eq no-display-p 'no-msg))   ; No-op.
+          (no-display-p (icicle-msg-maybe-in-minibuffer
+                         (format "Candidates updated (%s matching): %d"
+                                 icicle-current-completion-mode nb-cands)))
+          ((null icicle-completion-candidates)
+           (save-selected-window (icicle-remove-Completions-window))
+           (icicle-msg-maybe-in-minibuffer
+            (if (eq 'apropos icicle-current-completion-mode)
+                (let ((typ  (car (rassq icicle-apropos-complete-match-fn
+                                        icicle-S-TAB-completion-methods-alist))))
+                  (concat "No " typ (and typ " ") "completions"))
+              (case (icicle-current-TAB-method)
+                (fuzzy        "No fuzzy completions")
+                (swank        "No swank (fuzzy symbol) completions")
+                (vanilla      "No vanilla completions")
+                (t            "No prefix completions")))))
+          (t
+           (when (> nb-cands icicle-incremental-completion-threshold)
+             (message "Displaying completion candidates..."))
+           ;; Display `*Completions*' now, so we can get its window's width.
+           ;; We don't wait for `with-output-to-temp-buffer' to display it, because displaying it
+           ;; might lead to splitting the display window, which would change its width.
+           ;; We need to know the width in order to calculate the proper candidate formatting.
+           (when (consp icicle-completion-candidates)
+             (let ((fit-frame-inhibit-fitting-flag  t)
+                   (comp-buf                        (get-buffer-create "*Completions*")))
+               (unless (get-buffer-window comp-buf 'visible)
+                 (save-selected-window (display-buffer comp-buf t 0)
+                                       (deactivate-mark))))) ; Remove any leftover mouse selection.
+           (with-output-to-temp-buffer "*Completions*"
+             ;; Each candidate in `icicle-completion-candidates' is a string, regardless of the
+             ;; original type of candidate used (e.g. symbol, string, alist candidate,...).  Here,
+             ;; provided `icicle-fancy-cands-internal-p' is non-nil, we transform these candidates,
+             ;; replacing each by a string that takes into account symbol properties
+             ;; `icicle-display-string' and `icicle-special-candidate'.
+             ;;
+             ;; Because `icicle-completion-candidates' is affected, changes to the candidate strings
+             ;; (e.g. propertizing) are also reflected in the completion return value chosen by the
+             ;; user.  It is not only the display in `*Completions*' that is affected.
+             ;;
+             ;; The symbol whose properties are used is the one in the current obarray that is named
+             ;; by the string candidate to be transformed.  If there is no such symbol, then no
+             ;; transformation occurs.  Unless `minibuffer-completion-table' is an obarray, the
+             ;; global obarray is used to get the symbol.
+             ;;
+             ;; 1. If the symbol has an `icicle-display-string' property, then that property value
+             ;;    must be a string (possibly propertized).  We replace the candidate by that string.
+             ;;
+             ;; 2. If the symbol has an `icicle-special-candidate' property, then we transfer the
+             ;;    property to the candidate string as a set of text properties.  (If the value is
+             ;;    not a plist, and `icicle-special-candidate-regexp' is nil, then just apply face
+             ;;    `icicle-special-candidate'.)  The effect is similar to using
+             ;;    `icicle-special-candidate-regexp', but the completion return value is also
+             ;;    affected.
+             (when icicle-fancy-cands-internal-p
+               (setq icicle-completion-candidates
+                     (mapcar (lambda (cand)
+                               (let* ((symb          (intern-soft
+                                                      cand (and (arrayp minibuffer-completion-table)
+                                                                minibuffer-completion-table)))
+                                      (display-strg  (and symb
+                                                          (stringp (get symb 'icicle-display-string))
+                                                          (get symb 'icicle-display-string)))
+                                      (new-cand      (or display-strg cand))
+                                      (spec-prop     (and symb (get symb 'icicle-special-candidate))))
+                                 ;; Apply `icicle-special-candidate' property's value.
+                                 ;; If the value is a plist, then apply the properties as text props.
+                                 ;; Else (the value is t), apply face `icicle-special-candidate'.
+                                 (when spec-prop
+                                   (setq new-cand  (copy-sequence new-cand))
+                                   (if (consp spec-prop)
+                                       (add-text-properties 0 (length new-cand) spec-prop new-cand)
+                                     (unless icicle-special-candidate-regexp
+                                       (add-text-properties 0 (length new-cand)
+                                                            '(face icicle-special-candidate)
+                                                            new-cand))))
+                                 new-cand))
+                             icicle-completion-candidates)))
+             ;; The `icicle-condition-case-no-debug' should not be needed, but it prevents an
+             ;; "End of buffer" message from `display-completion-list' on Emacs 22.
+             (icicle-condition-case-no-debug nil
+                 (display-completion-list
+                  (if reverse-p (reverse icicle-completion-candidates) icicle-completion-candidates))
+               (error nil)))
+           (save-excursion
+             (save-window-excursion
+               (with-current-buffer (get-buffer "*Completions*")
+                 (let ((buffer-read-only  nil)
+                       (eob               (point-max))
+                       (dir               (and (icicle-file-name-input-p) icicle-last-input
+                                               (icicle-file-name-directory icicle-last-input)))
+                       (hist              (and (symbolp minibuffer-history-variable)
+                                               (boundp minibuffer-history-variable)
+                                               (symbol-value minibuffer-history-variable)))
+                       (case-fold-search
+                        ;; Don't bother with buffer completion, `read-buffer-completion-ignore-case'.
+                        (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                                 (boundp 'read-file-name-completion-ignore-case))
+                            read-file-name-completion-ignore-case
+                          completion-ignore-case)))
+                   (goto-char (icicle-start-of-candidates-in-Completions))
+                   (while (not (eobp))
+                     (let* ((beg    (point))
+                            (end    (next-single-property-change beg 'mouse-face nil eob))
+                            (next   (next-single-property-change end 'mouse-face nil eob))
+                            (faces  ()))
+
+                       ;; Highlight candidate specially if it is a proxy candidate.
+                       (let ((candidate  (icicle-current-completion-in-Completions)))
+                         ;;$$$ (when dir (setq candidate  (expand-file-name candidate dir)))
+                         (when (member candidate icicle-proxy-candidates)
+                           (setq faces  (cons 'icicle-proxy-candidate faces))
+                           (if (not icicle-proxy-candidate-regexp)
+                               (add-text-properties beg end (cons 'face (list faces)))
+                             (save-match-data
+                               (when (string-match icicle-proxy-candidate-regexp candidate)
+                                 (add-text-properties (+ beg (match-beginning 0)) (+ beg (match-end 0))
+                                                      (cons 'face (list faces))))))))
+
+                       ;; Highlight candidate specially if it is an extra candidate.
+                       (let ((candidate  (icicle-current-completion-in-Completions)))
+                         ;;$$$ (when dir (setq candidate  (expand-file-name candidate dir)))
+                         (save-match-data
+                           (when (member candidate icicle-extra-candidates)
+                             (setq faces  (cons 'icicle-extra-candidate faces))
+                             (add-text-properties beg end (cons 'face (list faces))))))
+
+                       ;; Highlight candidate specially if it is a special candidate.
+                       (let ((candidate  (icicle-current-completion-in-Completions)))
+                         ;;$$$ (when dir (setq candidate  (expand-file-name candidate dir)))
+                         (save-match-data
+                           (when (and icicle-special-candidate-regexp
+                                      (string-match icicle-special-candidate-regexp candidate))
+                             (setq faces  (cons 'icicle-special-candidate faces))
+                             (if (not icicle-special-candidate-regexp)
+                                 (add-text-properties beg end (cons 'face (list faces)))
+                               (add-text-properties (+ beg (match-beginning 0)) (+ beg (match-end 0))
+                                                    (cons 'face (list faces)))))))
+
+                       ;; Highlight candidate (`*-historical-candidate') if it was used previously.
+                       (when icicle-highlight-historical-candidates-flag
+                         (let ((candidate  (icicle-current-completion-in-Completions)))
+                           (when dir (setq candidate  (expand-file-name candidate dir)))
+                           (when (and (consp hist) (member candidate hist)
+                                      (not (member candidate icicle-hist-cands-no-highlight)))
+                             (add-text-properties
+                              beg end
+                              `(face ,(setq faces  (cons 'icicle-historical-candidate faces)))))))
+
+                       ;; Highlight, inside the candidate, the expanded common match.
+                       (when (and (or icicle-expand-input-to-common-match-flag
+                                      (eq icicle-current-completion-mode 'prefix))
+                                  icicle-current-input (not (string= "" icicle-current-input)))
+                         (save-excursion
+                           (save-restriction
+                             (narrow-to-region beg end) ; Restrict to the completion candidate.
+                             (when (re-search-forward (regexp-quote (icicle-minibuf-input-sans-dir
+                                                                     icicle-current-input))
+                                                      nil t)
+                               (setq faces  (cons 'icicle-common-match-highlight-Completions faces))
+                               (put-text-property (match-beginning 0) (point) 'face faces)))))
+
+                       ;; Hide match for `icicle-current-input' (expanded common match, if available),
+                       ;; if `icicle-hide-common-match-in-Completions-flag' is non-nil.
+                       (save-excursion
+                         (save-restriction
+                           (narrow-to-region beg end) ; Restrict to the completion candidate.
+                           (when (and icicle-hide-common-match-in-Completions-flag
+                                      icicle-common-match-string)
+                             (when (re-search-forward (regexp-quote icicle-common-match-string) nil t)
+                               (if (> emacs-major-version 20)
+                                   (put-text-property (match-beginning 0) (point) 'display "...")
+                                 (put-text-property (match-beginning 0) (point) 'invisible t))))))
+
+                       ;; Highlight, inside the candidate, what the input expression matches.
+                       (unless (and icicle-current-raw-input (string= "" icicle-current-raw-input)
+                                    icicle-apropos-complete-match-fn)
+                         (save-excursion
+                           (save-restriction
+                             (narrow-to-region beg end) ; Restrict to the completion candidate.
+                             (let ((fn  (if (and (eq 'prefix icicle-current-completion-mode)
+                                                 (not (memq (icicle-current-TAB-method)
+                                                            '(fuzzy swank))))
+                                            ;; $$$$$$ What is best for `vanilla' (Emacs 23) completion?
+                                            'search-forward
+                                          (case icicle-apropos-complete-match-fn
+                                            (icicle-scatter-match
+                                             (lambda (input bound noerror)
+                                               (re-search-forward (icicle-scatter input)
+                                                                  bound noerror)))
+                                            (icicle-levenshtein-match
+                                             (if (= icicle-levenshtein-distance 1)
+                                                 (lambda (input bound noerror)
+                                                   (re-search-forward (icicle-levenshtein-one-regexp
+                                                                       input)
+                                                                      bound noerror))
+                                               're-search-forward))
+                                            (otherwise 're-search-forward)))))
+                               (save-excursion
+                                 (when (and (funcall fn (icicle-minibuf-input-sans-dir
+                                                         icicle-current-raw-input)
+                                                     nil t)
+                                            (not (eq (match-beginning 0) (point))))
+                                   (setq faces  (cons 'icicle-match-highlight-Completions faces))
+                                   (put-text-property (match-beginning 0) (point) 'face faces)))
+
+                               ;; If `icicle-hide-non-matching-lines-flag' then hide all lines
+                               ;; of candidate that do not match current input.
+                               (let ((candidate  (icicle-current-completion-in-Completions))
+                                     (input      (icicle-minibuf-input-sans-dir
+                                                  icicle-current-raw-input))
+                                     (cbeg       beg))
+                                 (when (and icicle-hide-non-matching-lines-flag
+                                            (string-match "\n" candidate)
+                                            (not (string= "\n" candidate)))
+                                   (goto-char cbeg)
+                                   (while (not (eobp))
+                                     (unless (funcall fn input (line-end-position) t)
+                                       (if (> emacs-major-version 20)
+                                           (put-text-property
+                                            (line-beginning-position)
+                                            (min (1+ (line-end-position)) (point-max))
+                                            'display "...\n")
+                                         (put-text-property
+                                          (line-beginning-position)
+                                          (min (1+ (line-end-position)) (point-max))
+                                          'invisible t)))
+                                     (forward-line 1))))))))
+
+                       ;; Highlight candidate if it has been saved.
+                       (when (and icicle-highlight-saved-candidates-flag
+                                  icicle-saved-completion-candidates)
+                         (let ((candidate  (icicle-current-completion-in-Completions)))
+                           (when (member candidate icicle-saved-completion-candidates)
+                             (let ((ov  (make-overlay beg end)))
+                               (push ov icicle-saved-candidate-overlays)
+                               (overlay-put ov 'face 'icicle-saved-candidate)
+                               (overlay-put ov 'priority '10)))))
+
+                       ;; Treat `icicle-candidate-properties-alist'.
+                       ;; A `face' prop will unfortunately wipe out any `face' prop we just applied.
+                       (when icicle-candidate-properties-alist
+                         (save-excursion
+                           (save-restriction
+                             (narrow-to-region beg end) ; Restrict to the completion candidate.
+                             (let* ((candidate  (buffer-substring (point-min) (point-max)))
+                                    (orig-pt    (point))
+                                    (start      0)
+                                    (end        0)
+                                    (partnum    1)
+                                    (join       (concat "\\(" icicle-list-join-string "\\|$\\)"))
+                                    (len-cand   (length candidate))
+                                    (len-join   (length icicle-list-join-string))
+                                    (first      t))
+                               (save-match-data
+                                 (while (and (or first  (not (= end (match-beginning 0)))
+                                                 (< (+ end len-join) len-cand))
+                                             (string-match join candidate
+                                                           (if (and (not first)
+                                                                    (= end (match-beginning 0))
+                                                                    (< end len-cand))
+                                                               (+ end len-join)
+                                                             end))
+                                             (< end len-cand))
+                                   (setq first  nil
+                                         end    (or (match-beginning 0) len-cand))
+                                   (let* ((entry
+                                           (assq partnum icicle-candidate-properties-alist))
+                                          (properties              (cadr entry))
+                                          (propertize-join-string  (car (cddr entry))))
+                                     (when properties
+                                       (add-text-properties
+                                        (+ start orig-pt) (+ end orig-pt) properties))
+                                     (when propertize-join-string
+                                       (add-text-properties
+                                        (+ end orig-pt)
+                                        (+ end orig-pt len-join)
+                                        properties)))
+                                   (setq partnum  (1+ partnum)
+                                         start    (match-end 0))))))))
+
+                       ;; Show thumbnail for an image file.
+                       (when (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                                  (fboundp 'image-file-name-regexp)
+                                  icicle-image-files-in-Completions
+                                  (if (fboundp 'display-graphic-p) (display-graphic-p) window-system))
+                         (let ((image-file  (icicle-transform-multi-completion
+                                             (icicle-current-completion-in-Completions))))
+                           (when (and (require 'image-dired nil t)
+                                      (if (fboundp 'string-match-p)
+                                          (string-match-p (image-file-name-regexp) image-file)
+                                        (save-match-data
+                                          (string-match (image-file-name-regexp) image-file))))
+                             (let ((thumb-img  (append (image-dired-get-thumbnail-image image-file)
+                                                       '(:margin 2)))
+                                   (img-ov     (overlays-in (point) (1+ (point)))))
+                               (if img-ov
+                                   (delete-overlay (car img-ov))
+                                 (put-image thumb-img beg)
+                                 (setq img-ov (loop for ov in (overlays-in (point) (1+ (point)))
+                                                    when (overlay-get ov 'put-image) collect ov into ovs
+                                                    finally return (car ovs)))
+                                 (overlay-put img-ov 'image-file image-file)
+                                 (overlay-put img-ov 'thumb-img thumb-img)
+                                 (overlay-put img-ov 'image-size (image-size thumb-img))))
+                             ;; Replace file name with a space.
+                             (when (eq 'image-only icicle-image-files-in-Completions)
+                               (let ((name-ov  (overlays-in end end)))
+                                 (if name-ov
+                                     (delete-overlay (car name-ov))
+                                   (setq name-ov  (make-overlay beg end))  
+                                   (overlay-put name-ov 'display " ")))))))
+                       (goto-char next)))
+                   ;; Remove all newlines for images-only display.
+                   (when (eq icicle-image-files-in-Completions 'image-only)
+                     (save-excursion (goto-char (icicle-start-of-candidates-in-Completions))
+                                     (while (and (re-search-forward "$") (not (eobp)))
+                                       (delete-char 1)))))
+                 (set-buffer-modified-p nil)
+                 (setq buffer-read-only  t))))
+           (with-current-buffer (get-buffer "*Completions*")
+             (set (make-local-variable 'mode-line-frame-identification)
+                  (format "  %d %s  "
+                          nb-cands
+                          (if (and icicle-max-candidates
+                                   (< icicle-max-candidates icicle-nb-candidates-before-truncation))
+                              (format "shown / %d" icicle-nb-candidates-before-truncation)
+                            "candidates")))
+             (put-text-property 0 (length mode-line-frame-identification)
+                                'face 'icicle-mode-line-help
+                                mode-line-frame-identification)
+             (goto-char (icicle-start-of-candidates-in-Completions))
+             (set-window-point (get-buffer-window "*Completions*" 0) (point))
+             (icicle-fit-completions-window))
+           (message nil)))))            ; Clear out any "Looking for..."
+
+
+;; REPLACE ORIGINAL `display-completion-list' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; 1. Does not remove text properties from candidates when it displays them in `*Completions*'.
+;; 2. Adjusts number of columns and their widths to window size.
+;; 3. The optional second arg is ignored.  In vanilla Emacs < 23, this is a string
+;;    representing a common prefix, and faces `completions-first-difference' and
+;;    `completions-common-part' are used on candidates.
+;;
+(unless (fboundp 'old-display-completion-list)
+  (defalias 'old-display-completion-list (symbol-function 'display-completion-list)))
+
+(defun icicle-display-completion-list (completions &optional ignored)
+  "Display the list of completions, COMPLETIONS, using `standard-output'.
+Each element may be just a symbol or string or may be a list of two
+strings to be printed as if concatenated.
+If it is a list of two strings, the first is the actual completion
+alternative, the second serves as annotation.
+`standard-output' must be a buffer.
+The actual completion alternatives, as inserted, are given the
+`mouse-face' property of `highlight'.
+At the end, this runs the normal hook `completion-setup-hook'.
+It can find the completion buffer in `standard-output'.
+The optional second arg is ignored."
+  (if (not (bufferp standard-output))
+      (let ((standard-output  (current-buffer))) (icicle-display-completion-list completions))
+    (let ((mainbuf  (current-buffer)))  ; $$$$$$ For Emacs 23 crap that puts base-size in last cdr.
+      (with-current-buffer standard-output
+        (goto-char (point-max))
+        (when icicle-show-Completions-help-flag (icicle-insert-Completions-help-string))
+        (let ((cand-intro-string  (if completions
+                                      "Possible completions are:\n"
+                                    "There are no possible completions of what you have typed.")))
+          (put-text-property 0 (length cand-intro-string) 'face 'icicle-Completions-instruction-1
+                             cand-intro-string)
+          (insert cand-intro-string))
+        ;; $$$$$$$$ Emacs 23 nonsense.  Revisit this when Stefan finally removes that crud.
+        ;; This is done in Emacs 23 `display-completion-list'.
+        (when (and completions  (fboundp 'completion-all-sorted-completions)) ; Emacs 23
+          (let ((last  (last completions)))
+            ;; Set base-size from the tail of the list.
+            (set (make-local-variable 'completion-base-size)
+                 (or (cdr last) (and (minibufferp mainbuf) 0)))
+            (setcdr last nil)))         ; Make completions a properly nil-terminated list.
+        (icicle-insert-candidates completions)))
+    ;; In vanilla Emacs < 23, the hook is run with `completion-common-substring' bound to
+    ;; what is here called IGNORED.
+    (run-hooks 'completion-setup-hook)
+    nil))
+
+(defun icicle-insert-candidates (candidates)
+  "Insert completion candidates from list CANDIDATES into the current buffer."
+  (when (consp candidates)
+    (let* ((multilinep       #'(lambda (cand)
+                                 (if (consp cand)
+                                     (or (string-match "\n" (car cand)) (string-match "\n" (cdr cand)))
+                                   (string-match "\n" cand))))
+           (any-multiline-p  (loop for cand in candidates
+                                   if (funcall multilinep cand) return t
+                                   finally return nil))
+           (max-cand-len     (apply #'max (mapcar (lambda (cand)
+                                                    (if (consp cand)
+                                                        (+ (length (car cand)) (length (cadr cand)))
+                                                      (length cand)))
+                                                  candidates)))
+           (comp-win         (get-buffer-window (current-buffer) 0))
+           (wwidth
+            (let ((spcl-frame-params  (special-display-p (buffer-name))))
+              (cond ((and spcl-frame-params ; Special-buffer.  Use its default frame width.
+                          (or (and (consp spcl-frame-params)
+                                   (cdr (assq 'width (cadr spcl-frame-params))))
+                              (cdr (assq 'width special-display-frame-alist))
+                              (cdr (assq 'width default-frame-alist)))))
+                    (comp-win (1- (window-width comp-win))) ; Width picked by `display-buffer'.
+                    (t 40))))           ; Failsafe.
+           (nb-cands         (length candidates))
+           (columns          (if any-multiline-p
+                                 1
+                               (max 1 (min (/ (* 100 wwidth)
+                                              (* icicle-candidate-width-factor max-cand-len))
+                                           nb-cands))))
+           (colwidth         (if (eq 1 columns) (min max-cand-len wwidth) (/ wwidth columns)))
+           (column-nb        0)
+           (rows             (ceiling nb-cands columns))
+ 	   (row              0)
+           startpos endpos string)
+      (dolist (cand  candidates)
+        (setq endpos  (point))
+        (cond ((eq icicle-completions-format 'vertical) ; Vertical layout.
+               (when (>= row rows)
+                 (forward-line (- rows))
+                 (setq column-nb  (+ column-nb colwidth)
+                       row        0))
+               (when (> column-nb 0)
+                 (end-of-line)
+                 (let ((cand-end  (point)))
+                   (indent-to column-nb icicle-inter-candidates-min-spaces)
+                   (put-text-property cand-end (point) 'mouse-face nil) ; Turn off `mouse-face', `face'
+                   (put-text-property cand-end (point) 'face nil))))
+              (t                        ; Horizontal layout (`horizontal' or nil).
+               (unless (bolp)
+                 (put-text-property (point) (point) 'mouse-face nil) ; Turn off `mouse-face'
+                 (indent-to (* (max 1 column-nb) colwidth) icicle-inter-candidates-min-spaces)
+                 (when (< wwidth (+ (max colwidth (if (consp cand)
+                                                      (+ (length (car cand)) (length (cadr cand)))
+                                                    (length cand)))
+                                    (current-column)))
+                   (save-excursion      ; This is like `fixup-whitespace', but only forward.
+                     (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+                     (unless (or (looking-at "^\\|\\s)")
+                                 (save-excursion (forward-char -1) (looking-at "$\\|\\s(\\|\\s'")))
+                       (insert ?\ )))
+                   (insert "\n")
+                   (setq column-nb  columns))) ; End of the row. Simulate being in farthest column.
+               (when (< endpos (point)) (set-text-properties endpos (point) nil))))
+        ;; Convert candidate (but not annotation) to unibyte or to multibyte, if needed.
+        (setq string  (if (consp cand) (car cand) cand))
+        (cond ((and (null enable-multibyte-characters) (multibyte-string-p string))
+               (setq string  (string-make-unibyte string)))
+              ((and enable-multibyte-characters (not (multibyte-string-p string)))
+               (setq string  (string-make-multibyte string))))
+        ;; Insert candidate (and annotation).  Mouse-face candidate, except for any newline as final
+        ;; char.  This is so that candidates are visually separate in `*Completions*'.  Instead,
+        ;; however, put property `icicle-keep-newline' on any final \n in the candidate, so
+        ;; `icicle-mouse-choose-completion' and `icicle-current-completion-in-Completions' can put
+        ;; the newline back as part of the candidate.
+        (cond ((atom cand)              ; No annotation.
+               (put-text-property (point) (progn (insert string)
+                                                 (if (and (eq ?\n (char-before (point)))
+                                                          (> (length string) 1)) ; Not just "\n".
+                                                     (1- (point))
+                                                   (point)))
+                                  'mouse-face 'highlight)
+               (when (eq ?\n (char-before (point)))
+                 (put-text-property (1- (point)) (point) 'icicle-keep-newline t)))
+              (t                        ; Candidate plus annotation.
+               (put-text-property (point) (progn (insert string)
+                                                 (if (and (eq ?\n (char-before (point)))
+                                                          (> (length string) 1)) ; Not just "\n".
+                                                     (1- (point))
+                                                   (point)))
+                                  'mouse-face 'highlight)
+               (when (eq ?\n (char-before (point)))
+                 (put-text-property (1- (point)) (point) 'icicle-keep-newline t))
+               (set-text-properties (point) (progn (insert (cadr cand)) (point)) nil)))
+        (if (not (eq icicle-completions-format 'vertical))
+            (setq column-nb  (mod (1+ column-nb) columns))
+          (if (> column-nb 0) (forward-line) (insert "\n")) ; Vertical layout.
+          (setq row  (1+ row)))
+        (when (and any-multiline-p (not (string-match "\n\'" cand)))
+          (insert (if (eq 'vertical icicle-completions-format) "\n" "\n\n")))))))
+
+;; ARG is not used yet/currently.
+(defun icicle-fit-completions-window (&optional arg)
+  "Fit the window that is showing completions to its contents.
+Optional ARG determines what the effect is, as follows:
+
+ nil        - scale text size and fit window to contents
+ fit-only   - fit window to contents, but do not scale text size
+ scale-only - scale text size but do not fit window to contents
+
+Text size scaling uses `icicle-Completions-text-scale-decrease' and is
+only available for Emacs 23+.  (Do not scale in any case if using
+`oneonone.el' with a `*Completions*' frame.)."
+  (unless (or (eq arg 'scale-only)
+              (= emacs-major-version 23) ; `fit-window-to-buffer' is broken before 24: removes windows.
+              (= emacs-major-version 22))
+    (when (and (eq major-mode 'completion-list-mode) (fboundp 'fit-window-to-buffer))
+      (let ((win  (get-buffer-window "*Completions*" 0)))
+        (unless (< (window-width win) (frame-width)) ; Don't shrink if split horizontally.
+          (fit-window-to-buffer
+           win
+           (or (and (symbolp icicle-last-top-level-command)
+                    (get icicle-last-top-level-command 'icicle-Completions-window-max-height))
+               icicle-Completions-window-max-height))))))
+  (unless (eq arg 'fit-only)
+    (when (and (boundp 'icicle-Completions-text-scale-decrease) ; Emacs 23+
+               (eq major-mode 'completion-list-mode)
+               (or (not (boundp '1on1-*Completions*-frame-flag)) (not 1on1-*Completions*-frame-flag)))
+      (text-scale-decrease icicle-Completions-text-scale-decrease))))
+
+(defun icicle-highlight-initial-whitespace (input)
+  "Highlight any initial whitespace in your input.
+Only if `icicle-highlight-input-initial-whitespace-flag' is non-nil.
+INPUT is the current user input, that is, the completion root.
+This must be called in the minibuffer."
+  (when (and icicle-highlight-input-initial-whitespace-flag (not (string= "" input)))
+    (let ((case-fold-search
+           ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+           (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                    (boundp 'read-file-name-completion-ignore-case))
+               read-file-name-completion-ignore-case
+             completion-ignore-case)))
+      (save-excursion
+        (goto-char (icicle-minibuffer-prompt-end))
+        (when (and (icicle-file-name-input-p) insert-default-directory)
+          (search-forward (icicle-file-name-directory-w-default input) nil t)) ; Skip directory.
+        (save-excursion
+          (save-restriction
+            (narrow-to-region (point) (point-max)) ; Search within completion candidate.
+            (while (and (not (eobp)) (looking-at "\\(\\s-\\|\n\\)+"))
+              (put-text-property (point) (1+ (point)) 'face 'icicle-whitespace-highlight)
+              (forward-char 1))
+            ;; Remove any previous whitespace highlighting that is no longer part of prefix.
+            (while (not (eobp))
+              (when (eq (get-text-property (point) 'face) 'icicle-whitespace-highlight)
+                (put-text-property (point) (1+ (point)) 'face nil))
+              (forward-char 1))))))))
+
+(defun icicle-minibuffer-prompt-end ()
+  "Buffer position of end of minibuffer prompt, or `point-min'.
+Version of `minibuffer-prompt-end' that works for Emacs 20 and later."
+  (if (fboundp 'minibuffer-prompt-end) (minibuffer-prompt-end) (point-min)))
+ 
+;;(@* "Icicles functions - TAB completion cycling")
+
+;;; Icicles functions - TAB completion cycling --------------------
+
+(defun icicle-prefix-candidates (input)
+  "List of prefix or fuzzy completions for the current partial INPUT.
+INPUT is a string.  Each candidate is a string."
+  (setq icicle-candidate-nb  nil)
+  (if (or (and (eq 'fuzzy (icicle-current-TAB-method)) (featurep 'fuzzy-match))
+          (and (eq 'swank (icicle-current-TAB-method)) (featurep 'el-swank-fuzzy)))
+      (condition-case nil
+          (icicle-transform-candidates (append icicle-extra-candidates icicle-proxy-candidates
+                                               (icicle-fuzzy-candidates input)))
+        (quit (top-level)))             ; Let `C-g' stop it.
+    (let ((cands  (icicle-unsorted-prefix-candidates input)))
+      (cond (icicle-abs-file-candidates  (icicle-strip-ignored-files-and-sort cands))
+            (icicle-sort-comparer        (icicle-maybe-sort-maybe-truncate cands))
+            (t                           cands)))))
+
+(defun icicle-fuzzy-candidates (input)
+  "Return fuzzy matches for INPUT.  Handles also swank fuzzy symbol match."
+  (condition-case nil
+      (let ((candidates  ()))
+        ;; $$$$ Should treat other `minibuffer-completion-table' types also.
+        (cond ((and (vectorp minibuffer-completion-table)
+                    (not (eq (icicle-current-TAB-method) 'swank)))
+               (mapatoms (lambda (symb) (when (or (null minibuffer-completion-predicate)
+                                                  (funcall minibuffer-completion-predicate symb))
+                                          (push (symbol-name symb) candidates)))
+                         minibuffer-completion-table)
+               (setq candidates  (FM-all-fuzzy-matches input candidates)))
+              ((vectorp minibuffer-completion-table)
+               (setq candidates  (mapcar #'car
+                                         (car (el-swank-fuzzy-completions
+                                               input icicle-swank-timeout
+                                               (or minibuffer-completion-predicate 'fboundp)
+                                               icicle-swank-prefix-length)))))
+              ((and (consp minibuffer-completion-table) (consp (car minibuffer-completion-table)))
+               (dolist (cand minibuffer-completion-table)
+                 (when (or (null minibuffer-completion-predicate)
+                           (funcall minibuffer-completion-predicate cand))
+                   (push (car cand) candidates)))
+               (setq candidates  (FM-all-fuzzy-matches input candidates))))
+        (let ((icicle-extra-candidates
+               (icicle-remove-if-not
+                (lambda (cand) (save-match-data (string-match input cand))) icicle-extra-candidates))
+              (icicle-proxy-candidates
+               (icicle-remove-if-not
+                (lambda (cand) (save-match-data (string-match input cand))) icicle-proxy-candidates))
+              (filtered-candidates
+               (icicle-transform-candidates
+                (append icicle-extra-candidates icicle-proxy-candidates
+                        (icicle-remove-if-not
+                         (lambda (cand)
+                           (let ((case-fold-search  completion-ignore-case))
+                             (and (icicle-filter-wo-input cand)
+                                  (or (not icicle-must-pass-after-match-predicate)
+                                      (funcall icicle-must-pass-after-match-predicate cand)))))
+                         candidates)))))
+          (when (consp filtered-candidates)
+            (setq icicle-common-match-string  (icicle-expanded-common-match input filtered-candidates)))
+          (unless filtered-candidates  (setq icicle-common-match-string  nil))
+          filtered-candidates))
+    (quit (top-level))))                ; Let `C-g' stop it.
+
+(defun icicle-unsorted-prefix-candidates (input)
+  "Unsorted list of prefix completions for the current partial INPUT.
+this also sets `icicle-common-match-string' to the expanded common
+prefix over all candidates."
+  (condition-case nil
+      (let* ((candidates
+              (if (icicle-not-basic-prefix-completion-p)
+                  (icicle-completion-all-completions input minibuffer-completion-table
+                                                     minibuffer-completion-predicate
+                                                     ;; $$$$$$ (- (point) (field-beginning)))
+                                                     (length input)
+                                                     (and (fboundp 'completion--field-metadata) ;Emacs24
+                                                          (completion--field-metadata
+                                                           (field-beginning))))
+                (icicle-all-completions input minibuffer-completion-table
+                                        minibuffer-completion-predicate
+                                        icicle-ignore-space-prefix-flag)))
+             (icicle-extra-candidates
+              (icicle-remove-if-not
+               (lambda (cand)
+                 (save-match-data
+                   (string-match (concat "^" (regexp-quote input)) cand))) icicle-extra-candidates))
+             (icicle-proxy-candidates
+              (icicle-remove-if-not
+               (lambda (cand)
+                 (save-match-data
+                   (string-match (concat "^" (regexp-quote input)) cand))) icicle-proxy-candidates))
+             (filtered-candidates
+              (icicle-transform-candidates
+               (append icicle-extra-candidates icicle-proxy-candidates
+                       (icicle-remove-if-not
+                        (lambda (cand)
+                          (let ((case-fold-search  completion-ignore-case))
+                            (and (icicle-filter-wo-input cand)
+                                 (or (not icicle-must-pass-after-match-predicate)
+                                     (funcall icicle-must-pass-after-match-predicate cand)))))
+                        candidates)))))
+        (when (consp filtered-candidates)
+          (let ((common-prefix
+                 (if (icicle-not-basic-prefix-completion-p)
+                     (icicle-completion-try-completion input minibuffer-completion-table
+                                                       minibuffer-completion-predicate
+                                                       ;; $$$$$$ (- (point) (field-beginning)))
+                                                       (length input)
+                                                       (and (fboundp 'completion--field-metadata)
+                                                            (completion--field-metadata ; Emacs 24
+                                                             (field-beginning))))
+                   (try-completion input minibuffer-completion-table
+                                   minibuffer-completion-predicate))))
+            (setq icicle-common-match-string  (if (eq t common-prefix) input common-prefix))))
+        (unless filtered-candidates  (setq icicle-common-match-string  nil))
+        filtered-candidates)
+    (quit (top-level))))                ; Let `C-g' stop it.
+
+(defun icicle-file-name-prefix-candidates (input)
+  "List of prefix completions for partial file name INPUT.
+INPUT is a string.
+Candidates can be directories.  Each candidate is a string."
+  (setq icicle-candidate-nb  nil)
+  ;; $$$$$$ (let ((default-directory  (icicle-file-name-directory-w-default input)))
+  ;; $$$$$$   (icicle-unsorted-file-name-prefix-candidates
+  ;; $$$$$$     (or (icicle-file-name-nondirectory input) ""))))
+  (icicle-strip-ignored-files-and-sort (icicle-unsorted-file-name-prefix-candidates input)))
+
+(defun icicle-unsorted-file-name-prefix-candidates (input)
+  "Unsorted list of prefix completions for the current file-name INPUT.
+This also sets `icicle-common-match-string' to the expanded common
+prefix over all candidates."
+  (condition-case nil
+      (let* ((candidates
+              (if (icicle-not-basic-prefix-completion-p)
+                  (icicle-completion-all-completions input minibuffer-completion-table
+                                                     minibuffer-completion-predicate
+                                                     (length input)
+                                                     (and (fboundp 'completion--field-metadata) ;Emacs24
+                                                          (completion--field-metadata
+                                                           (field-beginning))))
+                (icicle-all-completions input minibuffer-completion-table
+                                        minibuffer-completion-predicate
+                                        icicle-ignore-space-prefix-flag)))
+             (icicle-extra-candidates
+              (icicle-remove-if-not
+               (lambda (cand)
+                 (save-match-data
+                   (string-match (concat "^" (regexp-quote input)) cand))) icicle-extra-candidates))
+             (icicle-proxy-candidates
+              (icicle-remove-if-not
+               (lambda (cand)
+                 (save-match-data
+                   (string-match (concat "^" (regexp-quote input)) cand))) icicle-proxy-candidates))
+             (filtered-candidates
+              (icicle-transform-candidates
+               (append icicle-extra-candidates icicle-proxy-candidates
+                       (icicle-remove-if-not
+                        (lambda (cand)
+                          (let ((case-fold-search
+                                 (if (boundp 'read-file-name-completion-ignore-case)
+                                     read-file-name-completion-ignore-case
+                                   completion-ignore-case)))
+                            (if (member cand '("../" "./"))
+                                (member input '(".." ".")) ; Prevent "" from matching "../"
+                              (and
+;;; $$$$$$ REMOVED - This was no good for PCM - e.g. input `ic-o' and candidates `icicles-opt.el[c]'.
+;;;                  We don't do it for non-file-name completion, anyway, and it doesn't seem needed.
+;;;                                  (save-match-data
+;;;                                    (string-match (concat "^" (regexp-quote input)) cand))
+                               (icicle-filter-wo-input cand)
+                               (or (not icicle-must-pass-after-match-predicate)
+                                   (funcall icicle-must-pass-after-match-predicate cand))))))
+                        candidates)))))
+        (when (consp filtered-candidates)
+          (let ((common-prefix
+                 (if (icicle-not-basic-prefix-completion-p)
+                     (icicle-completion-try-completion input minibuffer-completion-table
+                                                       minibuffer-completion-predicate
+                                                       (length input)
+                                                       (and (fboundp 'completion--field-metadata)
+                                                            (completion--field-metadata ; Emacs 24
+                                                             (field-beginning))))
+                   (try-completion input minibuffer-completion-table default-directory))))
+            ;; If common prefix matches an empty directory, use that dir as the sole completion.
+            (when (and (stringp common-prefix)
+                       (save-match-data (string-match "/\\.$" common-prefix))) ; Matches /., /..
+              (setq common-prefix  (substring common-prefix 0 (- (length common-prefix) 2))))
+            (setq icicle-common-match-string  (if (eq t common-prefix) input common-prefix))))
+        (unless filtered-candidates  (setq icicle-common-match-string  nil))
+        filtered-candidates)
+    (quit (top-level))))                ; Let `C-g' stop it.
+ 
+;;(@* "Icicles functions - S-TAB completion cycling")
+
+;;; Icicles functions - S-TAB completion cycling -------------------
+
+(defun icicle-apropos-candidates (input)
+  "List of candidate apropos completions for the current partial INPUT.
+INPUT is a string.  Each candidate is a string."
+  (setq icicle-candidate-nb  nil)
+  (let ((cands  (icicle-unsorted-apropos-candidates input)))
+    (cond (icicle-abs-file-candidates  (icicle-strip-ignored-files-and-sort cands))
+          (icicle-sort-comparer        (icicle-maybe-sort-maybe-truncate cands))
+          (t                           cands))))
+
+(defun icicle-unsorted-apropos-candidates (input)
+  "Unsorted list of apropos completions for the current partial INPUT.
+When `icicle-expand-input-to-common-match-flag' is non-nil, this also
+sets `icicle-common-match-string' to the expanded common match of
+input over all candidates."
+  (condition-case nil
+      (progn
+        (when icicle-regexp-quote-flag  (setq input  (regexp-quote input)))
+        (let* ((candidates
+                (if (and (functionp minibuffer-completion-table)
+                         (not icicle-apropos-complete-match-fn))
+                    ;; Let the function do it all.
+                    (icicle-all-completions input minibuffer-completion-table
+                                            minibuffer-completion-predicate
+                                            icicle-ignore-space-prefix-flag)
+                  (icicle-all-completions "" minibuffer-completion-table
+                                          minibuffer-completion-predicate
+                                          icicle-ignore-space-prefix-flag)))
+               (icicle-extra-candidates
+                (icicle-remove-if-not
+                 (lambda (cand) (save-match-data (string-match input cand))) icicle-extra-candidates))
+               (icicle-proxy-candidates
+                (icicle-remove-if-not
+                 (lambda (cand) (save-match-data (string-match input cand))) icicle-proxy-candidates))
+               (filtered-candidates
+                (icicle-transform-candidates
+                 (append icicle-extra-candidates icicle-proxy-candidates
+                         (icicle-remove-if-not
+                          (lambda (cand)
+                            (let ((case-fold-search  completion-ignore-case))
+                              (and (icicle-filter-wo-input cand)
+                                   (or (not icicle-apropos-complete-match-fn)
+                                       ;; Assume no match if error - e.g. due to `string-match' with
+                                       ;; binary data in Emacs 20.  Do this everywhere we call
+                                       ;; `icicle-apropos-complete-match-fn'.
+                                       (condition-case nil
+                                           (funcall icicle-apropos-complete-match-fn input cand)
+                                         (error nil)))
+                                   (or (not icicle-must-pass-after-match-predicate)
+                                       (funcall icicle-must-pass-after-match-predicate cand)))))
+                          candidates)))))
+          (when (and icicle-expand-input-to-common-match-flag (consp filtered-candidates))
+            (setq icicle-common-match-string  (icicle-expanded-common-match input filtered-candidates)))
+          (unless filtered-candidates  (setq icicle-common-match-string  nil))
+          filtered-candidates))         ; Return candidates.
+    (quit (top-level))))                ; Let `C-g' stop it.
+
+(defun icicle-file-name-apropos-candidates (input)
+  "List of apropos completions for partial file-name INPUT.
+INPUT is a string.
+Candidates can be directories.  Each candidate is a string."
+  (setq icicle-candidate-nb  nil)
+  (let ((default-directory  (icicle-file-name-directory-w-default input)))
+    (icicle-strip-ignored-files-and-sort
+     (icicle-unsorted-file-name-apropos-candidates (or (icicle-file-name-nondirectory input) "")))))
+
+(defun icicle-unsorted-file-name-apropos-candidates (input)
+  "Unsorted list of apropos completions for the partial file-name INPUT.
+When `icicle-expand-input-to-common-match-flag' is non-nil, this also
+sets `icicle-common-match-string' to the expanded common match of
+input over all candidates."
+  (condition-case nil
+      (progn
+        (when icicle-regexp-quote-flag (setq input  (regexp-quote input)))
+        (let* ((candidates
+                ;; $$$$$ Should we remove string test for Emacs 23?
+                (if (and (not (stringp minibuffer-completion-predicate))
+                         (not icicle-apropos-complete-match-fn)
+                         (functionp minibuffer-completion-table))
+                    ;; Let the function do it all.
+                    (icicle-all-completions input minibuffer-completion-table
+                                            minibuffer-completion-predicate
+                                            icicle-ignore-space-prefix-flag)
+                  (icicle-all-completions "" minibuffer-completion-table
+                                          minibuffer-completion-predicate
+                                          icicle-ignore-space-prefix-flag)))
+               (icicle-extra-candidates
+                (icicle-remove-if-not
+                 (lambda (cand) (save-match-data (string-match input cand)))
+                 icicle-extra-candidates))
+               (icicle-proxy-candidates
+                (icicle-remove-if-not
+                 (lambda (cand) (save-match-data (string-match input cand)))
+                 icicle-proxy-candidates))
+               (filtered-candidates
+                (icicle-transform-candidates
+                 (append icicle-extra-candidates icicle-proxy-candidates
+                         (icicle-remove-if-not
+                          (lambda (cand)
+                            (let ((case-fold-search
+                                   (if (boundp 'read-file-name-completion-ignore-case)
+                                       read-file-name-completion-ignore-case
+                                     completion-ignore-case)))
+                              (if (member cand '("../" "./"))
+                                  (member input '(".." ".")) ; Prevent "" from matching "../"
+                                (and (icicle-filter-wo-input cand)
+                                     (or (not icicle-apropos-complete-match-fn)
+                                         ;; Assume no match if error - e.g. due to `string-match'
+                                         ;; with binary data in Emacs 20.  Do this everywhere we
+                                         ;; call `icicle-apropos-complete-match-fn'.
+                                         (condition-case nil
+                                             (funcall icicle-apropos-complete-match-fn input cand)
+                                           (error nil)))
+                                     (or (not icicle-must-pass-after-match-predicate)
+                                         (funcall icicle-must-pass-after-match-predicate cand))))))
+                          candidates)))))
+          (when icicle-expand-input-to-common-match-flag
+            (setq icicle-common-match-string (if (consp filtered-candidates)
+                                                 (icicle-expanded-common-match
+                                                  input filtered-candidates)
+                                               nil)))
+          (unless filtered-candidates  (setq icicle-common-match-string  nil))
+          filtered-candidates))         ; Return candidates.
+    (quit (top-level))))                ; Let `C-g' stop it.
+
+(defun icicle-expanded-common-match (input candidates)
+  "Return the expanded common match for INPUT among all CANDIDATES.
+This assumes that INPUT matches each string in list CANDIDATES.
+Return nil if there is no common match.
+
+The expanded common match is typically, but not always, the longest
+common match.  See the documentation, section `Expanded-Common-Match
+Completion', for details."
+  ;; Since `icicle-expanded-common-match-1' checks only the first match for a single candidate,
+  ;; we call it twice, once using the first candidate and once using the second.
+  ;; Typically, one of these tries will give us the longest common match.
+  (catch 'ecm-error
+    (let ((first-try   (icicle-expanded-common-match-1 input candidates))
+          (second-try  nil))
+      (when (and first-try  (cadr candidates))
+        (setq second-try  (icicle-expanded-common-match-1
+                           input (cons (cadr candidates) (cons (car candidates) (cddr candidates))))))
+      (if (> (length second-try) (length first-try))  second-try  first-try))))
+
+(defun icicle-expanded-common-match-1 (input candidates)
+  "Helper function for `icicle-expanded-common-match."
+  ;; This does not always give a longest common match, because it looks only at the first match
+  ;; of INPUT with the first candidate.  What it returns is the longest match that is common to
+  ;; all CANDIDATES and also contains the first match in the first candidate.
+  (let ((case-fold-search
+         ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+         (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                  (boundp 'read-file-name-completion-ignore-case))
+             read-file-name-completion-ignore-case
+           completion-ignore-case))
+        (first  (car candidates)))
+    (and icicle-apropos-complete-match-fn ; Return nil if no match function.
+         (save-match-data
+           ;; Assume no common match in case of error - e.g. due to `string-match' with binary data
+           ;; in Emacs 20.  Do this throughout, whenever we call `icicle-apropos-complete-match-fn'.
+           (unless (condition-case nil
+                       (funcall icicle-apropos-complete-match-fn input first)
+                     (error (throw 'ecm-error nil)))
+             (error (throw 'ecm-error nil))) ; If input doesn't match candidate, return nil.
+           (let* ((len-first       (length first))
+                  (beg             0)
+                  (end             len-first)
+                  (orig-match-beg  (match-beginning 0))
+                  (orig-match-end  (match-end 0))
+                  (ecm             first) ; "ecm" for "expanded common match".
+                  (rest            (cdr candidates))
+                  beg-ecm beg-next)
+             (if (= orig-match-beg end)
+                 (setq ecm  "")         ; INPUT was, for instance, "$" or "\\>$; return "".
+               ;; Compare with the rest of the candidates, reducing as needed.
+               (while (and rest ecm)
+                 (condition-case nil
+                     (funcall icicle-apropos-complete-match-fn input (car rest))
+                   (error (throw 'ecm-error nil))) ; If input doesn't match candidate, return nil.
+                 (setq beg-next  (match-beginning 0))
+                 ;; Remove any prefix that doesn't match some other candidate.
+                 (while (and (< beg orig-match-beg)
+                             (not (condition-case nil
+                                      (funcall icicle-apropos-complete-match-fn
+                                               (regexp-quote (substring ecm 0 (- orig-match-end beg)))
+                                               (car rest))
+                                    (error (throw 'ecm-error nil))))
+                             (progn (setq beg-ecm  (match-beginning 0))  (>= beg-ecm beg-next)))
+                   ;; Take a character off of the left.
+                   (setq ecm  (substring ecm 1)
+                         beg  (1+ beg)))
+                 ;; Remove any suffix that doesn't match some other candidate.
+                 (while (and (> end 0) (not (condition-case nil
+                                                (funcall icicle-apropos-complete-match-fn
+                                                         (regexp-quote ecm) (car rest))
+                                              (error (throw 'ecm-error nil)))))
+                   ;; Take a character off of the right.
+                   (setq ecm  (substring ecm 0 (1- (length ecm)))
+                         end  (1- end)))
+                 (unless (and (condition-case nil
+                                  (funcall icicle-apropos-complete-match-fn
+                                           (regexp-quote ecm) (car rest))
+                                (error (throw 'ecm-error nil)))
+                              (condition-case nil ; Input must match the substring that is common.
+                                  (funcall icicle-apropos-complete-match-fn input ecm)
+                                (error (throw 'ecm-error nil))))
+                   (setq ecm  nil))     ; No possible expansion
+                 (pop rest))
+               ecm))))))
+
+(defun icicle-scatter-match (string completion)
+  "Returns non-nil if STRING scatter-matches COMPLETION.
+This means that all of the characters in STRING are also in string
+COMPLETION, in the same order, but perhaps scattered among other
+characters.  For example, STRING = \"ure\" matches COMPLETION
+\"curried\"."
+  (string-match (icicle-scatter string) completion))
+
+(defun icicle-scatter (string)
+  "Returns a regexp that matches a scattered version of STRING.
+The regexp will match any string that contains the characters in
+STRING, in the same order, but possibly with other characters as well.
+Returns, for example, \"a.*b.*c.*d\" for input string \"abcd\"."
+  (if (> emacs-major-version 21)
+      (mapconcat #'regexp-quote (split-string string "" t) ".*")
+    (mapconcat #'regexp-quote (split-string string "") ".*")))
+
+(defun icicle-levenshtein-strict-match (s1 s2)
+  "String S1 is within `icicle-levenshtein-distance' of string S2.
+This means that S1 differs by at most `icicle-levenshtein-distance'
+character deletions, insertions, or replacements from S2.  The string
+lengths too must differ by at most `icicle-levenshtein-distance'.
+You probably want to turn off incremental completion (`C-#') if you
+use this match method; it is quite slow.
+To use this match method, you must also have library `levenshtein.el'."
+  (and (require 'levenshtein nil t)  (<= (levenshtein-distance s1 s2) icicle-levenshtein-distance)))
+
+(defun icicle-levenshtein-match (s1 s2)
+  "String S1 is within `icicle-levenshtein-distance' of a substring of S2.
+S1 and S2 are strings.  This means that S1 and some substring of S2
+differ by at most `icicle-levenshtein-distance' character deletions,
+insertions, or replacements.
+
+You will probably want to turn off incremental completion (`C-#') if
+you use this match method; it can be quite slow, especially with a
+large value of `icicle-levenshtein-distance'.  To use this method with
+a value other than 1, you must also have library `levenshtein.el'."
+  (if (= icicle-levenshtein-distance 1)
+      (icicle-levenshtein-one-match s1 s2)
+    (unless (require 'levenshtein nil t)  (error "You need library `levenshtein.el' for this"))
+    (catch 'icicle-levenshtein-match
+      (dolist (sub  (icicle-substrings-of-length s2 (length s1)))
+        (when (<= (levenshtein-distance s1 sub) icicle-levenshtein-distance)
+          (throw 'icicle-levenshtein-match t)))
+      nil)))
+
+;; This is much faster than testing with `levenshtein-distance' and a value of 1.
+(defun icicle-levenshtein-one-match (s1 s2)
+  "S1 is within a Levenshtein distance of one of some substring of S2.
+That is, S1 with 0 or 1 char inserted, deleted or replaced is a
+substring of S2.  S1 and S2 are strings.
+You do not need library `levenshtein.el' to use this function."
+  (string-match (icicle-levenshtein-one-regexp s1) s2))
+
+(defun icicle-levenshtein-one-regexp (string)
+  "Return a regexp for strings that are 1 Levenshtein unit from STRING."
+  (let ((indx    0)
+        (regexp  "\\("))
+    (dotimes (indx  (length string))
+      (setq regexp (concat regexp (substring string 0 indx) ".?" (substring string (1+ indx)) "\\|"
+                           (substring string 0 indx) "."  (substring string indx)      "\\|")))
+    (setq regexp (concat (substring regexp 0 -1) ")"))))
+
+(defun icicle-substrings-of-length (string &optional len)
+  "Return a list of substrings of STRING that have length LEN.
+If LEN is nil, treat it as the length of STRING."
+  (unless len (setq len  (length string)))
+  (if (zerop len)
+      (list "")
+    (let ((subs  ()))
+      (dotimes (idx (- (length string) (1- len)))  (push (substring string idx (+ idx len))  subs))
+      (nreverse subs))))
+ 
+;;(@* "Icicles functions - common helper functions")
+
+;;; Icicles functions - common helper functions ----------------------
+
+;; Main cycling function - used by `icicle-next-prefix-candidate', `icicle-next-apropos-candidate'.
+(defun icicle-next-candidate (nth candidates-fn &optional regexp-p)
+  "Replace input by NTH next or previous completion for an input.
+Default value of NTH is 1, meaning use the next completion.
+Negative NTH means use a previous, not subsequent, completion.
+
+CANDIDATES-FN is a function that returns the list of candidate
+completions for its argument, the current partial input (a string).
+
+Optional arg REGEXP-P non-nil means that CANDIDATES-FN uses regexp
+matching. This is used to highlight the appropriate matching root.
+
+If option `icicle-help-in-mode-line-delay' is positive, then help on
+the current candidate is shown in the mode line."
+  (let ((saved-last-input  icicle-last-input)) ; For call to `icicle-recompute-candidates'.
+    (unless (stringp icicle-last-completion-candidate)
+      (setq icicle-last-completion-candidate  icicle-initial-value))
+    (setq nth                   (or nth 1)
+          icicle-current-input  (if (icicle-file-name-input-p)
+                                    (abbreviate-file-name (icicle-input-from-minibuffer 'leave-envar))
+                                  (icicle-input-from-minibuffer))
+          icicle-cycling-p      t)
+    (unless (and (symbolp this-command) (get this-command 'icicle-apropos-cycling-command)
+                 (or (and (symbolp last-command) (get last-command 'icicle-apropos-cycling-command))
+                     (memq last-command
+                           '(icicle-candidate-action
+                             icicle-remove-candidate icicle-mouse-remove-candidate
+                             icicle-apropos-complete icicle-apropos-complete-no-display))))
+      (setq icicle-common-match-string  nil)) ; Don't use old one, in `icicle-save-or-restore-input'.
+    (icicle-save-or-restore-input)
+    (when (and (icicle-file-name-input-p)  (icicle-file-directory-p icicle-current-input))
+      (setq icicle-default-directory  icicle-current-input))
+    (unless (eq this-command last-command)
+      (icicle-recompute-candidates nth candidates-fn saved-last-input))
+    (icicle-save-or-restore-input)      ; Again, based on updated `icicle-common-match-string'.
+    (cond ((null icicle-completion-candidates)
+           (save-selected-window (icicle-remove-Completions-window))
+           (minibuffer-message "  [No completion]"))
+          (t
+           (icicle-clear-minibuffer)
+           (let ((nb-cands  (length icicle-completion-candidates))
+                 (unit      (if (wholenump nth) 1 -1))
+                 next)
+             ;; So `icomplete+' can append the number of other candidates to the minibuffer.
+             (setq icicle-nb-of-other-cycle-candidates  (1- nb-cands))
+             (icicle-increment-cand-nb+signal-end nth nb-cands)
+             (setq next  (elt icicle-completion-candidates icicle-candidate-nb))
+             (while (null next)         ; Skip null candidates.
+               (icicle-increment-cand-nb+signal-end unit nb-cands)
+               (setq next  (elt icicle-completion-candidates icicle-candidate-nb)))
+
+             ;; Update last-candidate to NEXT.  Need a copy, because we change its text properties.
+             (setq icicle-last-completion-candidate  (copy-sequence next))
+
+             (icicle-insert-cand-in-minibuffer icicle-last-completion-candidate regexp-p)
+
+             ;; Highlight current completion candidate, if `*Completions*' is displayed.
+             (when (get-buffer-window "*Completions*" 0)
+
+               ;; Refresh `*Completions*', updating it to reflect the current candidates.
+               (unless (or (and (symbolp this-command)
+                                (get this-command 'icicle-apropos-cycling-command)
+                                (or (and (symbolp last-command)
+                                         (get last-command 'icicle-apropos-cycling-command))
+                                    (memq last-command '(icicle-candidate-action
+                                                         icicle-remove-candidate
+                                                         icicle-mouse-remove-candidate))))
+                           (and (symbolp this-command)
+                                (get this-command 'icicle-prefix-cycling-command)
+                                (or (and (symbolp last-command)
+                                         (get last-command 'icicle-prefix-cycling-command))
+                                    (memq last-command '(icicle-candidate-action
+                                                         icicle-remove-candidate
+                                                         icicle-mouse-remove-candidate)))))
+                 (icicle-display-candidates-in-Completions))
+               (save-selected-window
+                 (select-window (get-buffer-window "*Completions*" 'visible))
+                 (if (fboundp 'thumfr-only-raise-frame) (thumfr-only-raise-frame) (raise-frame)))
+               (icicle-highlight-candidate-in-Completions))
+             (icicle-show-help-in-mode-line icicle-last-completion-candidate))))))
+
+(defun icicle-insert-cand-in-minibuffer (candidate regexp-p)
+  "Insert CANDIDATE in minibuffer.  Highlight root and initial whitespace.
+REGEXP-P non-nil means use regexp matching to highlight root."
+  ;; Highlight any initial whitespace (probably a user typo).
+  (icicle-highlight-initial-whitespace (if regexp-p icicle-current-raw-input icicle-current-input))
+
+  ;; Underline the root that was completed, in the minibuffer.
+  (let ((inp  (icicle-minibuf-input-sans-dir icicle-current-input))
+        (case-fold-search
+         ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+         (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                  (boundp 'read-file-name-completion-ignore-case))
+             read-file-name-completion-ignore-case
+           completion-ignore-case))
+        indx)
+    (unless (and regexp-p (not icicle-regexp-quote-flag))  (setq inp  (regexp-quote inp)))
+    (save-match-data
+      (setq indx  (string-match inp icicle-last-completion-candidate))
+      (when indx (put-text-property indx (match-end 0) 'face 'icicle-match-highlight-minibuffer
+                                    icicle-last-completion-candidate))))
+
+  (goto-char (icicle-minibuffer-prompt-end)) ; Need for Emacs 22+, or can get `Text read-only' error.
+  ;; Insert candidate in minibuffer, and place cursor.
+  (insert (if (and (icicle-file-name-input-p) insert-default-directory
+                   (or (not (member icicle-last-completion-candidate icicle-extra-candidates))
+                       icicle-extra-candidates-dir-insert-p))
+              (icicle-dir-prefix-wo-wildcards icicle-current-input)
+            "")
+          candidate)
+  (icicle-place-cursor icicle-current-input))
+
+(defun icicle-dir-prefix-wo-wildcards (filename)
+  "Return the directory portion of FILENAME.
+If using partial completion, this is the portion before the first
+occurrence of `*'.  Otherwise, this is just `file-name-directory'."
+  (if (and (icicle-not-basic-prefix-completion-p) (boundp 'completion-styles)
+           (member 'partial-completion completion-styles)
+           (string-match "/[^/]*\\*" filename))
+      (substring filename 0 (1+ (match-beginning 0)))
+    (or (file-name-directory filename) ""))) ; Don't return nil, in any case.
+      
+(defun icicle-show-help-in-mode-line (candidate)
+  "If short help for CANDIDATE is available, show it in the mode-line.
+Do this only if `icicle-help-in-mode-line-delay' is positive."
+  (when (> icicle-help-in-mode-line-delay 0)
+    (let* ((cand       (cond (;; Call to `lacarte-execute(-menu)-command' (in `lacarte.el').
+                              ;; Use command associated with menu item.
+                              (consp lacarte-menu-items-alist)
+                              (cdr (assoc candidate lacarte-menu-items-alist)))
+                             (;; Key-completion candidate.  Get command from candidate.
+                              icicle-completing-keys-p
+                              (if (string= ".." candidate)
+                                  "GO UP"
+                                (let ((cmd-name  (save-match-data
+                                                   (string-match "\\(.+\\)  =  \\(.+\\)" candidate)
+                                                   (substring candidate (match-beginning 2)
+                                                              (match-end 2)))))
+                                  (if (string= "..." cmd-name) "Prefix key" (intern-soft cmd-name)))))
+                             (;; Buffer or file name.
+                              (or (get-buffer candidate)
+                                  (icicle-file-name-input-p)
+                                  icicle-abs-file-candidates)
+                              (icicle-transform-multi-completion candidate))
+                             (t         ; Convert to symbol or nil.
+                              (intern-soft (icicle-transform-multi-completion candidate)))))
+           (doc        (progn (when (stringp candidate)
+                                (setq candidate  (icicle-transform-multi-completion candidate)))
+                              (cond ((and (stringp candidate) ; String with help as property.
+                                          (get-text-property 0 'icicle-mode-line-help candidate)))
+                                    ((and cand (symbolp cand) ; Symbol.
+                                          (cond ((get cand 'icicle-mode-line-help)) ; Help prop.
+                                                ((fboundp cand) ; Function.
+                                                 (or (documentation cand t) ; Functon's doc string.
+                                                     (if (string-match ; Easy-menu item.
+                                                          "^menu-function-[0-9]+$" (symbol-name cand))
+                                                         (format "%s" (symbol-function cand))
+                                                       (format "Command `%s'" cand))))
+                                                ((facep cand) (face-documentation cand)) ; Face.
+                                                (t (documentation-property ; Variable.
+                                                    cand 'variable-documentation t)))))
+                                    ((and (consp cand) (eq (car cand) 'lambda)) ; Lambda form.
+                                     (format "%s" cand))
+                                    ((and (stringp cand) ; Prefix key, `..'.
+                                          (member cand '("Prefix key" "GO UP")))
+                                     cand)
+                                    ((stringp candidate) ; String without help property.
+                                     (cond ((and (or (icicle-file-name-input-p) ; File name.
+                                                     icicle-abs-file-candidates)
+                                                 (file-exists-p candidate))
+                                            (if (get-file-buffer candidate)
+                                                (concat (icicle-help-line-buffer
+                                                         (get-file-buffer candidate) 'no-bytes-p) " "
+                                                         (icicle-help-line-file cand))
+                                              (icicle-help-line-file candidate)))
+                                           ((get-buffer candidate) ; Non-file buffer.
+                                            (icicle-help-line-buffer candidate))
+                                           (t nil)))))) ; Punt.
+           (doc-line1  (and (stringp doc)  (string-match ".+$" doc)  (match-string 0 doc))))
+      (when doc-line1
+        (put-text-property 0 (length doc-line1) 'face 'icicle-mode-line-help doc-line1)
+        (icicle-show-in-mode-line
+         doc-line1
+         (cond ((get-buffer-window "*Completions*" 'visible) "*Completions*")
+               ((eq (current-buffer) (window-buffer (minibuffer-window))) (cadr (buffer-list)))
+               (t (current-buffer))))))))
+
+(defun icicle-help-line-buffer (buffer &optional no-bytes-p)
+  "Simple help string for BUFFER."
+  (with-current-buffer buffer
+    (if no-bytes-p
+        (format "Mode: %s" mode-name)
+      (format "Bytes: %d, Mode: %s" (buffer-size) mode-name))))
+
+(defun icicle-help-line-file (file)
+  "Simple help string for FILE."
+  (let ((attrs  (file-attributes file)))
+    (and attrs (format "Bytes: %d, Saved: %s, Access: %s" (nth 7 attrs)
+                       (format-time-string  "%c" (nth 5 attrs)) (nth 8 attrs))))) ; "%Y-%m-%d %H"
+
+(defun icicle-show-in-mode-line (text &optional buffer)
+  "Display TEXT in BUFFER's mode line.
+The text is shown for `icicle-help-in-mode-line-delay' seconds, or
+until a user event.  So call this last in a sequence of user-visible
+actions."
+  (message nil)                         ; Remove any msg, such as "Computing completion candidates...".
+  (with-current-buffer (or buffer (current-buffer))
+    (make-local-variable 'mode-line-format) ; Needed for Emacs 21+.
+    (let ((mode-line-format  text))  (force-mode-line-update) (sit-for icicle-help-in-mode-line-delay))
+    (force-mode-line-update)))
+
+(defun icicle-recompute-candidates (nth candidates-fn saved-last-input)
+  "Recompute `icicle-completion-candidates', if needed.
+If buffer `*Completions*' is already displayed, it is updated.
+This does nothing, unless the user changed the minibuffer input or the
+completion type has changed (from apropos to prefix or vice versa).
+NTH < 0 means candidate order is reversed in `*Completions*'.
+Argument CANDIDATES-FN is a function that recomputes the candidates.
+SAVED-LAST-INPUT is the last input, as in `icicle-last-input'."
+  (unless (and icicle-last-completion-command
+               (symbolp this-command)   ; Need symbol for `get', below.
+               (string= icicle-current-input saved-last-input) ; No change in user input.
+               ;; No change in completion type: apropos vs prefix.
+               (or (and (or (get icicle-last-completion-command 'icicle-apropos-completing-command)
+                            (memq icicle-last-completion-command
+                                  '(icicle-candidate-set-complement icicle-mouse-remove-candidate
+                                    icicle-keep-only-past-inputs)))
+                        (or (get this-command 'icicle-apropos-completing-command)
+                            (get this-command 'icicle-apropos-cycling-command)))
+                   (and (or (get icicle-last-completion-command 'icicle-prefix-completing-command)
+                            (memq icicle-last-completion-command
+                                  '(icicle-candidate-set-complement icicle-mouse-remove-candidate
+                                    icicle-keep-only-past-inputs)))
+                        (or (get this-command 'icicle-prefix-completing-command)
+                            (get this-command 'icicle-prefix-cycling-command)))))
+    (when (string= icicle-current-input saved-last-input) ; Changed completion type, not user input.
+      ;; Set `icicle-last-completion-command', to record new completion type.
+      (cond ((and (symbolp this-command) (get this-command 'icicle-prefix-cycling-command))
+             (setq icicle-last-completion-command
+                   (if (eq icicle-last-completion-command 'icicle-apropos-complete-no-display)
+                       'icicle-prefix-complete-no-display
+                     'icicle-prefix-complete)))
+            ((and (symbolp this-command) (get this-command 'icicle-apropos-cycling-command))
+             (setq icicle-last-completion-command
+                   (if (eq icicle-last-completion-command 'icicle-prefix-complete-no-display)
+                       'icicle-apropos-complete-no-display
+                     'icicle-apropos-complete)))))
+
+    ;; Recompute and redisplay completion candidates.  Reset candidate number.
+    (setq icicle-completion-candidates
+          (condition-case nil
+              (funcall candidates-fn icicle-current-input)
+            (error icicle-completion-candidates))) ; No change if completion error.
+    (when (get-buffer-window "*Completions*" 0) ; Update `*Completions*' display or remove it.
+      (if icicle-completion-candidates
+          (icicle-display-candidates-in-Completions (not (wholenump nth)))
+        (save-selected-window (icicle-remove-Completions-window))))))
+
+(defun icicle-save-raw-input ()
+  "Save `icicle-current-raw-input' as the latest previous input.
+It is saved to `icicle-previous-raw-file-name-inputs', if completing a
+file name, or `icicle-previous-raw-non-file-name-inputs', otherwise."
+  (let* ((prev-inputs-var  (if (icicle-file-name-input-p)
+                               'icicle-previous-raw-file-name-inputs
+                             'icicle-previous-raw-non-file-name-inputs))
+         (prev-inputs      (symbol-value prev-inputs-var)))
+    (unless (string= "" icicle-current-raw-input)
+      (set prev-inputs-var (icicle-put-at-head prev-inputs-var icicle-current-raw-input)))
+    (when (> (length prev-inputs) icicle-completion-history-max-length)
+      (setcdr (nthcdr (1- icicle-completion-history-max-length) prev-inputs) ()))))
+
+(defun icicle-save-or-restore-input ()
+  "Save the current minibuffer input, or restore the last input.
+If there is a previous input and we are cycling, then restore the last
+ input.  (Cycled completions don't count as input.)
+Otherwise, save the current input for use by `C-l', and then compute
+ the expanded common match.
+
+There are several particular cases that modulate the behavior - see
+the code."
+  (cond
+    ;; Restore last input, if there is some to restore and we are cycling.
+    ((and icicle-last-input icicle-cycling-p icicle-last-completion-candidate)
+     (setq icicle-current-input  icicle-last-input)) ; Return `icicle-current-input'.
+    (t
+     (cond
+       ;; Save the current input for `C-l', then update it to the expanded common match.
+       ;; Do NOT do this if:
+       ;;      the user doesn't want to use the expanded common match
+       ;;   or there is no common match string
+       ;;   or the last command was a cycling command
+       ;;   or the input and the completion mode have not changed
+       ;;      (so saved regexp will not be overwritten).
+       ((not (or (and (not icicle-expand-input-to-common-match-flag)
+                      (eq icicle-current-completion-mode 'apropos))
+                 (not icicle-common-match-string)
+                 (and (symbolp last-command) (get last-command 'icicle-cycling-command)
+                      (not (get last-command 'icicle-completing-command))) ; Not `TAB' or `S-TAB'.
+                 (and (equal icicle-last-input icicle-current-input)
+                      (eq icicle-current-completion-mode
+                          (if (get icicle-last-completion-command 'icicle-prefix-completing-command)
+                              'prefix
+                            'apropos)))))
+
+        ;; Expand current input to expanded common match, after saving it for `C-l'.
+        (let ((common  (if (and (icicle-file-name-input-p) insert-default-directory)
+                           (if (string= "" icicle-common-match-string)
+                               (or (icicle-file-name-directory icicle-current-input) "")
+                             (directory-file-name (icicle-abbreviate-or-expand-file-name
+                                                   icicle-common-match-string
+                                                   (icicle-file-name-directory icicle-current-input))))
+                         icicle-common-match-string)))
+            
+          ;; Save current input for `C-l', then save common match as current input.
+          ;; Do NOT do anything if we're ignoring letter case and that is the only difference
+          ;; between the common match and the input (e.g. MS Windows file names).
+          (unless (and case-fold-search
+                       (string= (icicle-upcase icicle-current-input) (icicle-upcase common))
+                       (not (string= icicle-current-input common)))
+
+            ;; Save input for `C-l' if this is not `C-l' or `C-L'.
+            ;; Save it also if this is the first cycling command, or the first after completion.
+            (unless (or (memq this-command '(icicle-retrieve-previous-input
+                                             icicle-retrieve-next-input))
+                        (and icicle-cycling-p
+                             (or icicle-candidate-nb ; Not the first cycling command.
+                                 (and (symbolp last-command)
+                                      (get last-command 'icicle-completing-command)))))
+              (setq icicle-current-raw-input  icicle-current-input)
+              ;; Save it for `C-l', unless it is "".  Drop old entries when too big.
+              (icicle-save-raw-input))
+
+            ;; Save expanded common match as current input, unless input is a directory.
+            ;; Use `icicle-file-directory-p'.
+            ;; `file-directory-p' fails to consider "~/foo//usr/" a directory.
+            ;; $$$$$$ We could use the `icicle-file-directory-p' code with `icicle-file-name-directory'
+            ;;        instead of `icicle-file-name-directory-w-default', if that presents a problem.
+            (unless (and (icicle-file-name-input-p) (icicle-file-directory-p icicle-current-input))
+              (setq icicle-current-input  common)))))
+
+       ;; Save input for `C-l'.
+       ;; Do NOT do this if:
+       ;;      this command is `C-l' or `C-L'
+       ;;   or we are cycling or the last command was a cycling command
+       ;;   or this command is the same as last command.
+       ((not (or (memq this-command '(icicle-retrieve-previous-input icicle-retrieve-next-input))
+                 icicle-cycling-p
+                 (and (symbolp last-command) (get last-command 'icicle-cycling-command)
+                      (not (get this-command 'icicle-completing-command)))
+                 ;;$$$ (and (symbolp last-command) (get last-command 'icicle-completing-command))
+                 (eq last-command this-command)))
+        (setq icicle-current-raw-input  icicle-current-input)
+        ;; Save it for `C-l', unless it is "".  Drop old entries when too big.
+        (icicle-save-raw-input))
+       ;; Forget last raw input, so it is not highlighted in `*Completions*'.
+       ;; Do NOT do this if we are cycling.
+       ((not icicle-cycling-p)
+        (setq icicle-current-raw-input  "")))))
+  (setq icicle-last-input  icicle-current-input)) ; Return `icicle-current-input'.
+
+(defun icicle-put-at-head (list-var element)
+  "Put ELEMENT at the front of the value of LIST-VAR.
+If ELEMENT is already a member of the list, then it is moved to the
+front.  Otherwise, it is added to the front.  Membership is tested
+with `equal'.  The return value is the new value of LIST-VAR.
+This is a destructive operation: the list structure is changed."
+  (let* ((lis  (symbol-value list-var))
+         (tl   (member element lis)))
+    (cond ((null lis) (set list-var (list element)))
+          ;;;((eq tl lis) (set list-var (cdr lis)))
+          ((not (eq tl lis))
+           (when tl (setcdr (nthcdr (1- (- (length lis) (length tl))) lis) (cdr tl)))
+           (set list-var (cons element lis)))))
+  (symbol-value list-var))
+
+(defun icicle-remove-dots (filename)
+  "Strip leading string through last ../ or ./ from FILENAME."
+  (let ((newname  filename))
+    (save-match-data
+      (while (or (string-match "\\.\\./" newname)
+                 (string-match "\\./" newname)
+                 ;; Emacs 21+ `file-relative-name' returns ".." and "." (no slash) for "" first arg
+                 (string-match "^\\.\\.$" newname)
+                 (string-match "^\\.$" newname))
+        (setq newname  (substring newname (match-end 0)))))
+    newname))
+
+(defun icicle-increment-cand-nb+signal-end (incr max)
+  "Increment candidate number by INCR modulo MAX, and signal end of cycle."
+  (setq icicle-candidate-nb  (if icicle-candidate-nb
+                                 (+ incr icicle-candidate-nb)
+                               (if (natnump incr) 0 (1- max))))
+  (let ((wrapped  (mod icicle-candidate-nb max)))
+    (when (and (/= wrapped icicle-candidate-nb) (eq last-command this-command))
+      (let ((visible-bell  t))  (ding)))
+    (setq icicle-candidate-nb  wrapped)))
+
+(defun icicle-place-cursor (input &optional dont-activate-p)
+  "Position point and mark with respect to the minibuffer candidate.
+Positions are `icicle-point-position-in-candidate' and
+`icicle-mark-position-in-candidate', respectively.
+INPUT is the current user input, that is, the completion root.
+Optional argument DONT-ACTIVATE-P means do not activate the mark."
+  (let ((case-fold-search
+         ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+         (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                  (boundp 'read-file-name-completion-ignore-case))
+             read-file-name-completion-ignore-case
+           completion-ignore-case))
+        input-start-position)
+    (goto-char (icicle-minibuffer-prompt-end))
+    (setq input-start-position  (point))
+    (when (and (icicle-file-name-input-p) insert-default-directory)
+      (search-forward (icicle-file-name-directory-w-default input) nil t)
+      (setq input-start-position  (point))) ; Skip directory.
+    ;; Locate completion root within current completion candidate.
+    (when (or (memq icicle-point-position-in-candidate '(root-start root-end))
+              (memq icicle-mark-position-in-candidate  '(root-start root-end)))
+      (save-excursion
+        (save-restriction
+          (narrow-to-region (point) (point-max)) ; Search within the completion candidate.
+          (condition-case lossage
+              (re-search-forward (if icicle-regexp-quote-flag
+                                     (regexp-quote (icicle-minibuf-input-sans-dir input))
+                                   (icicle-minibuf-input-sans-dir input))
+                                 nil t)
+            (invalid-regexp  (when (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
+                                                 (cadr lossage))
+                               (goto-char (point-max))))))))
+    ;; Position point.
+    (case icicle-point-position-in-candidate
+      (input-start (goto-char input-start-position))
+      (input-end (goto-char (point-max)))
+      (root-start (goto-char (max input-start-position (match-beginning 0))))
+      (root-end (goto-char (max input-start-position (match-end 0)))))
+    ;; Position mark.
+    (unless (eq icicle-point-position-in-candidate icicle-mark-position-in-candidate)
+      (push-mark (case icicle-mark-position-in-candidate
+                   (input-start input-start-position)
+                   (input-end (point-max))
+                   (root-start (max input-start-position (match-beginning 0)))
+                   (root-end (max input-start-position (match-end 0))))
+                 'nomsg
+                 (not dont-activate-p)))))
+
+(defun icicle-highlight-candidate-in-Completions ()
+  "Highlight the current candidate in `*Completions*'."
+  (let ((compl-win  (get-buffer-window "*Completions*" 0))
+        curr-cand-pos)
+    (when compl-win
+      (set-window-dedicated-p compl-win t)
+      (save-window-excursion (select-window compl-win)
+                             (goto-char (icicle-start-of-candidates-in-Completions))
+                             (icicle-move-to-next-completion icicle-candidate-nb t)
+                             (set-buffer-modified-p nil)
+                             (setq curr-cand-pos  (point)))
+      (set-window-point compl-win curr-cand-pos))))
+
+(defun icicle-place-overlay (start end overlay face priority buffer &rest properties)
+  "Put OVERLAY with FACE and PRIORITY between START and END in BUFFER.
+OVERLAY is a symbol whose value is the overlay.  If nil, the overlay
+  is created.  If non-nil, it is simply moved.
+PROPERTIES are additional overlay properties to add: pairs of a
+property and a value."
+  (if (symbol-value overlay)            ; Overlay exists, just move it.
+      (move-overlay (symbol-value overlay) start end buffer)
+    (set overlay (make-overlay start end buffer))
+    (overlay-put (symbol-value overlay) 'face face)
+    (overlay-put (symbol-value overlay) 'priority priority)))
+
+(defun icicle-strip-ignored-files-and-sort (candidates)
+  "Remove file names with ignored extensions, and \".\".  Sort CANDIDATES.
+If `icicle-sort-comparer' is nil, then do not sort."
+  (when (fboundp 'completion-ignored-build-apply) ; In `completion-ignored-build.el'.
+    (let ((completion-ignored-extensions  completion-ignored-extensions))
+      (completion-ignored-build-apply)
+      (icicle-update-ignored-extensions-regexp)))
+  (let* ((pred1           (lambda (cand) (or (save-match-data
+                                               (string-match icicle-ignored-extensions-regexp cand))
+                                             (string= "./" cand))))
+         (pred2           (lambda (cand) (string= "./" cand)))
+         (new-candidates  (icicle-remove-if (if icicle-ignored-extensions-regexp pred1 pred2)
+                                            candidates)))
+    ;; If the only candidates have ignored extensions, then use them.
+    (unless new-candidates (setq new-candidates  (icicle-remove-if pred2 candidates)))
+    (icicle-maybe-sort-maybe-truncate new-candidates)))
+
+(defun icicle-transform-candidates (candidates)
+  "Apply `icicle-transform-function' to CANDIDATES.
+If `icicle-transform-function' is nil, return CANDIDATES.
+
+Note that this transformation is applied before completion candidates
+are made available to the user, in particular, before they are
+displayed in `*Completions*'.  Its use is thus quite different from
+that of `icicle-transform-sole-candidate'."
+  (if icicle-transform-function  (funcall icicle-transform-function candidates)  candidates))
+
+(defun icicle-transform-multi-completion (candidate)
+  "Transform display CANDIDATE according to `icicle-list-use-nth-parts'.
+If CANDIDATE is not a multi-completion, return CANDIDATE unchanged.
+Return the possibly transformed candidate."
+  (if (and icicle-list-use-nth-parts (not (equal "" candidate)))
+      (let ((parts  (split-string candidate icicle-list-join-string)))  (icicle-join-nth-parts parts))
+    candidate))
+
+(defun icicle-join-nth-parts (parts)
+  "Join the elements in PARTS using `icicle-list-nth-parts-join-string'."
+  (let* ((maxpart  (length parts))
+         (indexes  icicle-list-use-nth-parts)
+         (cand     "")
+         (firstp   t)
+         partnum)
+    (if (< maxpart 2)
+        (car parts)                     ; Nothing to join.
+      (while indexes
+        (setq partnum  (car indexes))
+        (unless firstp (setq cand  (concat cand icicle-list-nth-parts-join-string)))
+        (setq firstp  nil)
+        (unless (> partnum maxpart) (setq cand  (concat cand (nth (1- partnum) parts))))
+        (setq indexes  (cdr indexes)))
+      cand)))
+
+(defun icicle-display-cand-from-full-cand (cand)
+  "Return the display candidate corresponding to full candidate CAND."
+  (let ((parts  (car cand)))
+    (if (atom parts)
+        parts                           ; Not a multi-completion.
+      (if icicle-list-use-nth-parts
+          (icicle-join-nth-parts parts) ; Join mult-completion parts per `icicle-list-use-nth-parts'.
+        ;; Multi-completion, but no joining specified.  Reconstitute the display candidate.
+        ;; $$$$$$        (concat (mapconcat #'identity parts icicle-list-join-string)
+        ;;                       icicle-list-end-string) ; $$$$$$ 
+        (mapconcat #'identity parts icicle-list-join-string)))))
+
+(defun icicle-file-name-directory (file)
+  "Like `file-name-directory', but backslash is not a directory separator.
+Do not treat backslash as a directory separator, even on MS Windows.
+Escape any backslashes, then call `file-name-directory' and return
+what it returns."
+  (let* ((escaped-file  (subst-char-in-string ?\\ ?\a file))
+         (dir           (file-name-directory escaped-file)))
+    (and dir (subst-char-in-string ?\a ?\\ dir))))
+
+(defun icicle-file-name-directory-w-default (file)
+  "`icicle-file-name-directory', or `default-directory' if that is nil."
+  (or (icicle-file-name-directory file) default-directory))
+
+(defun icicle-file-name-nondirectory (file)
+  "Like `file-name-nondirectory', but does not treat backslash specially.
+That is, backslash is never treated as a directory separator."
+  (let ((escaped-file  (subst-char-in-string ?\\ ?\a file)))
+    (subst-char-in-string ?\a ?\\ (file-name-nondirectory escaped-file))))
+
+;; $$$$$
+;; (defun icicle-file-name-input-p ()
+;;   "Return non-nil if expected input is a file name.
+;; This is used, instead of variable `minibuffer-completing-file-name',
+;; because we sometimes complete against an explicit alist of file names,
+;; even in the overall context of file-name input.  In that case, we do
+;; not want to use file-name completion.  An example of this is
+;; completing against a history list of file names, using
+;; `icicle-history'."
+;;   ;; Note that some Emacs 20 code uses this as the equivalent of
+;;   ;; `minibuffer-completing-file-name':
+;;   ;; (memq minibuffer-completion-table '(read-file-name-internal read-directory-name-internal))
+;;   (and (symbolp minibuffer-completion-table) (stringp minibuffer-completion-predicate)))
+
+(defun icicle-file-name-input-p ()
+  "Return non-nil if reading a file name using `read-file-name'.
+This means that completion candidates are relative file names.
+If instead you want to test whether input is a file name, absolute or
+relative, use this test:
+
+ (or (icicle-file-name-input-p) icicle-abs-file-candidates)"
+  minibuffer-completing-file-name)
+
+(defun icicle-file-directory-p (file)
+  "Local, faster replacement for `file-directory-p'.
+This does not do all of the file-handler processing that
+`file-directory-p' does, so it is not a general replacement."
+  (and (stringp file)  (string= file (icicle-file-name-directory-w-default file))))
+
+(defun icicle-minibuf-input ()
+  "Return the user minibuffer input as a string, without text-properties."
+  (save-selected-window (select-window (minibuffer-window)) (icicle-input-from-minibuffer)))
+
+;;$$$ Do we need to double all $'s in output from `icicle-subst-envvar-in-file-name',
+;;      before calling `substitute-in-file-name'?
+(defun icicle-input-from-minibuffer (&optional leave-envvars-p)
+  "Return the minibuffer input as a string, without text-properties.
+Unless optional arg LEAVE-ENVVARS-P is non-nil, substitute any
+environment vars by their values.
+The current buffer must be a minibuffer."
+  (let ((input  (if (fboundp 'minibuffer-contents)
+                    (minibuffer-contents) ; e.g. Emacs 22
+                  (buffer-substring (point-min) (point-max))))) ; e.g. Emacs 20
+    ;; $$$$$$$$ (if (fboundp 'minibuffer-contents-no-properties)
+    ;;              (minibuffer-contents-no-properties) ; e.g. Emacs 22
+    ;;            (buffer-substring-no-properties (point-min) (point-max))))) ; e.g. Emacs 20
+    (when (and (icicle-file-name-input-p)
+               (not (string= "" input)) ; Do nothing if user deleted everything in minibuffer.
+               (not leave-envvars-p))
+      (let ((last-char  ""))
+        (when (eq ?\$ (aref input (1- (length input))))
+          (setq last-char  "$"
+                input      (substring input 0 (1- (length input)))))
+        (setq input
+              (save-match-data
+                (concat (subst-char-in-string ?\a ?\\
+                                              (condition-case nil
+                                                  (substitute-in-file-name
+                                                   (icicle-subst-envvar-in-file-name
+                                                    (subst-char-in-string ?\\ ?\a input 'in-place)))
+                                                (error input))
+                                              'in-place)
+                        last-char)))))
+    input))
+
+(defun icicle-minibuf-input-sans-dir (&optional input)
+  "Return the user input, except for a directory portion if reading a file."
+  (unless input (setq input  (icicle-minibuf-input)))
+  (if (icicle-file-name-input-p)  (icicle-file-name-nondirectory input)  input))
+
+(defun icicle-subst-envvar-in-file-name (input)
+  "Substitute any environment vars in INPUT by their values.
+Unlike `substitute-in-file-name', this does not make any other
+changes, such as switching `\\' to `/' on MS Windows."
+  (let ((pat1  "[^$]\\([$]{\\([^$}]+\\)}\\)") ; e.g. aaa${HOME}
+        (pat2  "^[$]{\\([^$}]+\\)}")          ; e.g. ${HOME}
+        (pat3  "[^$]\\([$]\\([^$]+\\)\\)")    ; e.g. aaa$HOME
+        (pat4  "^[$]\\([^$]+\\)"))            ; e.g. $HOME
+    (cond ((string-match pat1 input)
+           (replace-regexp-in-string pat1 (or (getenv (match-string 2 input))
+                                              (concat "$" (match-string 2 input)))
+                                     input t t 1))
+          ((string-match pat2 input)
+           (replace-regexp-in-string pat2 (or (getenv (match-string 1 input))
+                                              (concat "$" (match-string 1 input)))
+                                     input t t))
+          ((string-match pat3 input)
+           (replace-regexp-in-string pat3 (or (getenv (match-string 2 input))
+                                              (concat "$" (match-string 2 input)))
+                                     input t t 1))
+          ((string-match pat4 input)
+           (replace-regexp-in-string pat4 (or (getenv (match-string 1 input))
+                                              (concat "$" (match-string 1 input)))
+                                     input t t))
+          (t input))))
+
+;; Provide for Emacs 20.
+;;
+(unless (fboundp 'replace-regexp-in-string)
+  (defun replace-regexp-in-string (regexp rep string &optional
+                                   fixedcase literal subexp start)
+    "Replace all matches for REGEXP with REP in STRING.
+
+Return a new string containing the replacements.
+
+Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
+arguments with the same names of function `replace-match'.  If START
+is non-nil, start replacements at that index in STRING.
+
+REP is either a string used as the NEWTEXT arg of `replace-match' or a
+function.  If it is a function it is applied to each match to generate
+the replacement passed to `replace-match'; the match-data at this
+point are such that match 0 is the function's argument.
+
+To replace only the first match (if any), make REGEXP match up to \\'
+and replace a sub-expression, e.g.
+  (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil nil 1)
+    => \" bar foo\"
+"
+
+    ;; To avoid excessive consing from multiple matches in long strings,
+    ;; don't just call `replace-match' continually.  Walk down the
+    ;; string looking for matches of REGEXP and building up a (reversed)
+    ;; list MATCHES.  This comprises segments of STRING which weren't
+    ;; matched interspersed with replacements for segments that were.
+    ;; [For a `large' number of replacements it's more efficient to
+    ;; operate in a temporary buffer; we can't tell from the function's
+    ;; args whether to choose the buffer-based implementation, though it
+    ;; might be reasonable to do so for long enough STRING.]
+    (let ((l      (length string))
+          (start  (or start 0))
+          matches str mb me)
+      (save-match-data
+        (while (and (< start l)  (string-match regexp string start))
+          (setq mb  (match-beginning 0)
+                me  (match-end 0))
+          ;; If we matched the empty string, make sure we advance by one char
+          (when (= me mb) (setq me  (min l (1+ mb))))
+          ;; Generate a replacement for the matched substring.
+          ;; Operate only on the substring to minimize string consing.
+          ;; Set up match data for the substring for replacement;
+          ;; presumably this is likely to be faster than munging the
+          ;; match data directly in Lisp.
+          (string-match regexp (setq str  (substring string mb me)))
+          (setq matches  (cons (replace-match (if (stringp rep)
+                                                  rep
+                                                (funcall rep (match-string 0 str)))
+                                              fixedcase literal str subexp)
+                               (cons (substring string start mb) matches))) ; unmatched prefix
+          (setq start  me))
+        ;; Reconstruct a string from the pieces.
+        (setq matches  (cons (substring string start l) matches)) ; leftover
+        (apply #'concat (nreverse matches))))))
+
+(defun icicle-filter-wo-input (candidate)
+  "Filter completion (string) CANDIDATE using regexps and predicate.
+If CANDIDATE passes the filtering, return CANDIDATE.  Else return nil.
+
+In addition to filtering out empty-string candidates, these variables
+are used for the filtering:
+  `icicle-must-match-regexp'
+  `icicle-must-not-match-regexp'
+  `icicle-must-pass-predicate'
+
+This filtering is in addition to and prior to matching user input.
+Users do not see any candidates filtered out here.
+This filtering does not affect proxy candidates or extra candidates.
+
+See also variable `icicle-must-pass-after-match-predicate', which is
+similar to `icicle-must-pass-predicate' but is used after filtering
+using the user input."
+  (and (not (string= "" candidate))     ; Filter out empty strings.
+       (or (not icicle-must-match-regexp)
+           (save-match-data (string-match icicle-must-match-regexp candidate)))
+       (or (not icicle-must-not-match-regexp)
+           (not (save-match-data (string-match icicle-must-not-match-regexp candidate))))
+       (or (not icicle-must-pass-predicate)  (funcall icicle-must-pass-predicate candidate))
+       candidate))
+
+(defun icicle-complete-again-update (&optional no-display)
+  "Complete again and update completions list.
+Update display too, if already shown and NO-DISPLAY is nil."
+  (setq icicle-completion-candidates
+        (condition-case nil
+            (funcall (case icicle-last-completion-command
+                       ((icicle-prefix-complete icicle-prefix-complete-no-display
+                                                icicle-prefix-word-complete)
+                        (if (icicle-file-name-input-p)
+                            #'icicle-file-name-prefix-candidates
+                          #'icicle-prefix-candidates))
+                       (t
+                        (if (icicle-file-name-input-p)
+                            #'icicle-file-name-apropos-candidates
+                          #'icicle-apropos-candidates)))
+                     icicle-current-input)
+          (error icicle-completion-candidates))) ; No change if completion error.
+  (when (and (get-buffer-window "*Completions*" 0) (not no-display))
+    (icicle-display-candidates-in-Completions)))
+
+(defun icicle-msg-maybe-in-minibuffer (format-string &rest args)
+  "Display FORMAT-STRING as a message.
+If called with the minibuffer inactive, use `message'.
+Otherwise:
+ If `icicle-minibuffer-message-ok-p', then use `minibuffer-message'.
+ Else do nothing (no message display)."
+  (if (active-minibuffer-window)
+      (when icicle-minibuffer-message-ok-p
+        (save-selected-window
+          (select-window (minibuffer-window))
+          (minibuffer-message (apply #'format (concat "  [" format-string "]") args))))
+    (apply #'message format-string args)))
+
+(defun icicle-delete-count (elt elts count)
+  "Delete by side effect the first COUNT occurrences of ELT from list ELTS.
+This is like `delete', but it deletes only the first COUNT `equal'
+occurrences."
+  (while (and elts  (equal elt (car elts))  (>= (setq count  (1- count)) 0))
+    (setq elts  (cdr elts)))
+  (let ((tail  elts)
+        (nn    count))
+    (if (cdr tail)
+        (while (and (cdr tail)  (> nn 0))
+          (when (equal elt (cadr tail))
+            (setq nn  (1- nn))
+            (setcdr tail (cddr tail)))
+          (setq tail  (cdr tail)))
+      (when (and (equal elt (car tail))  (> count 0))
+        (setq tail  (cdr tail)))))       ; Remove matching singleton.
+  elts)
+
+(defun icicle-position (item list)
+  "Zero-based position of first occurrence of ITEM in LIST, else nil."
+  (let ((index  0))
+    (catch 'icicle-position
+      (dolist (xx list)
+        (when (equal xx item) (throw 'icicle-position index))
+        (setq index  (1+ index)))
+      nil)))
+
+(defun icicle-remove-if (pred xs)
+  "A copy of list XS with no elements that satisfy predicate PRED."
+  (let ((result  ()))
+    (dolist (x xs) (unless (funcall pred x) (push x result)))
+    (nreverse result)))
+
+(defun icicle-remove-if-not (pred xs)
+  "A copy of list XS with only elements that satisfy predicate PRED."
+  (let ((result  ()))
+    (dolist (x xs) (when (funcall pred x) (push x result)))
+    (nreverse result)))
+
+(defun icicle-frames-on (buffer &optional frame) ; From `frames-on' in `frame-fns.el'.
+  "List of all live frames showing BUFFER (a buffer or its name).
+The optional FRAME argument is as for function `get-buffer-window'."
+  (filtered-frame-list (function (lambda (fr) (get-buffer-window buffer fr)))))
+
+(defun icicle-candidate-set-1 (set-fn msg)
+  "Helper function for defining Icicle set commands.
+SET-FN is the function to apply to the current and saved candidates.
+MESSAGE is the confirmation message to display in the minibuffer."
+  (setq icicle-completion-candidates
+        (funcall set-fn icicle-completion-candidates icicle-saved-completion-candidates))
+  (if (null icicle-completion-candidates)
+      (save-selected-window (select-window (minibuffer-window)) (minibuffer-message "  [EMPTY SET]"))
+    (icicle-maybe-sort-and-strip-candidates)
+    (icicle-scroll-or-update-Completions msg)))
+
+(defun icicle-maybe-sort-and-strip-candidates ()
+  "Sort `icicle-completion-candidates'.  Strip ignored file names too."
+  (if (or (icicle-file-name-input-p) icicle-abs-file-candidates) ; File names: relative or absolute.
+      (setq icicle-completion-candidates
+            (icicle-strip-ignored-files-and-sort icicle-completion-candidates))
+    (setq icicle-completion-candidates  (icicle-maybe-sort-maybe-truncate
+                                         icicle-completion-candidates))))
+
+(defun icicle-scroll-or-update-Completions (msg)
+  "Scroll `*Completions*' if this command was repeated; else update it."
+  (if (get-buffer-window "*Completions*" 0)
+      (if (eq last-command this-command)
+          ;; User repeated the command.  Scroll window around.
+          (icicle-scroll-Completions-forward)
+        ;; User did something else (e.g. changed input).  Update the display.
+        (icicle-display-candidates-in-Completions)
+        (save-selected-window (select-window (minibuffer-window)) (minibuffer-message msg)))
+    ;; No window yet.  Show window.
+    (icicle-display-candidates-in-Completions)
+    (save-selected-window (select-window (minibuffer-window)) (minibuffer-message msg))))
+
+;; $$ No longer used.
+(defun icicle-display-Completions ()
+  "Display `*Completions*' buffer."
+  (let ((completions  (icicle-all-completions "" minibuffer-completion-table
+                                              minibuffer-completion-predicate
+                                              icicle-ignore-space-prefix-flag)))
+    (when (> (length icicle-completion-candidates) icicle-incremental-completion-threshold)
+      (message "Displaying completion candidates..."))
+    (with-output-to-temp-buffer "*Completions*"
+      (display-completion-list (icicle-maybe-sort-maybe-truncate completions)))))
+
+(defun icicle-maybe-sort-maybe-truncate (cands)
+  "Return a copy of candidate list CANDS, maybe sorted, maybe truncated.
+Sort according to `icicle-sort-comparer'.
+Truncate according to `icicle-max-candidates'."
+  (let ((new-cands  cands))
+    (when icicle-sort-comparer (setq new-cands  (icicle-reversible-sort new-cands)))
+    (when icicle-max-candidates
+      (let ((lighter  (cadr (assoc 'icicle-mode minor-mode-alist)))
+            (regexp   (concat (regexp-quote icicle-lighter-truncation) "$")))
+        (cond ((and new-cands (< icicle-max-candidates ; Save total number before truncation
+                                 (setq icicle-nb-candidates-before-truncation  (length new-cands))))
+               (unless (string-match regexp lighter)
+                 (icicle-clear-lighter 'not-truncated)
+                 (add-to-list
+                  'minor-mode-alist `(icicle-mode ,(concat lighter icicle-lighter-truncation)))))
+              (new-cands
+               ;; Save total number before truncation in `icicle-nb-candidates-before-truncation'.
+               (setq icicle-nb-candidates-before-truncation  (length new-cands))
+               (when (string-match regexp lighter)
+                 (icicle-clear-lighter 'truncated)
+                 (add-to-list
+                  'minor-mode-alist
+                  `(icicle-mode
+                    ,(substring lighter 0
+                                (- (length lighter) (length icicle-lighter-truncation)))))))))
+      (setq new-cands  (icicle-take icicle-max-candidates new-cands)))
+    new-cands))
+
+(defun icicle-take (num xs)
+  "Return a copy of list XS but with only the first NUM items.
+No error handling.  NUM must be in the range 0 to (length XS)."
+  ;; Recursive version would be just this:
+  ;; (and xs (not (zerop num)) (cons (car xs) (icicle-take (1- num) (cdr xs)))))
+  (and xs (not (zerop num))
+       (let ((new-xs  ())
+             (count   0))
+         (catch 'icicle-take
+           (dolist (x  xs)
+             (when (> (setq count  (1+ count)) num) (throw 'icicle-take new-xs))
+             (setq new-xs  (cons x new-xs)))
+           new-xs))))
+
+;; From `cl-seq.el', function `union', without keyword treatment.
+;; Same as `simple-set-union' in `misc-fns.el'.
+(defun icicle-set-union (list1 list2)
+  "Combine LIST1 and LIST2 using a set-union operation.
+The result list contains all items that appear in either LIST1 or
+LIST2.  This is a non-destructive function; it copies the data if
+necessary."
+  (cond ((null list1)         list2)
+        ((null list2)         list1)
+        ((equal list1 list2)  list1)
+        (t
+         (unless (>= (length list1) (length list2))
+           (setq list1  (prog1 list2 (setq list2  list1)))) ; Swap them.
+         (while list2
+           (unless (member (car list2) list1)  (setq list1  (cons (car list2) list1)))
+           (setq list2  (cdr list2)))
+         list1)))
+
+;; From `cl-seq.el', function `intersection', without keyword treatment.
+;; Same as `simple-set-intersection' in `misc-fns.el'.
+(defun icicle-set-intersection (list1 list2)
+  "Set intersection of lists LIST1 and LIST2.
+This is a non-destructive operation: it copies the data if necessary."
+  (and list1 list2
+       (if (equal list1 list2)
+           list1
+         (let ((result  ()))
+           (unless (>= (length list1) (length list2))
+             (setq list1  (prog1 list2 (setq list2  list1)))) ; Swap them.
+           (while list2
+             (when (member (car list2) list1)  (setq result  (cons (car list2) result)))
+             (setq list2  (cdr list2)))
+           result))))
+
+;; From `cl-seq.el', function `set-difference', without keyword treatment.
+;; Same as `simple-set-difference' in `misc-fns.el'.
+(defun icicle-set-difference (list1 list2)
+  "Combine LIST1 and LIST2 using a set-difference operation.
+The result list contains all items that appear in LIST1 but not LIST2.
+This is non-destructive; it makes a copy of the data if necessary, to
+avoid corrupting the original LIST1 and LIST2."
+  (if (or (null list1) (null list2)) list1
+    (let ((result  ()))
+      (while list1
+        (unless (member (car list1) list2)  (setq result  (cons (car list1) result)))
+        (setq list1  (cdr list1)))
+      result)))
+
+(defun icicle-get-candidates-from-saved-set (set-name &optional dont-expand-filesets-p)
+  "Return the saved set of completion candidates named SET-NAME.
+SET-NAME can be the name of either an Icicles saved completion set or,
+ if `icicle-filesets-as-saved-completion-sets-flag', an Emacs fileset.
+If optional arg DONT-EXPAND-FILESETS-P is non-nil, then don't expand
+ fileset entries in a saved completion set.  Instead, return them as
+string candidates."
+  (let ((cache-file  (cdr (assoc set-name icicle-saved-completion-sets)))
+        fst)
+    (cond ((and (not cache-file)        ; Fileset - get explicit file list.
+                icicle-filesets-as-saved-completion-sets-flag (featurep 'filesets) filesets-data
+                (setq fst  (filesets-get-fileset-from-name set-name)))
+           (icicle-explicit-saved-completion-candidates (list fst)))
+          ((not cache-file) (error "No such saved set: `%s'" set-name))
+          ((not (icicle-file-readable-p cache-file)) (error "Cannot read cache file `%s'" cache-file))
+          (t                            ; Icicles saved completion set.
+           (let ((list-buf    (find-file-noselect cache-file 'nowarn))
+                 (cands-read  ())
+                 (candidates  ()))
+             (message "Retrieving saved candidates from `%s'..." cache-file)
+             (unwind-protect
+                  (condition-case err
+                      (when (listp (setq cands-read  (read list-buf)))
+                        (message "Set `%s' read from file `%s'" set-name cache-file))
+                    (error (error "Could not read cache file.  %s" (error-message-string err))))
+               (icicle-kill-a-buffer list-buf))
+             (unless cands-read (error "No completion candidates in file `%s'" cache-file))
+             (dolist (cand  (nreverse cands-read)) ; Convert saved to displayable candidates.
+               (if (not (icicle-saved-fileset-p cand))
+                   (push (icicle-displayable-cand-from-saved-set cand) candidates)
+                 (condition-case err
+                     (require 'filesets)
+                   (error "Set `%s' includes a fileset, but cannot load `fileset.el'" set-name))
+                 (filesets-init)
+                 (if dont-expand-filesets-p
+                     (push cand candidates)
+                   (setq candidates
+                         (append (mapcar #'icicle-displayable-cand-from-saved-set
+                                         (icicle-get-candidates-from-saved-set (cadr cand)))
+                                 candidates)))))
+             candidates)))))
+
+(defun icicle-explicit-saved-completion-candidates (&optional saved-set)
+  "Return the list of files represented by a saved completion set.
+Any fileset entries in the saved set are expanded to an explicit list
+of file names.
+Optional arg SAVED-SET is the Icicles saved completion set to use.
+ It can be the set itself or its name.
+ If SAVED-SET is nil, use `icicle-saved-completion-candidates'."
+  (unless saved-set (setq saved-set  icicle-saved-completion-candidates))
+  (when (stringp saved-set)  (setq saved-set  (icicle-get-candidates-from-saved-set saved-set)))
+  (let ((files  ())
+        (mode   nil))
+    (dolist (entry  saved-set)
+      (cond ((atom entry) (push entry files))
+            ((and (featurep 'filesets)
+                  (or (setq mode  (filesets-entry-mode entry)) ; ("my-fs" (:files "a" "b"))
+                      (setq entry  (cons "dummy" entry) ; (:files "a" "b")
+                            mode   (filesets-entry-mode entry))))
+             (message "Gathering file names...")
+             (dolist (file  (filesets-get-filelist entry mode)) (push file files)))
+            (t (error "Bad `icicle-saved-completion-candidates' entry: `%S'" entry))))
+    (nreverse files)))
+
+(defun icicle-saved-fileset-p (entry)
+  "Return non-nil if ENTRY is a fileset entry in a saved completion set.
+ENTRY is a list whose car is `:fileset' - it is not a fileset name."
+  (and (consp entry) (eq (car entry) ':fileset)))
+
+(defun icicle-displayable-cand-from-saved-set (cand)
+  "Return display candidate for saved candidate CAND.
+If CAND is an atom, then return it as is."
+  (let ((cand-w-mrkrs  (icicle-readable-to-markers cand)))
+    (if (atom cand-w-mrkrs)
+        cand-w-mrkrs
+      (let ((icicle-whole-candidate-as-text-prop-p  t))
+        (car (icicle-mctized-full-candidate cand-w-mrkrs))))))
+
+(defun icicle-readable-to-markers (cand)
+  "Convert (deserialize) Lisp-readable representation CAND of candidate.
+A Lisp-readable candidate uses the following to represent a marker:
+   (icicle-file-marker FILE-NAME   MARKER-POSITION)
+or (icicle-marker      BUFFER-NAME MARKER-POSITION)"
+  (if (and (consp cand) (consp (cdr cand)) (consp (cddr cand)) (null (cdr (cddr cand)))
+           (memq (car cand) '(icicle-file-marker icicle-marker)))
+      (let ((file-or-buf  (cadr cand))
+            (pos          (car (cddr cand)))
+            mrker buf)
+        (if (eq (car cand) 'icicle-file-marker)
+            (let ((buf  (find-file-noselect file-or-buf)))
+              (unless buf (error "Cannot find file `%s'" file-or-buf))
+              (setq file-or-buf  buf))
+          (unless (get-buffer file-or-buf) (error "You must first visit buffer `%s'" file-or-buf)))
+        (set-marker (setq mrker  (make-marker)) pos (get-buffer file-or-buf))
+        mrker)
+    (if (consp cand)
+        (cons (icicle-readable-to-markers (car cand)) (icicle-readable-to-markers (cdr cand)))
+      cand)))
+
+
+;; REPLACE ORIGINAL `filesets-get-filelist' in `filesets.el'.
+;;  The original is bugged (I filed Emacs bug #976 on 2008-09-13).
+;; For `:tree':
+;;  * First get the tree from the ENTRY.
+;;  * Return all matching files under the directory, including in subdirs up to
+;;    `filesets-tree-max-level' for the entry.
+;;
+(eval-after-load 'filesets
+  '(defun filesets-get-filelist (entry &optional mode event)
+    "Get all files for fileset ENTRY.
+Assume MODE (see `filesets-entry-mode'), if provided."
+    (let* ((mode  (or mode (filesets-entry-mode entry)))
+           (fl    (case mode
+                    ((:files)   (filesets-entry-get-files entry))
+                    ((:file)    (list (filesets-entry-get-file entry)))
+                    ((:ingroup) (let ((entry  (expand-file-name
+                                               (if (stringp entry)
+                                                   entry
+                                                 (filesets-entry-get-master entry)))))
+                                  (cons entry (filesets-ingroup-cache-get entry))))
+                    ((:tree)    (let* ((dirpatt  (filesets-entry-get-tree entry)) ; Added this line.
+                                       (dir      (nth 0 dirpatt)) ; Use DIRPATT, not ENTRY.
+                                       (patt     (nth 1 dirpatt)) ; Use DIRPATT, not ENTRY.
+                                       (depth    (or (filesets-entry-get-tree-max-level entry)
+                                                     filesets-tree-max-level)))
+                                  (icicle-filesets-files-under 0 depth entry dir patt
+                                                               (and icicle-mode
+                                                                    (icicle-file-name-input-p)))))
+                    ((:pattern) (let ((dirpatt  (filesets-entry-get-pattern entry)))
+                                  (if dirpatt
+                                      (let ((dir   (filesets-entry-get-pattern--dir dirpatt))
+                                            (patt  (filesets-entry-get-pattern--pattern dirpatt)))
+                                        ;;(filesets-message 3 "Filesets: scanning %s" dirpatt)
+                                        (filesets-directory-files dir patt ':files t))
+                                    ;; (message "Filesets: malformed entry: %s" entry)))))))
+                                    (filesets-error 'error "Filesets: malformed entry: " entry)))))))
+      (filesets-filter-list fl (lambda (file) (not (filesets-filetype-property file event)))))))
+
+(defun icicle-filesets-files-under (level depth entry dir patt &optional relativep)
+  "Files under DIR that match PATT.
+LEVEL is the current level under DIR.
+DEPTH is the maximal tree scanning depth for ENTRY.
+ENTRY is a fileset.
+DIR is a directory.
+PATT is a regexp that included file names must match.
+RELATIVEP non-nil means use relative file names."
+  (and (or (= depth 0) (< level depth))
+       (let* ((dir         (file-name-as-directory dir))
+              (files-here  (filesets-directory-files dir patt nil (not relativep)
+                                                     (filesets-entry-get-filter-dirs-flag entry)))
+              (subdirs     (filesets-filter-dir-names files-here)) ; Subdirectories at this level.
+              (files       (filesets-filter-dir-names ; Remove directory names.
+                            (apply #'append
+                                   files-here
+                                   (mapcar (lambda (subdir) ; Files below this level.
+                                             (let* ((subdir       (file-name-as-directory subdir))
+                                                    (full-subdir  (concat dir subdir)))
+                                               (icicle-filesets-files-under
+                                                (+ level 1) depth entry full-subdir patt)))
+                                           subdirs))
+                            t)))
+         files)))
+
+;; Note that initial and trailing spaces will not be noticeable.  That's OK.
+(defun icicle-highlight-complete-input ()
+  "Highlight minibuffer input, showing that it is a sole completion.
+Overlay `icicle-complete-input-overlay' is created with `match' face,
+unless it exists."
+  (let ((case-fold-search
+         ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+         (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                  (boundp 'read-file-name-completion-ignore-case))
+             read-file-name-completion-ignore-case
+           completion-ignore-case))
+        input-start-position)
+    (save-excursion
+      (goto-char (icicle-minibuffer-prompt-end))
+      (setq input-start-position  (point))
+      (when (and (icicle-file-name-input-p) insert-default-directory)
+        (search-forward (icicle-file-name-directory-w-default
+                         (icicle-input-from-minibuffer 'leave-envvars))
+                        nil t)
+        (setq input-start-position  (point))) ; Skip directory.
+      (if icicle-complete-input-overlay ; Don't recreate if exists.
+          (move-overlay icicle-complete-input-overlay
+                        input-start-position (point-max) (current-buffer))
+        (setq icicle-complete-input-overlay  (make-overlay input-start-position (point-max)))
+        (overlay-put icicle-complete-input-overlay 'face 'icicle-complete-input)))))
+
+(defun icicle-call-then-update-Completions (fn &rest args)
+  "Call FN with ARGS, then update `*Completions*' with input matches."
+  (save-match-data
+    (apply fn args)
+    ;;$$$ (let ((tramp-completion-mode  t))    ; Fool Tramp into thinking it is in completion mode.
+    (setq icicle-current-input   (icicle-input-from-minibuffer)
+          icicle-input-fail-pos  nil)
+    (setq icicle-last-input  nil) ; $$$$$$$$ So icicle-save-or-restore-input => recompute candidates.
+    (when (overlayp icicle-complete-input-overlay) (delete-overlay icicle-complete-input-overlay))
+    (icicle-highlight-initial-whitespace icicle-current-input)
+    (if (< (length icicle-current-input) icicle-Completions-display-min-input-chars)
+        (save-selected-window (icicle-remove-Completions-window))
+      ;; `icicle-highlight-input-noncompletion' return value saves call to `icicle-file-remote-p'.
+      (let ((remote-test  (icicle-highlight-input-noncompletion)))
+        ;; If ALL of the following are true, then update `*Completions*' (complete again):
+        ;;   * incremental completion,
+        ;;   * `icicle-highlight-input-noncompletion' determined that it's a remote or local file
+        ;;        or we're not completing file names
+        ;;        or user said not to test for remote file names
+        ;;        or we check now and it's not a remote file,
+        ;;   * `*Completions*' is already displayed or `icicle-incremental-completion-p' is not t,
+        ;;   * there are not too many candidates or we have waited the full delay.
+        (when (and icicle-incremental-completion-p
+                   (or (memq remote-test '(file-local-p file-remote-p))
+                       (not (icicle-file-name-input-p))
+                       (not icicle-test-for-remote-files-flag)
+                       ;; Might still be remote if `icicle-highlight-input-completion-failure'
+                       ;; is `always' or `explicit-remote' - cannot tell from `remote-test'.
+                       (and (not (eq remote-test 'file-local-p)) ; We don't know if it's local.
+                            (not (icicle-file-remote-p icicle-current-input))))
+                   (or (get-buffer-window "*Completions*" 0) ; Already displayed.
+                       ;; If value is, say, `always' or `display' then update anyway.
+                       (not (eq t icicle-incremental-completion-p)))
+                   (let ((len  (length icicle-completion-candidates)))
+                     (or (and (> len 1) (> icicle-incremental-completion-threshold len)) ; Not many
+                         (sit-for icicle-incremental-completion-delay)))) ; Wait, unless input.
+          (let ((icicle-edit-update-p  t))
+            (funcall (or icicle-last-completion-command
+                         (if (eq icicle-current-completion-mode 'prefix)
+                             #'icicle-prefix-complete
+                           #'icicle-apropos-complete)))
+            (run-hooks 'icicle-update-input-hook)))))
+    (setq mark-active  nil)))
+
+(defun icicle-highlight-input-noncompletion ()
+  "Highlight the portion of the current input that does not complete.
+See the doc strings of `icicle-highlight-input-completion-failure' and
+`icicle-test-for-remote-files-flag' for information about when this
+highlighting occurs.
+
+If we know the input is a remote file name, return `file-remote-p'.
+If we know it is a local file name, return `file-local-p'.
+If part of the input matches candidates, return that matching part.
+If no highlighting was attempted, return nil."
+  (let ((input-start   (icicle-minibuffer-prompt-end))
+        (input         (icicle-input-from-minibuffer))
+        (file-local-p  nil))
+    (cond
+      ;; No input.
+      ((string= "" input) "")           ; Return string: highlighting attempted.
+
+      ;; One of these: pending input,
+      ;;               not highlighting,
+      ;;               highlighting `explicit-*' but not explicitly completing (TAB/S-TAB),
+      ;;               highlighting `implicit-*' but not incrementally completing,
+      ;;               highlighting `*-strict'   but not strict completion (and testing remote files)
+      ;;               there are more candidates than the threshold for highlighting.
+      ((or (input-pending-p)
+           (not icicle-highlight-input-completion-failure)
+           (and (not (get this-command 'icicle-completing-command))
+                (memq icicle-highlight-input-completion-failure
+                      '(explicit explicit-strict explicit-remote)))
+           (and (not icicle-incremental-completion-flag)
+                (memq icicle-highlight-input-completion-failure '(implicit implicit-strict)))
+           (and (not (icicle-require-match-p))
+                icicle-test-for-remote-files-flag ; nil flag ignores strict setting for highlighting 
+                (memq icicle-highlight-input-completion-failure '(implicit-strict explicit-strict)))
+           (let ((len  (length icicle-completion-candidates)))
+             (and (> len 1)  (> len icicle-highlight-input-completion-failure-threshold))))
+       nil)                             ; Return nil: no highlighting attempted.
+
+      ;; Cursor is to the left of the last mismatch position.
+      ((and icicle-input-fail-pos (< (point) icicle-input-fail-pos))
+       (setq icicle-input-fail-pos  nil) ; Reset failure position.
+       ;; Remove vestigial highlighting on matched part (e.g. from another completion mode).
+       (when (and (> (or icicle-input-fail-pos (point-max)) input-start)
+                  (overlayp icicle-input-completion-fail-overlay))
+         (delete-overlay icicle-input-completion-fail-overlay))
+       nil)                             ; Return nil: no highlighting attempted.
+
+      ;; Remote file-name input, user didn't say to skip testing for remote files,
+      ;; and highlighting is not `always' or `explicit-remote'.
+      ((and (icicle-file-name-input-p)
+            (not (memq icicle-highlight-input-completion-failure '(always explicit-remote)))
+            icicle-test-for-remote-files-flag
+            (let ((remotep  (icicle-file-remote-p input)))
+              (unless remotep (setq file-local-p  'file-local-p)) ; We know it's local, so save that.
+              remotep))
+       ;; Do the same as for the previous, except return indication that we know it is a remote file.
+       (setq icicle-input-fail-pos  nil)
+
+       (when (and (> (or icicle-input-fail-pos (point-max)) input-start)
+                  (overlayp icicle-input-completion-fail-overlay))
+         (delete-overlay icicle-input-completion-fail-overlay))
+       'file-remote-p)                  ; Return `file-remote-p': we know it is a remote file.
+
+      ((and icicle-highlight-input-completion-failure-delay
+            (progn (message nil)        ; Clear any message, e.g. "Computing completion candidates..."
+                   (sit-for icicle-highlight-input-completion-failure-delay)))
+       ;; First, a quick check through last two chars.
+       ;; If last succeeds, then done.
+       ;; If last fails and next-to-last succeeds, then done.
+       ;; Otherwise, highlight the others using a binary search.
+       (let ((matchp  (icicle-any-candidates-p input))) ; Entire input, through last char.
+         (unless matchp
+           ;; Record failure position and highlight last char.
+           (setq icicle-input-fail-pos  (if icicle-input-fail-pos
+                                            (min icicle-input-fail-pos (point-max))
+                                          (point-max)))
+
+           (cond (icicle-input-completion-fail-overlay ; Don't recreate if exists.
+                  ;; Specify buffer in case overlay exists but is in a diff (e.g. recursive) minibuffer.
+                  (move-overlay icicle-input-completion-fail-overlay
+                                (1- icicle-input-fail-pos) (point-max)
+                                (window-buffer (active-minibuffer-window)))
+                  (overlay-put icicle-input-completion-fail-overlay
+                               'face (if (icicle-require-match-p)
+                                         'icicle-input-completion-fail
+                                       'icicle-input-completion-fail-lax)))
+                 (t
+                  (setq icicle-input-completion-fail-overlay (make-overlay (1- icicle-input-fail-pos)
+                                                                           (point-max)))
+                  (overlay-put icicle-input-completion-fail-overlay
+                               'face (if (icicle-require-match-p)
+                                         'icicle-input-completion-fail
+                                       'icicle-input-completion-fail-lax))))
+           ;; See if next-to-last char gives a match.  Typical use case: mistyping a char at end.
+           (setq input  (substring input 0 (1- (length input))))
+           (unless (string= "" input)
+             (setq matchp  (icicle-any-candidates-p input))
+             ;; If more than just the last char fails, highlight the others using binary search.
+             (unless matchp (icicle-highlight-input-noncompletion-rest)))))
+       ;; Highlighting attempted, so return non-nil.  If we know it's local, return `file-local-p'.
+       ;; If we don't know that, return the part of INPUT that matches.
+       (or file-local-p input))
+      (t nil))))                        ; Return nil: no highlighting attempted.
+
+(defun icicle-highlight-input-noncompletion-rest ()
+  "Helper function for `icicle-highlight-input-noncompletion'."
+  (let* ((input-start  (icicle-minibuffer-prompt-end))
+         (pos          (1- icicle-input-fail-pos))
+         (delta        pos)
+         (last-pos     input-start)
+         (matchp       nil)
+         input)
+    (while (and (> pos input-start)  (or (not matchp)  (< pos icicle-input-fail-pos))) ; Binary search.
+      (setq input   (buffer-substring input-start pos)
+            delta   (max 1 (/ (abs (- pos last-pos)) 2))
+            matchp  (icicle-any-candidates-p input))
+      ;; $$$$$$ Emacs BUG (prefix completion): c:/foo/$$ does not highlight the `$$', because
+      ;; (try-completion "c:/foo/$" 'read-file-name-internal "c:/foo/") returns "c:/foo/$".
+      ;; (However, c:/foo/$ highlights the `$' correctly.)
+      (unless matchp (setq icicle-input-fail-pos  (min pos icicle-input-fail-pos)))
+      (setq last-pos  pos
+            pos       (if matchp (+ pos delta) (- pos delta))))
+    (unless (or (< pos input-start)  (> pos icicle-input-fail-pos))
+      (cond (icicle-input-completion-fail-overlay ; Don't recreate if exists.
+             (move-overlay icicle-input-completion-fail-overlay (1- icicle-input-fail-pos) (point-max))
+             (overlay-put icicle-input-completion-fail-overlay
+                          'face (if (icicle-require-match-p)
+                                    'icicle-input-completion-fail
+                                  'icicle-input-completion-fail-lax)))
+            (t
+             (setq icicle-input-completion-fail-overlay (make-overlay (1- icicle-input-fail-pos)
+                                                                      (point-max)))
+             (overlay-put icicle-input-completion-fail-overlay
+                          'face (if (icicle-require-match-p)
+                                    'icicle-input-completion-fail
+                                  'icicle-input-completion-fail-lax)))))
+    input))                             ; Return part of INPUT that matches.
+
+(defun icicle-ms-windows-NET-USE (drive)
+  "Return result of calling MS Windows `NET USE' command on DRIVE.
+DRIVE is a Windows drive name, such as `f:'.
+A return value of zero means DRIVE is a mapped network drive."
+  (if (and (fboundp 'hash-table-p) (hash-table-p icicle-ms-windows-drive-hash))
+      (let ((lookup  (gethash drive icicle-ms-windows-drive-hash 'no-assoc)))
+        (if (eq lookup 'no-assoc)
+            (puthash drive (call-process shell-file-name nil nil nil shell-command-switch
+                                         (concat "NET USE " drive)) icicle-ms-windows-drive-hash)
+          lookup))
+    ;; Don't bother to hash for Emacs 20, 21, unless `cl.el' happens to be loaded.
+    (call-process shell-file-name nil nil nil shell-command-switch (concat "NET USE " drive))))
+
+;; $$$$$ TRYING WITHOUT `save-match-data', but probably need it.
+(defun icicle-file-remote-p (file)
+  "Non-nil means FILE is likely to name a file on a remote system.
+For MS Windows, this includes a file on a mapped network drive.
+Otherwise, this uses `ffap-file-remote-p' and `file-remote-p' (if
+defined)."
+  ;; $$$$  (save-match-data        ; $$$$$ IS THIS NEEDED?
+  (if (and (eq system-type 'windows-nt)
+           (let ((case-fold-search  t)) (string-match "\\`\\([a-z]:\\)" file)))
+      (eq 0 (condition-case nil
+                (icicle-ms-windows-NET-USE (match-string 1 file))
+              (error nil)))
+    (or (and (fboundp 'ffap-file-remote-p) (ffap-file-remote-p file))
+        (and (fboundp 'file-remote-p) (file-remote-p file)))))
+
+;;; $$$$$ Should these `*-any-*' fns call `icicle-transform-candidates'?  For now, no, to save time.
+(defun icicle-any-candidates-p (input)
+  "Return non-nil if there is any completion for INPUT, nil otherwise."
+  (condition-case nil
+      (funcall (case icicle-current-completion-mode
+                 (apropos (if (icicle-file-name-input-p)
+                              #'icicle-apropos-any-file-name-candidates-p
+                            #'icicle-apropos-any-candidates-p))
+                 (otherwise (if (icicle-file-name-input-p)
+                                #'icicle-prefix-any-file-name-candidates-p
+                              #'icicle-prefix-any-candidates-p)))
+               input)
+    (error nil)))
+
+(defun icicle-prefix-any-candidates-p (input)
+  "Return non-nil if current partial INPUT has prefix completions."
+  (let ((minibuffer-completion-table      minibuffer-completion-table)
+        (minibuffer-completion-predicate  minibuffer-completion-predicate))
+    (if (icicle-not-basic-prefix-completion-p)
+        (icicle-completion-try-completion input minibuffer-completion-table
+                                          minibuffer-completion-predicate
+                                          ;; $$$$$$ (- (point) (field-beginning)))
+                                          (length input)
+                                          (and (fboundp 'completion--field-metadata) ; Emacs 24
+                                               (completion--field-metadata (field-beginning))))
+      (try-completion input minibuffer-completion-table minibuffer-completion-predicate))))
+
+(defun icicle-prefix-any-file-name-candidates-p (input)
+  "Return non-nil if partial file-name INPUT has prefix completions."
+  (let* ((minibuffer-completion-table      minibuffer-completion-table)
+         (minibuffer-completion-predicate  minibuffer-completion-predicate))
+    (if (icicle-not-basic-prefix-completion-p)
+        (icicle-completion-try-completion input minibuffer-completion-table
+                                          minibuffer-completion-predicate
+                                          (length input)
+                                          (and (fboundp 'completion--field-metadata) ; Emacs 24
+                                               (completion--field-metadata (field-beginning))))
+      (try-completion input minibuffer-completion-table default-directory))))
+
+(defun icicle-apropos-any-candidates-p (input)
+  "Return non-nil if current partial INPUT has apropos completions."
+  (when icicle-regexp-quote-flag (setq input  (regexp-quote input)))
+  (let* ((minibuffer-completion-table      minibuffer-completion-table)
+         (minibuffer-completion-predicate  minibuffer-completion-predicate)
+         (all                              (icicle-all-completions "" minibuffer-completion-table
+                                                                   minibuffer-completion-predicate
+                                                                   icicle-ignore-space-prefix-flag)))
+    (catch 'icicle-apropos-any-candidates-p
+      (dolist (cand all)
+        ;; Assume no match if error - e.g. due to `string-match' with binary data in Emacs 20.
+        ;; Do this everywhere we call `icicle-apropos-complete-match-fn'.
+        (when (condition-case nil (funcall icicle-apropos-complete-match-fn input cand) (error nil))
+          (throw 'icicle-apropos-any-candidates-p cand)))
+      nil)))
+
+(defun icicle-apropos-any-file-name-candidates-p (input)
+  "Return non-nil if partial file-name INPUT has apropos completions."
+  (when (and input (not (string= "" input)) (eq (aref input (1- (length input))) ?\/))
+    (setq input  (substring input 0 (1- (length input))))) ; So we don't non-match highlight the /.
+  (let* ((default-directory                (icicle-file-name-directory-w-default input))
+         (minibuffer-completion-table      minibuffer-completion-table)
+         (minibuffer-completion-predicate  minibuffer-completion-predicate))
+    (setq input  (or (icicle-file-name-nondirectory input)  ""))
+    (condition-case nil
+        (progn (when icicle-regexp-quote-flag (setq input  (regexp-quote input)))
+               (let ((candidates        (icicle-all-completions "" minibuffer-completion-table
+                                                                minibuffer-completion-predicate
+                                                                icicle-ignore-space-prefix-flag))
+                     (case-fold-search  (if (boundp 'read-file-name-completion-ignore-case)
+                                            read-file-name-completion-ignore-case
+                                          completion-ignore-case)))
+                 (catch 'icicle-apropos-any-file-name-candidates-p
+                   (dolist (cand candidates)
+                     (when (if (member cand '("../" "./"))
+                               (member input '(".." ".")) ; Prevent "" from matching "../"
+                             (and (or (not icicle-apropos-complete-match-fn)
+                                      ;; Assume no match if error - e.g. due to `string-match' with
+                                      ;; binary data in Emacs 20.  Do this everywhere we call
+                                      ;; `icicle-apropos-complete-match-fn'.
+                                      (condition-case nil
+                                          (funcall icicle-apropos-complete-match-fn input cand)
+                                        (error nil)))))
+                       (throw 'icicle-apropos-any-file-name-candidates-p cand)))
+                   nil)))
+      (quit (top-level)))))             ; Let `C-g' stop it.
+
+(defun icicle-clear-minibuffer ()
+  "Delete all user input in the minibuffer.
+This must be called from the minibuffer."
+  (if (fboundp 'delete-minibuffer-contents)  (delete-minibuffer-contents)  (erase-buffer)))
+
+;; Same as `delete-dups' from Emacs 22+.
+(if (fboundp 'delete-dups)
+    (defalias 'icicle-delete-dups (symbol-function 'delete-dups))
+  (defun icicle-delete-dups (list)
+    "Destructively remove `equal' duplicates from LIST.
+Store the result in LIST and return it.  LIST must be a proper list.
+Of several `equal' occurrences of an element in LIST, the first
+one is kept."
+    (let ((tail list))
+      (while tail
+        (setcdr tail (delete (car tail) (cdr tail)))
+        (setq tail (cdr tail))))
+    list))
+
+;; Borrowed from `ps-print.el'
+(defun icicle-remove-duplicates (list)
+  "Copy of LIST with duplicate elements removed.  Tested with `equal'."
+  (let ((tail  list)
+        new)
+    (while tail
+      (unless (member (car tail) new) (push (car tail) new))
+      (pop tail))
+    (nreverse new)))
+
+(defun icicle-remove-dups-if-extras (list)
+  "`icicle-remove-duplicates' if `icicle-extra-candidates' is non-nil.
+If `icicle-extra-candidates' is nil, then return LIST.
+
+Note: When you use this as the value of `icicle-transform-function',
+be aware that during completion and before applying this function,
+`icicle-extra-candidates' is redefined locally by removing its
+candidates that don't match the current input.  So this function then
+has the effect of removing any duplicates that match the input.  If
+there are no such matching candidates, then LIST is returned."
+  (if icicle-extra-candidates
+      (let ((tail  list)
+            new)
+        (while tail
+          (unless (member (car tail) new) (push (car tail) new))
+          (pop tail))
+        (nreverse new))
+    list))
+
+(defun icicle-file-readable-p (file)
+  "Return non-nil if FILE (a string) names a readable file."
+  (and (not (string= "" file))  (file-readable-p file)  (not (file-directory-p file))))
+
+(defun icicle-file-writable-p (file)
+  "Return non-nil if FILE (a string) names a writable file."
+  (and (not (string= "" file))  (file-writable-p file)  (not (file-directory-p file))))
+
+(defvar icicle-dirs-done ()
+  "Directories already processed.")
+
+(defun icicle-files-within (file-list accum &optional no-symlinks-p)
+  "List of all readable files in FILE-LIST.
+Accessible directories in FILE-LIST are processed recursively to
+include their files and the files in their subdirectories.
+
+Optional arg NO-SYMLINKS-P non-nil means do not follow symbolic links.
+
+The list of files is accumulated in ACCUM, which is used for recursive
+calls.
+Bind `icicle-dirs-done' for use as free var elsewhere."
+  (let ((icicle-dirs-done  ()))
+    (icicle-files-within-1 file-list accum no-symlinks-p)))
+
+(defun icicle-files-within-1 (file-list accum no-symlinks-p) ; `icicle-dirs-done' is free here.
+  "Helper for `icicle-files-within'."
+  (let ((res  accum)
+        file)
+    (while file-list
+      (setq file  (car file-list))
+      (unless (and no-symlinks-p (file-symlink-p file))
+        (if (file-directory-p file)
+            ;; Skip directory if ignored, already treated, or inaccessible.
+            (when (and (not (member (file-name-nondirectory file) icicle-ignored-directories))
+                       (not (member (file-truename file) icicle-dirs-done))
+                       (file-accessible-directory-p file))
+              (setq res  (icicle-files-within-1 (directory-files file 'full icicle-re-no-dot)
+                                                res
+                                                no-symlinks-p))
+              (push (file-truename file) icicle-dirs-done))
+          (when (file-readable-p file) (setq res  (cons file res)))))
+      (pop file-list))
+    res))
+
+(defun icicle-delete-whitespace-from-string (string &optional from to)
+  "Remove whitespace from substring of STRING from FROM to TO.
+If FROM is nil, then start at the beginning of STRING (FROM = 0).
+If TO is nil, then end at the end of STRING (TO = length of STRING).
+FROM and TO are zero-based indexes into STRING.
+Character FROM is affected (possibly deleted).  Character TO is not."
+  (setq from  (or from 0)
+        to    (or to (length string)))
+  (with-temp-buffer
+    (insert string)
+    (goto-char (+ from (point-min)))
+    (let ((count  from)
+          char)
+      (while (and (not (eobp))  (< count to))
+        (setq char  (char-after))
+        (if (memq char '(?\  ?\t ?\n))  (delete-char 1)  (forward-char 1))
+        (setq count  (1+ count)))
+      (buffer-string))))
+
+(defun icicle-barf-if-outside-minibuffer ()
+  "Raise an error if `this-command' is called outside the minibuffer."
+  (unless (eq (current-buffer) (window-buffer (minibuffer-window)))
+    (error "Command `%s' must be called from the minibuffer" this-command)))
+
+(defun icicle-barf-if-outside-Completions ()
+  "Raise error if `this-command' is called outside buffer `*Completions*'."
+  (unless (eq (current-buffer) (get-buffer "*Completions*"))
+    (error "Command `%s' must be called from `*Completions*' buffer" this-command)))
+
+(defun icicle-barf-if-outside-Completions-and-minibuffer ()
+  "Error if `this-command' called outside `*Completions*' and minibuffer."
+  (unless (or (eq (current-buffer) (window-buffer (minibuffer-window)))
+              (eq (current-buffer) (get-buffer "*Completions*")))
+    (error "`%s' must be called from `*Completions*' or the minibuffer" this-command)))
+
+(defun icicle-command-abbrev-save ()
+  "Save `icicle-command-abbrev-alist'.  Used on `kill-emacs-hook'."
+  (icicle-condition-case-no-debug err   ; Don't raise an error, since it's on `kill-emacs-hook.
+      (let ((sav  (get 'icicle-command-abbrev-alist 'saved-value)))
+        (unless (and (or (null sav)
+                         (and (consp sav)  (consp (car sav))  (consp (cdar sav))
+                              (consp (car (cdar sav)))))
+                     (equal icicle-command-abbrev-alist (car (cdar sav))))
+          (funcall icicle-customize-save-variable-function 'icicle-command-abbrev-alist
+                   icicle-command-abbrev-alist)))
+    (error (message "Cannot save new value of `icicle-command-abbrev-alist'") (sleep-for 3))))
+
+(defun icicle-expand-file-or-dir-name (input dir)
+  "Expand file-name INPUT in directory DIR.
+Similar to `expand-file-name', except:
+
+ - If INPUT does not end in a slash, and DIR/INPUT is a directory,
+   add a trailing slash.
+
+ - If INPUT ends in a slash, but DIR/INPUT is not a directory, then
+   remove the trailing slash.
+
+ - if INPUT or DIR contains consecutive slashes (`/'), do not collapse
+   them to a single slash."
+  (let ((expanded-input  (directory-file-name (icicle-expand-file-name-20 input dir))))
+    ;; Add trailing slash if input is a directory.
+    (when (file-directory-p expanded-input)
+      (setq expanded-input  (file-name-as-directory expanded-input)))
+    expanded-input))
+
+(defun icicle-expand-file-name-20 (input dir)
+  "Emacs 20's `expand-file-name': does not collapse consecutive slashes."
+  ;; Replace // with five ^Gs, then replace back again.
+  (let ((escaped-input  (and input (replace-regexp-in-string "//" (make-string 5 7) input)))
+        (escaped-dir    (and dir (replace-regexp-in-string "//" (make-string 5 7) dir))))
+    (replace-regexp-in-string (make-string 5 7) "//" (expand-file-name escaped-input escaped-dir))))
+
+(defun icicle-start-of-candidates-in-Completions ()
+  "Return buffer position of the first candidate in `*Completions*'."
+  (save-excursion
+    (goto-char (point-min))
+    (forward-line (if icicle-show-Completions-help-flag 2 1))
+    (point)))
+
+(defun icicle-key-description (keys &optional no-angles)
+  "`key-description', but non-nil NO-ANGLES means use no angle brackets."
+  (let ((result  (key-description keys)))
+    (when no-angles                     ; Assume space separates angled keys.
+      (setq result  (replace-regexp-in-string "<\\([^>]+\\)>" "\\1" result 'fixed-case)))
+    result))
+
+;; $$ Not used.
+;; (defun icicle-alist-delete-all (key alist &optional test)
+;;     "Delete from ALIST all elements whose car is the same as KEY.
+;; Optional arg TEST is the equality test to use.  If nil, `eq' is used.
+;; Return the modified alist.
+;; Elements of ALIST that are not conses are ignored."
+;;     (setq test  (or test #'eq))
+;;     (while (and (consp (car alist)) (funcall test (car (car alist)) key))
+;;       (setq alist  (cdr alist)))
+;;     (let ((tail  alist) tail-cdr)
+;;       (while (setq tail-cdr  (cdr tail))
+;;         (if (and (consp (car tail-cdr)) (funcall test (car (car tail-cdr)) key))
+;;             (setcdr tail (cdr tail-cdr))
+;;           (setq tail  tail-cdr))))
+;;     alist)
+
+;; Standard Emacs 21+ function, defined here for Emacs 20.
+(unless (fboundp 'assq-delete-all)
+  (defun assq-delete-all (key alist)
+    "Delete from ALIST all elements whose car is `eq' to KEY.
+Return the modified alist.
+Elements of ALIST that are not conses are ignored."
+    (while (and (consp (car alist)) (eq (car (car alist)) key)) (setq alist  (cdr alist)))
+    (let ((tail  alist) tail-cdr)
+      (while (setq tail-cdr  (cdr tail))
+        (if (and (consp (car tail-cdr))  (eq (car (car tail-cdr)) key))
+            (setcdr tail (cdr tail-cdr))
+          (setq tail  tail-cdr))))
+    alist))
+
+(defun icicle-first-N (n list)
+  "Return a new list of at most the N first elements of LIST."
+  (let ((firstN  ()))
+    (while (and list (> n 0))
+      (push (car list) firstN)
+      (setq n     (1- n)
+            list  (cdr list)))
+    (setq firstN (nreverse firstN))))
+
+(defun icicle-abbreviate-or-expand-file-name (filename &optional dir)
+  "Expand FILENAME, and abbreviate it if `icicle-use-~-for-home-dir-flag'.
+If FILENAME is not absolute, call `icicle-expand-file-name-20' to make
+ it absolute.  This does not collapse consecutive slashes (`/').
+If `icicle-use-~-for-home-dir-flag', call `abbreviate-file-name'.
+
+If DIR is absolute, pass it to `icicle-expand-file-name-20'.
+Otherwise, ignore it (treat it as nil)."
+  (unless (file-name-absolute-p filename)
+    (when (and dir (not (file-name-absolute-p dir))) (setq dir  nil)) ; Don't use a relative dir.
+    (setq filename (icicle-expand-file-name-20 filename dir)))
+  (if icicle-use-~-for-home-dir-flag (abbreviate-file-name filename) filename))
+
+(defun icicle-reversible-sort (list &optional key)
+  "`sort' LIST using `icicle-sort-comparer'.
+Reverse the result if `icicle-reverse-sort-p' is non-nil.
+If `icicle-sort-comparer' is a cons (other than a lambda form), then
+ use `icicle-multi-sort' as the sort predicate.
+Otherwise, use `icicle-sort-comparer' as the sort predicate.
+
+Optional arg KEY is a selector function to apply to each item to be be
+compared.  If nil, then the entire item is used."
+  ;;$$ (when (and icicle-edit-update-p icicle-completion-candidates
+  ;;              (> (length icicle-completion-candidates) icicle-incremental-completion-threshold))
+  ;;     (message "Sorting candidates..."))
+  (unless key (setq key  'identity))
+  (let ((sort-fn  (and icicle-sort-comparer
+                       (lambda (s1 s2)
+                         (when icicle-transform-before-sort-p
+                           (setq s1  (icicle-transform-multi-completion s1)
+                                 s2  (icicle-transform-multi-completion s2)))
+                         ;; If we have an inappropriate sort order, get rid of it.  This can happen if
+                         ;; the user chooses a sort appropriate to one kind of candidate and then
+                         ;; tries completion for a different kind of candidate.
+                         (condition-case nil
+                             (and icicle-sort-comparer ; nil in case of error earlier in list.
+                                  (if (and (not (functionp icicle-sort-comparer))
+                                           (consp icicle-sort-comparer))
+                                      (icicle-multi-sort (funcall key s1) (funcall key s2))
+                                    (funcall icicle-sort-comparer (funcall key s1) (funcall key s2))))
+                           (error (message "Inappropriate sort order - reverting to unsorted")
+                                  (sit-for 1)
+                                  (setq icicle-sort-comparer  nil)
+                                  nil))))))
+    (when sort-fn
+      (setq list  (sort list (if icicle-reverse-sort-p
+                                 (lambda (a b) (not (funcall sort-fn a b)))
+                               sort-fn)))))
+  list)
+
+;; Essentially the same as `bmkp-multi-sort'.
+(defun icicle-multi-sort (s1 s2)
+  "Try predicates in `icicle-sort-comparer', in order, until one decides.
+The (binary) predicates are applied to S1 and S2.
+See the description of `icicle-sort-comparer'.
+If `icicle-reverse-multi-sort-p' is non-nil, then reverse the order
+for using multi-sorting predicates."
+  (let ((preds       (car icicle-sort-comparer))
+        (final-pred  (cadr icicle-sort-comparer))
+        (result      nil))
+    (when icicle-reverse-multi-sort-p (setq preds  (reverse preds)))
+    (catch 'icicle-multi-sort
+      (dolist (pred  preds)
+        (setq result  (funcall pred s1 s2))
+        (when (consp result)
+          (when icicle-reverse-multi-sort-p (setq result  (list (not (car result)))))
+          (throw 'icicle-multi-sort (car result))))
+      (and final-pred  (if icicle-reverse-multi-sort-p
+                           (not (funcall final-pred s1 s2))
+                         (funcall final-pred s1 s2))))))
+
+(defun icicle-make-plain-predicate (pred &optional final-pred)
+  "Return a plain predicate that corresponds to component-predicate PRED.
+PRED and FINAL-PRED correspond to their namesakes in
+`icicle-sort-comparer' (which see).
+
+PRED should return `(t)', `(nil)', or nil.
+
+Optional arg FINAL-PRED is the final predicate to use if PRED cannot
+decide (returns nil).  If FINAL-PRED is nil, then `icicle-alpha-p' is
+used as the final predicate."
+  `(lambda (b1 b2)
+    (let ((res  (funcall ',pred b1 b2)))
+      (if res  (car res)  (funcall ',(or final-pred 'icicle-alpha-p) b1 b2)))))
+
+(defun icicle-alpha-p (s1 s2)
+  "True if string S1 sorts alphabetically before string S2.
+Comparison respects `case-fold-search'."
+  (when case-fold-search (setq s1  (icicle-upcase s1)
+                               s2  (icicle-upcase s2)))
+  (string-lessp s1 s2))
+
+(defun icicle-get-alist-candidate (string &optional no-error-p)
+  "Return full completion candidate that corresponds to displayed STRING.
+STRING is the name of the candidate, as shown in `*Completions*'.
+Non-nil optional argument NO-ERROR-P means display a message and
+return nil instead of raising an error if STRING is ambiguous.
+If the value of NO-ERROR-P is `no-error-no-msg', then show no message
+and just return nil.
+
+If `icicle-whole-candidate-as-text-prop-p' is non-nil, then the full
+candidate might be available as text property `icicle-whole-candidate'
+of STRING.  If so, then that is used.
+
+Otherwise, the full candidate is obtained from
+`icicle-candidates-alist'.  In this case:
+ If the user cycled among candidates or used `mouse-2', then use the
+   current candidate number, and ignore STRING.
+ Otherwise:
+   If only one candidate matches STRING, use that.
+   Else respect NO-ERROR-P and tell user to use cycling or `mouse-2'."
+  (or (and icicle-whole-candidate-as-text-prop-p
+           (get-text-property 0 'icicle-whole-candidate string))
+      (and icicle-candidates-alist
+           (let ((cand-entries  (icicle-filter-alist icicle-candidates-alist
+                                                     icicle-completion-candidates)))
+             (if (wholenump icicle-candidate-nb) ; Cycled or used `mouse-2' to choose the candidate.
+                 (elt cand-entries (mod icicle-candidate-nb (length icicle-candidates-alist)))
+               ;; If `icicle-completion-candidates' is nil, because user didn't use `TAB' or `S-TAB',
+               ;; then `icicle-candidates-alist' can contain non-matches.  So, we check for more than
+               ;; one match.  However, we cannot just use `assoc', because candidates might be
+               ;; multi-completions (lists).
+               (let ((first-match  (icicle-first-matching-candidate string icicle-candidates-alist)))
+                 (if (and first-match
+                          (not (icicle-first-matching-candidate
+                                string
+                                (setq cand-entries  (delete first-match cand-entries)))))
+                     first-match        ; Only one match, so use it.
+                   (let ((msg  "Ambiguous choice. Cycle or use `mouse-2' to choose unique matching \
+candidate."))
+                     (unless no-error-p (error msg))
+                     (unless (eq no-error-p 'no-error-no-msg) (icicle-msg-maybe-in-minibuffer msg))
+                     nil))))))))        ; Return nil for ambiguous string if NO-ERROR-P.
+
+(defun icicle-filter-alist (alist filter-keys)
+  "Filter ALIST, keeping items whose cars match FILTER-KEYS, in order.
+The original ALIST is not altered; a copy is filtered and returned.
+If FILTER-KEYS is empty, then ALIST is returned, not a copy."
+  (if filter-keys
+      (icicle-remove-if-not
+       (lambda (item)
+         (member (if (consp (car item))
+                     ;; $$$$$$  (concat (mapconcat #'identity (car item) icicle-list-join-string)
+                     ;;                 icicle-list-end-string) ; $$$$$$
+                     (mapconcat #'identity (car item) icicle-list-join-string)
+                   (car item))
+                 filter-keys))
+       alist)
+    alist))
+
+;;; $$$$$$$$$$$$$$$$$$
+;;; (defun icicle-first-matching-candidate (cand candidates)
+;;;   "Return the first element of alist CANDIDATES that matches CAND.
+;;; If CANDIDATES is a normal list of completion candidates, then this is
+;;; just `assoc'.
+;;; If CANDIDATES contains multi-completions, then matching means matching
+;;; the concatenated multi-completion parts, joined by
+;;; `icicle-list-join-string'."
+;;;   (cond ((null candidates) nil)
+;;;         ((if (consp (caar candidates))  ; Multi-completion candidate
+;;;              (save-match-data
+;;;                (string-match cand (mapconcat #'identity (caar candidates)
+;;;                                              icicle-list-join-string)))
+;;;            (equal cand (caar candidates))) ; This case is just `assoc'.
+;;;          (car candidates))
+;;;         (t (icicle-first-matching-candidate cand (cdr candidates)))))
+
+(defun icicle-first-matching-candidate (cand candidates)
+  "Return the first element of alist CANDIDATES that matches CAND.
+Return nil if there is no such element.
+If CANDIDATES is a normal list of completion candidates, then this is
+just `assoc'.
+If CANDIDATES contains multi-completions, then matching means matching
+the concatenated multi-completion parts, joined by
+`icicle-list-join-string'."
+  (let ((res  nil))
+    (if (null candidates)
+        (setq res  nil)
+      (while (and candidates (not res))
+        (when (or (and (consp (caar candidates)) ; Multi-completion candidate
+                       (save-match-data
+                         (string-match (regexp-quote cand)
+                                       ;; $$$$$$ (concat (mapconcat #'identity (caar candidates)
+                                       ;;                           icicle-list-join-string)
+                                       ;;                icicle-list-end-string) ; $$$$$$
+                                       (mapconcat #'identity (caar candidates)
+                                                  icicle-list-join-string))))
+                  (equal cand (caar candidates)))
+          (setq res  (car candidates)))
+        (setq candidates  (cdr candidates))))
+    res))
+
+(defun icicle-completing-p ()
+  "Non-nil if reading minibuffer input with completion.
+This caches the value returned in variable `icicle-completing-p'.
+Use the function, not the variable, to test, if not sure to be in the
+minibuffer."
+  (setq icicle-completing-p             ; Cache the value.
+        (and (active-minibuffer-window)
+             ;; $$$ (where-is-internal 'icicle-candidate-action nil 'first-only)
+             (let* ((loc-map  (current-local-map))
+                    (parent   (keymap-parent loc-map))
+                    (maps     (cond ((boundp 'minibuffer-local-filename-must-match-map)
+                                     (list minibuffer-local-completion-map
+                                           minibuffer-local-must-match-map
+                                           minibuffer-local-filename-completion-map
+                                           minibuffer-local-filename-must-match-map))
+                                    ((boundp 'minibuffer-local-must-match-filename-map)
+                                     (list minibuffer-local-completion-map
+                                           minibuffer-local-must-match-map
+                                           minibuffer-local-filename-completion-map
+                                           minibuffer-local-must-match-filename-map))
+                                    ((boundp 'minibuffer-local-filename-completion-map)
+                                     (list minibuffer-local-completion-map
+                                           minibuffer-local-must-match-map
+                                           minibuffer-local-filename-completion-map))
+                                    (t
+                                     (list minibuffer-local-completion-map
+                                           minibuffer-local-must-match-map)))))
+               (and (or (and parent (member parent maps)) (member loc-map maps))
+                    t)))))              ; Cache t, not the keymap portion.
+
+;; This is just `substring-no-properties', defined also for Emacs < 22.
+(defun icicle-substring-no-properties (string &optional from to)
+  "Return a substring of STRING, without text properties.
+It starts at index FROM and ending before TO.
+TO may be nil or omitted; then the substring runs to the end of STRING.
+If FROM is nil or omitted, the substring starts at the beginning of STRING.
+If FROM or TO is negative, it counts from the end.
+
+With one argument, just copy STRING without its properties."
+  (if (fboundp 'substring-no-properties)
+      (substring-no-properties string from to) ; Emacs 22.
+    (let ((substrg  (copy-sequence (substring string (or from 0) to))))
+      (set-text-properties 0 (length substrg) nil substrg)
+      substrg)))
+
+(defun icicle-highlight-lighter ()
+  "Highlight `Icy' mode-line indicator of Icicle mode.
+Highlighting indicates the current completion status."
+  (when icicle-highlight-lighter-flag
+    (let ((strg
+           ;; Don't bother with buffer completion and `read-buffer-completion-ignore-case'.
+           (if (if (and (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+                        (boundp 'read-file-name-completion-ignore-case))
+                   read-file-name-completion-ignore-case
+                 completion-ignore-case)
+               " ICY"
+             " Icy"))
+          (face  (cond ((and icicle-candidate-action-fn (icicle-require-match-p))
+                        '(icicle-multi-command-completion icicle-mustmatch-completion))
+                       (icicle-candidate-action-fn 'icicle-multi-command-completion)
+                       ((icicle-require-match-p)
+                        '(icicle-completion icicle-mustmatch-completion))
+                       (t 'icicle-completion))))
+      (when icicle-candidate-action-fn (setq strg  (concat strg "+")))
+      (put-text-property 0 (length strg) 'face face strg)
+      (icicle-clear-lighter)
+      (add-to-list 'minor-mode-alist `(icicle-mode ,strg)))
+    (condition-case nil
+        (if (fboundp 'redisplay) (redisplay t) (force-mode-line-update t))
+      (error nil))))                    ; Ignore errors from, e.g., killed buffers.
+
+(defun icicle-unhighlight-lighter ()
+  "Unhighlight `Icy' mode-line indicator of Icicle mode."
+  (when icicle-highlight-lighter-flag
+    (let ((strg  (if case-fold-search  " ICY"  " Icy")))
+      (icicle-clear-lighter)
+      (add-to-list 'minor-mode-alist `(icicle-mode ,strg)))
+    (condition-case nil
+        (if (fboundp 'redisplay) (redisplay t) (force-mode-line-update t))
+      (error nil))))                    ; Ignore errors from, e.g., killed buffers.
+
+(defun icicle-clear-lighter (&optional only)
+  "Remove Icicle mode lighter from `minor-mode-alist'."
+  (unless (eq only 'truncated)
+    (setq minor-mode-alist  (delete '(icicle-mode " Icy")  minor-mode-alist)
+          minor-mode-alist  (delete '(icicle-mode " Icy+") minor-mode-alist)
+          minor-mode-alist  (delete '(icicle-mode " ICY")  minor-mode-alist)
+          minor-mode-alist  (delete '(icicle-mode " ICY+") minor-mode-alist)))
+  (unless (eq only 'not-truncated)
+    (setq minor-mode-alist  (delete `(icicle-mode ,(concat " Icy" icicle-lighter-truncation))
+                                    minor-mode-alist)
+          minor-mode-alist  (delete `(icicle-mode ,(concat " Icy+" icicle-lighter-truncation))
+                                    minor-mode-alist)
+          minor-mode-alist  (delete `(icicle-mode ,(concat " ICY" icicle-lighter-truncation))
+                                    minor-mode-alist)
+          minor-mode-alist  (delete `(icicle-mode ,(concat " ICY+" icicle-lighter-truncation))
+                                    minor-mode-alist))))
+
+(defun icicle-ding ()
+  "Same as `ding', but respects `icicle-inhibit-ding-flag'."
+  (unless icicle-inhibit-ding-flag (ding)))
+
+(defun icicle-kill-a-buffer (buf &optional nomsg)
+  "Kill buffer BUF.
+Optional arg NOMSG non-nil means don't display an error message."
+  (save-selected-window
+    (setq buf  (get-buffer buf))
+    (if buf
+        (icicle-condition-case-no-debug err
+            (if (not (buffer-live-p buf))
+                (unless nomsg (message "Buffer already deleted: `%s'" buf))
+              (let ((enable-recursive-minibuffers  t)) ; In case called from minibuffer, and modified.
+                (if (fboundp 'kill-buffer-and-its-windows)
+                    (kill-buffer-and-its-windows buf) ; Defined in `misc-cmds.el'.
+                  (kill-buffer buf))))
+          (error nil))
+      (unless nomsg (message "No such live buffer: `%s'" buf)))))
+
+(defun icicle-unpropertize (string)
+  "Remove text properties from STRING.
+If STRING is not a string, just return it (raise no error).
+If `icicle-remove-icicles-props-p' is nil, just return STRING.  This
+ is the case for some Icicles functions that need to further process
+ the completion result.
+Otherwise, if option `icicle-unpropertize-completion-result-flag' is
+ non-nil, then remove all text properties.
+Otherwise remove only Icicles internal text properties:
+ 1. any text properties in `icicle-candidate-properties-alist'.
+ 2. The following internal text properties added by Icicles:
+    `display', `help-echo', `icicle-fancy-candidates',
+    `icicle-keep-newline', `icicle-mode-line-help',
+    `icicle-special-candidate', `icicle-user-plain-dot',
+    `icicle-whole-candidate', `invisible'.
+    \(Property `mouse-face' is removed by `choose-completion-string'.\)"
+  (when (and (stringp string) icicle-remove-icicles-props-p) ; Do nothing if we're inhibiting removal.
+    (let ((len  (length string)))
+      (if icicle-unpropertize-completion-result-flag
+          (set-text-properties 0 len nil string)
+        (remove-text-properties
+         0 len '(display nil  help-echo nil  icicle-fancy-candidates nil  icicle-keep-newline nil
+                 icicle-mode-line-help nil  icicle-special-candidate nil  icicle-user-plain-dot nil
+                 icicle-whole-candidate nil  invisible nil)
+         string)
+        (dolist (entry  icicle-candidate-properties-alist)
+          (put-text-property 0 len (car (cadr entry)) nil string)))))
+  string)
+
+(defun icicle-isearch-complete-past-string ()
+  "Set `isearch-string' to a past search string chosen by completion."
+  (isearch-done 'nopush)
+  (let ((icicle-whole-candidate-as-text-prop-p  nil)
+        (completion-ignore-case                 case-fold-search)
+        (enable-recursive-minibuffers           t))
+    (setq isearch-string
+          (completing-read
+           "Search string (completing): "
+           (mapcar #'list (icicle-remove-duplicates (symbol-value (if isearch-regexp
+                                                                      'regexp-search-ring
+                                                                    'search-ring))))
+           nil nil isearch-string (if isearch-regexp 'regexp-search-ring 'search-ring)))))
+
+;; $$$$$$ Filed Emacs BUG #8795.  They added a non-optional arg, METADATA (with no doc).
+;;
+(defun icicle-completion-all-completions (string table pred point &optional metadata)
+  "Icicles version of `completion-all-completions'.
+1. Handle all Emacs versions.
+2. Append `$' to each candidate, if current input ends in `$'.
+3. Remove the last cdr, which might hold the base size.
+4. METADATA is optional and defaults to `completion--field-metadata'
+   at `field-beginning'."
+  (let* ((mdata  (and (fboundp 'completion--field-metadata)
+                      (or metadata  (completion--field-metadata (field-beginning)))))
+         ;; $$$$$$$$ UNLESS BUG #8795 is fixed, need METADATA even if nil.
+         (res    (if (fboundp 'completion--field-metadata) ; Emacs 24 added a 5th arg, METADATA.
+                     (completion-all-completions string table pred point mdata)
+                   (completion-all-completions string table pred point))))
+    (when (consp res)  (let ((last  (last res)))  (when last (setcdr last nil))))
+    (let* ((input-sans-dir  (icicle-minibuf-input-sans-dir icicle-current-input))
+           (env-var-p       (and (icicle-not-basic-prefix-completion-p)
+                                 (> (length input-sans-dir) 0)
+                                 (eq ?\$ (aref input-sans-dir 0)))))
+      (when env-var-p (setq res  (mapcar #'(lambda (cand) (concat "$" cand)) res))))
+    res))
+
+;; $$$$$$ Filed Emacs BUG #4708.  `completion-try-completion' does not return nil when it should.
+;; E.g. (completion-try-completion "c:/some-dir/$HOMj" nil 17) returns: ("c:/some-dir/$$HOMj" . 18)
+;;
+;; This causes `icicle-highlight-input-noncompletion' not to highlight the `j' in the above example.
+;;
+;; $$$$$$ Filed Emacs BUG #8795.  They added a non-optional arg, METADATA (with no doc).
+;;
+(defun icicle-completion-try-completion (string table pred point &optional metadata)
+  "Icicles version of `completion-try-completion'.
+1. Handle all Emacs versions.
+2. Remove the last cdr, which might hold the base size.
+3. METADATA is optional and defaults to `completion--field-metadata'
+   at `field-beginning'."
+  (let* ((mdata  (and (fboundp 'completion--field-metadata)
+                      (or metadata  (completion--field-metadata (field-beginning)))))
+         ;; $$$$$$$$ UNLESS BUG #8795 is fixed, still need METADATA, even if nil.
+         (res    (if (fboundp 'completion--field-metadata) ; Emacs 24 added a 5th arg, METADATA.
+                     (completion-try-completion string table pred point mdata)
+                   (completion-try-completion string table pred point))))
+    (when (consp res) (setq res (car res)))
+    res))
+
+(defun icicle-require-match-p ()
+  "Return non-nil if completion is strict.
+Return non-nil if current REQUIRE-MATCH arg to `completing-read' or
+`read-file-name' really means require match (sheesh!)."
+  (if (> emacs-major-version 22)  (eq t icicle-require-match-p)  icicle-require-match-p))
+
+(defun icicle-candidate-short-help (help string)
+  "Put string of text HELP on STRING as text properties.
+Put `help-echo' property if `tooltip-mode' is non-nil.
+Put `icicle-mode-line-help' property (on the first character only) if
+ `icicle-help-in-mode-line-delay' is positive.
+Return STRING, whether propertized or not."
+  (unless (equal "" string)
+    (when (> icicle-help-in-mode-line-delay 0)
+      (put-text-property 0 1 'icicle-mode-line-help help string))
+    (when (and (boundp 'tooltip-mode) tooltip-mode)
+      (put-text-property 0 (length string) 'help-echo help string)))
+  string)
+
+;; This is not used by Icicles, since the color functions require `hexrgb.el'.
+(defun icicle-remove-color-duplicates (list)
+  "Copy of LIST with duplicate color candidates removed.
+Candidates are considered duplicates if they have the same color name,
+abstracting from whitespace and letter case."
+  (let ((tail  list)
+        new)
+    (save-match-data (while tail
+                       (let* ((this            (car tail))
+                              (pseudo-color-p  (string-match "^\*" this)))
+                         (string-match ": " this)
+                         (unless pseudo-color-p
+                           (setq this  (icicle-delete-whitespace-from-string
+                                        (downcase this) 0 (match-beginning 0))))
+                         (unless (member this new) (push this new)))
+                       (pop tail)))
+    (nreverse new)))
+
+;;;###autoload
+(defmacro icicle-maybe-cached-action (action)
+  "Evaluate and return ACTION or `icicle-all-candidates-action'.
+If `icicle-all-candidates-action' is nil, use ACTION.
+If it is t, then set it to the value of ACTION, so the next call
+ returns the same value."
+  `(if icicle-all-candidates-action
+    (if (eq icicle-all-candidates-action t)
+        (setq icicle-all-candidates-action  ,action)
+      icicle-all-candidates-action)
+    ,action))
+
+(defun icicle-alt-act-fn-for-type (type)
+  "Returns an action function chosen by user for type TYPE (a string).
+Typical use: Bind `icicle-candidate-alt-action-fn' and 
+`icicle-all-candidates-list-alt-action-fn' to the return value.
+However, you must first bind `icicle-orig-window' to the window that
+is current before user input is read from the minibuffer."
+  (lexical-let ((type  type))           ; Does this binding really help?
+    `(lambda (cands)
+      (unless (listp cands) (setq cands (list cands))) ; So it works for both single and all cands.
+      (let* ((enable-recursive-minibuffers     t)
+             (anything-actions                 (and (> emacs-major-version 21)
+                                                    icicle-use-anything-candidates-flag
+                                                    (require 'anything nil t)
+                                                    (icicle-get-anything-actions-for-type
+                                                     (intern ,type))))
+             (actions                   ; Must sort, for `icicle-candidates-alist',
+              (sort                     ; or else `icicle-candidate-nb' will be wrong.
+               (append anything-actions
+                       (mapcar (lambda (act) (cons (format "%s" act) act))
+                               (icicle-remove-if-not #'functionp
+                                                     (cdr (assoc ,type icicle-type-actions-alist)))))
+               (lambda (a1 a2) (funcall 'string-lessp (car a1) (car a2)))))
+             (icicle-sort-comparer             'string-lessp) ; Must be the same order as actions.
+             (icicle-candidate-action-fn ; For "how".
+              (lambda (fn)
+                (let ((icicle-candidate-alt-action-fn  (icicle-alt-act-fn-for-type "function"))
+                      icicle-saved-completion-candidate)
+                  (icicle-with-selected-window
+                   (if (and (boundp 'icicle-orig-window) (window-live-p icicle-orig-window))
+                       icicle-orig-window
+                     (selected-window)) ; Punt wo `icicle-orig-window'.
+                   (dolist (cand  cands)
+                     (setq icicle-saved-completion-candidate  cand)
+                     (icicle-apply-to-saved-candidate fn t ,type))))))
+             ;; Save & restore these, so `icomplete-exhibit' on `post-command-hook' has no error.
+             (minibuffer-completion-table      minibuffer-completion-table)
+             (minibuffer-completion-predicate  minibuffer-completion-predicate))
+
+        (setq cands  (mapcar (lambda (obj)
+                               (setq obj  (icicle-transform-multi-completion obj))
+                               (cond ((not (stringp obj))  obj)
+                                     ((memq (intern ,type)
+                                            '(command face function option symbol variable))
+                                      (intern obj))
+                                     ((and (eq (intern ,type) 'frame) (fboundp 'get-a-frame))
+                                      (get-a-frame obj))
+                                     (t  obj)))
+                             cands))
+        (setq icicle-candidates-alist  actions)
+        (let (icicle-saved-completion-candidate)
+          (cond ((null actions)
+                 ;; Undefined TYPE - provide all Emacs `functionp' symbol names as candidates.
+                 (let* ((icicle-must-pass-after-match-predicate  #'(lambda (s) (functionp (intern s))))
+                        (action                                  (icicle-maybe-cached-action
+                                                                  (completing-read "How (action): "
+                                                                                   obarray))))
+                   (dolist (cand  cands)
+                     (setq icicle-saved-completion-candidate  cand)
+                     (icicle-apply-to-saved-candidate action))))
+                ((null (cdr actions))
+                 (dolist (cand  cands)  (funcall (icicle-maybe-cached-action (cdar actions)) cand)))
+                (t
+                 (let* ((icicle-show-Completions-initially-flag  t)
+                        (action                                  (icicle-maybe-cached-action
+                                                                  (completing-read "How (action): "
+                                                                                   actions))))
+                   (icicle-with-selected-window
+                    (if (and (boundp 'icicle-orig-window) (window-live-p icicle-orig-window))
+                        icicle-orig-window
+                      (selected-window)) ; Punt: no `icicle-orig-window'.
+                    (let ((icicle-candidate-alt-action-fn  (icicle-alt-act-fn-for-type "function")))
+                      (dolist (cand  cands)
+                        (setq icicle-saved-completion-candidate  cand)
+                        (icicle-apply-to-saved-candidate action t ,type))))))))))))
+
+(defun icicle-toggle-icicle-mode-twice ()
+  "Toggle Icicle mode twice.  Load `icicles-mode.el' if not loaded."
+  ;; Just a convenience function, to avoid Emacs warning about calling `icy-mode' with no arg.
+  (require 'icicles-mode)
+  (let ((curr  (if (and (boundp 'icicle-mode) icicle-mode) 1 -1)))
+    (icy-mode (- curr))  (icy-mode curr)))
+
+(defun icicle-current-TAB-method ()
+  "Current completion method for \
+`\\\\[icicle-prefix-complete]'.
+This resets variable `icicle-current-TAB-method' when needed."
+  (or (car (memq icicle-current-TAB-method icicle-TAB-completion-methods))
+      (car icicle-TAB-completion-methods)))
+
+(defun icicle-not-basic-prefix-completion-p ()
+  "`icicle-current-TAB-method' is `vanilla', and Emacs > release 22."
+  (and (eq 'vanilla (icicle-current-TAB-method)) (boundp 'completion-styles)))
+
+(defun icicle-all-completions (string collection &optional predicate hide-spaces)
+  "Version of vanilla `all-completions' that works for all Emacs releases.
+Starting with Emacs23.2, `all-completions' no longer accepts a fourth
+argument, so we drop that arg in that case."
+  (condition-case nil                   ; Emacs 23.2+ has no 4th parameter.
+      (all-completions string collection predicate hide-spaces)
+    (wrong-number-of-arguments (all-completions string collection predicate))))
+ 
+;;(@* "Icicles functions - sort functions")
+
+;;; Icicles functions - sort functions -------------------------------
+
+(defun icicle-merge-saved-order-less-p (s1 s2)
+  "String S1 has a lower index than S2 in current and saved candidates list."
+  (let ((cs1  (icicle-position s1 icicle-completion-candidates))
+        (cs2  (icicle-position s2 icicle-completion-candidates))
+        (ss1  (icicle-position s1 icicle-saved-completion-candidates))
+        (ss2  (icicle-position s2 icicle-saved-completion-candidates))
+        len)
+    (unless cs1 (error "`%s' is not currently a candidate" s1))
+    (unless cs2 (error "`%s' is not currently a candidate" s2))
+    (unless ss1 (setq ss1  (setq len  (length icicle-saved-completion-candidates))))
+    (unless ss2 (setq ss2  (or len (length icicle-saved-completion-candidates))))
+    (< (+ cs1 ss1) (+ cs2 ss2))))
+
+(defun icicle-historical-alphabetic-p (s1 s2)
+  "Non-nil means S1 is a past input and S2 is not or S1 < S2 (alphabet).
+Return non-nil if S1 is a previous input and either S2 is not or
+S1 `icicle-case-string-less-p' S2.  S1 and S2 must be strings.
+
+When used as a comparison function for completion candidates, this
+makes candidates matching previous inputs available first (at the top
+of buffer `*Completions*').  Candidates are effectively in two groups,
+each of which is sorted alphabetically separately: matching previous
+inputs, followed by matching candidates that have not yet been used."
+  ;; We could use `icicle-delete-duplicates' to shorten the history, but that takes time too.
+  ;; And, starting in Emacs 22, histories will not contain duplicates anyway.
+  (let ((hist  (and (symbolp minibuffer-history-variable) (boundp minibuffer-history-variable)
+                    (symbol-value minibuffer-history-variable)))
+        (dir   (and (icicle-file-name-input-p)
+                    (icicle-file-name-directory-w-default (or icicle-last-input
+                                                              icicle-current-input)))))
+    (if (not (consp hist))
+        (icicle-case-string-less-p s1 s2)
+      (when dir (setq s1  (expand-file-name s1 dir)
+                      s2  (expand-file-name s2 dir)))
+      (let ((s1-previous-p  (member s1 hist))
+            (s2-previous-p  (member s2 hist)))
+        (or (and (not s1-previous-p) (not s2-previous-p) (icicle-case-string-less-p s1 s2))
+            (and s1-previous-p (not s2-previous-p))
+            (and s1-previous-p s2-previous-p (icicle-case-string-less-p s1 s2)))))))
+
+;; $$ Alternative definition, but it doesn't seem any faster, and is slightly less clear.
+;; (defun icicle-most-recent-first-p (s1 s2)
+;;   "Non-nil means S1 was used more recently than S2.
+;; Also:
+;;  S1 < S2 if S1 was used previously but S2 was not.
+;;  S1 < S2 if neither was used previously
+;;   and S1 `icicle-case-string-less-p' S2."
+;;   ;; We could use `icicle-delete-duplicates' to shorten the history, but that takes time too.
+;;   ;; And, starting in Emacs 22, histories will not contain duplicates anyway.
+;;   (let ((hist  (and (symbolp minibuffer-history-variable)
+;;                     (symbol-value minibuffer-history-variable)))
+;;         (dir   (and (icicle-file-name-input-p)
+;;                     (icicle-file-name-directory-w-default
+;;                      (or icicle-last-input icicle-current-input))))
+;;         (s1-in-hist nil)
+;;         (s2-in-hist nil))
+;;     (if (not (consp hist))
+;;         (icicle-case-string-less-p s1 s2)
+;;       (when dir (setq s1  (expand-file-name s1 dir)  s2  (expand-file-name s2 dir)))
+;;       (while (and hist (not (setq s1-in-hist  (equal s1 (car hist)))))
+;;         (when (setq s2-in-hist  (equal s2 (car hist))) (setq hist  nil))
+;;         (setq hist  (cdr hist)))
+;;       (or (and hist s1-in-hist) (and (not s2-in-hist) (icicle-case-string-less-p s1 s2))))))
+
+(defun icicle-most-recent-first-p (s1 s2)
+  "Non-nil means S1 was used more recently than S2.
+Also:
+ S1 < S2 if S1 was used previously but S2 was not.
+ S1 < S2 if neither was used previously
+  and S1 `icicle-case-string-less-p' S2."
+  ;; We could use `icicle-delete-duplicates' to shorten the history, but that takes time too.
+  ;; And, starting in Emacs 22, histories do not contain duplicates anyway.
+  (let ((hist     (and (symbolp minibuffer-history-variable) (boundp minibuffer-history-variable)
+                       (symbol-value minibuffer-history-variable)))
+        (dir      (and (icicle-file-name-input-p)
+                       (icicle-file-name-directory-w-default (or icicle-last-input
+                                                                 icicle-current-input))))
+        (s1-tail  ())
+        (s2-tail  ()))
+    (if (not (consp hist))
+        (icicle-case-string-less-p s1 s2)
+      (when dir (setq s1  (expand-file-name s1 dir)
+                      s2  (expand-file-name s2 dir)))
+      (setq s1-tail  (member s1 hist)
+            s2-tail  (member s2 hist))
+      (cond ((and s1-tail s2-tail)  (>= (length s1-tail) (length s2-tail)))
+            (s1-tail                t)
+            (s2-tail                nil)
+            (t                      (icicle-case-string-less-p s1 s2))))))
+
+
+(put 'icicle-buffer-smaller-p 'icicle-buffer-sort-predicate t)
+;; This predicate is used for buffer-name completion.
+(defun icicle-buffer-smaller-p (b1 b2)
+  "Non-nil means buffer named B1 is smaller than buffer named B2."
+  (< (with-current-buffer b1 (buffer-size)) (with-current-buffer b2 (buffer-size))))
+
+
+(put 'icicle-major-mode-name-less-p 'icicle-buffer-sort-predicate t)
+;; This predicate is used for buffer-name completion.
+(defun icicle-major-mode-name-less-p (b1 b2)
+  "Non-nil means major mode name of buffer B1 is `string-less-p' that of B2.
+If those names are identical, then buffer names are compared.
+Comparison is not case-sensitive."
+  (let ((bm1  (icicle-upcase (symbol-name (with-current-buffer b1 major-mode))))
+        (bm2  (icicle-upcase (symbol-name (with-current-buffer b2 major-mode)))))
+    (if (string= bm1 bm2)  (string-lessp b1 b2)  (string-lessp bm1 bm2))))
+
+
+(when (fboundp 'format-mode-line)       ; Emacs 22+
+  (put 'icicle-mode-line-name-less-p 'icicle-buffer-sort-predicate t)
+  ;; This predicate is used for buffer-name completion.
+  (defun icicle-mode-line-name-less-p (b1 b2)
+    "Non-nil means buffer B1 mode in mode line is `string-less-p' that of B2.
+If those names are identical, then buffer names are compared.
+Comparison is not case-sensitive."
+    (let ((bm1  (icicle-upcase (with-current-buffer b1 (format-mode-line mode-name))))
+          (bm2  (icicle-upcase (with-current-buffer b2 (format-mode-line mode-name)))))
+      (if (string= bm1 bm2)  (string-lessp b1 b2)  (string-lessp bm1 bm2)))))
+
+
+(put 'icicle-buffer-file/process-name-less-p 'icicle-buffer-sort-predicate t)
+;; This predicate is used for buffer-name completion.
+(defun icicle-buffer-file/process-name-less-p (b1 b2)
+  "Non-nil means file/process name of buffer B1 is `string-less-p' that of B2.
+The absolute file name of a buffer is used, not the relative name.
+Comparison is case-insensitive on systems where file-name case is
+ insignificant.
+
+Buffers not associated with files or processes are sorted last."
+  (setq b1  (get-buffer b1)
+        b2  (get-buffer b2))
+  (let ((fp-b1  (or (buffer-file-name b1) (let ((pb1  (get-buffer-process b1)))
+                                            (and (processp pb1) (process-name pb1)))))
+        (fp-b2  (or (buffer-file-name b2) (let ((pb2  (get-buffer-process b2)))
+                                            (and (processp pb2) (process-name pb2))))))
+    (and fp-b1 (or (not fp-b2)
+                   (if (memq system-type '(ms-dos windows-nt cygwin))
+                       (string-lessp (icicle-upcase fp-b1) (icicle-upcase fp-b2))
+                     (string-lessp fp-b1 fp-b2))))))
+
+
+(put 'icicle-file-type-less-p 'icicle-file-name-sort-predicate t)
+;; This predicate is used for file-name completion.
+(defun icicle-file-type-less-p (s1 s2)
+  "Non-nil means type of file S1 is less than that of S2, or S1 < S2 (alpha).
+A directory has a lower file type than a non-directory.
+The type of a non-directory is its extension.  Extensions are compared
+ alphabetically.
+If not doing file-name completion, then this is the same as
+`icicle-case-string-less-p'."
+  (if (icicle-file-name-input-p)
+      (let ((s1-dir-p  (icicle-file-directory-p s1))
+            (s2-dir-p  (icicle-file-directory-p s2)))
+        (cond ((and s1-dir-p s2-dir-p) (icicle-case-string-less-p s1 s2)) ; Both are dirs, so alpha.
+              ((not (or s1-dir-p s2-dir-p)) ; Neither is a dir.  Compare extensions.
+               (let ((es1  (file-name-extension s1 t))
+                     (es2  (file-name-extension s2 t)))
+                 (if (string= es1 es2)  ; If extensions the same, then compare file names.
+                     (icicle-case-string-less-p s1 s2)
+                   (icicle-case-string-less-p es1 es2))))
+              (s1-dir-p)))              ; Directories come before files.
+    (icicle-case-string-less-p s1 s2)))
+
+
+(put 'icicle-dirs-first-p 'icicle-file-name-sort-predicate t)
+;; This predicate is used for file-name completion.
+(defun icicle-dirs-first-p (s1 s2)
+  "Non-nil means S1 is a dir and S2 a file, or S1 < S2 (alphabet).
+If not doing file-name completion, then this is the same as
+`icicle-case-string-less-p'."
+  (if (icicle-file-name-input-p)
+      (let ((s1-dir-p  (icicle-file-directory-p s1))
+            (s2-dir-p  (icicle-file-directory-p s2)))
+        (if (or (and s1-dir-p s2-dir-p) ; Both or neither are directories.
+                (not (or s1-dir-p s2-dir-p)))
+            (icicle-case-string-less-p s1 s2)  ; Compare equals.
+          s1-dir-p))                 ; Directories come before files.
+    (icicle-case-string-less-p s1 s2)))
+
+
+(put 'icicle-dirs-last-p 'icicle-file-name-sort-predicate t)
+;; This predicate is used for file-name completion.
+(defun icicle-dirs-last-p (s1 s2)
+  "Non-nil means S1 is a file and S2 a dir, or S1 < S2 (alphabet).
+This is especially useful when `icicle-cycle-into-subdirs-flag' is
+non-nil.  Otherwise, cycling into subdirectories is depth-first, not
+breadth-first.
+If not doing file-name completion, then this is the same as
+`icicle-case-string-less-p'."
+  (if (icicle-file-name-input-p)
+      (let ((s1-dir-p  (icicle-file-directory-p s1))
+            (s2-dir-p  (icicle-file-directory-p s2)))
+        (if (or (and s1-dir-p s2-dir-p) ; Both or neither are directories.
+                (not (or s1-dir-p s2-dir-p)))
+            (icicle-case-string-less-p s1 s2)  ; Compare equals.
+          s2-dir-p))                 ; Files come before directories.
+    (icicle-case-string-less-p s1 s2)))
+
+
+(put 'icicle-2nd-part-string-less-p 'icicle-multi-completion-sort-predicate t)
+;; This predicate is used for multi-completion.
+(defun icicle-2nd-part-string-less-p (s1 s2)
+  "`icicle-case-string-less-p' for second parts, then for first parts.
+S1 and S2 are multi-completion strings.
+Returns non-nil if either of these is true:
+
+* The second parts of S1 and S2 are the equivalent and the first part
+  of S1 comes before the first part of S2, alphabetically.
+
+* The second part of S1 comes before the second part of S2,
+  alphabetically.
+
+Alphabetical comparison is done using `icicle-case-string-less-p'."
+  (let* ((icicle-list-use-nth-parts  '(2))
+         (s1-2nd                     (icicle-transform-multi-completion s1))
+         (s2-2nd                     (icicle-transform-multi-completion s2)))
+    (or (icicle-case-string-less-p s1-2nd s2-2nd)
+        (and (string= s1-2nd s2-2nd)
+             (let* ((icicle-list-use-nth-parts  '(1))
+                    (s1-1st                     (icicle-transform-multi-completion s1))
+                    (s2-1st                     (icicle-transform-multi-completion s2))))))))
+
+
+(put 'icicle-last-modified-first-p 'icicle-file-name-sort-predicate t)
+;; This predicate is used for file-name completion.
+(defun icicle-last-modified-first-p (s1 s2)
+  "Non-nil means file S1 was last modified after S2.
+If not doing file-name completion, then this is the same as
+`icicle-case-string-less-p'."
+  (if (icicle-file-name-input-p)
+      (let ((mod-date1  (nth 5 (file-attributes s1)))
+            (mod-date2  (nth 5 (file-attributes s2))))
+        (or (< (car mod-date2)  (car mod-date1)) ; High-order bits.
+            (and (= (car mod-date2) (car mod-date1)) ; Low-order bits.
+                 (< (cadr mod-date2) (cadr mod-date1)))))
+    (icicle-case-string-less-p s1 s2)))
+
+
+(put 'icicle-command-abbrev-used-more-p 'icicle-command-sort-predicate t)
+;; This predicate is used for command and abbreviation completion.
+(defun icicle-command-abbrev-used-more-p (s1 s2)
+  "Return non-nil if S1 was invoked more often than S2 via an abbrev.
+S1 and S2 are strings naming commands.
+If neither was invoked or both were invoked the same number of times,
+then return non-nil if S1 is `string-lessp' S2."
+  (let* ((alist-tails  (mapcar #'cdr icicle-command-abbrev-alist))
+         (s1-entry     (assq (intern s1) alist-tails))
+         (s2-entry     (assq (intern s2) alist-tails)))
+    (if (and (not s1-entry) (not s2-entry))
+        (string-lessp s1 s2)
+      (let ((s1-rank  (elt s1-entry 1))
+            (s2-rank  (elt s2-entry 1)))
+        (cond ((and (not s1-rank) (not s2-rank))           (string-lessp s1 s2))
+              ((and s1-rank s2-rank (eq s1-rank s2-rank))  (string-lessp s1 s2))
+              (t                                           (>= (or s1-rank 0) (or s2-rank 0))))))))
+
+(defun icicle-part-N-lessp (n s1 s2)
+  "`icicle-case-string-less-p' applied to the Nth parts of S1 and S2.
+The strings each have at least N parts, separated by
+`icicle-list-join-string'.  Parts other than the Nth are ignored.
+Return non-nil if and only if the Nth part of S1 is less than the Nth
+part of S2.  The Nth parts are compared lexicographically without
+regard to letter case.  N is one-based, so a value of 1 means compare
+the first parts."
+  (unless (and (wholenump n) (> n 0)) (error "`icicle-part-N-lessp': N must be > 0"))
+  (let ((case-fold-search  t)
+        (part-N-s1         (elt (split-string s1 icicle-list-join-string) (1- n)))
+        (part-N-s2         (elt (split-string s2 icicle-list-join-string) (1- n))))
+    (and part-N-s1 part-N-s2            ; In case strings were not multipart.
+         (icicle-case-string-less-p part-N-s1 part-N-s2))))
+
+(defun icicle-part-1-lessp (s1 s2)
+  "`icicle-part-N-lessp', with N = 1."
+  (icicle-part-N-lessp 1 s1 s2))
+
+(defun icicle-part-2-lessp (s1 s2)
+  "`icicle-part-N-lessp', with N = 2."
+  (icicle-part-N-lessp 2 s1 s2))
+
+(defun icicle-part-3-lessp (s1 s2)
+  "`icicle-part-N-lessp', with N = 3."
+  (icicle-part-N-lessp 3 s1 s2))
+
+(defun icicle-part-4-lessp (s1 s2)
+  "`icicle-part-N-lessp', with N = 4."
+  (icicle-part-N-lessp 4 s1 s2))
+
+(defun icicle-cdr-lessp (s1 s2)
+  "Non-nil means the cdr of S1's entry < the cdr of S2's entry.
+Entry here means the complete alist element candidate that corresponds
+to the displayed candidate (string) S1 or S2.
+Returns nil if comparing the cdrs using `<' would raise an error."
+  (condition-case nil
+      (< (cdr (funcall icicle-get-alist-candidate-function s1))
+         (cdr (funcall icicle-get-alist-candidate-function s2)))
+    (error nil)))
+
+(defun icicle-part-1-cdr-lessp (s1 s2)
+  "First part and cdr of S1 are less than those of S2."
+  (or (icicle-part-1-lessp s1 s2)
+      (and (not (icicle-part-1-lessp s2 s1))  (icicle-cdr-lessp s1 s2))))
+
+
+;; This predicate is used for color completion.
+(defun icicle-color-rgb-lessp (s1 s2)
+  "Non-nil means the RGB components of S1 are less than those of S2.
+Specifically, the red components are compared first, then if they are
+equal the blue components are compared, then if those are also equal
+the green components are compared.
+
+The strings are assumed to have at least two parts, with the parts
+separated by `icicle-list-join-string' The second parts of the strings
+are RGB triplets that start with `#'."
+  (icicle-part-2-lessp s1 s2))          ; Just compare lexicographically.
+
+;; This predicate is used for key completion.
+(defun icicle-prefix-keys-first-p (s1 s2)
+  "Non-nil if S1 is a prefix key and S2 is not or S1 < S2 (alphabet).
+For this function, a prefix key is represented by a string that ends
+in \"...\".
+
+When used as a comparison function for completion candidates, this
+makes prefix keys that match your input available first (at the top of
+buffer `*Completions*').  Candidates are effectively in two groups,
+each of which is sorted alphabetically separately: prefix keys,
+followed by non-prefix keys.  Letter case is ignored.
+
+The special key representation \"..\" is, however, less than all other
+keys, including prefix keys."
+  (let* ((prefix-string           "  =  \\.\\.\\.$")
+         (parent-string           "..")
+         (s1-prefix-p             (save-match-data (string-match prefix-string s1)))
+         (s2-prefix-p             (save-match-data (string-match prefix-string s2)))
+         (completion-ignore-case  t))
+    (and (not (string= parent-string s2))
+         (or (string= parent-string s1)
+             (and (not s1-prefix-p)  (not s2-prefix-p)  (icicle-case-string-less-p s1 s2))
+             (and s1-prefix-p  (not s2-prefix-p))
+             (and s1-prefix-p  s2-prefix-p  (icicle-case-string-less-p s1 s2))))))
+
+;; This predicate is used for key completion.
+(defun icicle-local-keys-first-p (s1 s2)
+  "Non-nil if S1 is a local key and S2 is not or S1 < S2 (alphabet).
+For this function, a local key is highlighted as a special candidate.
+
+When used as a comparison function for completion candidates, this
+makes local keys that match your input available first (at the top of
+buffer `*Completions*').  Candidates are effectively in two groups,
+each of which is sorted alphabetically separately: local keys,
+followed by non-prefix keys.  Letter case is ignored.
+
+The special key representation \"..\" is, however, less than all other
+keys, including local keys."
+  (or (string= ".." s1)
+      (and (not (string= ".." s2))  (icicle-special-candidates-first-p s1 s2))))
+
+;; This predicate is used for key completion.
+(defun icicle-command-names-alphabetic-p (s1 s2)
+  "Non-nil if command name of S1 `icicle-case-string-less-p' that of S2.
+When used as a comparison function for completion candidates, this
+assumes that each candidate, S1 and S2, is composed of a key name
+followed by \"  =  \", followed by the corresponding command name."
+  (let ((icicle-list-join-string  "  =  ")) ; Fake a multi-completion.  Candidate is key  =  cmd.
+    (icicle-part-2-lessp s1 s2)))
+
+(defun icicle-special-candidates-first-p (s1 s2)
+  "Non-nil if S1 is special candidate and S2 is not or S1 "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "User Options")
+;;  (@> "Macros")
+;;  (@> "Functions")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street,
+;; Fifth Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; Byte-compiling this file, you will likely get some error or warning
+;; messages. All of the following are benign.  They are due to
+;; differences between different versions of Emacs.
+;;
+;; Compiling in Emacs 20:
+;;
+;; the function x-focus-frame is not known to be defined.
+
+(eval-when-compile (when (< emacs-major-version 21) (require 'cl))) ;; for Emacs < 21: dolist, push
+
+;; Quiet the byte compiler for Emacs versions before 22.  For some reason, a value is required.
+(unless (boundp 'minibuffer-completing-symbol)
+  (defvar minibuffer-completing-symbol nil)
+  (defvar minibuffer-message-timeout 2)
+  (defvar minibuffer-prompt-properties nil))
+
+;; Quiet the byte-compiler.
+(defvar icicle-inhibit-try-switch-buffer)
+(defvar read-file-name-completion-ignore-case)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "User Options")
+
+;;; User Options -----------------------------------------------------
+
+;;;###autoload
+(defcustom icicle-byte-compile-eval-after-load-flag t
+  "*Non-nil means byte-compile definitions made within `eval-after-load'.
+Some Icicles functions (commands, in particular) work only if a given
+library is loaded.  Some such functions are defined inside an
+`eval-after-load' form, which means they are defined only, and as soon
+as, the required library is loaded.
+
+If this option is non-nil then those function definitions are
+byte-compiled.  This compilation adds a bit to the load time, in
+effect, but it means that the functions run faster."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+ 
+;;(@* "Macros")
+
+;;; Macros -----------------------------------------------------------
+
+;; $$$$$$
+;; Same as vanilla `condition-case-no-debug', which is available starting with Emacs 23.
+;; (defmacro icicle-condition-case-no-debug (var bodyform &rest handlers)
+;;   "Like `condition-case', but does not catch anything when debugging.
+;; Specifically, non-nil `debug-on-error' means catch no signals.
+;; This is the same as `condition-case-no-debug': added to use in older
+;; Emacs versions too."
+;;   (let ((bodysym  (make-symbol "body")))
+;;     `(let ((,bodysym  (lambda () ,bodyform)))
+;;       (if debug-on-error
+;;           (funcall ,bodysym)
+;;         (condition-case ,var
+;;             (funcall ,bodysym)
+;;           ,@handlers)))))
+
+(defmacro icicle-condition-case-no-debug (var bodyform &rest handlers)
+  "Like `condition-case', but do not catch per `debug-on-(error|quit)'.
+If both `debug-on-error' and `debug-on-quit' are non-nil, then handle
+only other signals - enter the debugger for errors and `C-g'.
+
+If `debug-on-error' is non-nil and `debug-on-quit' is nil, then handle
+all signals except errors that would be caught by an `error' handler.
+Enter the debugger on such errors.
+
+If `debug-on-quit' is non-nil and `debug-on-error' is nil, then handle
+all signals except quitting.  Enter the debugger on quit (`C-g').
+
+NOTE:
+1. This does not treat `error' and `quit' handlers specially when
+   they are in a list that is the car of a handler.  In such a case
+   the handler remains in effect in spite of the values of
+   `debug-on-(error|quit)'.
+
+2. Only errors that would be caught by an `error' handler (if one were
+   present) enter the debugger when `debug-on-error' is non-nil.  When
+   a specific error handler (e.g. `arith-error') is present, it still
+   handles such an error - the debugger is not entered just because
+   `debug-on-error' is non-nil."
+  (let ((bodysym  (make-symbol "body")))
+    `(let ((,bodysym  (lambda () ,bodyform)))
+      (cond ((and debug-on-error debug-on-quit)
+             (condition-case ,var
+                 (funcall ,bodysym)
+               ,@(icicle-remove-if
+                  (lambda (hh) (memq (car hh) '(error quit)))
+                  handlers)))
+            (debug-on-error
+             (condition-case ,var
+                 (funcall ,bodysym)
+               ,@(icicle-remove-if
+                  (lambda (hh) (eq (car hh) 'error))
+                  handlers)))
+            (debug-on-quit
+             (condition-case ,var
+                 (funcall ,bodysym)
+               ,@(icicle-remove-if
+                  (lambda (hh) (eq (car hh) 'quit))
+                  handlers)))
+            (t
+             (condition-case ,var
+                 (funcall ,bodysym)
+               ,@handlers))))))
+
+(defmacro icicle-maybe-byte-compile-after-load (function)
+  "Byte-compile FUNCTION if `icicle-byte-compile-eval-after-load-flag'.
+Do nothing if FUNCTION has not been defined (`fboundp')."
+  `(when (and icicle-byte-compile-eval-after-load-flag (fboundp ',function))
+    (require 'bytecomp)
+    (let ((byte-compile-warnings  ())
+          (byte-compile-verbose   nil))
+      (byte-compile ',function))))
+
+(if (fboundp 'with-selected-window)     ; Emacs 22+
+    (defalias 'icicle-with-selected-window (symbol-function 'with-selected-window))
+  (defmacro icicle-with-selected-window (window &rest body)
+    "Execute the forms in BODY with WINDOW as the selected window.
+The value returned is the value of the last form in BODY.
+
+This macro saves and restores the selected window, as well as the
+selected window of each frame.  It does not change the order of
+recently selected windows.  If the previously selected window of
+some frame is no longer live at the end of BODY, that frame's
+selected window is left alone.  If the selected window is no
+longer live, then whatever window is selected at the end of BODY
+remains selected.
+
+This macro uses `save-current-buffer' to save and restore the
+current buffer, since otherwise its normal operation could
+potentially make a different buffer current.  It does not alter
+the buffer list ordering."
+    ;; Most of this code is a copy of save-selected-window.
+    `(let ((save-selected-window-window  (selected-window))
+           ;; It is necessary to save all of these, because calling
+           ;; select-window changes frame-selected-window for whatever
+           ;; frame that window is in.
+           (save-selected-window-alist   (mapcar #'(lambda (frame)
+                                                     (list frame (frame-selected-window frame)))
+                                          (frame-list))))
+      (save-current-buffer
+        (unwind-protect
+             (progn (if (> emacs-major-version 21)
+                        (select-window ,window 'norecord) ; Emacs 22+
+                      (select-window ,window))
+                    ,@body)
+          (dolist (elt save-selected-window-alist)
+            (and (frame-live-p (car elt))
+                 (window-live-p (cadr elt))
+                 (if (> emacs-major-version 22)
+                     (set-frame-selected-window (car elt) (cadr elt) 'norecord) ; Emacs 23+
+                   (set-frame-selected-window (car elt) (cadr elt)))))
+          (when (window-live-p save-selected-window-window)
+            (if (> emacs-major-version 21)
+                (select-window save-selected-window-window 'norecord) ; Emacs 22+
+              (select-window save-selected-window-window))))))))
+
+;;;###autoload
+(defmacro icicle-define-add-to-alist-command (command doc-string construct-item-fn alist-var
+                                              &optional dont-save)
+  "Define COMMAND that adds an item to an alist user option.
+Any items with the same key are first removed from the alist.
+DOC-STRING is the doc string of COMMAND.
+CONSTRUCT-ITEM-FN is a function that constructs the new item.
+  It reads user input.
+ALIST-VAR is the alist user option.
+Optional arg DONT-SAVE non-nil means do not call
+`customize-save-variable' to save the updated variable."
+  `(defun ,command ()
+    ,(concat doc-string "\n\nNote: Any items with the same key are first removed from the alist.")
+    (interactive)
+    (let ((new-item  (funcall ,construct-item-fn)))
+      (setq ,alist-var  (icicle-assoc-delete-all (car new-item) ,alist-var))
+      (push new-item ,alist-var)
+      ,(unless dont-save `(customize-save-variable ',alist-var ,alist-var))
+      (message "Added to `%s': `%S'" ',alist-var new-item))))
+
+(defmacro icicle-buffer-bindings (&optional pre-bindings post-bindings)
+  "Bindings to use in multi-command definitions for buffer names.
+PRE-BINDINGS is a list of additional bindings, which are created
+before the others.  POST-BINDINGS is similar, but the bindings are
+created after the others."
+  ;; We use `append' rather than backquote syntax (with ,@post-bindings in particular) because of a bug
+  ;; in Emacs 20.  This ensures that you can byte-compile in, say, Emacs 20 and still use the result
+  ;; in later Emacs releases.
+  `,(append
+     pre-bindings
+     `((completion-ignore-case                      (or (and (boundp 'read-buffer-completion-ignore-case)
+                                                         read-buffer-completion-ignore-case)
+                                                     completion-ignore-case))
+       (icicle-show-Completions-initially-flag      (or icicle-show-Completions-initially-flag
+                                                     icicle-buffers-ido-like-flag))
+       (icicle-top-level-when-sole-completion-flag  (or icicle-top-level-when-sole-completion-flag
+                                                     icicle-buffers-ido-like-flag))
+       (icicle-default-value                        (if (and icicle-buffers-ido-like-flag
+                                                             icicle-default-value)
+                                                        icicle-buffers-ido-like-flag
+                                                      icicle-default-value))
+       (icicle-must-match-regexp                    icicle-buffer-match-regexp)
+       (icicle-must-not-match-regexp                icicle-buffer-no-match-regexp)
+       (icicle-must-pass-after-match-predicate      icicle-buffer-predicate)
+       (icicle-require-match-flag                   icicle-buffer-require-match-flag)
+       (icicle-extra-candidates                     icicle-buffer-extras)
+       (icicle-ignore-space-prefix-flag             icicle-buffer-ignore-space-prefix-flag)
+       (icicle-delete-candidate-object              'icicle-kill-a-buffer) ; `S-delete' kills current buf
+       (icicle-transform-function                   'icicle-remove-dups-if-extras)
+       (icicle--temp-orders
+        (append (list
+                 '("by last access")    ; Renamed from "turned OFF'.
+                 '("*...* last" . icicle-buffer-sort-*...*-last)
+                 '("by buffer size" . icicle-buffer-smaller-p)
+                 '("by major mode name" . icicle-major-mode-name-less-p)
+                 (and (fboundp 'icicle-mode-line-name-less-p)
+                  '("by mode-line mode name" . icicle-mode-line-name-less-p))
+                 '("by file/process name" . icicle-buffer-file/process-name-less-p))
+         (delete '("turned OFF") (copy-sequence icicle-sort-orders-alist))))
+       ;; Put `icicle-buffer-sort' first.  If already in the list, move it, else add it, to beginning.
+       (icicle-sort-orders-alist
+        (progn (when (and icicle-buffer-sort-first-time-p icicle-buffer-sort)
+                 (setq icicle-sort-comparer           icicle-buffer-sort
+                       icicle-buffer-sort-first-time-p  nil))
+               (if icicle-buffer-sort
+                   (let ((already-there  (rassq icicle-buffer-sort icicle--temp-orders)))
+                     (if already-there
+                         (cons already-there (setq icicle--temp-orders
+                                                   (delete already-there icicle--temp-orders)))
+                       (cons `("by `icicle-buffer-sort'" . ,icicle-buffer-sort) icicle--temp-orders)))
+                 icicle--temp-orders)))
+       (icicle-candidate-alt-action-fn
+        (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+       (icicle-all-candidates-list-alt-action-fn
+        (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
+       (icicle-bufflist
+        (if current-prefix-arg
+            (cond ((zerop (prefix-numeric-value current-prefix-arg))
+                   (let ((this-mode  major-mode))
+                     (icicle-remove-if-not #'(lambda (bf)
+                                               (with-current-buffer bf (eq major-mode this-mode)))
+                                           (buffer-list))))
+                  ((< (prefix-numeric-value current-prefix-arg) 0)
+                   (cdr (assq 'buffer-list (frame-parameters))))
+                  (t
+                   (icicle-remove-if-not #'(lambda (bf) (buffer-file-name bf)) (buffer-list))))
+          (buffer-list))))
+     post-bindings))
+
+(defmacro icicle-file-bindings (&optional pre-bindings post-bindings)
+  "Bindings to use in multi-command definitions for file names.
+PRE-BINDINGS is a list of additional bindings, which are created
+before the others.  POST-BINDINGS is similar, but the bindings are
+created after the others."
+  ;; We use `append' rather than backquote syntax (with ,@post-bindings in particular) because of a bug
+  ;; in Emacs 20.  This ensures that you can byte-compile in, say, Emacs 20 and still use the result
+  ;; in later Emacs releases.
+  `,(append
+     pre-bindings
+     `((completion-ignore-case
+        (or (and (boundp 'read-file-name-completion-ignore-case) read-file-name-completion-ignore-case)
+         completion-ignore-case))
+       (icicle-show-Completions-initially-flag      (or icicle-show-Completions-initially-flag
+                                                     icicle-files-ido-like-flag))
+       (icicle-top-level-when-sole-completion-flag  (or icicle-top-level-when-sole-completion-flag
+                                                     icicle-files-ido-like-flag))
+       (icicle-default-value                        (if (and icicle-files-ido-like-flag
+                                                             icicle-default-value)
+                                                        icicle-files-ido-like-flag
+                                                      ;;  Get default via `M-n', but do not insert it.
+                                                      (and (memq icicle-default-value '(t nil))
+                                                           icicle-default-value)))
+       (icicle-must-match-regexp                    icicle-file-match-regexp)
+       (icicle-must-not-match-regexp                icicle-file-no-match-regexp)
+       (icicle-must-pass-after-match-predicate      icicle-file-predicate)
+       (icicle-require-match-flag                   icicle-file-require-match-flag)
+       (icicle-extra-candidates                     icicle-file-extras)
+       (icicle-transform-function                   'icicle-remove-dups-if-extras)
+       ;; Put `icicle-file-sort' first.  If already in the list, move it, else add it, to beginning.
+       (icicle--temp-orders                         (copy-sequence icicle-sort-orders-alist))
+       (icicle-sort-orders-alist
+        (progn (when (and icicle-file-sort-first-time-p icicle-file-sort)
+                 (setq icicle-sort-comparer           icicle-file-sort
+                       icicle-file-sort-first-time-p  nil))
+               (if icicle-file-sort
+                   (let ((already-there  (rassq icicle-file-sort icicle--temp-orders)))
+                     (if already-there
+                         (cons already-there (setq icicle--temp-orders
+                                                   (delete already-there icicle--temp-orders)))
+                       (cons `("by `icicle-file-sort'" ,@icicle-file-sort) icicle--temp-orders)))
+                 icicle--temp-orders)))
+       (icicle-candidate-help-fn                    #'(lambda (cand)
+                                                        (icicle-describe-file cand current-prefix-arg)))
+       (icicle-candidate-alt-action-fn
+        (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "file")))
+       (icicle-all-candidates-list-alt-action-fn
+        (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "file")))
+       (icicle-delete-candidate-object              'icicle-delete-file-or-directory))
+     post-bindings))
+
+;;;###autoload
+(defmacro icicle-define-command
+    (command doc-string function prompt collection &optional
+     predicate require-match initial-input hist def inherit-input-method
+     bindings first-sexp undo-sexp last-sexp not-interactive-p)
+  ;; Hard-code these in doc string, because \\[...] prefers ASCII
+  ;; `C-RET'   instead of `\\[icicle-candidate-action]'
+  ;; `C-down'  instead of `\\[icicle-next-candidate-per-mode-action]'
+  ;; `C-up', `C-wheel-up' instead of `\\[icicle-previous-candidate-per-mode-action]'
+  ;; `C-next'  instead of `\\[icicle-next-apropos-candidate-action]'
+  ;; `C-prior' instead of `\\[icicle-previous-apropos-candidate-action]'
+  ;; `C-end'   instead of `\\[icicle-next-prefix-candidate-action]'
+  ;; `C-home'  instead of `\\[icicle-previous-prefix-candidate-action]'
+  "Define COMMAND with DOC-STRING based on FUNCTION.
+COMMAND is a symbol.  DOC-STRING is a string.
+FUNCTION is a function that takes one argument, read as input.
+  (If the argument to FUNCTION is a file name or directory name, then
+  use macro `icicle-define-file-command', instead.)
+
+BINDINGS is a list of `let*' bindings added around the command code.
+  The following bindings are pre-included - you can refer to them in
+  the command body (including in FIRST-SEXP, LAST-SEXP, UNDO-SEXP).
+
+  `icicle-orig-buff'   is bound to (current-buffer)
+  `icicle-orig-window' is bound to (selected-window)
+BINDINGS is macroexpanded, so it can also be a macro call that expands
+to a list of bindings.  For example, you can use
+`icicle-buffer-bindings' here.
+
+In case of user quit (`C-g') or error, an attempt is made to restore
+the original buffer.
+
+FIRST-SEXP is a sexp evaluated before the main body of the command.
+UNDO-SEXP is a sexp evaluated in case of error or if the user quits.
+LAST-SEXP is a sexp evaluated after the main body of the command.
+ It is always evaluated, in particular, even in case of error or quit.
+NOT-INTERACTIVE-P non-nil means to define COMMAND as a non-interactive
+ function that reads multi-command input.
+
+Other arguments are as for `completing-read'.
+
+In order, the created command does this:
+
+ - Uses DOC-STRING, with information about Icicles bindings appended.
+ - Binds BINDINGS for the rest of the command.
+ - Evaluates FIRST-SEXP.
+ - Reads input with `completing-read', using PROMPT, COLLECTION,
+   PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, DEF, and
+   INHERIT-INPUT-METHOD.
+ - Calls FUNCTION on the input that was read.
+ - Evaluates UNDO-SEXP in case of error or if the user quits.
+ - Evaluates LAST-SEXP.
+
+The created command also binds `icicle-candidate-action-fn' to a
+function that calls FUNCTION on the current completion candidate.
+Note that the BINDINGS are of course not in effect within
+`icicle-candidate-action-fn'."
+  `(defun ,command ()
+    ,(concat doc-string "\n\nRead input, then "
+             (and (symbolp function) (concat "call `" (symbol-name function) "'\nto "))
+             "act on it.
+
+Input-candidate completion and cycling are available.  While cycling,
+these keys with prefix `C-' are active:
+
+\\\
+`C-mouse-2', `C-RET' - Act on current completion candidate only
+`C-down', `C-wheel-down' - Move to next completion candidate and act
+`C-up', `C-wheel-up' - Move to previous completion candidate and act
+`C-next'  - Move to next apropos-completion candidate and act
+`C-prior' - Move to previous apropos-completion candidate and act
+`C-end'   - Move to next prefix-completion candidate and act
+`C-home'  - Move to previous prefix-completion candidate and act
+`\\[icicle-all-candidates-action]'     - Act on *all* candidates, successively (careful!)
+
+When candidate action and cycling are combined (e.g. `C-next'), user
+option `icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
+`C-g' to quit.
+
+This is an Icicles command - see command `icicle-mode'.")
+    ,(and (not not-interactive-p) '(interactive))
+    (let* ((icicle-orig-buff    (current-buffer))
+           (icicle-orig-window  (selected-window))
+           ,@(macroexpand bindings)
+           (icicle-candidate-action-fn
+            (lambda (candidate)
+              (let ((minibuffer-completion-table      minibuffer-completion-table)
+                    (minibuffer-completion-predicate  minibuffer-completion-predicate)
+                    (minibuffer-completion-confirm    minibuffer-completion-confirm)
+                    (minibuffer-completing-file-name  minibuffer-completing-file-name)
+                    (minibuffer-completing-symbol     (and (boundp 'minibuffer-completing-symbol)
+                                                           minibuffer-completing-symbol))
+                    (minibuffer-exit-hook             minibuffer-exit-hook)
+                    (minibuffer-help-form             minibuffer-help-form)
+                    (minibuffer-history-variable      minibuffer-history-variable)
+                    (minibuffer-history-case-insensitive-variables
+                     minibuffer-history-case-insensitive-variables)
+                    (minibuffer-history-sexp-flag     minibuffer-history-sexp-flag)
+                    (minibuffer-message-timeout       (and (boundp 'minibuffer-message-timeout)
+                                                           minibuffer-message-timeout))
+                    (minibuffer-prompt-properties     (and (boundp 'minibuffer-prompt-properties)
+                                                           minibuffer-prompt-properties))
+                    (minibuffer-setup-hook            minibuffer-setup-hook)
+                    (minibuffer-text-before-history   minibuffer-text-before-history))
+                (icicle-condition-case-no-debug in-action-fn
+                    ;; Treat 3 cases, because previous use of `icicle-candidate-action-fn'
+                    ;; might have killed the buffer or deleted the window.
+                    (cond ((and (buffer-live-p icicle-orig-buff) (window-live-p icicle-orig-window))
+                           (with-current-buffer icicle-orig-buff
+                             (save-selected-window (select-window icicle-orig-window)
+                                                   (funcall #',function candidate))))
+                          ((window-live-p icicle-orig-window)
+                           (save-selected-window (select-window icicle-orig-window)
+                                                 (funcall #',function candidate)))
+                          (t
+                           (funcall #',function candidate)))
+                  (error (unless (string= "Cannot switch buffers in minibuffer window"
+                                          (error-message-string in-action-fn))
+                           (error "%s" (error-message-string in-action-fn)))
+                         (when (window-live-p icicle-orig-window)
+                           (select-window icicle-orig-window)
+                           (select-frame-set-input-focus (selected-frame)))
+                         (funcall #',function candidate)))
+                (select-window (minibuffer-window))
+                (select-frame-set-input-focus (selected-frame))
+                nil))))                 ; Return nil for success.
+      ,first-sexp
+      (icicle-condition-case-no-debug act-on-choice
+          (let ((cmd-choice  (completing-read ,prompt ,collection ,predicate ,require-match
+                                              ,initial-input ,hist ,def ,inherit-input-method)))
+            ;; Reset after reading input, so that commands can tell whether input has been read.
+            (setq icicle-candidate-action-fn  nil)
+            (funcall #',function cmd-choice))
+        (quit  (icicle-try-switch-buffer icicle-orig-buff) ,undo-sexp)
+        (error (icicle-try-switch-buffer icicle-orig-buff) ,undo-sexp
+               (error "%s" (error-message-string act-on-choice))))
+      ,last-sexp)))
+
+;;;###autoload
+(defmacro icicle-define-file-command
+    (command doc-string function prompt &optional
+     dir default-filename require-match initial-input predicate
+     bindings first-sexp undo-sexp last-sexp not-interactive-p)
+  ;; Hard-code these in doc string, because \\[...] prefers ASCII
+  ;; `C-RET'   instead of `\\[icicle-candidate-action]'
+  ;; `C-down'  instead of `\\[icicle-next-candidate-per-mode-action]'
+  ;; `C-up', `C-wheel-up' instead of `\\[icicle-previous-candidate-per-mode-action]'
+  ;; `C-next'  instead of `\\[icicle-next-apropos-candidate-action]'
+  ;; `C-prior' instead of `\\[icicle-previous-apropos-candidate-action]'
+  ;; `C-end'   instead of `\\[icicle-next-prefix-candidate-action]'
+  ;; `C-home'  instead of `\\[icicle-previous-prefix-candidate-action]'
+  "Define COMMAND with DOC-STRING based on FUNCTION.
+COMMAND is a symbol.  DOC-STRING is a string.
+FUNCTION is a function that takes one file-name or directory-name
+argument, read as input.  (Use macro `icicle-define-command' for a
+FUNCTION whose argument is not a file or directory name.)
+
+BINDINGS is a list of `let*' bindings added around the command code.
+  The following bindings are pre-included - you can refer to them in
+  the command body (including in FIRST-SEXP, LAST-SEXP, UNDO-SEXP).
+
+  `icicle-orig-buff'   is bound to (current-buffer)
+  `icicle-orig-window' is bound to (selected-window)
+BINDINGS is macroexpanded, so it can also be a macro call that expands
+to a list of bindings.  For example, you can use
+`icicle-buffer-bindings' or `icicle-file-bindings' here.
+
+In case of user quit (`C-g') or error, an attempt is made to restore
+the original buffer.
+
+FIRST-SEXP is a sexp evaluated before the main body of the command.
+UNDO-SEXP is a sexp evaluated in case of error or if the user quits.
+LAST-SEXP is a sexp evaluated after the main body of the command.
+ It is always evaluated, in particular, even in case of error or quit.
+NOT-INTERACTIVE-P non-nil means to define COMMAND as a non-interactive
+ function that reads multi-command input.
+
+Other arguments are as for `read-file-name'.
+
+In order, the created command does this:
+
+ - Uses DOC-STRING, with information about Icicles bindings appended.
+ - Binds BINDINGS for the rest of the command.
+ - Evaluates FIRST-SEXP.
+ - Reads input with `read-file-name', using PROMPT, DIR,
+   DEFAULT-FILENAME, REQUIRE-MATCH, INITIAL-INPUT, and PREDICATE.
+ - Calls FUNCTION on the input that was read.
+ - Evaluates UNDO-SEXP in case of error or if the user quits.
+ - Evaluates LAST-SEXP.
+
+The created command also binds `icicle-candidate-action-fn' to a
+function that calls FUNCTION on the current completion candidate.
+Note that the BINDINGS are of course not in effect within
+`icicle-candidate-action-fn'."
+  `(defun ,command ()
+    ,(concat doc-string "\n\nRead input, then "
+             (and (symbolp function) (concat "call `" (symbol-name function) "'\nto "))
+             "act on it.
+
+Input-candidate completion and cycling are available.  While cycling,
+these keys with prefix `C-' are active:
+
+\\\
+`C-mouse-2', `C-RET' - Act on current completion candidate only
+`C-down', `C-wheel-down' - Move to next completion candidate and act
+`C-up', `C-wheel-up' - Move to previous completion candidate and act
+`C-next'  - Move to next apropos-completion candidate and act
+`C-prior' - Move to previous apropos-completion candidate and act
+`C-end'   - Move to next prefix-completion candidate and act
+`C-home'  - Move to previous prefix-completion candidate and act
+`\\[icicle-all-candidates-action]'     - Act on *all* candidates, successively (careful!)
+
+When candidate action and cycling are combined (e.g. `C-next'), user
+option `icicle-act-before-cycle-flag' determines which occurs first.
+
+With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
+`C-M-RET', `C-M-down', and so on) provide help about candidates.
+
+Use `mouse-2', `RET', or `S-RET' to finally choose a candidate, or
+`C-g' to quit.
+
+This is an Icicles command - see command `icicle-mode'.")
+    ,(and (not not-interactive-p) '(interactive))
+    (let* ((icicle-orig-buff    (current-buffer))
+           (icicle-orig-window  (selected-window))
+           ,@(macroexpand bindings)
+           (icicle-candidate-action-fn
+            (lambda (candidate)
+              (let ((minibuffer-completion-table      minibuffer-completion-table)
+                    (minibuffer-completion-predicate  minibuffer-completion-predicate)
+                    (minibuffer-completion-confirm    minibuffer-completion-confirm)
+                    (minibuffer-completing-file-name  minibuffer-completing-file-name)
+                    (minibuffer-completing-symbol     (and (boundp 'minibuffer-completing-symbol)
+                                                           minibuffer-completing-symbol))
+                    (minibuffer-exit-hook             minibuffer-exit-hook)
+                    (minibuffer-help-form             minibuffer-help-form)
+                    (minibuffer-history-variable      minibuffer-history-variable)
+                    (minibuffer-history-case-insensitive-variables
+                     minibuffer-history-case-insensitive-variables)
+                    (minibuffer-history-sexp-flag     minibuffer-history-sexp-flag)
+                    (minibuffer-message-timeout       (and (boundp 'minibuffer-message-timeout)
+                                                           minibuffer-message-timeout))
+                    (minibuffer-prompt-properties     (and (boundp 'minibuffer-prompt-properties)
+                                                           minibuffer-prompt-properties))
+                    (minibuffer-setup-hook            minibuffer-setup-hook)
+                    (minibuffer-text-before-history   minibuffer-text-before-history))
+                (setq candidate  (expand-file-name
+                                  candidate (icicle-file-name-directory icicle-last-input)))
+                (icicle-condition-case-no-debug in-action-fn
+                    ;; Treat 3 cases, because previous use of `icicle-candidate-action-fn'
+                    ;; might have deleted the file or the window.
+                    (cond ((and (buffer-live-p icicle-orig-buff) (window-live-p icicle-orig-window))
+                           (with-current-buffer icicle-orig-buff
+                             (save-selected-window (select-window icicle-orig-window)
+                                                   (funcall #',function candidate))))
+                          ((window-live-p icicle-orig-window)
+                           (save-selected-window (select-window icicle-orig-window)
+                                                 (funcall #',function candidate)))
+                          (t
+                           (funcall #',function candidate)))
+                  (error (unless (string= "Cannot switch buffers in minibuffer window"
+                                          (error-message-string in-action-fn))
+                           (error "%s" (error-message-string in-action-fn)))
+                         (when (window-live-p icicle-orig-window)
+                           (select-window icicle-orig-window)
+                           (select-frame-set-input-focus (selected-frame)))
+                         (funcall #',function candidate)))
+                (select-window (minibuffer-window))
+                (select-frame-set-input-focus (selected-frame))
+                nil))))                 ; Return nil for success.
+      ,first-sexp
+      (icicle-condition-case-no-debug act-on-choice
+          (let ((file-choice
+                 (if (< emacs-major-version 21) ; No predicate arg for Emacs 20.
+                     (read-file-name ,prompt ,dir ,default-filename ,require-match ,initial-input)
+                   (read-file-name ,prompt ,dir ,default-filename ,require-match
+                                   ,initial-input ,predicate))))
+            ;; Reset after reading input, so that commands can tell whether input has been read.
+            (setq icicle-candidate-action-fn  nil) ; Reset after completion.
+            (funcall #',function file-choice))
+        (quit  (icicle-try-switch-buffer icicle-orig-buff) ,undo-sexp)
+        (error (icicle-try-switch-buffer icicle-orig-buff) ,undo-sexp
+               (error "%s" (error-message-string act-on-choice))))
+      ,last-sexp)))
+
+;;;###autoload
+(defmacro icicle-define-sort-command (sort-order comparison-fn doc-string)
+  "Define a command to sort completions by SORT-ORDER.
+SORT-ORDER is a short string (or symbol) describing the sort order.
+ It is used after the phrase \"Sorting is now \".  Examples: \"by date\",
+ \"alphabetically\", \"directories first\", and \"previously used first\".
+
+The new command is named by replacing any spaces in SORT-ORDER with
+hyphens (`-') and then adding the prefix `icicle-sort-'.
+
+COMPARISON-FN is a function that compares two strings, returning
+ non-nil if and only if the first string sorts before the second.
+
+DOC-STRING is the doc string of the new command."
+  (unless (stringp sort-order) (setq sort-order  (symbol-name sort-order)))
+  (let ((command  (intern (concat "icicle-sort-"
+                                  (replace-regexp-in-string "\\s-+" "-" sort-order)))))
+    `(progn
+      (setq icicle-sort-orders-alist  (icicle-assoc-delete-all
+                                       ,sort-order
+                                       icicle-sort-orders-alist))
+      (push (cons ,sort-order ',comparison-fn) icicle-sort-orders-alist)
+      (defun ,command ()
+        ,doc-string
+        (interactive)
+        (setq icicle-sort-comparer  #',comparison-fn)
+        (message "Sorting is now %s%s" ,sort-order (if icicle-reverse-sort-p ", REVERSED" ""))
+        (icicle-complete-again-update)))))
+ 
+;;(@* "Functions")
+
+;;; Functions --------------------------------------------------------
+
+(defun icicle-assoc-delete-all (key alist)
+  "Delete from ALIST all elements whose car is `equal' to KEY.
+Return the modified alist.
+Elements of ALIST that are not conses are ignored."
+  (while (and (consp (car alist)) (equal (car (car alist)) key))
+    (setq alist  (cdr alist)))
+  (let ((tail  alist)  tail-cdr)
+    (while (setq tail-cdr  (cdr tail))
+      (if (and (consp (car tail-cdr))  (equal (car (car tail-cdr)) key))
+          (setcdr tail (cdr tail-cdr))
+        (setq tail  tail-cdr))))
+  alist)
+
+(defun icicle-try-switch-buffer (buffer)
+  "Try to switch to BUFFER, first in same window, then in other window."
+  (when (and (buffer-live-p buffer) (not icicle-inhibit-try-switch-buffer))
+    (condition-case err-switch-to
+        (switch-to-buffer buffer)
+      (error (and (string= "Cannot switch buffers in minibuffer window"
+                           (error-message-string err-switch-to))
+                  ;; Try another window.  Don't bother if the buffer to switch to is a minibuffer.
+                  (condition-case err-switch-other
+                      (unless (string-match "\\` \\*Minibuf-[0-9]+\\*\\'" (buffer-name buffer))
+                        (switch-to-buffer-other-window buffer))
+                    (error (error-message-string err-switch-other)))))))) ; Return error message string.
+
+(unless (fboundp 'select-frame-set-input-focus) ; Defined in Emacs 22.
+  (defun select-frame-set-input-focus (frame)
+    "Select FRAME, raise it, and set input focus, if possible."
+    (select-frame frame)
+    (raise-frame frame)
+    ;; Ensure, if possible, that frame gets input focus.
+    (cond ((eq window-system 'x) (x-focus-frame frame))
+          ((eq window-system 'w32) (w32-focus-frame frame)))
+    (cond (focus-follows-mouse (set-mouse-position (selected-frame) (1- (frame-width)) 0)))))
+
+
+;;; Miscellaneous  -----------------------------------------
+
+;; Make Emacs-Lisp mode fontify definitions of Icicles commands.
+(font-lock-add-keywords
+ 'emacs-lisp-mode
+ `((,(concat "(" (regexp-opt '("icicle-define-add-to-alist-command" "icicle-define-command"
+                               "icicle-define-file-command" "icicle-define-sort-command")
+                             t)
+             ;; $$ "\\s-+\\(\\sw\\(\\sw\\|\\s_\\)+\\)")
+             "\\>[ \t'\(]*\\(\\sw+\\)?")
+    (1 font-lock-keyword-face)
+    ;; Index (2 or 3) depends on whether or not shy groups are supported.
+    ,(list (if (string-match "\\(?:\\)" "") 2 3) 'font-lock-function-name-face nil t))
+   ("(\\(icicle-condition-case-no-debug\\)\\>" 1 font-lock-keyword-face)))
+
+;; Make Icicles macros indent better.
+(put 'icicle-define-command              'common-lisp-indent-function '(4 &body))
+(put 'icicle-define-file-command         'common-lisp-indent-function '(4 &body))
+(put 'icicle-define-sort-command         'common-lisp-indent-function '(4 4 &body))
+(put 'icicle-define-add-to-alist-command 'common-lisp-indent-function '(4 &body))
+(put 'icicle-with-selected-window        'common-lisp-indent-function '(4 &body))
+(put 'icicle-condition-case-no-debug     'common-lisp-indent-function '(4 4 &body))
+
+;; You might also want to use the following or something similar.
+;; (defun lisp-indentation-hack ()
+;;   "Better Lisp indenting.  Use in Lisp mode hooks
+;; such as `lisp-mode-hook', `emacs-lisp-mode-hook', and
+;; `lisp-interaction-mode-hook'."
+;;   (load "cl-indent" nil t)
+;;   (set (make-local-variable 'lisp-indent-function) 'common-lisp-indent-function)
+;;   (setq lisp-indent-maximum-backtracking  10)
+;;   (put 'define-derived-mode 'common-lisp-indent-function '(4 4 4 2 &body))
+;;   (put 'if                  'common-lisp-indent-function '(nil nil &body)))
+;;
+;; (add-hook 'emacs-lisp-mode-hook       'lisp-indentation-hack)
+;; (add-hook 'lisp-mode-hook             'lisp-indentation-hack)
+;; (add-hook 'lisp-interaction-mode-hook 'lisp-indentation-hack)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-mac)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-mac.el ends here
diff --git a/auto-install/icicles-mcmd.el b/auto-install/icicles-mcmd.el
new file mode 100644
index 0000000..72b1af6
--- /dev/null
+++ b/auto-install/icicles-mcmd.el
@@ -0,0 +1,7432 @@
+;;; icicles-mcmd.el --- Minibuffer commands for Icicles
+;;
+;; Filename: icicles-mcmd.el
+;; Description: Minibuffer commands for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:25:04 2006
+;; Version: 22.0
+;; Last-Updated: Fri Sep  9 10:26:30 2011 (-0700)
+;;           By: dradams
+;;     Update #: 17246
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-mcmd.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos-fn+var', `backquote', `bytecomp', `cl',
+;;   `doremi', `el-swank-fuzzy', `ffap', `ffap-', `fuzzy',
+;;   `fuzzy-match', `hexrgb', `icicles-face', `icicles-fn',
+;;   `icicles-mac', `icicles-opt', `icicles-var', `image-dired',
+;;   `kmacro', `levenshtein', `mouse3', `mwheel', `pp', `pp+',
+;;   `regexp-opt', `ring', `ring+', `thingatpt', `thingatpt+',
+;;   `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  commands to be used mainly in the minibuffer or buffer
+;;  `*Completions*' (and a few non-interactive functions used in those
+;;  commands).  For top-level commands, see `icicles-cmd1.el' and
+;;  `icicles-cmd2.el'.  For Icicles documentation, see
+;;  `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Commands defined here:
+;;
+;;    `cycle-icicle-image-file-thumbnail',
+;;    `icicle-abort-recursive-edit', `icicle-add-file-to-fileset',
+;;    `icicle-add/update-saved-completion-set',
+;;    `icicle-all-candidates-action',
+;;    `icicle-all-candidates-alt-action',
+;;    `icicle-all-candidates-list-action',
+;;    `icicle-all-candidates-list-alt-action',
+;;    `icicle-apropos-complete', `icicle-apropos-complete-and-exit',
+;;    `icicle-apropos-complete-and-narrow',
+;;    `icicle-apropos-complete-and-widen',
+;;    `icicle-apropos-complete-no-display',
+;;    `icicle-backward-char-dots',
+;;    `icicle-backward-delete-char-untabify',
+;;    `icicle-backward-kill-paragraph',
+;;    `icicle-backward-kill-sentence', `icicle-backward-kill-sexp',
+;;    `icicle-backward-kill-word', `icicle-beginning-of-line+',
+;;    `icicle-candidate-action', `icicle-candidate-alt-action',
+;;    `icicle-candidate-read-fn-invoke',
+;;    `icicle-candidate-set-complement',
+;;    `icicle-candidate-set-define',
+;;    `icicle-candidate-set-difference',
+;;    `icicle-candidate-set-intersection',
+;;    `icicle-candidate-set-retrieve',
+;;    `icicle-candidate-set-retrieve-from-variable',
+;;    `icicle-candidate-set-retrieve-more',
+;;    `icicle-candidate-set-retrieve-persistent',
+;;    `icicle-candidate-set-save', `icicle-candidate-set-save-more',
+;;    `icicle-candidate-set-save-more-selected',
+;;    `icicle-candidate-set-save-persistently',
+;;    `icicle-candidate-set-save-selected',
+;;    `icicle-candidate-set-save-to-variable',
+;;    `icicle-candidate-set-swap', `icicle-candidate-set-truncate',
+;;    `icicle-candidate-set-union',
+;;    `icicle-change-alternative-sort-order',
+;;    `icicle-change-history-variable', `icicle-change-sort-order',
+;;    `icicle-choose-completion', `icicle-completing-read+insert',
+;;    `icicle-Completions-mouse-3-menu',
+;;    `icicle-cycle-image-file-thumbnail',
+;;    `icicle-delete-backward-char', `icicle-delete-candidate-object',
+;;    `icicle-delete-char', `icicle-delete-windows-on',
+;;    `icicle-describe-file', `icicle-digit-argument',
+;;    `icicle-dispatch-C-^', `icicle-dispatch-C-.',
+;;    `icicle-dispatch-C-x.', `icicle-dispatch-M-_',
+;;    `icicle-dispatch-M-comma', `icicle-dispatch-M-q',
+;;    `icicle-doremi-candidate-width-factor+',
+;;    `icicle-doremi-increment-max-candidates+',
+;;    `icicle-doremi-increment-swank-prefix-length+',
+;;    `icicle-doremi-increment-swank-timeout+',
+;;    `icicle-doremi-inter-candidates-min-spaces+',
+;;    `icicle-doremi-zoom-Completions+', `icicle-end-of-line+',
+;;    `icicle-erase-minibuffer',
+;;    `icicle-erase-minibuffer-or-history-element',
+;;    `icicle-exit-minibuffer', `icicle-forward-char-dots',
+;;    `icicle-goto/kill-failed-input', `icicle-help-on-candidate',
+;;    `icicle-help-on-next-apropos-candidate',
+;;    `icicle-help-on-next-prefix-candidate',
+;;    `icicle-help-on-previous-apropos-candidate',
+;;    `icicle-help-on-previous-prefix-candidate',
+;;    `icicle-help-string-completion',
+;;    `icicle-help-string-non-completion', `icicle-history',
+;;    `icicle-insert-completion', `icicle-insert-dot-command',
+;;    `icicle-insert-history-element',
+;;    `icicle-insert-key-description',
+;;    `icicle-insert-list-join-string',
+;;    `icicle-insert-newline-in-minibuffer',
+;;    `icicle-insert-string-at-point',
+;;    `icicle-insert-string-from-variable', `icicle-isearch-complete',
+;;    `icicle-keep-only-past-inputs', `icicle-kill-line',
+;;    `icicle-kill-paragraph', `icicle-kill-region',
+;;    `icicle-kill-region-wimpy', `icicle-kill-sentence',
+;;    `icicle-kill-sexp', `icicle-kill-word', `icicle-make-directory',
+;;    `icicle-minibuffer-complete-and-exit', `icicle-minibuffer-help',
+;;    `icicle-mouse-candidate-action',
+;;    `icicle-mouse-candidate-alt-action',
+;;    `icicle-mouse-candidate-read-fn-invoke',
+;;    `icicle-mouse-candidate-set-save',
+;;    `icicle-mouse-candidate-set-save-more',
+;;    `icicle-mouse-choose-completion',
+;;    `icicle-mouse-help-on-candidate',
+;;    `icicle-mouse-remove-candidate',
+;;    `icicle-mouse-save/unsave-candidate',
+;;    `icicle-mouse-save-then-kill', `icicle-mouse-yank-secondary',
+;;    `icicle-move-to-next-completion',
+;;    `icicle-move-to-previous-completion',
+;;    `icicle-narrow-candidates',
+;;    `icicle-narrow-candidates-with-predicate',
+;;    `icicle-negative-argument', `icicle-next-apropos-candidate',
+;;    `icicle-next-apropos-candidate-action',
+;;    `icicle-next-apropos-candidate-alt-action',
+;;    `icicle-next-candidate-per-mode',
+;;    `icicle-next-candidate-per-mode-action',
+;;    `icicle-next-candidate-per-mode-alt-action',
+;;    `icicle-next-history-element', `icicle-next-line',
+;;    `icicle-next-prefix-candidate',
+;;    `icicle-next-prefix-candidate-action',
+;;    `icicle-next-prefix-candidate-alt-action',
+;;    `icicle-next-S-TAB-completion-method',
+;;    `icicle-next-TAB-completion-method', `icicle-other-history',
+;;    `icicle-plus-saved-sort',
+;;    `icicle-pp-eval-expression-in-minibuffer',
+;;    `icicle-prefix-complete', `icicle-prefix-complete-no-display',
+;;    `icicle-prefix-word-complete',
+;;    `icicle-previous-apropos-candidate',
+;;    `icicle-previous-apropos-candidate-action',
+;;    `icicle-previous-apropos-candidate-alt-action',
+;;    `icicle-previous-candidate-per-mode',
+;;    `icicle-previous-candidate-per-mode-action',
+;;    `icicle-previous-candidate-per-mode-alt-action',
+;;    `icicle-previous-line', `icicle-previous-prefix-candidate',
+;;    `icicle-previous-prefix-candidate-action',
+;;    `icicle-previous-prefix-candidate-alt-action',
+;;    `icicle-read+insert-file-name', `icicle-regexp-quote-input',
+;;    `icicle-remove-candidate', `icicle-remove-Completions-window',
+;;    `icicle-resolve-file-name', `icicle-retrieve-last-input',
+;;    `icicle-retrieve-next-input', `icicle-retrieve-previous-input',
+;;    `icicle-reverse-sort-order',
+;;    `icicle-save-predicate-to-variable',
+;;    `icicle-save/unsave-candidate',
+;;    `icicle-scroll-Completions-backward',
+;;    `icicle-scroll-Completions-forward', `icicle-scroll-backward',
+;;    `icicle-scroll-forward', `icicle-search-define-replacement',
+;;    `icicle-self-insert', `icicle-sit-for',
+;;    `icicle-sort-alphabetical', `icicle-sort-by-abbrev-frequency',
+;;    `icicle-sort-by-directories-first',
+;;    `icicle-sort-by-directories-last', `icicle-sort-by-file-type',
+;;    `icicle-sort-by-last-file-modification-time',
+;;    `icicle-sort-by-last-use-as-input',
+;;    `icicle-sort-by-previous-use-alphabetically',
+;;    `icicle-sort-by-2nd-parts-alphabetically',
+;;    `icicle-sort-case-insensitive',
+;;    `icicle-sort-extra-candidates-first',
+;;    `icicle-sort-proxy-candidates-first',
+;;    `icicle-sort-special-candidates-first',
+;;    `icicle-sort-turned-OFF', `icicle-switch-to-Completions-buf',
+;;    `icicle-switch-to-completions',
+;;    `icicle-switch-to/from-minibuffer', `icicle-toggle-.',
+;;    `icicle-toggle-~-for-home-dir',
+;;    `icicle-toggle-alternative-sorting',
+;;    `icicle-toggle-angle-brackets',
+;;    `icicle-toggle-case-sensitivity', `icicle-toggle-C-for-actions',
+;;    `icicle-toggle-dot', `icicle-toggle-expand-to-common-match',
+;;    `icicle-toggle-hiding-common-match',
+;;    `icicle-toggle-hiding-non-matching-lines',
+;;    `icicle-toggle-highlight-all-current',
+;;    `icicle-toggle-highlight-historical-candidates',
+;;    `icicle-toggle-highlight-saved-candidates',
+;;    `icicle-toggle-ignored-extensions',
+;;    `icicle-toggle-ignored-space-prefix',
+;;    `icicle-toggle-ignoring-comments',
+;;    `icicle-toggle-incremental-completion',
+;;    `icicle-toggle-literal-replacement',
+;;    `icicle-toggle-proxy-candidates', `icicle-toggle-regexp-quote',
+;;    `icicle-toggle-remote-file-testing',
+;;    `icicle-toggle-search-cleanup',
+;;    `icicle-toggle-search-complementing-domain',
+;;    `icicle-toggle-search-replace-common-match',
+;;    `icicle-toggle-search-replace-whole',
+;;    `icicle-toggle-search-whole-word',
+;;    `icicle-toggle-show-multi-completion', `icicle-toggle-sorting',
+;;    `icicle-toggle-transforming',
+;;    `icicle-toggle-WYSIWYG-Completions', `icicle-transpose-chars',
+;;    `icicle-transpose-sexps', `icicle-transpose-words',
+;;    `icicle-universal-argument', `icicle-universal-argument-minus',
+;;    `icicle-universal-argument-more',
+;;    `icicle-universal-argument-other-key', `icicle-up-directory',
+;;    `icicle-use-interactive-command-history',
+;;    `icicle-widen-candidates', `icicle-yank', `icicle-yank-pop',
+;;    `icicle-yank-secondary', `old-choose-completion',
+;;    `old-exit-minibuffer', `old-minibuffer-complete-and-exit',
+;;    `old-sit-for', `old-switch-to-completions', `toggle-icicle-.',
+;;    `toggle-icicle-~-for-home-dir',
+;;    `toggle-icicle-alternative-sorting',
+;;    `toggle-icicle-angle-brackets',
+;;    `toggle-icicle-case-sensitivity', `toggle-icicle-C-for-actions',
+;;    `toggle-icicle-dot', `toggle-icicle-expand-to-common-match',
+;;    `toggle-icicle-hiding-common-match',
+;;    `toggle-icicle-hiding-non-matching-lines',
+;;    `toggle-icicle-highlight-all-current',
+;;    `toggle-icicle-highlight-historical-candidates',
+;;    `toggle-icicle-highlight-saved-candidates',
+;;    `toggle-icicle-ignored-extensions',
+;;    `toggle-icicle-ignored-space-prefix',
+;;    `toggle-icicle-incremental-completion',
+;;    `toggle-icicle-literal-replacement',
+;;    `toggle-icicle-proxy-candidates', `toggle-icicle-regexp-quote',
+;;    `toggle-icicle-remote-file-testing',
+;;    `toggle-icicle-search-cleanup',
+;;    `toggle-icicle-search-complementing-domain',
+;;    `toggle-icicle-search-replace-common-match',
+;;    `toggle-icicle-search-replace-whole',
+;;    `toggle-icicle-search-whole-word',
+;;    `toggle-icicle-show-multi-completion', `toggle-icicle-sorting',
+;;    `toggle-icicle-transforming',
+;;    `toggle-icicle-WYSIWYG-Completions'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `icicle-add/remove-tags-and-refresh',
+;;    `icicle-all-candidates-action-1', `icicle-all-exif-data',
+;;    `icicle-anychar-regexp', `icicle-apply-to-saved-candidate',
+;;    `icicle-apropos-complete-1',
+;;    `icicle-backward-delete-char-untabify-dots',
+;;    `icicle-bind-file-candidate-keys', `icicle-candidate-action-1',
+;;    `icicle-candidate-set-retrieve-1',
+;;    `icicle-candidate-set-save-1',
+;;    `icicle-candidate-set-save-selected-1',
+;;    `icicle-column-wise-cand-nb', `icicle-Completions-popup-choice',
+;;    `icicle-Completions-popup-choice-1', `icicle-convert-dots',
+;;    `icicle-current-completion-in-Completions',
+;;    `icicle-current-sort-functions', `icicle-current-sort-order',
+;;    `icicle-delete-backward-char-dots',
+;;    `icicle-delete-candidate-object-1', `icicle-delete-char-dots',
+;;    `icicle-delete-current-candidate-object',
+;;    `icicle-ensure-overriding-map-is-bound',
+;;    `icicle-help-on-candidate-symbol',
+;;    `icicle-input-is-a-completion-p', `icicle-insert-dot',
+;;    `icicle-insert-input', `icicle-insert-thing',
+;;    `icicle-looking-at-anychar-regexp-p',
+;;    `icicle-looking-back-at-anychar-regexp-p',
+;;    `icicle-markers-to-readable',
+;;    `icicle-maybe-multi-completion-completing-p',
+;;    `icicle-mouse-candidate-action-1', `icicle-nb-Completions-cols',
+;;    `icicle-nb-of-cand-at-Completions-pos',
+;;    `icicle-nb-of-cand-in-Completions-horiz',
+;;    `icicle-prefix-complete-1', `icicle-raise-Completions-frame',
+;;    `icicle-remove-cand-from-lists',
+;;    `icicle-remove-candidate-display-others',
+;;    `icicle-replace-input-w-parent-dir',
+;;    `icicle-retrieve-candidates-from-set',
+;;    `icicle-row-wise-cand-nb', `icicle-signum',
+;;    `icicle-substitute-keymap-vars', `icicle-successive-action',
+;;    `icicle-transform-sole-candidate',
+;;    `icicle-transpose-chars-dots',
+;;    `icicle-unbind-file-candidate-keys',
+;;    `icicle-upcase-if-ignore-case', `icicle-update-and-next'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `overriding-map-is-bound', `saved-overriding-map'.
+;;
+;;
+;;  ***** NOTE: These EMACS PRIMITIVES have been REDEFINED HERE:
+;;
+;;  `exit-minibuffer'              - Remove *Completion* window and
+;;                                   input mismatch highlighting
+;;  `minibuffer-complete-and-exit' - Use Icicles prefix completion
+;;
+;;
+;;  ***** NOTE: The following function defined in `mouse.el' has
+;;              been REDEFINED HERE:
+;;
+;;  `choose-completion'       - Don't iconify frame or bury buffer.
+;;  `mouse-choose-completion' - Return the number of the completion.
+;;
+;;
+;;  ***** NOTE: The following function defined in `simple.el' has
+;;              been REDEFINED HERE:
+;;
+;;  `switch-to-completions' - Always selects `*Completions*' window.
+;;
+;;
+;;  Key bindings made by Icicles: See "Key Bindings" in
+;;  `icicles-doc2.el'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Redefined standard commands")
+;;  (@> "Icicles commands")
+;;    (@> "Minibuffer editing commands")
+;;    (@> "Commands to sort completion candidates")
+;;    (@> "Other commands to be used mainly in the minibuffer")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;; case, flet, lexical-let, loop
+                                  ;; plus, for Emacs < 21: dolist, push
+(eval-when-compile (require 'filesets nil t)) ; Emacs 22+.
+  ;; filesets-data, filesets-entry-get-files, filesets-entry-mode, filesets-entry-set-files,
+  ;; filesets-files-equalp, filesets-init, filesets-member, filesets-set-config
+
+(eval-when-compile
+ (or (condition-case nil
+         (load-library "icicles-mac")   ; Use load-library to ensure latest .elc.
+       (error nil))
+     (require 'icicles-mac)))           ; Require, so can load separately if not on `load-path'.
+  ;; icicle-assoc-delete-all, icicle-define-sort-command
+(require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
+  ;; icicle-alternative-sort-comparer, icicle-move-Completions-frame,
+  ;; icicle-Completions-mouse-3-menu-entries, icicle-default-cycling-mode,
+  ;; icicle-default-thing-insertion, icicle-expand-input-to-common-match-flag,
+  ;; icicle-hide-common-match-in-Completions-flag, icicle-hide-non-matching-lines-flag,
+  ;; icicle-ignore-space-prefix-flag, icicle-incremental-completion-flag, icicle-input-string,
+  ;; icicle-key-descriptions-use-<>-flag, icicle-regexp-quote-flag, icicle-saved-completion-sets,
+  ;; icicle-search-cleanup-flag, icicle-search-highlight-all-current-flag, icicle-sort-comparer,
+  ;; icicle-sort-orders-alist, icicle-TAB-shows-candidates-flag, icicle-thing-at-point-functions,
+  ;; icicle-transform-function
+(eval-and-compile (require 'icicles-var)) ; (This is required anyway by `icicles-fn.el'.)
+  ;; lacarte-menu-items-alist, icicle-candidate-action-fn, icicle-candidate-nb,
+  ;; icicle-complete-keys-alist, icicle-completion-candidates, 
+  ;; icicle-current-completion-candidate-overlay, icicle-current-completion-mode,
+  ;; icicle-current-input, icicle-current-raw-input, icicle-default-directory,
+  ;; icicle-default-thing-insertion-flipped-p, icicle-edit-update-p, icicle-general-help-string,
+  ;; icicle-get-alist-candidate-function, icicle-ignored-extensions, icicle-ignored-extensions-regexp,
+  ;; icicle-incremental-completion-p, icicle-insert-string-at-pt-end, `icicle-insert-string-at-pt-start,
+  ;; icicle-last-completion-candidate, icicle-last-completion-command, icicle-last-input,
+  ;; icicle-last-sort-comparer, icicle-last-transform-function, 
+  ;; icicle-nb-of-other-cycle-candidates, icicle-pre-minibuffer-buffer,
+  ;; icicle-saved-candidates-variables-obarray, icicle-saved-completion-candidates,
+  ;; icicle-saved-ignored-extensions, icicle-successive-grab-count, icicle-thing-at-pt-fns-pointer,
+  ;; icicle-universal-argument-map, icicle-variable-name-history
+(require 'icicles-fn)
+  ;; icicle-isearch-complete-past-string, icicle-minibuf-input-sans-dir,
+  ;; icicle-toggle-icicle-mode-twice
+
+(require 'pp+ nil t) ;; (no error if not found): pp-eval-expression
+(require 'doremi nil t) ;; (no error if not found):
+                        ;; doremi, doremi(-boost)-(up|down)-keys, doremi-limit, doremi-wrap
+(when (> emacs-major-version 22) (require 'help-fns+ nil t)) ;; (no error if not found):
+                                                             ;; help-commands-to-key-buttons
+
+(eval-when-compile (require 'fit-frame nil t)) ;; (no error if not found): fit-frame
+(eval-when-compile
+ (when (> emacs-major-version 21) (require 'linkd nil t))) ;; (no error if not found): linkd-mode
+
+;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
+;; These are probably benign - ignore them.  Icicles is designed to work with multiple
+;; versions of Emacs, and that fact provokes compiler warnings.  If you get byte-compiler
+;; errors (not warnings), then please report a bug, using `M-x icicle-send-bug-report'.
+
+;; Some defvars to quiet byte-compiler a bit:
+
+(when (< emacs-major-version 22)
+  (defvar overriding-map-is-bound)
+  (defvar read-file-name-completion-ignore-case) ; In `minibuffer.el'
+  (defvar read-file-name-predicate)
+  (defvar saved-overriding-map))
+
+(when (< emacs-major-version 23)
+  (defvar read-buffer-completion-ignore-case)
+  (defvar mouse-drag-copy-region))
+
+(defvar doremi-boost-down-keys)         ; In `doremi.el'
+(defvar doremi-boost-up-keys)           ; In `doremi.el'
+(defvar doremi-down-keys)               ; In `doremi.el'
+(defvar doremi-up-keys)                 ; In `doremi.el'
+(defvar filesets-data)                  ; In `filesets.el'.
+(defvar ignore-comments-flag)           ; In `thing-cmds.el'.
+(defvar minibuffer-confirm-exit-commands) ; In `minibuffer.el' in Emacs 23+.
+(defvar minibuffer-local-filename-completion-map) ; In Emacs 22+.
+(defvar minibuffer-local-filename-must-match-map) ; In Emacs 23.2 (but not Emacs 24+).
+(defvar minibuffer-local-must-match-filename-map) ; In Emacs 22+.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Redefined standard commands")
+
+;;; Redefined standard commands --------------------------------------
+
+
+;; REPLACE ORIGINAL `next-history-element' in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Selects minibuffer contents and leaves point at its beginning.
+;;
+(unless (fboundp 'old-next-history-element)
+  (defalias 'old-next-history-element (symbol-function 'next-history-element)))
+
+;;;###autoload
+(defun icicle-next-history-element (arg) ; Bound to `M-n' in minibuffer.
+  "Insert the next element of the minibuffer history in the minibuffer.
+With argument N, it uses the Nth following element."
+  (interactive "p")
+  (old-next-history-element (prefix-numeric-value arg))
+  (when (and icicle-mode (memq icicle-default-value '(preselect-start preselect-end)))
+    (icicle-select-minibuffer-contents)
+    (setq deactivate-mark  nil)))
+
+
+;; REPLACE ORIGINAL `exit-minibuffer' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Remove input mismatch highlighting.
+;; Remove *Completion* window.
+;;
+(unless (fboundp 'old-exit-minibuffer)
+  (defalias 'old-exit-minibuffer (symbol-function 'exit-minibuffer)))
+
+;;;###autoload
+(defun icicle-exit-minibuffer ()        ; Bound to `C-m' (`RET') in minibuffer.
+  "Terminate this minibuffer argument.
+Remove `*Completions*' window.  Remove Icicles minibuffer faces."
+  ;; This removal lets users retrieve candidates that have other faces, and saves input-history space.
+  (interactive)
+  (when (active-minibuffer-window)
+    (with-current-buffer (window-buffer (minibuffer-window))
+      (let ((pos                (icicle-minibuffer-prompt-end))
+            (icy-minibuf-faces  '(icicle-input-completion-fail  icicle-input-completion-fail-lax
+                                  icicle-whitespace-highlight   icicle-match-highlight-minibuffer
+                                  icicle-complete-input))
+            (keep-faces         ()))
+        (while (< pos (point-max))
+          (let ((faces  (get-text-property pos 'face)))
+            (when (or (and (consp faces) (cdr faces) (atom (cdr faces))) ; (background-color . "abc")
+                      (and faces (atom faces))) ; face name
+              (setq faces  (list faces))) ; No-op: (foo (background-color . "abc") (:foreground "abc"))
+            (setq keep-faces  (icicle-set-union keep-faces
+                                                (icicle-set-difference faces icy-minibuf-faces))))
+          (setq pos  (1+ pos)))
+        (when keep-faces                ; Don't add a nil `face' property.
+          (put-text-property (icicle-minibuffer-prompt-end) (point-max) 'face keep-faces)))
+      ;; $$$$$  (let ((pos  (icicle-minibuffer-prompt-end)))
+      ;;     (while (< pos (point-max))
+      ;;       (when (memq (get-text-property pos 'face)
+      ;;                   '(icicle-input-completion-fail icicle-input-completion-fail-lax))
+      ;;         (remove-text-properties pos (point-max) '(face))
+      ;;         (setq pos  (point-max)))
+      ;;       (setq pos  (1+ pos))))
+      ))
+  (icicle-remove-Completions-window)
+  (old-exit-minibuffer))
+
+
+;; REPLACE ORIGINAL `minibuffer-complete-and-exit' (built-in function),
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Use Icicles completion.
+;;
+(unless (fboundp 'old-minibuffer-complete-and-exit)
+  (defalias 'old-minibuffer-complete-and-exit (symbol-function 'minibuffer-complete-and-exit)))
+
+;; Bound to `C-m' (`RET') in `minibuffer-local-must-match-map'.
+;;;###autoload
+(defun icicle-minibuffer-complete-and-exit ()
+  "If the minibuffer contents is a valid completion, then exit.
+Otherwise try to complete it."
+  (interactive)
+  (let ((last-cmd  last-command))
+    (cond ((string= "" (if (icicle-file-name-input-p) ;  Empty input - exit.
+                           (icicle-minibuf-input-sans-dir)
+                         (icicle-input-from-minibuffer)))
+           (icicle-exit-minibuffer))
+          ;; This case serves when property `icicle-display-string' is used.
+          ;; What's returned is the replacement display string, not the original candidate.
+          ;; If you want to get the original candidate back, you'll need to search the obarray for a
+          ;; symbol that has this `icicle-display-string' value.  Or put the symbol on the display
+          ;; string as a text property.
+          ((icicle-input-is-a-completion-p) (icicle-exit-minibuffer))
+          ((eq minibuffer-completion-confirm 'confirm) ; User wants it anyway? - Emacs 23+.
+           (if (eq last-cmd this-command)
+               (icicle-exit-minibuffer)
+             (minibuffer-message "Confirm")
+             nil))
+          ((eq minibuffer-completion-confirm 'confirm-after-completion) ; Emacs 23+.
+           ;; Similar to `confirm', but only if trying to exit immediately
+           ;; after completing (this catches most minibuffer typos).
+           (if (not (memq last-cmd (and (boundp 'minibuffer-confirm-exit-commands)
+                                        (append icicle-confirm-exit-commands
+                                                minibuffer-confirm-exit-commands))))
+               (icicle-exit-minibuffer)
+             (minibuffer-message "Confirm")
+             nil))
+          (t
+           (setq icicle-current-input  (icicle-input-from-minibuffer))
+           (let* (;; Bind these first two to suppress (a) the throw or (b) the message, highlighting,
+                  ;; mode-line help, and the wait involved in completing again.
+                  (icicle-prefix-complete-and-exit-p   t)
+                  (icicle-apropos-complete-and-exit-p  t)
+
+                  (candidates
+                   ;; If we're not using `icicle-candidates-alist', complete the input again.
+                   ;; If we're using `icicle-candidates-alist', try filtering it against just the
+                   ;; input.
+                   ;;   If the input is already complete, then we're done.  If not, then filtering
+                   ;;   will give nil and we will just continue to display the candidates.  If there
+                   ;;   are multiple matches, then the user can either cycle or complete again.
+                   (if (not icicle-candidates-alist)
+                       (if (eq icicle-current-completion-mode 'apropos)
+                           (icicle-apropos-complete-no-display 'nomsg)
+                         (icicle-prefix-complete-no-display 'nomsg))
+                     (icicle-filter-alist icicle-candidates-alist (list icicle-current-input)))))
+             (cond ((and (eq icicle-require-match-p t) ; Don't exit if non-nil and non-t.
+                         (icicle-input-is-a-completion-p))
+                    (icicle-exit-minibuffer))
+                   (t
+                    (icicle-display-candidates-in-Completions))))))))
+
+(defun icicle-upcase-if-ignore-case (string)
+  "Return (icicle-upcase STRING) if `completion-ignore-case', else STRING."
+  (if completion-ignore-case (icicle-upcase string) string))
+
+;;;###autoload
+(defun icicle-apropos-complete-and-exit () ; Bound to `S-RET' in `minibuffer-local-must-match-map'.
+  "If the minibuffer contents is a valid apropos completion, then exit.
+Otherwise try to complete it.  If completion leads to a valid
+completion, then exit.
+This is to `minibuffer-complete-and-exit' as `icicle-apropos-complete'
+is to `minibuffer-complete'.  That is, it is the regexp-match version."
+  (interactive)
+  (setq icicle-last-input  (icicle-input-from-minibuffer))
+  (let* ((icicle-apropos-complete-and-exit-p  t) ; Suppress the throw or the msg plus the wait.
+         (candidates                          (icicle-apropos-complete)))
+    (when (and candidates (null (cdr candidates))) (old-exit-minibuffer)))) ; Single candidate.
+
+
+;; REPLACE ORIGINAL `choose-completion' in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Don't iconify frame or bury buffer.
+;; Don't strip text properties.
+;;
+(unless (fboundp 'old-choose-completion)
+  (defalias 'old-choose-completion (symbol-function 'choose-completion)))
+
+;;;###autoload
+(defun icicle-choose-completion ()
+  "Choose the completion that point is in or next to."
+  (interactive)
+  (let ((buffer     completion-reference-buffer)
+	(base-size  completion-base-size)
+        beg end completion)
+    (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+      (setq end  (point)
+            beg  (1+ (point))))
+    (when (and (>= (point) (icicle-start-of-candidates-in-Completions))
+               (get-text-property (1- (point)) 'mouse-face))
+      (setq end  (1- (point))
+            beg  (point)))
+    (unless beg	(error "No completion here"))
+    (setq beg         (previous-single-property-change beg 'mouse-face)
+          end         (or (next-single-property-change end 'mouse-face) (point-max))
+          ;; $$$$ completion  (buffer-substring-no-properties beg end))
+          completion  (buffer-substring beg end))
+    ;; (let ((owindow  (selected-window)))
+    ;;   (if (and (one-window-p t 'selected-frame) (window-dedicated-p (selected-window)))
+    ;;    (iconify-frame (selected-frame)) ; Iconify special buffer's frame
+    ;;  (or (window-dedicated-p (selected-window)) (bury-buffer)))
+    ;;   (select-window owindow))
+    (unless (or (not (member completion icicle-extra-candidates))
+                icicle-extra-candidates-dir-insert-p)
+      (setq base-size  0))
+    (choose-completion-string completion buffer base-size)))
+
+
+;; REPLACE ORIGINAL `mouse-choose-completion' in `mouse.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Return the number of the completion.
+;; Don't strip text properties.
+;;
+(when (and (fboundp 'mouse-choose-completion) (not (fboundp 'old-mouse-choose-completion)))
+  (defalias 'old-mouse-choose-completion (symbol-function 'mouse-choose-completion)))
+
+;;;###autoload
+(defun icicle-mouse-choose-completion (event) ; Bound to `mouse-2' in `*Completions*'.
+  "Click a completion candidate in buffer `*Completions*', to choose it.
+Return the number of the candidate: 0 for first, 1 for second, ..."
+  (interactive "e")
+  ;; $$$$$ (unless (active-minibuffer-window) (error "Minibuffer is not active"))
+  ;; Give temporary modes such as isearch a chance to turn off.
+  (run-hooks 'mouse-leave-buffer-hook)
+  (let ((buffer  (window-buffer))
+         ;; $$$$$$ (icicle-orig-buff  buffer)
+        choice base-size)
+    (with-current-buffer (window-buffer (posn-window (event-start event)))
+      (save-excursion
+        (when completion-reference-buffer (setq buffer  completion-reference-buffer))
+        (setq base-size  completion-base-size)
+        (save-excursion
+          (goto-char (posn-point (event-start event)))
+          (let (beg end)
+            (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+              (setq end  (point)
+                    beg  (1+ (point))))
+            (unless beg (error "No completion here"))
+            (setq beg  (previous-single-property-change beg 'mouse-face)
+                  end  (or (next-single-property-change end 'mouse-face) (point-max)))
+            ;; `icicle-insert-candidates' doesn't put `mouse-face' on the final \n of a candidate
+            ;; in `*Completions*'. Add the newline back. `icicle-insert-candidates' puts property
+            ;; `icicle-keep-newline' on the newline if it is part of the candidate, as opposed to
+            ;; being just part of the display in columns.
+            (when (and (eq ?\n (char-after end)) (get-text-property end 'icicle-keep-newline))
+              (setq end  (1+ end)))
+            ;; $$$$$$ (setq choice  (buffer-substring-no-properties beg end)))))
+            (setq choice  (buffer-substring beg end))))))
+    ;; $$$$$ (if (eq icicle-orig-buff (get-buffer "*Completions*"))
+    ;;    (icicle-remove-Completions-window)
+    ;;    (save-selected-window (icicle-remove-Completions-window)))
+    (setq icicle-candidate-nb  (icicle-nb-of-cand-at-Completions-pos (posn-point (event-start event))))
+    (when (and (icicle-file-name-input-p) insert-default-directory
+               (or (not (member choice icicle-extra-candidates))
+                   icicle-extra-candidates-dir-insert-p))
+      (let ((dir  (icicle-file-name-directory-w-default icicle-current-input)))
+        (with-current-buffer buffer
+          (icicle-clear-minibuffer)
+          (insert dir)
+          (setq choice     (concat dir choice)
+                base-size  0))))
+    (choose-completion-string choice buffer base-size))
+  icicle-candidate-nb)
+
+(defun icicle-nb-of-cand-at-Completions-pos (position)
+  "Return number of candidate at POSITION in `*Completions*'.
+POSITION is a buffer position."
+  (let ((hor-nb  (icicle-nb-of-cand-in-Completions-horiz position)))
+    (save-excursion
+      (with-current-buffer (get-buffer "*Completions*")
+        (goto-char position)
+        (if (memq icicle-completions-format '(horizontal nil))
+            hor-nb
+          (let* ((cols      (icicle-nb-Completions-cols))
+                 (nb-cands  (length icicle-completion-candidates))
+                 (rows      (/ nb-cands cols)))
+            (unless (zerop (% nb-cands cols)) (setq rows  (1+ rows)))
+            (icicle-column-wise-cand-nb hor-nb nb-cands rows cols)))))))
+
+(defun icicle-nb-of-cand-in-Completions-horiz (position)
+  "Return number of horizontal candidate at POSITION in `*Completions*'.
+POSITION is a buffer position."
+  (let ((compl-buf  (get-buffer "*Completions*")))
+    (unless compl-buf (error "No `*Completions*' buffer"))
+    (save-window-excursion
+      (set-buffer compl-buf)
+      (goto-char position)
+      ;; If in a completion, move to its start, and set POSITION there.
+      (let ((prop  (get-text-property  (1- (point)) 'mouse-face)))
+        (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+          (goto-char (previous-single-property-change (point) 'mouse-face nil
+                                                      (icicle-start-of-candidates-in-Completions)))))
+      (setq position  (point))
+      ;; Binary search.
+      (let ((cand-nb                             (/ (length icicle-completion-candidates) 2))
+            (last-nb                             0)
+            (icicle-completions-format           'horizontal)
+            delta)
+        (goto-char (point-min))
+        (icicle-move-to-next-completion cand-nb t)
+        (while (/= (point) position)
+          (setq delta    (max 1 (/ (abs (- cand-nb last-nb)) 2))
+                last-nb  cand-nb)
+          (cond ((< (point) position)
+                 (icicle-move-to-next-completion delta t)
+                 (setq cand-nb  (+ cand-nb delta)))
+                (t
+                 (icicle-move-to-next-completion (- delta) t)
+                 (setq cand-nb  (- cand-nb delta)))))
+        (set-buffer-modified-p nil)
+        (1- cand-nb)))))
+
+(defun icicle-nb-Completions-cols ()
+  "Return the number of candidate columns in `*Completions*'."
+  (let* ((start       (icicle-start-of-candidates-in-Completions))
+         (eol         (save-excursion (goto-char start) (line-end-position)))
+         (mouse-chgs  0)
+         mousef)
+    (save-excursion
+      (goto-char start)
+      (while (< (point) eol)
+        (setq mousef  (next-single-property-change (point) 'mouse-face nil eol))
+        (when mousef
+          (goto-char mousef)
+          (setq mouse-chgs  (1+ mouse-chgs)))))
+    (/ (1+ mouse-chgs) 2)))             ; Return # of columns.
+
+(defun icicle-column-wise-cand-nb (horiz-nb nb-cands rows cols)
+  "Column-wise number of horizontal candidate number HORIZ-NB."
+  (let ((row-lim  (- rows (- (* rows cols) nb-cands)))
+        (row      (/ horiz-nb cols))
+        (col      (mod horiz-nb cols))
+        nb)
+    (setq nb  (+ row (* col rows)))
+    (when (>= row row-lim)
+      (setq cols      (1- cols)
+            horiz-nb  (- horiz-nb row-lim)
+            row       (/ horiz-nb cols)
+            col       (mod horiz-nb cols)
+            nb        (+ row (* col rows))))
+    nb))
+
+(defun icicle-row-wise-cand-nb (vert-nb nb-cands rows cols)
+  "Row-wise number of vertical candidate number VERT-NB."
+  (let* ((row  (mod vert-nb rows))
+         (col  (/ vert-nb rows))
+         (nb   (+ col (* row cols)))
+         (lim  (- rows (- (* rows cols) nb-cands))))
+    (when (> row lim) (setq nb  (- nb (- row lim))))
+    nb))
+
+
+;; REPLACE ORIGINAL `switch-to-completions' defined in `simple.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Selects `*Completions*' window even if on another frame.
+;;
+(unless (fboundp 'old-switch-to-completions)
+  (defalias 'old-switch-to-completions (symbol-function 'switch-to-completions)))
+
+;;;###autoload
+(defun icicle-switch-to-completions ()
+  "Select the completion list window, `*Completions*'."
+  (interactive)
+  ;; Make sure we have a completions window.
+  (or (get-buffer-window "*Completions*") (minibuffer-completion-help))
+  (let ((window  (get-buffer-window "*Completions*" 0))) ; Added 0 arg.
+    (when window
+      (select-window window)
+      (goto-char (icicle-start-of-candidates-in-Completions)))))
+
+;; The branch that deletes a history element is based on Juri Linkov's
+;; `delete-history-element', proposed for Emacs 22 but rejected by RMS.
+;;;###autoload
+(defun icicle-erase-minibuffer-or-history-element () ; Bound to `M-k' in minibuffer.
+  "`icicle-erase-minibuffer' or, if using history, delete history element."
+  (interactive)
+  (if (not (memq last-command '(previous-history-element next-history-element
+                                icicle-erase-minibuffer-or-history-element
+                                previous-matching-history-element next-matching-history-element)))
+      (icicle-erase-minibuffer)
+    (let* ((curr-pos  (1- minibuffer-history-position))
+           (current   (nth curr-pos (and (boundp minibuffer-history-variable)
+                                         (symbol-value minibuffer-history-variable)))))
+      (cond ((= minibuffer-history-position 1)
+             (set minibuffer-history-variable (and (boundp minibuffer-history-variable)
+                                                   (cdr (symbol-value minibuffer-history-variable)))))
+            ((> minibuffer-history-position 1)
+             (setcdr (nthcdr (- minibuffer-history-position 2)
+                             (and (boundp minibuffer-history-variable)
+                                  (symbol-value minibuffer-history-variable)))
+                     (nthcdr minibuffer-history-position
+                             (and (boundp minibuffer-history-variable)
+                                  (symbol-value minibuffer-history-variable))))))
+      (condition-case nil
+          (cond ((memq last-command '(next-history-element next-matching-history-element))
+                 (next-history-element 1)
+                 (setq this-command  'next-history-element))
+                ((memq last-command '(previous-history-element previous-matching-history-element))
+                 (next-history-element 1)
+                 (previous-history-element 1)
+                 (setq this-command  'previous-history-element)))
+        (error (icicle-condition-case-no-debug nil
+                   (cond ((memq last-command '(next-history-element next-matching-history-element))
+                          (previous-history-element 1)
+                          (setq this-command  'previous-history-element))
+                         ((memq last-command
+                                '(previous-history-element previous-matching-history-element))
+                          (next-history-element 1)
+                          (setq this-command  'next-history-element)))
+                 (error nil))))
+      (when (and current (wholenump curr-pos))
+        (icicle-msg-maybe-in-minibuffer "Deleted `%s'" current)))))
+ 
+;;(@* "Icicles commands")
+
+;;; Icicles commands -------------------------------------------------
+
+;;(@* "Minibuffer editing commands")
+
+;;; Minibuffer editing commands  . . . . . . . . . . . . . . . . . . .
+;;;
+;;; All except `icicle-erase-minibuffer' are bound in the minibuffer to whatever the same
+;;; command without `icicle-' is bound to globally.
+
+(defun icicle-looking-back-at-anychar-regexp-p ()
+  "Return non-nil if `icicle-anychar-regexp' immediately precedes point."
+  (let ((len  (length icicle-anychar-regexp)))
+    (save-excursion (save-match-data
+                      (search-backward icicle-anychar-regexp
+                                       (max (- (point) len) (icicle-minibuffer-prompt-end)) t)))))
+
+(defun icicle-looking-at-anychar-regexp-p ()
+  "Return non-nil if `icicle-anychar-regexp' immediately succeeds point."
+  (let ((len  (length icicle-anychar-regexp)))
+    (save-excursion (save-match-data
+                      (search-forward icicle-anychar-regexp (min (+ (point) len) (point-max)) t)))))
+
+;;;###autoload
+(defun icicle-forward-char-dots (&optional n)
+  "Move forward N chars (backward if N is negative).  Handles dots (`.')."
+  (interactive "p")
+  (let ((len  (length icicle-anychar-regexp)))
+    (dotimes (i  (abs n))
+      (or (save-match-data
+            (if (wholenump n)
+                (search-forward icicle-anychar-regexp (min (+ (point) len) (point-max)) t)
+              (search-backward icicle-anychar-regexp
+                               (max (- (point) len) (icicle-minibuffer-prompt-end)) t)))
+          (forward-char (if (wholenump n) 1 -1))))))
+
+;;;###autoload
+(defun icicle-backward-char-dots (&optional n)
+  "Move backward N chars (forward if N is negative).  Handles dots (`.')."
+  (interactive "p")
+  (icicle-forward-char-dots (- n)))
+
+
+;; Make delete-selection mode recognize it, so region is deleted.
+(put 'icicle-backward-delete-char-untabify 'delete-selection 'supersede)
+;;;###autoload
+(defun icicle-backward-delete-char-untabify (n &optional killflag)
+  "`backward-delete-char-untabify' + update `*Completions*' with matches.
+Handles Icicles dots (`.')."
+  (interactive "*p\nP")
+  (icicle-call-then-update-Completions #'icicle-backward-delete-char-untabify-dots n killflag))
+
+(defun icicle-backward-delete-char-untabify-dots (n killflag)
+  "`backward-delete-char-untabify', but also handle dots (`.')."
+  (let ((len  (length icicle-anychar-regexp)))
+    (dotimes (i  (abs n))
+      (if (icicle-looking-back-at-anychar-regexp-p)
+          (backward-delete-char-untabify len killflag)
+        (backward-delete-char-untabify 1 killflag)))))
+
+
+;; Make delete-selection mode recognize it, so region is deleted.
+(put 'icicle-delete-backward-char 'delete-selection 'supersede)
+;;;###autoload
+(defun icicle-delete-backward-char (n &optional killflag) ; Bound to `DEL' in minibuffer.
+  "`delete-backward-char' and update `*Completions*' with input matches.
+Handles Icicles dots (`.')."
+  (interactive "*p\nP")
+  (icicle-call-then-update-Completions #'icicle-delete-backward-char-dots n killflag))
+
+(defun icicle-delete-backward-char-dots (n killflag)
+  "`delete-backward-char', but also handle dots (`.')."
+  (let ((len  (length icicle-anychar-regexp)))
+    (dotimes (i  (abs n))
+      (if (icicle-looking-back-at-anychar-regexp-p)
+          (delete-char (- len) killflag)
+        (delete-char -1 killflag)))))
+
+
+;; Make delete-selection mode recognize it, so region is deleted.
+(put 'icicle-delete-char 'delete-selection 'supersede)
+;;;###autoload
+(defun icicle-delete-char (n &optional killflag) ; Bound to `C-d' in minibuffer.
+  "`delete-char' and update `*Completions*' with input matches.
+Handles Icicles dots (`.')."
+  (interactive "*p\nP")
+  (icicle-call-then-update-Completions #'icicle-delete-char-dots n killflag))
+
+(defun icicle-delete-char-dots (n killflag)
+  "`delete-char', but also handle dots (`.')."
+  (let ((len  (length icicle-anychar-regexp)))
+    (dotimes (i  (abs n))
+      (if (icicle-looking-at-anychar-regexp-p)
+          (delete-char len killflag)
+        (delete-char 1 killflag)))))
+
+;;;###autoload
+(defun icicle-backward-kill-word (arg)  ; Bound to `M-DEL' (`M-backspace') in minibuffer.
+  "`backward-kill-word' and update `*Completions*' with input matches.
+See description of `backward-kill-word'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'backward-kill-word arg))
+
+;;;###autoload
+(defun icicle-kill-word (arg)           ; Bound to `M-d' in minibuffer.
+  "`kill-word' and update `*Completions*' with regexp input matches.
+See description of `kill-word'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'kill-word arg))
+
+;;;###autoload
+(defun icicle-backward-kill-sexp (arg)  ; Bound to `C-M-backspace' in minibuffer.
+  "`backward-kill-sexp' and update `*Completions*' with input matches.
+See description of `backward-kill-sexp'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'backward-kill-sexp arg))
+
+;;;###autoload
+(defun icicle-kill-sexp (arg)           ; Bound to `C-M-delete' and `C-M-k' in minibuffer.
+  "`kill-sexp' and update `*Completions*' with regexp input matches.
+See description of `kill-sexp'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'kill-sexp arg))
+
+;;;###autoload
+(defun icicle-backward-kill-sentence (arg) ; Bound to `C-x DEL' in minibuffer.
+  "`backward-kill-sentence' and update `*Completions*' with input matches.
+See description of `backward-kill-sentence'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'backward-kill-sentence arg))
+
+;;;###autoload
+(defun icicle-kill-sentence (arg)
+  "`kill-sentence' and update `*Completions*' with regexp input matches.
+See description of `kill-sentence'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'kill-sentence arg))
+
+;;;###autoload
+(defun icicle-backward-kill-paragraph (arg) ; Bound to `C-backspace' in minibuffer, except for files.
+  "`backward-kill-paragraph' and update `*Completions*' with input matches.
+See description of `backward-kill-paragraph'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'backward-kill-paragraph arg))
+
+;;;###autoload
+(defun icicle-kill-paragraph (arg)      ; Bound to `C-delete' in minibuffer.
+  "`kill-paragraph' and update `*Completions*' with regexp input matches.
+See description of `kill-paragraph'."
+  (interactive "p")
+  (icicle-call-then-update-Completions #'kill-paragraph arg))
+
+;;;###autoload
+(defun icicle-kill-line (arg)           ; Bound to `C-k' and `deleteline' in minibuffer.
+  "`kill-line' and update `*Completions*' with regexp input matches.
+See description of `kill-line'."
+  (interactive "P")
+  (icicle-call-then-update-Completions #'kill-line arg))
+
+;;;###autoload
+(defun icicle-kill-region (beg end)     ; Bound to `C-w' in minibuffer.
+;; Don't bother with Emacs 22 optional 3rd arg.
+  "`kill-region' and update `*Completions*' with regexp input matches.
+See description of `kill-region'."
+  (interactive "r")
+  (icicle-call-then-update-Completions #'kill-region beg end))
+
+(when (fboundp 'kill-region-wimpy)
+  (defun icicle-kill-region-wimpy (beg end) ; Bound to `C-w' in minibuffer.
+    "`kill-region-wimpy' and update `*Completions*' with input matches.
+See description of `kill-region-wimpy'."
+    (interactive "r")
+    (icicle-call-then-update-Completions #'kill-region-wimpy beg end)))
+
+;;;###autoload
+(defun icicle-make-directory (dir)
+  "Create a directory."
+  (interactive
+   (let ((enable-recursive-minibuffers  t))
+     (list (funcall (if (fboundp 'read-directory-name) #'read-directory-name #'read-file-name)
+                    "Create directory: " default-directory default-directory))))
+  (setq dir  (directory-file-name (expand-file-name dir)))
+  (while (file-exists-p dir)
+    (message "%s already exists" dir) (sit-for 1)
+    (let ((enable-recursive-minibuffers  t))
+      (setq dir  (funcall (if (fboundp 'read-directory-name) #'read-directory-name #'read-file-name)
+                          "Create directory: " default-directory default-directory))))
+  ;;(setq dir  (directory-file-name (expand-file-name dir)))
+  (if (not (y-or-n-p (format "Really create %s? " (file-name-as-directory dir))))
+      (message "Directory creation canceled")
+    (make-directory dir 'PARENTS-TOO)
+    (unless (file-accessible-directory-p dir)
+      (error "Could not create %s" (file-name-as-directory dir)))
+    (message "Created %s" (file-name-as-directory dir))))
+
+;;;###autoload
+(defun icicle-up-directory () ; Bound to `C-backspace' in minibuffer, for file-name completion.
+  "Replace minibuffer input with parent directory, then upate `*Completions*'."
+  (interactive)
+  (icicle-call-then-update-Completions #'icicle-replace-input-w-parent-dir))
+
+;;;###autoload
+(defun icicle-replace-input-w-parent-dir ()
+  "Replace minibuffer input with the parent directory."
+  (interactive)
+  (goto-char (point-max))
+  (let ((directoryp  (equal ?/ (char-before)))
+        (bob         (icicle-minibuffer-prompt-end)))
+    (while (and (> (point) bob) (not (equal ?/ (char-before))))  (delete-char -1))
+    (when directoryp
+      (delete-char -1)
+      (while (and (> (point) bob) (not (equal ?/ (char-before))))  (delete-char -1)))))
+
+;;; ;;;###autoload
+;;; (defun icicle-kill-failed-input ()      ; Bound to `C-M-l' in minibuffer during completion.
+;;;   "Kill (delete) the part of the input that does not complete.
+;;; Repeat to delete more."
+;;;   (interactive)
+;;;   (goto-char (1- (point-max)))
+;;;   (while (and (not (bobp))
+;;;               (memq (get-text-property (point) 'face)
+;;;                     '(icicle-input-completion-fail icicle-input-completion-fail-lax)))
+;;;     (delete-char 1)
+;;;     (backward-char 1))
+;;;   (unless (eobp) (forward-char))
+;;;   (icicle-highlight-input-noncompletion))
+
+;;;###autoload
+(defun icicle-goto/kill-failed-input () ; Bound to `C-M-l' in minibuffer during completion.
+  "Go to start of input portion that does not complete.  Repeat to kill.
+Kill (delete) the part of the input that does not complete.
+Repeat to delete more."
+  (interactive)
+  (if (eq last-command this-command)
+      (unless (eobp) (kill-line))
+    (when (and (overlayp icicle-input-completion-fail-overlay)
+               (overlay-start icicle-input-completion-fail-overlay))
+      (goto-char (overlay-start icicle-input-completion-fail-overlay)))))
+
+;;;###autoload
+(defun icicle-transpose-chars (arg)     ; Bound to `C-t' in minibuffer.
+  "`transpose-chars' and update `*Completions*' with regexp input matches.
+Handles Icicles dots (`.')."
+  (interactive "*P")
+  (icicle-call-then-update-Completions #'icicle-transpose-chars-dots arg))
+
+(defun icicle-transpose-chars-dots (arg)
+  "`transpose-chars', but also handle dots (`.')."
+  (and (null arg) (eolp) (icicle-forward-char-dots -1))
+  (transpose-subr 'icicle-forward-char-dots (prefix-numeric-value arg)))
+
+;;;###autoload
+(defun icicle-transpose-words (arg)     ; Bound to `M-t' in minibuffer.
+  "`transpose-words' and update `*Completions*' with regexp input matches.
+See description of `transpose-words'."
+  (interactive "*p")
+  (icicle-call-then-update-Completions #'transpose-words arg))
+
+;;;###autoload
+(defun icicle-transpose-sexps (arg)    ; Bound to `C-M-t' in minibuffer.
+  "`transpose-sexps' and update `*Completions*' with regexp input matches.
+See description of `transpose-sexps'."
+  (interactive "*p")
+  (icicle-call-then-update-Completions #'transpose-sexps arg))
+
+;;;###autoload
+(defun icicle-yank (arg)                ; Bound to `C-y' and `S-insert' in minibuffer.
+  "`yank' and update `*Completions*' with regexp input matches.
+See description of `yank'."
+  (interactive "*P")
+  (icicle-call-then-update-Completions #'yank arg))
+
+;;;###autoload
+(defun icicle-yank-pop (arg)            ; Bound to `M-y' and `M-insert' in minibuffer.
+  "`yank-pop' and update `*Completions*' with regexp input matches.
+See description of `yank-pop'."
+  (interactive "*p")
+  (icicle-call-then-update-Completions #'yank-pop arg))
+
+(when (fboundp 'yank-secondary)         ; In `second-sel.el'.
+  (defun icicle-yank-secondary ()       ; Bound to `C-M-y' in minibuffer.
+    "Insert the secondary selection at point.
+Move point to the end of the inserted text.  Does not change mark."
+    (interactive "*")
+    (icicle-call-then-update-Completions #'yank-secondary))
+  ;; Tell `delete-selection-mode' to replace active region by yanked secondary selection.
+  (put 'icicle-yank-secondary 'delete-selection 'yank))
+
+
+;; Tell `delete-selection-mode' to replace active region by yanked secondary selection.
+(put 'icicle-mouse-yank-secondary 'delete-selection 'yank)
+;;;###autoload
+(defun icicle-mouse-yank-secondary (event) ; Bound to `M-mouse-2' in minibuffer.
+  "Insert the secondary selection where you click.
+Move point to the end of the inserted text.
+If `mouse-yank-at-point' is non-nil, insert at point
+regardless of where you click."
+  (interactive "*e")
+  (if (fboundp 'yank-secondary)         ; In `mouse+.el'.
+      (icicle-call-then-update-Completions #'mouse-yank-secondary event current-prefix-arg)
+    (icicle-call-then-update-Completions #'mouse-yank-secondary event)))
+
+
+;; Make delete-selection mode recognize self-insertion, so it replaces region text.
+(put 'icicle-self-insert 'delete-selection t)
+;;;###autoload
+(defun icicle-self-insert (n) ;; Bound in minibuffer to stuff bound globally to `self-insert-command'.
+  "`self-insert' and update `*Completions*' with regexp input matches.
+See description of `self-insert'."
+  (interactive "p")
+  (if executing-kbd-macro
+      (funcall #'self-insert-command n)
+    (icicle-call-then-update-Completions #'self-insert-command n)))
+
+;;;###autoload
+(defun icicle-insert-a-space ()
+  "Insert a space.
+For convenience in the minibuffer - does the same thing as `C-q SPC'.
+To use this, bind it to some key sequence in keymaps
+`minibuffer-local-completion-map',
+`minibuffer-local-filename-completion-map', and
+`minibuffer-local-must-match-map'."
+  (interactive) (insert ?\ ))
+
+;;;###autoload
+(defun icicle-insert-dot-command (&optional arg) ; Bound to `.' in minibuffer during completion.
+  "Insert `icicle-dot-string': either `.' or `icicle-anychar-regexp'.
+With a numeric prefix argument, insert the dot that many times.
+
+With a plain prefix arg (`C-u'), insert the opposite kind of dot
+\(once) from what is indicated by the current value of
+`icicle-dot-string'."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (if (consp arg)
+      (let ((opposite  (if (string= icicle-dot-string-internal ".")
+                           (icicle-anychar-regexp)
+                         (let ((strg  "."))
+                           (add-text-properties
+                            0 1 '(icicle-user-plain-dot t rear-nonsticky (icicle-user-plain-dot))
+                            strg)
+                           strg))))
+        (if executing-kbd-macro
+            (insert opposite)
+          (icicle-call-then-update-Completions (lambda () (insert opposite)))))
+    (setq arg  (prefix-numeric-value arg))
+    (if executing-kbd-macro
+        (funcall #'icicle-insert-dot arg)
+      (icicle-call-then-update-Completions #'icicle-insert-dot arg))))
+
+(defun icicle-insert-dot (n)
+  "Insert `icicle-dot-string' N times."
+  (dotimes (i n)
+    (if (not (string= icicle-dot-string-internal "."))
+        (insert (icicle-anychar-regexp))
+      (insert ".")
+      (add-text-properties (1- (point)) (point) '(icicle-user-plain-dot t rear-nonsticky t)))))
+
+(defun icicle-anychar-regexp ()
+  "Return a regexp that matches any single character, including newline.
+The value returned is like that of constant `icicle-anychar-regexp',
+but the `display' string is unique for each call."
+  (let ((strg  (copy-sequence "\\(.\\|[\n]\\)")))
+    (set-text-properties 0 (length strg)
+                         (if icicle-dot-show-regexp-flag
+                             '(face highlight rear-nonsticky t)
+                           `(display ,(copy-sequence ".") face highlight rear-nonsticky t))
+                         strg)
+    strg))
+
+;;;###autoload
+(defun icicle-erase-minibuffer ()       ; Bound to `M-S-backspace', `M-S-delete' in minibuffer.
+  "Delete all user input in the minibuffer, then update completions."
+  (interactive)
+  (icicle-call-then-update-Completions #'icicle-clear-minibuffer))
+ 
+;;(@* "Commands to sort completion candidates")
+
+;;; Commands to sort completion candidates . . . . . . . . . . . . . .
+
+;; We don't bother to define a command for the sort functions `icicle-prefix-keys-first-p' and
+;; `icicle-command-names-alphabetic-p'.  They are bound in `icicle-complete-keys'.
+
+;; The order here defines the reverse order of `icicle-sort-orders-alist'.
+;; The first here is also the default sort order.  Entries are traversed by `C-,' in
+;; `icicle-sort-orders-alist' order.
+
+;;;###autoload (autoload 'icicle-sort-alphabetical "icicles-mcmd.el")
+(icicle-define-sort-command "alphabetical" ; `icicle-sort-alphabetical'
+    icicle-case-string-less-p
+  "Sort completion candidates alphabetically.
+Ignore letter case if `completion-ignore-case' or `case-fold-search'
+is non-nil.")
+
+;;;###autoload (autoload 'icicle-sort-special-candidates-first "icicles-mcmd.el")
+(icicle-define-sort-command "special candidates first" ; `icicle-sort-special-candidates-first'
+    icicle-special-candidates-first-p
+  "Sort completion candidates by putting special candidates first.
+Otherwise, sorting is alphabetical.  Ignore letter case if
+`completion-ignore-case' or `case-fold-search' is non-nil.")
+
+;;;###autoload (autoload 'icicle-sort-extra-candidates-first "icicles-mcmd.el")
+(icicle-define-sort-command "extra candidates first" ; `icicle-sort-extra-candidates-first'
+    icicle-extra-candidates-first-p
+  "Sort completion candidates by putting extra candidates first.
+Otherwise, sorting is alphabetical.  Ignore letter case if
+`completion-ignore-case' or `case-fold-search' is non-nil.
+An extra candidate is one that is a member of
+`icicle-extra-candidates'.")
+
+;;;###autoload (autoload 'icicle-sort-proxy-candidates-first "icicles-mcmd.el")
+(icicle-define-sort-command "proxy candidates first" ; `icicle-sort-proxy-candidates-first'
+    icicle-proxy-candidate-first-p
+  "Sort completion candidates by putting proxy candidates first.
+Otherwise, sorting is alphabetical.  Ignore letter case if
+`completion-ignore-case' or `case-fold-search' is non-nil.")
+
+;;;###autoload (autoload 'icicle-sort-case-insensitive "icicles-mcmd.el")
+(icicle-define-sort-command "case insensitive" ; `icicle-sort-case-insensitive'
+    icicle-case-insensitive-string-less-p
+  "Sort completion candidates alphabetically, but case-insenstively.")
+
+;;;###autoload (autoload 'icicle-sort-by-2nd-parts-alphabetically "icicles-mcmd.el")
+(icicle-define-sort-command "by 2nd parts alphabetically" ; `icicle-sort-by-2nd-parts-alphabetically'
+    icicle-2nd-part-string-less-p
+  "Sort multi-completion candidates alphabetically by their second parts.
+After that, sort alphabetically by the first parts.  Ignore letter
+case if `completion-ignore-case' or `case-fold-search' is non-nil.")
+
+;;;###autoload (autoload 'icicle-sort-by-last-file-modification-time "icicles-mcmd.el")
+(icicle-define-sort-command "by last file modification time"
+    icicle-last-modified-first-p        ; `icicle-sort-by-last-file-modification-time'
+  "Sort file-name completion candidates in order of last modification.
+If not doing file-name completion, then sort alphabetically.")
+
+;;;###autoload (autoload 'icicle-sort-by-file-type "icicles-mcmd.el")
+(icicle-define-sort-command "by file type" ; `icicle-sort-by-file-type'
+    icicle-file-type-less-p
+  "Sort file-name completion candidates by file type.
+Directories sort first, alphabetically.
+Then sort by file type (extension), alphabetically.
+Sort names that have the same extension alphabetically.
+If not doing file-name completion, sort candidates alphabetically.")
+
+;;;###autoload (autoload 'icicle-sort-by-directories-first "icicles-mcmd.el")
+(icicle-define-sort-command "by directories first" ; `icicle-sort-by-directories-first'
+    icicle-dirs-first-p
+  "Sort file-name completion candidates so that directories are first.
+If not doing file-name completion, then sort alphabetically.")
+
+;;;###autoload (autoload 'icicle-sort-by-directories-last "icicles-mcmd.el")
+(icicle-define-sort-command "by directories last" ; `icicle-sort-by-directories-last'
+    icicle-dirs-last-p
+  "Sort file-name completion candidates so that directories are last.
+If not doing file-name completion, then sort alphabetically.")
+
+;;;###autoload (autoload 'icicle-sort-by-last-use-as-input "icicles-mcmd.el")
+(icicle-define-sort-command "by last use as input" ; `icicle-sort-by-last-use-as-input'
+    icicle-most-recent-first-p
+  "Sort completion candidates in order of last use as minibuffer input.")
+
+;;;###autoload (autoload 'icicle-sort-by-previous-use-alphabetically "icicles-mcmd.el")
+(icicle-define-sort-command "by previous use alphabetically"
+    icicle-historical-alphabetic-p      ; `icicle-sort-by-previous-use-alphabetically'
+  "Sort completion candidates by previous use and alphabetically.
+Candidates matching previous inputs are available first.  Candidates
+are in two groups, each of which is sorted alphabetically separately:
+those matching previous inputs, followed by those that have not yet
+been used.")
+
+;;;###autoload (autoload 'icicle-sort-by-abbrev-frequency "icicles-mcmd.el")
+(icicle-define-sort-command "by abbrev frequency" ; `icicle-sort-by-abbrev-frequency'
+    icicle-command-abbrev-used-more-p
+  "Sort abbrev completion candidates by frequency of use
+Otherwise, sort alphabetically.  Ignore letter case if
+`completion-ignore-case' or `case-fold-search' is non-nil.")
+
+;;;###autoload (autoload 'icicle-sort-turned-OFF "icicles-mcmd.el")
+(icicle-define-sort-command "turned OFF" nil ; `icicle-sort-turned-OFF'
+  "Do not sort completion candidates.")
+
+;;;###autoload
+(defun icicle-dispatch-M-_ ()           ; Bound to `M-_' in minibuffer.
+  "Do the right thing for `M-_'.
+During Icicles search, call `icicle-toggle-search-replace-whole'.
+Otherwise, call `icicle-toggle-ignored-space-prefix'.
+
+Bound to `M-_' in the minibuffer."
+  (interactive)
+  (if icicle-searching-p
+      (icicle-toggle-search-replace-whole)
+    (call-interactively #'icicle-toggle-ignored-space-prefix)))
+
+;;; No longer used.
+;;; (defun icicle-dispatch-C-comma ()
+;;;   "Do the right thing for `C-,'.
+;;; When candidate sorting is possible, call `icicle-change-sort-order'.
+;;; When searching, call `icicle-toggle-search-replace-whole'.
+;;; Otherwise, do nothing.
+;;;
+;;; Bound to `C-,' in the minibuffer."
+;;;   (interactive)
+;;;   (cond (icicle-searching-p (icicle-toggle-search-replace-whole))
+;;;         (icicle-inhibit-sort-p (message "Cannot sort candidates now"))
+;;;         (t (call-interactively #'icicle-change-sort-order))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-ignoring-comments 'icicle-toggle-ignoring-comments)
+;;;###autoload
+(defun icicle-toggle-ignoring-comments () ; Bound to `C-M-;' in minibuffer.
+  "Toggle the value of option `icicle-ignore-comments-flag'.
+If option `ignore-comments-flag' is defined (in library
+`thing-cmds.el') then it too is toggled.
+Bound to `C-M-;' in the minibuffer."
+  (interactive)
+  (setq icicle-ignore-comments-flag  (not icicle-ignore-comments-flag))
+  (when (boundp 'ignore-comments-flag) (setq ignore-comments-flag  (not ignore-comments-flag)))
+  (icicle-msg-maybe-in-minibuffer (if icicle-ignore-comments-flag
+                                      "Ignoring comments is now ON"
+                                    "Ignoring comments is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-search-replace-common-match 'icicle-toggle-search-replace-common-match)
+;;;###autoload
+(defun icicle-toggle-search-replace-common-match () ; Bound to `M-;' in minibuffer.
+  "Toggle the value of `icicle-search-replace-common-match-flag'.
+Note that that option has no effect if
+`icicle-expand-input-to-common-match-flag' is nil.
+Bound to `M-;' in the minibuffer."
+  (interactive)
+  (setq icicle-search-replace-common-match-flag  (not icicle-search-replace-common-match-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-search-replace-common-match-flag
+                                      "Replacing expanded common match is now ON"
+                                    "Replacing expanded common match is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-search-replace-whole 'icicle-toggle-search-replace-whole)
+;;;###autoload
+(defun icicle-toggle-search-replace-whole ()
+  "Toggle the value of `icicle-search-replace-whole-candidate-flag'.
+Bound to `M-_' in the minibuffer when searching."
+  (interactive)
+  (setq icicle-search-replace-whole-candidate-flag  (not icicle-search-replace-whole-candidate-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-search-replace-whole-candidate-flag
+                                      "Replacing whole search context is now ON"
+                                    "Replacing whole search context is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-dot 'icicle-toggle-dot)
+;;;###autoload
+(defalias 'toggle-icicle-.   'icicle-toggle-dot)
+;;;###autoload
+(defalias 'icicle-toggle-.   'icicle-toggle-dot)
+;;;###autoload
+(defun icicle-toggle-dot ()             ; Bound to `C-M-.' in minibuffer.
+  "Toggle `icicle-dot-string' between `.' and `icicle-anychar-regexp'.
+Bound to `C-M-.' in the minibuffer."
+  (interactive)
+  (setq icicle-dot-string  (if (string= icicle-dot-string ".") (icicle-anychar-regexp) "."))
+  (icicle-msg-maybe-in-minibuffer
+   (cond ((string= icicle-dot-string ".")
+          (icicle-convert-dots (equal icicle-current-input icicle-last-input) t)
+          "`.' now matches any char EXCEPT newline")
+         (t
+          (icicle-convert-dots (equal icicle-current-input icicle-last-input))
+          "`.' now matches any char, including NEWLINE")))
+  (setq icicle-dot-string-internal  icicle-dot-string))
+
+(defun icicle-convert-dots (&optional no-confirm-p plainp)
+  "Convert existing dots.
+Optional arg NO-CONFIRM-P means don't ask user for confirmation.
+Optional arg PLAINP means convert to plain `.'.
+  Otherwise, convert to `icicle-anychar-regexp'."
+  (if plainp
+      (save-excursion
+        (when (and (goto-char (icicle-minibuffer-prompt-end))
+                   (search-forward icicle-anychar-regexp nil t))
+          (goto-char (icicle-minibuffer-prompt-end))
+          (while (search-forward icicle-anychar-regexp nil t)
+            (replace-match "." nil t))))
+    (save-excursion
+      (when (and (goto-char (icicle-minibuffer-prompt-end)) (search-forward "." nil t))
+        (goto-char (icicle-minibuffer-prompt-end))
+        (let ((allp  nil))
+          (while (search-forward "." nil t)
+            ;; If we hit a plain dot inserted by user explicitly, ask if we should convert all such.
+            (when (and (not allp)
+                       (get-text-property (match-beginning 0) 'icicle-user-plain-dot)
+                       (not no-confirm-p)
+                       (y-or-n-p "Should all dots (`.') in current input match newlines too? "))
+              (setq allp  t))
+            (when (or allp (not (get-text-property (match-beginning 0) 'icicle-user-plain-dot)))
+              (replace-match (icicle-anychar-regexp) nil t))))))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+(when (require 'image-dired nil t)      ; Emacs 22+.
+  (defalias 'cycle-icicle-image-file-thumbnail 'icicle-toggle-show-image-file-thumbnail)
+  (defun icicle-cycle-image-file-thumbnail () ; Bound to `C-x t' in minibuffer.
+    "Toggle `icicle-image-files-in-Completions'.
+This has no effect if you do not have library `image-dired.el' (Emacs 23+).
+Bound to `C-x t' in the minibuffer."
+    (interactive)
+    (if (not (require 'image-dired nil t))
+        (message "No-op: this command requires library `image-dired.el'")
+      (setq icicle-image-files-in-Completions
+            (case icicle-image-files-in-Completions
+              ((nil)       'image-only)
+              (image-only  t)
+              (t           nil)))
+      (icicle-complete-again-update)
+      (icicle-msg-maybe-in-minibuffer
+       (case icicle-image-files-in-Completions
+         ((nil)       "Image files in `*Completions*': showing only NAMES")
+         (image-only  "Image files in `*Completions*': showing only IMAGES")
+         (t           "Image files in `*Completions*': showing IMAGES and NAMES"))))))
+
+;;;###autoload
+(defun icicle-doremi-increment-max-candidates+ (&optional increment) ; `C-x #' in minibuffer
+  "Change `icicle-max-candidates' incrementally.
+Use `up', `down' or the mouse wheel to increase or decrease.  You can
+ use the `Meta' key (e.g. `M-up') to increment in larger steps.
+You can use a numeric prefix arg to specify the increment.
+A plain prefix arg (`C-u') resets `icicle-max-candidates' to nil,
+ meaning no limit."
+  (interactive "P")
+  (cond ((consp increment)
+         (setq icicle-max-candidates  nil)
+         (icicle-msg-maybe-in-minibuffer "No longer any limit on number of candidates"))
+        (t
+         (setq increment  (prefix-numeric-value increment))
+         (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))
+         (let ((mini  (active-minibuffer-window)))
+           (unwind-protect
+                (save-selected-window
+                  (select-window (minibuffer-window))
+                  (unless icicle-completion-candidates (message "Hit `TAB' or `S-TAB'"))
+                  (let ((enable-recursive-minibuffers  t)
+                        (nb-cands                      (length icicle-completion-candidates)))
+                    (when (or (not icicle-max-candidates) (> icicle-max-candidates nb-cands))
+                      (setq icicle-max-candidates  nb-cands))
+                    (when (zerop icicle-max-candidates) (setq icicle-max-candidates 10))
+                    (doremi (lambda (new-val)
+                              (setq icicle-max-candidates
+                                    (setq new-val (doremi-limit new-val 2 nil)))
+                              (unless (input-pending-p)
+                                (let ((icicle-edit-update-p  t)
+                                      (icicle-last-input     nil))
+                                  (funcall (or icicle-last-completion-command
+                                               (if (eq icicle-current-completion-mode 'prefix)
+                                                   #'icicle-prefix-complete
+                                                 #'icicle-apropos-complete)))
+                                  (run-hooks 'icicle-update-input-hook)))
+                              new-val)
+                            icicle-max-candidates
+                            increment))
+                  (setq unread-command-events  ()))
+             (unless mini (icicle-remove-Completions-window)))))))
+
+;;;###autoload
+(defun icicle-doremi-increment-swank-timeout+ () ; Bound to `C-x 1' in minibuffer (swank only)
+  "Change `icicle-swank-timeout' incrementally.
+Use `up', `down' or the mouse wheel to increase or decrease.  You can
+use the `Meta' key (e.g. `M-up') to increment in larger steps."
+  (interactive)
+  (icicle-doremi-increment-variable+ 'icicle-swank-timeout 1000))
+
+;;;###autoload
+(defun icicle-doremi-increment-swank-prefix-length+ () ; Bound to `C-x 2' in minibuffer (swank only)
+  "Change `icicle-swank-prefix-length' incrementally.
+Use `up', `down' or the mouse wheel to increase or decrease.  You can
+use the `Meta' key (e.g. `M-up') to increment in larger steps."
+  (interactive)
+  (icicle-doremi-increment-variable+ 'icicle-swank-prefix-length 1))
+
+;;;###autoload
+(defun icicle-next-TAB-completion-method (temporary-p) ; Bound to `C-(' in minibuffer.
+  "Cycle to the next `TAB' completion method.
+Bound to \\`\\[icicle-next-TAB-completion-method]' \
+in the minibuffer.
+Option `icicle-TAB-completion-methods' determines the TAB completion
+methods that are available.
+
+With a prefix argument, the newly chosen method is used only for the
+current command.  More precisely, the previously active method is
+restored as soon as you return to the top level."
+  (interactive "P")
+  (unless icicle-current-TAB-method     ; nil means the same as the default (first).
+    (setq icicle-current-TAB-method  (car icicle-TAB-completion-methods)))
+  (if temporary-p
+      (unless (get 'icicle-last-top-level-command 'icicle-current-TAB-method)
+        (put 'icicle-last-top-level-command 'icicle-current-TAB-method icicle-current-TAB-method))
+    (put 'icicle-last-top-level-command 'icicle-current-TAB-method nil))
+
+  (let ((now  (memq icicle-current-TAB-method icicle-TAB-completion-methods)))
+    (setq icicle-current-TAB-method  (or (cadr now) (car icicle-TAB-completion-methods)))
+    ;; Skip any method that is not currently supported.
+    (while (or (and (eq icicle-current-TAB-method 'fuzzy)        (not (featurep 'fuzzy-match)))
+               (and (eq icicle-current-TAB-method 'vanilla)      (not (boundp 'completion-styles)))
+               (and (eq icicle-current-TAB-method 'swank)        (not (featurep 'el-swank-fuzzy))))
+      (setq now                        (memq icicle-current-TAB-method icicle-TAB-completion-methods)
+            icicle-current-TAB-method  (or (cadr now) (car icicle-TAB-completion-methods)))))
+  (cond ((and (eq icicle-current-TAB-method 'swank) (fboundp 'doremi))
+         (define-key minibuffer-local-completion-map "\C-x1"
+           'icicle-doremi-increment-swank-timeout+)
+         (define-key minibuffer-local-must-match-map "\C-x1"
+           'icicle-doremi-increment-swank-timeout+)
+         (define-key minibuffer-local-completion-map "\C-x2"
+           'icicle-doremi-increment-swank-prefix-length+)
+         (define-key minibuffer-local-must-match-map "\C-x2"
+           'icicle-doremi-increment-swank-prefix-length+))
+        ((fboundp 'doremi)
+         (define-key minibuffer-local-completion-map "\C-x1" nil)
+         (define-key minibuffer-local-must-match-map "\C-x1" nil)
+         (define-key minibuffer-local-completion-map "\C-x2" nil)
+         (define-key minibuffer-local-must-match-map "\C-x2" nil)))
+  ;; $$$$$$ Inhibiting sorting is not correct for file-name completion, and sorting would not be
+  ;;        restored when change back to non-fuzzy.
+  ;; (when (eq 'fuzzy icicle-current-TAB-method) (setq icicle-inhibit-sort-p  t))
+  (icicle-msg-maybe-in-minibuffer "TAB completion is %s %s"
+                                  (icicle-upcase (symbol-name icicle-current-TAB-method))
+                                  (if temporary-p "for this command" "now")))
+
+;;;###autoload
+(defun icicle-next-S-TAB-completion-method (temporary-p) ; Bound to `M-(' in minibuffer.
+  "Cycle to the next `S-TAB' completion method.
+Bound to `M-(' in the minibuffer.
+Option `icicle-S-TAB-completion-methods-alist' customizes the
+available TAB completion methods.
+
+With a prefix argument, the newly chosen method is used only for the
+current command.  More precisely, the previously active method is
+restored as soon as you return to the top level."
+  (interactive "P")
+  (if temporary-p
+      (unless (get 'icicle-last-top-level-command 'icicle-apropos-complete-match-fn)
+        (put 'icicle-last-top-level-command 'icicle-apropos-complete-match-fn
+             icicle-apropos-complete-match-fn))
+    (put 'icicle-last-top-level-command 'icicle-apropos-complete-match-fn nil))
+  (let ((entry  (rassq icicle-apropos-complete-match-fn icicle-S-TAB-completion-methods-alist)))
+    (setq icicle-apropos-complete-match-fn
+          (or (cdadr (member entry icicle-S-TAB-completion-methods-alist))
+              (cdar icicle-S-TAB-completion-methods-alist))
+          icicle-last-apropos-complete-match-fn  icicle-apropos-complete-match-fn) ; Backup copy.
+    (icicle-msg-maybe-in-minibuffer
+     (format "S-TAB completion is %s%s %s"
+             (icicle-upcase (car (rassq icicle-apropos-complete-match-fn
+                                        icicle-S-TAB-completion-methods-alist)))
+             (if (memq icicle-apropos-complete-match-fn
+                       '(icicle-levenshtein-match icicle-levenshtein-strict-match))
+                 (format " (%d)" icicle-levenshtein-distance)
+               "")
+             (if temporary-p "for this command" "now")))))
+    ;; (icicle-complete-again-update) ; No - too slow for some completion methods.
+
+;;;###autoload
+(defun icicle-change-sort-order (&optional arg alternativep) ; Bound to `C-,' in minibuffer.
+  "Choose a sort order.
+With a numeric prefix arg, reverse the current sort order.
+
+If plain `C-u' is used or `C-u' is not used at all:
+
+- Use completion if `icicle-change-sort-order-completion-flag' is
+  non-nil and no prefix arg is used, or if it is nil and a prefix arg
+  is used.
+
+- Otherwise, just cycle to the next sort order.
+
+This command updates `icicle-sort-comparer'.  Non-interactively,
+optional arg ALTERNATIVEP means change the current alternative sort
+order instead, updating `icicle-alternative-sort-comparer'."
+  (interactive "P")
+  (setq icicle-sort-orders-alist  (delq nil icicle-sort-orders-alist)) ; Purge any nil entries.
+  (if (and (interactive-p) icicle-inhibit-sort-p)
+      (icicle-msg-maybe-in-minibuffer "Cannot sort candidates now")
+    (if (and arg (not (consp arg)))
+        (icicle-reverse-sort-order)
+      (let (next-order)
+        (cond ((or (and icicle-change-sort-order-completion-flag (not arg)) ; Use completion.
+                   (and (not icicle-change-sort-order-completion-flag) arg))
+               (setq next-order  (let ((icicle-whole-candidate-as-text-prop-p  nil)
+                                       (enable-recursive-minibuffers           t))
+                                   (save-selected-window
+                                     (completing-read
+                                      (format "New %ssort order: " (if alternativep "alternative " ""))
+                                      (icicle-current-sort-functions)
+                                      nil t))))
+               (set (if alternativep 'icicle-alternative-sort-comparer 'icicle-sort-comparer)
+                    (cdr (assoc next-order icicle-sort-orders-alist))))
+              (t                        ; Cycle to next sort order.
+               (let ((orders  (mapcar #'car (icicle-current-sort-functions))))
+                 (setq next-order  (or (cadr (memq (icicle-current-sort-order alternativep) orders))
+                                       (car orders)))
+                 (set (if alternativep 'icicle-alternative-sort-comparer 'icicle-sort-comparer)
+                      (cdr (assoc next-order icicle-sort-orders-alist))))))
+        (icicle-complete-again-update)
+        (icicle-msg-maybe-in-minibuffer
+         "%sorting is now %s%s.  Reverse: `C-9 C-,'"
+         (if alternativep "Alternative s" "S") next-order
+         (if icicle-reverse-sort-p ", REVERSED" ""))))))
+
+(defun icicle-current-sort-functions ()
+  "Subset of `icicle-sort-orders-alist' that is currently appropriate.
+For some common kinds of completion, remove simple sort functions (not
+multi-sort comparers) that are not pertinent for the current kind of
+completion."
+  (icicle-remove-if (lambda (pred)
+                      (setq pred  (cdr pred))
+                      (and pred (symbolp pred) ; Do not handle multi-sort comparers.
+                           (or (and (get pred 'icicle-proxy-sort-predicate)
+                                    (not icicle-add-proxy-candidates-flag))
+                               (and (get pred 'icicle-file-name-sort-predicate)
+                                    (not (icicle-file-name-input-p)))
+                               ;; Not really needed yet, because we only add such sorts dynamically.
+                               (and (get pred 'icicle-buffer-name-sort-predicate) ; Better than nothing.
+                                    (not (eq minibuffer-history-variable 'buffer-name-history)))
+                               (and (get pred 'icicle-command-sort-predicate)
+                                    (not (and (eq minibuffer-completion-table obarray)
+                                              ;; But this will fail if predicate is more complex.
+                                              (eq minibuffer-completion-predicate 'commandp))))
+                               ;; Sort order for multi-completions. `minibuffer-completion-table'
+                               ;; could be a function (e.g. `icicle-describe-opt-of-type-complete')
+                               ;; or it could be a list of multi-completions.
+                               (and (get pred 'icicle-multi-completion-sort-predicate)
+                                    (not (icicle-maybe-multi-completion-completing-p))))))
+                    icicle-sort-orders-alist))
+
+(defun icicle-maybe-multi-completion-completing-p ()
+  "Returns non-nil if we might currently be multi-completion completing.
+Note: If `minibuffer-completion-table' is a function, multi-completion
+is possible but not sure.  Return non-nil in that case."
+  (or (functionp minibuffer-completion-table) icicle-list-use-nth-parts))
+
+;;;###autoload
+(defun icicle-dispatch-M-comma ()       ; Bound to `M-,' in minibuffer.
+  "Do the right thing for `M-,'.
+If sorting is possible, call `icicle-change-alternative-sort-order'.
+If using `icicle-search', call `icicle-search-define-replacement'.
+Otherwise, do nothing.
+
+Bound to `M-,' in the minibuffer."
+  (interactive)
+  (cond (icicle-searching-p (icicle-search-define-replacement))
+        (icicle-inhibit-sort-p (message "Cannot sort candidates now"))
+        (t (icicle-change-alternative-sort-order))))
+
+;; Free vars here: `icicle-scan-fn-or-regexp' is bound in `icicle-search'.
+;;;###autoload
+(defun icicle-search-define-replacement () ; Bound to `M-,' in minibuffer during `icicle-search'.
+  "Prompt user and set new value of `icicle-search-replacement'.
+Bound to `M-,' in the minibuffer."
+  (interactive)
+  (save-selected-window
+    (icicle-remove-Completions-window)) ; Prevent incremental completion kicking in from the get-go.
+  (setq icicle-search-replacement
+        (let ((enable-recursive-minibuffers        t)
+              (icicle-incremental-completion-flag  t) ; Override current upgrade to `always'.
+              (icicle-completion-candidates        icicle-completion-candidates)
+              (icicle-current-input                icicle-current-input)
+              (icicle-candidate-nb                 icicle-candidate-nb)
+              (icicle-update-input-hook            nil))
+          (icicle-completing-read-history "Replace with: " 'icicle-search-replacement-history)))
+  ;; Just a sanity check.  Cannot really test equivalence of two regexps.
+  (while (if icicle-search-replace-whole-candidate-flag
+             (equal icicle-search-replacement icicle-scan-fn-or-regexp)
+           (equal icicle-search-replacement icicle-current-input))
+    (setq icicle-search-replacement
+          (let ((enable-recursive-minibuffers        t)
+                (icicle-incremental-completion-flag  t) ; Override current upgrade to `always'.
+                (icicle-completion-candidates        icicle-completion-candidates)
+                (icicle-current-input                icicle-current-input)
+                (icicle-candidate-nb                 icicle-candidate-nb)
+                (icicle-update-input-hook            nil))
+            (icicle-completing-read-history "Replacement = replaced.  Replace with: "
+                                            'icicle-search-replacement-history)))))
+
+;;;###autoload
+(defun icicle-change-alternative-sort-order (&optional arg) ; Bound to `M-,' in minibuffer (not search).
+  "Choose an alternative sort order.
+Similar to command `icicle-change-sort-order', but change the
+alternative sort order, not the current sort order."
+  (interactive "P")
+  (if (and (interactive-p) icicle-inhibit-sort-p)
+      (icicle-msg-maybe-in-minibuffer "Cannot sort candidates now")
+    (icicle-change-sort-order arg t)))
+
+(defun icicle-current-sort-order (alternativep)
+  "Current sort order, or nil if sorting is inactive.
+If ALTERNATIVEP is non-nil, the alternative sort order is returned."
+  (car (rassq (if alternativep icicle-alternative-sort-comparer icicle-sort-comparer)
+              icicle-sort-orders-alist)))
+
+;;;###autoload
+(defun icicle-reverse-sort-order ()
+  "Reverse the current sort order."
+  (interactive)
+  (if (and (interactive-p) icicle-inhibit-sort-p)
+      (icicle-msg-maybe-in-minibuffer "Cannot sort candidates now")
+    (setq icicle-reverse-sort-p  (not icicle-reverse-sort-p))
+    (icicle-display-candidates-in-Completions icicle-reverse-sort-p)
+    (icicle-complete-again-update)
+    (icicle-msg-maybe-in-minibuffer
+     (format "Sort order is %s%s"
+             (icicle-current-sort-order nil) (if icicle-reverse-sort-p ", REVERSED" "")))))
+
+;;;###autoload
+(defun icicle-plus-saved-sort ()        ; Bound to `C-M-+' during completion.
+  "Sort candidates by combining their current order with the saved order."
+  (interactive)
+  (let ((icicle-sort-comparer  'icicle-merge-saved-order-less-p)
+        (cands                 (copy-sequence icicle-completion-candidates)))
+    (setq icicle-completion-candidates
+          (if (or (icicle-file-name-input-p) icicle-abs-file-candidates)
+              (icicle-strip-ignored-files-and-sort cands)
+            (icicle-maybe-sort-maybe-truncate cands))))
+  (when (get-buffer-window "*Completions*" 0) (icicle-display-candidates-in-Completions))
+  (when (interactive-p) (icicle-msg-maybe-in-minibuffer "Added in the saved sort order")))
+
+ 
+;;(@* "Other commands to be used mainly in the minibuffer")
+
+;;; Other commands to be used mainly in the minibuffer . . . . . . . .
+
+;; $$ Probably need to do something to work around problem of Windows
+;; selecting the new frame, when `pop-up-frames' is non-nil.  Need to
+;; redirect focus back to the frame with the minibuffer.  Leave it as
+;; is, for now, in hopes Emacs will eventually fix this.
+;;
+;;;###autoload
+(defun icicle-minibuffer-help ()        ; Bound to `C-?' in minibuffer.
+  "Describe Icicles minibuffer and *Completion* buffer bindings."
+  (interactive)
+  (let ((cur-buf  (current-buffer)))
+    (with-output-to-temp-buffer "*Help*"
+      (help-setup-xref (list #'icicle-minibuffer-help) (interactive-p))
+      (when (icicle-completing-p)
+        (princ (concat "You are completing input" (and icicle-candidate-action-fn
+                                                       " for an Icicles multi-command")
+                       ".\n\n"))
+        (princ "To show help on individual completion candidates:
+     Current candidate                       C-M-RET, C-M-mouse-2
+     Next, previous candidate                C-M-down, C-M-up,
+                                              C-M- plus mouse wheel
+                    prefix-match candidate   C-M-end, C-M-home
+                    apropos-match candidate  C-M-next, C-M-prior\n\n")
+        (when icicle-candidate-action-fn
+          (princ "To act on individual candidates:
+     Current candidate                       C-RET, C-mouse-2
+     Next, previous candidate                C-down, C-up,
+                                              C- plus mouse wheel
+                    prefix-match candidate   C-end, C-home
+                    apropos-match candidate  C-next, C-prior
+     All candidates at once                  C-! (each) or M-! (list)
+     Delete object named by candidate        S-delete
+     Object-action: apply a fn to candidate  M-RET"))
+        (when icicle-candidate-alt-action-fn
+          (princ "\n\nFor alt action, use `C-S-' instead of `C-', but use `C-|' or `M-|',\n\
+     instead of `C-!' or `M-!', to act on all.\n")))
+      (if icicle-completing-p
+          (with-current-buffer standard-output
+            (insert (concat "\n" (icicle-help-string-completion))))
+        (princ (icicle-help-string-non-completion))))
+    ;; Don't bother to do this for Emacs 21.3.  Its `help-insert-xref-button' signature is different.
+    (when (and (> emacs-major-version 21)
+               (require 'help-mode nil t) (fboundp 'help-insert-xref-button)) ; In `help-mode.el'.
+      (save-excursion
+        (with-current-buffer (get-buffer "*Help*")
+          (let ((buffer-read-only  nil))
+            (goto-char (point-min))
+            (help-insert-xref-button "[Icicles Help on the Web]" 'icicle-help-button)
+            (insert "                        ")
+            (help-insert-xref-button "[Icicles Doc, Part 1]" 'icicle-commentary1-button)
+            (insert "\n")
+            (help-insert-xref-button "[Icicles Options & Faces]" 'icicle-customize-button)
+            (insert "                        ")
+            (help-insert-xref-button "[Icicles Doc, Part 2]" 'icicle-commentary2-button)
+            (insert "\n\n")
+            (goto-char (point-max))
+            (insert (make-string 70 ?_))
+            (insert (funcall
+                     (if (fboundp 'help-commands-to-key-buttons) ; In `help-fns.el'.
+                         #'help-commands-to-key-buttons
+                       #'substitute-command-keys)
+                     "\n\nSend an Icicles bug report: `\\[icicle-send-bug-report]'.\n\n"))
+            (help-insert-xref-button "[Icicles Help on the Web]" 'icicle-help-button)
+            (insert "                        ")
+            (help-insert-xref-button "[Icicles Doc, Part 1]" 'icicle-commentary1-button)
+            (insert "\n")
+            (help-insert-xref-button "[Icicles Options & Faces]" 'icicle-customize-button)
+            (insert "                        ")
+            (help-insert-xref-button "[Icicles Doc, Part 2]" 'icicle-commentary2-button)
+            (insert "\n\n")
+            (goto-char (point-min))))))
+    (when (memq cur-buf (list (window-buffer (minibuffer-window)) (get-buffer "*Completions*")))
+      (select-window (minibuffer-window))
+      (select-frame-set-input-focus (selected-frame)))))
+
+(defun icicle-help-string-completion ()
+  "Update the bindings within the Icicles completion help string."
+  (icicle-S-iso-lefttab-to-S-TAB
+   (funcall
+    (if (fboundp 'help-commands-to-key-buttons) ; In `help-fns+.el'.
+        #'help-commands-to-key-buttons
+      #'substitute-command-keys)
+    (concat
+     (format "\\ 
+
+                    Icicles Minibuffer Completion
+                    -----------------------------
+
+Minibuffer input can be completed in several ways.
+These are the main Icicles actions and their minibuffer key bindings:
+
+ * Show Icicles minibuffer help (this).      \\[icicle-minibuffer-help]
+     For help on individual completion candidates, see \"Show help on
+     individual completion candidates\", below.
+
+ * Abandon or commit your input.
+     Abandon input                           \\[icicle-abort-recursive-edit]
+     Commit input to Emacs                   RET
+       Complete partial input, then commit   \\\
+\\[icicle-apropos-complete-and-exit]\\
+
+ * Toggle/cycle Icicles options on the fly.  Key:   \tCurrently:
+     Highlighting of past inputs             \\[icicle-toggle-highlight-historical-candidates]\t%S
+     Highlighting of saved candidates        \\[icicle-toggle-highlight-saved-candidates]\t%S
+     Removal of duplicate candidates         \\[icicle-toggle-transforming]\t%S
+     Sort order                              \\[icicle-change-sort-order]\t%s
+     Alternative sort order                  \\[icicle-dispatch-M-comma]\t%s
+     Swap alternative/normal sort            \\[icicle-toggle-alternative-sorting]\t- (swaps) -
+     Case sensitivity                        \\[icicle-toggle-case-sensitivity]\t%S
+     `.' matching newlines too (any char)    \\[icicle-toggle-dot]\t%S
+     Escaping of special regexp chars        \\[icicle-toggle-regexp-quote]\t%S
+     Incremental completion                  \\[icicle-toggle-incremental-completion]\t%S
+     Input expansion to common match         \\[icicle-toggle-expand-to-common-match]\t%S
+     Hiding common match in `*Completions*'  \\[icicle-dispatch-C-x.]\t%S
+     Hiding no-match lines in `*Completions*' C-u \\[icicle-dispatch-C-x.]\t%S
+     S-TAB completion method                 \\[icicle-next-S-TAB-completion-method]\t%s
+     TAB completion method                   \\[icicle-next-TAB-completion-method]\t%s
+     Showing image-file thumbnails (E22+)    C-x t\t%S
+     Inclusion of proxy candidates           \\[icicle-toggle-proxy-candidates]\t%S
+     Ignoring certain file extensions        \\[icicle-dispatch-C-.]\t%S
+     Checking for remote file names          \\[icicle-dispatch-C-^]\t%S
+     Ignoring space prefix                   \\[icicle-dispatch-M-_]\t%S
+     Using `C-' for multi-command actions    \\[icicle-toggle-C-for-actions]\t%S
+     Using `~' for your home directory       \\[icicle-toggle-~-for-home-dir]\t%S
+     `icicle-search' all-current highlights  \\[icicle-dispatch-C-^]\t%S
+     Whole-word searching                    \\[icicle-dispatch-M-q]\t%S
+     Removal of `icicle-search' highlighting \\[icicle-dispatch-C-.]\t%S
+     Replacement of whole search hit         \\[icicle-dispatch-M-_]\t%S
+     Replacement of expanded common match    \\[icicle-toggle-search-replace-common-match]\t%S
+
+ * Regexp-quote input, then apropos-complete \\[icicle-regexp-quote-input]
+
+ * Change the set of completion candidates.  Modify your input.
+     Edit your input                         (just edit in minibuffer)
+     Erase your input (clear minibuffer)     \\[icicle-erase-minibuffer-or-history-element]
+     Goto/kill non-matching portion of input \\[icicle-goto/kill-failed-input]
+     Retrieve previous completion inputs     \\[icicle-retrieve-previous-input], \
+\\[icicle-retrieve-next-input]
+     Match another regexp (chaining)         \\[icicle-narrow-candidates]
+     Satisfy another predicate (chaining)    \\[icicle-narrow-candidates-with-predicate]
+     Remove a candidate from set of matches  delete, S-mouse-2
+     Yank text at cursor into minibuffer     \\[icicle-insert-string-at-point]
+     Insert text (string) from a variable    \\[icicle-insert-string-from-variable]
+     Insert `icicle-list-join-string'        \\[icicle-insert-list-join-string]
+     Insert previously entered input         \\[icicle-insert-history-element]
+     Insert key description (key completion) \\[icicle-dispatch-M-q]
+
+ * Complete your current input in the minibuffer.
+     Apropos (regexp) completion             \\[icicle-apropos-complete]
+       Without displaying candidates         \\[icicle-apropos-complete-no-display]
+       Complete and match another regexp     \\[icicle-apropos-complete-and-narrow]
+     Prefix completion
+       As much as possible                   \\[icicle-prefix-complete]
+         Without displaying candidates       \\[icicle-prefix-complete-no-display]
+       A word at a time                      \\[icicle-prefix-word-complete]
+     Complete and commit (if required match) \\\
+\\[icicle-apropos-complete-and-exit]\\
+     Complete search string using past input \\[icicle-apropos-complete]
+
+ * Display/navigate completions for current input (in `*Completions*').
+     Show completion candidates
+       Prefix completion                     \\[icicle-prefix-complete] (repeat)
+       Apropos completion                    \\[icicle-apropos-complete]
+     Move between minibuffer and list        \\\
+\\[icicle-insert-completion]
+     Cycle among completion candidates       right, left, \
+\\[icicle-move-to-next-completion], \\[icicle-move-to-previous-completion]
+       Within a `*Completions*' column       down, up
+     Choose a completion candidate           \\[choose-completion], \
+\\[mouse-choose-completion]\\
+
+ * Cycle among input candidates.
+     Completion candidates
+       Current mode                          down, up, mouse wheel
+       Prefix completion                     end, home
+       Apropos completion                    next, prior
+     Minibuffer history items                \\[next-history-element], \
+\\[previous-history-element]
+     Completion history items                \\[icicle-retrieve-previous-input], \
+\\[icicle-retrieve-next-input]
+
+ * Show help on individual completion candidates.
+     Current candidate                       C-M-RET, C-M-mouse-2
+     Next, previous candidate                C-M-down, C-M-up,
+                                              C-M- plus mouse wheel
+                    prefix-match candidate   C-M-end, C-M-home
+                    apropos-match candidate  C-M-next, C-M-prior
+
+ * Choose a previous input from the minibuffer history.
+     Complete to insert a previous input     \\[icicle-insert-history-element]
+     Complete against history items          \\[icicle-history], \
+\\[icicle-keep-only-past-inputs]
+     Restrict candidates to history items    \\[icicle-keep-only-past-inputs]
+     Change to another history               \\[icicle-other-history]
+     List history items first in Completions \\[icicle-toggle-alternative-sorting]
+     Cycle among minibuffer history items    \\[next-history-element], \
+\\[previous-history-element]
+     Search among minibuffer history items   \
+\\[next-matching-history-element], \\[previous-matching-history-element]
+
+ * Delete history entries
+     Delete current entry (cycling)          \\[icicle-erase-minibuffer-or-history-element]
+     Delete any or all entries               \\[icicle-clear-current-history]
+
+ * Multi-commands: Act on completion candidates.
+   For alternative action, use `C-S-' instead of `C-', but
+   `C-|' and `M-|' are alternative action versions of `C-!' and `M-!'.
+     Current candidate                       C-RET, C-mouse-2
+     Next, previous candidate                C-down, C-up,
+                                              C- plus mouse wheel
+                    prefix-match candidate   C-end, C-home
+                    apropos-match candidate  C-next, C-prior
+     Act on each matching candidate, in turn C-!
+     Act on the list of matching candidates  M-!
+     Delete object named by candidate        S-delete
+     Remove candidate from set of matches    delete, S-mouse-2
+     Save candidate (add to those saved)     insert, M-S-mouse-2
+     Object-action: apply a fn to candidate  M-RET
+
+ * Search and replace (e.g. `C-c `').  See also `icicle-search'.
+     Use action keys (prefix `C-') to navigate.
+     Use alternative action keys (prefix `C-S-') to replace matches.
+     Toggle input highlighting at all hits   \\[icicle-dispatch-C-^]
+     Toggle whole-word searching             \\[icicle-dispatch-M-q]
+     Toggle `.' matching newlines too        \\[icicle-toggle-dot]
+     Toggle escaping of special regexp chars \\[icicle-toggle-regexp-quote]
+     Toggle removal of search highlighting   \\[icicle-dispatch-C-.]
+
+     Replace all                             M-|
+     Redefine the replacement string         \\[icicle-dispatch-M-comma]
+     Toggle literal replacement              \\[icicle-toggle-literal-replacement]
+     Toggle replacement of whole search hit  \\[icicle-dispatch-M-_]
+     Toggle replacement of common match      \\[icicle-toggle-search-replace-common-match]
+
+ * Perform set operations on candidate sets.
+     Remove candidate from current set       delete, S-mouse-2
+     Add current candidate to saved set      insert, M-S-mouse-2
+     Retrieve saved candidates from...
+       `icicle-saved-completion-candidates'  \\[icicle-candidate-set-retrieve]
+       another variable                      \\[icicle-candidate-set-retrieve-from-variable]
+       a cache file                          \\[icicle-candidate-set-retrieve-persistent]
+     Retrieve more saved candidates          \\[icicle-candidate-set-retrieve-more]
+     Save candidates in current set to...
+       `icicle-saved-completion-candidates'  \\[icicle-candidate-set-save]
+       another variable                      \\[icicle-candidate-set-save-to-variable]
+       a cache file                          \\[icicle-candidate-set-save-persistently]
+     Save more candidates to current set     \\[icicle-candidate-set-save-more]
+     Save, save more selected candidates     \\[icicle-candidate-set-save-selected], \
+\\[icicle-candidate-set-save-more-selected]  with region
+     Clear all saved candidates              \\[icicle-candidate-set-save-selected] \
+with empty region
+     Add new or update existing saved set
+       \\[icicle-add/update-saved-completion-set]
+     Remove a saved completion set
+       \\[icicle-remove-saved-completion-set]
+     Swap current and saved sets             \\[icicle-candidate-set-swap]
+     Define current set by evaluating sexp   \\[icicle-candidate-set-define]
+     Restrict candidates to history items    \\[icicle-keep-only-past-inputs]
+     Set complement                          \\[icicle-candidate-set-complement]
+     Set difference                          \\[icicle-candidate-set-difference]
+     Set union                               \\[icicle-candidate-set-union]
+     Set intersection                        \\[icicle-candidate-set-intersection]
+     Set intersection using regexp           \\[icicle-narrow-candidates]
+     Set intersection using predicate        \\[icicle-narrow-candidates-with-predicate]
+       Save current predicate to a variable  \\[icicle-save-predicate-to-variable]
+       Insert string variable as input       \\[icicle-insert-string-from-variable]
+
+ * Adjust Icicles options incrementally on the fly (uses Do Re Mi).
+     `icicle-candidate-width-factor'        \\[icicle-doremi-candidate-width-factor+]
+     `icicle-max-candidates'                \\[icicle-doremi-increment-max-candidates+]
+     `icicle-swank-timeout'                 C-x 1
+     `icicle-swank-prefix-length'           C-x 2
+     `icicle-inter-candidates-min-spaces'   \\[icicle-doremi-inter-candidates-min-spaces+]
+     Zoom `*Completions*' (not an option)   C-x -   (Emacs 23+)
+
+Remember: You can always input any character (e.g. \\[icicle-prefix-complete]) that is bound
+          to a command by preceding it with \\\\[quoted-insert].
+
+Though it has no direct connection with completion, you can use \
+`\\\\[icicle-pp-eval-expression-in-minibuffer]'
+in the minibuffer at any time to evaluate an Emacs-Lisp expression.
+This calls `icicle-pp-eval-expression-in-minibuffer', which displays
+the result in the echo area or a popup buffer, *Pp Eval Output*.
+It also provides some of the Emacs-Lisp key bindings during expression
+editing."
+             icicle-highlight-historical-candidates-flag
+             icicle-highlight-saved-candidates-flag
+             icicle-transform-function
+             (icicle-current-sort-order nil)
+             (icicle-current-sort-order 'ALTERNATIVE)
+             (not case-fold-search)
+             (string= icicle-dot-string icicle-anychar-regexp)
+             icicle-regexp-quote-flag
+             icicle-incremental-completion-flag
+             icicle-expand-input-to-common-match-flag
+             icicle-hide-common-match-in-Completions-flag
+             icicle-hide-non-matching-lines-flag
+             (car (rassq icicle-apropos-complete-match-fn icicle-S-TAB-completion-methods-alist))
+             (icicle-current-TAB-method)
+             icicle-add-proxy-candidates-flag
+             (and completion-ignored-extensions t)
+             icicle-image-files-in-Completions
+             icicle-test-for-remote-files-flag
+             icicle-ignore-space-prefix-flag
+             icicle-use-C-for-actions-flag
+             icicle-use-~-for-home-dir-flag
+             icicle-search-highlight-all-current-flag
+             icicle-search-whole-word-flag
+             icicle-search-cleanup-flag                
+             icicle-search-replace-whole-candidate-flag
+             icicle-search-replace-common-match-flag)
+     icicle-general-help-string
+     " 
+
+These are all of the minibuffer bindings during completion:
+
+\\{minibuffer-local-completion-map}"))))
+
+(defun icicle-help-string-non-completion ()
+  "Description of Icicles minibuffer bindings when not completing input."
+  (icicle-S-iso-lefttab-to-S-TAB
+   (substitute-command-keys
+    (concat "\\\
+              Icicles Minibuffer Input when Not Completing
+              --------------------------------------------
+
+These are the main Icicles minibuffer key bindings when completion is
+not available:
+
+ * Show this help.                           \\[icicle-minibuffer-help]
+
+ * Abandon your input.                       \\[icicle-abort-recursive-edit]
+
+ * Commit your input to Emacs.               RET
+
+ * Modify your input.
+     Edit your input                         (just edit in minibuffer)
+     Erase your input (clear minibuffer)     \\[icicle-erase-minibuffer-or-history-element]
+     Yank text at cursor into minibuffer     \\[icicle-insert-string-at-point]
+     Insert text (string) from a variable    \\[icicle-insert-string-from-variable]
+     Insert previously entered input         \\[icicle-insert-history-element]
+
+ * Choose a previous input from the minibuffer history.
+     Complete to insert a previous input     \\[icicle-insert-history-element]
+     Cycle among minibuffer history items    \\[next-history-element], \
+\\[previous-history-element]
+     Search among minibuffer history items   \
+\\[next-matching-history-element], \\[previous-matching-history-element]
+
+ * Delete history entries
+     Delete current entry (cycling)          \\[icicle-erase-minibuffer-or-history-element]
+     Delete any or all entries               \\[icicle-clear-current-history]
+
+ * Evaluate an Emacs-Lisp sexp on the fly    \\[icicle-pp-eval-expression-in-minibuffer]
+
+Remember: You can always input any character that is bound to a
+          command by preceding it with \\\\[quoted-insert]."
+            icicle-general-help-string
+
+            " 
+These are the minibuffer bindings when not completing input:
+
+\\{minibuffer-local-map}"))))
+
+(when (and (> emacs-major-version 21)
+           (require 'help-mode nil t) (get 'help-xref 'button-category-symbol)) ; In `button.el'
+  (define-button-type 'icicle-help-button
+      :supertype 'help-xref
+      'help-function #'(lambda () (browse-url "http://www.emacswiki.org/cgi-bin/wiki/Icicles"))
+      'help-echo
+      (purecopy "mouse-2, RET: Icicles documentation on the Emacs Wiki (requires Internet access)"))
+  (define-button-type 'icicle-commentary1-button
+      :supertype 'help-xref
+      'help-function #'(lambda ()
+                         (finder-commentary "icicles-doc1")
+                         (when (require 'linkd nil t) (linkd-mode 1))
+                         (when (require 'fit-frame nil t) (fit-frame)))
+      'help-echo (purecopy "mouse-2, RET: Icicles documentation, Part 1 (no Internet needed)"))
+  (define-button-type 'icicle-commentary2-button
+      :supertype 'help-xref
+      'help-function #'(lambda ()
+                         (finder-commentary "icicles-doc2")
+                         (when (require 'linkd nil t) (linkd-mode 1))
+                         (when (require 'fit-frame nil t) (fit-frame)))
+      'help-echo (purecopy "mouse-2, RET: Icicles documentation, Part 2 (no Internet needed)"))
+  (define-button-type 'icicle-customize-button
+      :supertype 'help-xref
+      'help-function #'(lambda () (customize-group-other-window 'Icicles))
+      'help-echo (purecopy "mouse-2, RET: Customize/Browse Icicles Options & Faces")))
+
+
+;; This is just the macro expansion of the following:
+;; `(def-completion-wrapper icicle-abort-recursive-edit :minibuffer-separator)'.
+;; Taken from the definition of `def-completion-wrapper' in `completion.el'.
+(put 'icicle-abort-recursive-edit 'completion-function 'use-completion-minibuffer-separator)
+;;;###autoload
+(defun icicle-abort-recursive-edit ()   ; Bound to `C-]',`C-g' in minibuf, `C-g',`q' in `*Completions*'.
+  "Abort command that requested this recursive edit or minibuffer input.
+This calls `abort-recursive-edit' after killing the `*Completions*'
+buffer or (if called from the minibuffer) removing its window.
+
+By default, Icicle mode remaps all key sequences that are normally
+bound to `abort-recursive-edit' to `icicle-abort-recursive-edit'.  If
+you do not want this remapping, then customize option
+`icicle-top-level-key-bindings'."
+  (interactive)
+  (if (not (active-minibuffer-window))
+      (when (get-buffer "*Completions*") (kill-buffer (get-buffer "*Completions*")))
+    (icicle-remove-Completions-window 'FORCE))
+  (abort-recursive-edit))
+
+(unless (fboundp 'save&set-overriding-map) ; Only Emacs 20-23 use `ensure-overriding-map-is-bound'.
+  (defun icicle-ensure-overriding-map-is-bound ()
+    "Set `overriding-terminal-local-map' to `icicle-universal-argument-map'."
+    (if (not (boundp 'overriding-map-is-bound)) ; Emacs 20, 21.
+        (setq overriding-terminal-local-map  icicle-universal-argument-map)
+      (unless overriding-map-is-bound   ; Emacs 22+.
+        (setq saved-overriding-map           overriding-terminal-local-map
+              overriding-terminal-local-map  icicle-universal-argument-map
+              overriding-map-is-bound        t)))))
+
+;;;###autoload
+(defun icicle-digit-argument (arg)      ; Bound to `C-<0-9>', `M-<0-9>', `C-M-<0-9>' in minibuffer.
+  "`digit-argument', but also echo the prefix."
+  (interactive "P")
+  (let* ((char   (if (integerp last-command-char)
+                     last-command-char
+                   (get last-command-char 'ascii-character)))
+         (digit  (- (logand char ?\177) ?0)))
+    (cond ((integerp arg)
+           (setq prefix-arg  (+ (* arg 10) (if (< arg 0) (- digit) digit))))
+          ((eq arg '-)
+           ;; Treat -0 as just -, so that -01 will work.
+           (setq prefix-arg  (if (zerop digit) '- (- digit))))
+          (t
+           (setq prefix-arg  digit))))
+  (setq universal-argument-num-events  (length (this-command-keys)))
+  (if (fboundp 'save&set-overriding-map) ; Emacs 24+
+      (save&set-overriding-map icicle-universal-argument-map)
+    (icicle-ensure-overriding-map-is-bound))
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+;;;###autoload
+(defun icicle-negative-argument (arg)   ; Bound to `M--', `C-M--' in minibuffer.
+  "`negative-argument', but also echo the prefix."
+  (interactive "P")
+  (cond ((integerp arg) (setq prefix-arg  (- arg)))
+        ((eq arg '-) (setq prefix-arg  nil))
+        (t (setq prefix-arg  '-)))
+  (setq universal-argument-num-events  (length (this-command-keys)))
+  (if (fboundp 'save&set-overriding-map) ; Emacs 24+
+      (save&set-overriding-map icicle-universal-argument-map)
+    (icicle-ensure-overriding-map-is-bound))
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+;;;###autoload
+(defun icicle-universal-argument ()     ; Bound to `C-u' in minibuffer.
+  "`universal-argument', but also echo the prefix."
+  (interactive)
+  (setq prefix-arg                     (list 4)
+        universal-argument-num-events  (length (this-command-keys)))
+  (if (fboundp 'save&set-overriding-map) ; Emacs 24+
+      (save&set-overriding-map icicle-universal-argument-map)
+    (icicle-ensure-overriding-map-is-bound))
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+;;;###autoload
+(defun icicle-universal-argument-more (arg)
+  "`universal-argument-more', but also echo the prefix."
+  (interactive "P")
+  (universal-argument-more arg)
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+;;;###autoload
+(defun icicle-universal-argument-other-key (arg)
+  "`universal-argument-other-key', but also echo the prefix."
+  (interactive "P")
+  (universal-argument-other-key arg)
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+;;;###autoload
+(defun icicle-universal-argument-minus (arg)
+  "`universal-argument-minus', but also echo the prefix."
+  (interactive "P")
+  (universal-argument-minus arg)
+  (icicle-msg-maybe-in-minibuffer "prefix %S" prefix-arg))
+
+
+;; REPLACE ORIGINAL `sit-for' in `subr.el',
+;; saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Ensure that `sit-for' after `C-u' in the minibuffer is immediately interrupted by user input.
+;; This fix is not needed for Emacs < 23.
+;;
+(unless (fboundp 'old-sit-for)
+  (defalias 'old-sit-for (symbol-function 'sit-for)))
+
+(when (> emacs-major-version 22)
+  (defun icicle-sit-for (seconds &optional nodisp obsolete)
+    "Perform redisplay, then wait for SECONDS seconds or until input is available.
+SECONDS may be a floating-point value.
+\(On operating systems that do not support waiting for fractions of a
+second, floating-point values are rounded down to the nearest integer.)
+
+If optional arg NODISP is t, don't redisplay, just wait for input.
+Redisplay does not happen if input is available before it starts.
+
+Value is t if waited the full time with no input arriving, and nil otherwise.
+
+An obsolete, but still supported form is
+\(sit-for SECONDS &optional MILLISECONDS NODISP)
+where the optional arg MILLISECONDS specifies an additional wait period,
+in milliseconds; this was useful when Emacs was built without
+floating point support."
+    (if (numberp nodisp)
+        (setq seconds  (+ seconds (* 1e-3 nodisp))
+              nodisp   obsolete)
+      (if obsolete (setq nodisp  obsolete)))
+    (cond (noninteractive
+           (sleep-for seconds)
+           t)
+          ((input-pending-p)
+           nil)
+          ((<= seconds 0)
+           (or nodisp (redisplay)))
+          (t
+           (or nodisp (redisplay))
+           (let ((read (read-event nil nil seconds)))
+             (or (null read)
+                 (progn
+                   ;; If last command was a prefix arg, e.g. C-u, push this event onto
+                   ;; `unread-command-events' as (t . EVENT) so it will be added to
+                   ;; `this-command-keys' by `read-key-sequence'.
+                   (if (memq overriding-terminal-local-map
+                             (list universal-argument-map icicle-universal-argument-map))
+                       (setq read (cons t read)))
+                   (push read unread-command-events)
+                   nil)))))))
+
+;;;###autoload
+(defun icicle-retrieve-next-input (&optional arg) ; Bound to `C-S-l' (`C-L') in minibuffer.
+  "Retrieve next minibuffer input.
+Like `icicle-retrieve-previous-input', but traverses history toward
+the present.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-retrieve-next-input]')."
+  (interactive "P")
+  (icicle-retrieve-previous-input arg 'interactive-p)) ; Must be `interactive-p'.
+
+;;;###autoload
+(defun icicle-retrieve-previous-input (&optional arg reversep allow-empty-p) ; `C-l' in minibuffer.
+  "Retrieve previous minibuffer input.
+The possible inputs were not necessarily those entered with `RET'.
+With a negative prefix arg, this just empties the completion history.
+Otherwise:
+ Use completion if `icicle-C-l-uses-completion-flag' is non-nil and no
+   prefix arg is used, or if it is nil and a prefix arg is used, or if
+   `icicle-retrieve-previous-input' is not used interactively.
+ Otherwise, just cycle to the previous input.
+
+Non-interactively:
+ Non-nil argument REVERSEP means reverse the history order: return the
+  next, not the previous, input.
+ Non-nil ALLOW-EMPTY-P means the retrieved input can be \"\".
+
+You can use this command only from buffer *Completions or from the
+minibuffer (`\\\
+\\[icicle-retrieve-previous-input]')."
+  (interactive "P")
+  (let ((interactive-p       (or (interactive-p) (eq reversep 'interactive-p)))
+        (prev-inputs-var     (if (icicle-file-name-input-p)
+                                 'icicle-previous-raw-file-name-inputs
+                               'icicle-previous-raw-non-file-name-inputs))
+        ;; `irpi-was-cycling-p' is used to remember, for the second `C-l' in a row, that the first
+        ;; `C-l' came after cycling.  In that case, the second `C-l' restores the current raw input.
+        (irpi-was-cycling-p  icicle-cycling-p))
+    (when interactive-p (icicle-barf-if-outside-Completions-and-minibuffer))
+    (cond ((wholenump (prefix-numeric-value arg))
+           (let ((input  ""))
+             (save-selected-window
+               (select-window (minibuffer-window))
+               (icicle-clear-minibuffer)
+               (let ((prev-inputs
+                      (if allow-empty-p
+                          (symbol-value prev-inputs-var)
+                        (icicle-remove-if (lambda (x) (string= "" x)) ; Exclude "".
+                                          (symbol-value prev-inputs-var)))))
+                 (setq input
+                       (if (and interactive-p (or (and icicle-C-l-uses-completion-flag (not arg))
+                                                  (and (not icicle-C-l-uses-completion-flag) arg)))
+                           (let ((icicle-whole-candidate-as-text-prop-p   nil)
+                                 (enable-recursive-minibuffers            t)
+                                 (icicle-show-Completions-initially-flag  t))
+                             (prog1 (completing-read
+                                     "Retrieve input: " (mapcar #'list prev-inputs) nil t)
+                               (setq icicle-last-input  nil)))
+                         (if (or (not interactive-p)
+                                 (not (memq last-command '(icicle-retrieve-next-input
+                                                           icicle-retrieve-previous-input))))
+                             ;; We use this one, to exclude common-match expansions from completion
+                             ;; history, and to save the typed input only when you complete.
+                             (let ((try  (if icicle-cycling-p
+                                             icicle-last-input
+                                           icicle-current-raw-input)))
+                               (if (or allow-empty-p (not (equal "" try))) try (car prev-inputs)))
+
+                           ;; You can use this one instead, if you want to include common-match
+                           ;; expansions and save the typed input even when you don't complete.
+                           ;; (or icicle-last-input icicle-current-raw-input)
+                           
+                           (let ((next  (member icicle-current-raw-input prev-inputs)))
+                             (unless next (setq next  prev-inputs))
+                             (if reversep
+                                 (or (let ((res     ())
+                                           (inputs  prev-inputs))
+                                       (while (and (consp inputs) (not (eq inputs next)))
+                                         (push (pop inputs) res))
+                                       (car res))
+                                     (car (last prev-inputs)))
+                               ;; If we were cycling before the first `C-l', then need to pick up the
+                               ;; current raw input.  Otherwise, we need to pick up the previous one.
+                               (prog1 (if irpi-was-cycling-p (car next) (cadr next))
+                                 (setq irpi-was-cycling-p  nil))))))) ; So third `C-l' acts normally.
+                 (when input
+                   (setq icicle-current-raw-input  input)
+                   (insert input)
+                   (icicle-highlight-initial-whitespace input) ; (e.g. user typo).
+                   (icicle-place-cursor input 'deactivate-mark))))
+             (let ((icicle-edit-update-p  t))
+               (funcall (or icicle-last-completion-command 'icicle-apropos-complete))
+               ;; Restore raw input.  Cycling resets it to "", so `icicle-save-or-restore-input'
+               ;; doesn't use out-of-date raw input (cycling does not necessarily follow completion
+               ;; or completion of the same kind).
+               (setq icicle-current-raw-input  input))
+             (setq icicle-last-input  nil ; So `TAB' will expand it - `icicle-save-or-restore-input'.
+                   icicle-cycling-p   irpi-was-cycling-p))) ; Let next `C-l' know the state.
+          (t
+           (set prev-inputs-var nil)
+           (setq icicle-current-raw-input  "")
+           (icicle-msg-maybe-in-minibuffer "Cleared completion history")))))
+
+;; $$ No longer bound.  Now we bind `icicle-retrieve-previous-input', instead, to `C-l'.
+;;;###autoload
+(defun icicle-retrieve-last-input ()
+  "Put the last real input into the minibuffer.
+Use this to replace a completion candidate inserted during cycling.
+If `icicle-expand-input-to-common-match-flag' is non-nil or this is
+prefix completion, then using this once restores the expanded common
+match string, and using it twice in succession restores your original
+input.
+
+You can use this command only from buffer *Completions or from the
+minibuffer."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (save-selected-window
+    (select-window (minibuffer-window))
+    (icicle-clear-minibuffer)
+    (if (and (or icicle-expand-input-to-common-match-flag (eq icicle-current-completion-mode 'prefix))
+             (eq last-command 'icicle-retrieve-last-input))
+        (insert icicle-current-raw-input)
+      (insert icicle-current-input))
+    ;;$$$ (when (interactive-p) (setq icicle-last-completion-command  nil))
+    (let ((input  (if (and (or icicle-expand-input-to-common-match-flag
+                               (eq icicle-current-completion-mode 'prefix))
+                           (eq last-command this-command))
+                      icicle-current-raw-input
+                    icicle-current-input)))
+      (icicle-highlight-initial-whitespace input) ; Highlight initial whitespace (e.g. user typo).
+      (icicle-place-cursor input 'deactivate-mark))))
+
+;; $$ No longer used.  It was originally used in `icicle-retrieve-last-input'.
+(defun icicle-insert-input (input)
+  "Insert INPUT.  Prepend the directory if appropriate."
+  (insert (if (and (icicle-file-name-input-p) insert-default-directory
+                   (or (not (member input icicle-extra-candidates))
+                       icicle-extra-candidates-dir-insert-p))
+              (icicle-expand-file-or-dir-name input (icicle-file-name-directory input))
+            input)))
+
+;;;###autoload
+(defun icicle-insert-history-element () ; Bound to `M-o' in minibuffer.
+  "Use completion to insert a previously entered input in the minibuffer.
+Always available for any minibuffer input, not just during completion."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (when (and (boundp minibuffer-history-variable) (consp (symbol-value minibuffer-history-variable)))
+    (let ((enable-recursive-minibuffers  t))
+      (insert (icicle-completing-read-history "Choose input: " minibuffer-history-variable))))
+  (when (and icicle-mode (memq icicle-default-value '(preselect-start preselect-end)))
+    (icicle-select-minibuffer-contents)
+    (setq deactivate-mark  nil)))
+
+;;;###autoload
+(defun icicle-insert-string-at-point (&optional arg) ; Bound to `M-.' in minibuffer.
+  "Insert text at the cursor into the minibuffer.
+Each time this command is called, some text at or near the cursor is
+inserted into the minibuffer.  One of two things happens, depending on
+the value of option `icicle-default-thing-insertion' and whether or
+not you use `C-u'.
+
+See the doc for option `icicle-thing-at-point-functions' for a
+complete description of its behavior.  What follows is an overview.
+
+`icicle-thing-at-point-functions' is a cons of two parts - call them
+ALTERNATIVES and FORWARD-THING.
+
+If ALTERNATIVES is not nil and one of the following is true:
+ - FORWARD-THING is nil
+ - the value of `icicle-default-thing-insertion' is `alternatives' and
+   you have not used plain `C-u' in this series of `M-.'
+ - the value of `icicle-default-thing-insertion' is `more-of-the-same'
+   and you have used plain `C-u' in this series of `M-.'
+then the next function in ALTERNATIVES is used to retrieve the text to
+be inserted.
+
+If FORWARD-THING is not nil and one of the following is true:
+ - ALTERNATIVES is nil
+ - the value of `icicle-default-thing-insertion' is `more-of-the-same'
+   and you have not used `C-u' in this series of `M-.'
+ - the value of `icicle-default-thing-insertion' is `alternatives' and
+   you have used `C-u' in this series of `M-.'
+then function FORWARD-THING is used to retrieve the text to be
+inserted.
+
+If you use a numeric prefix arg (not just plain `C-u'), the behavior
+is as follows.
+
+* If a function in ALTERNATIVES is used (see above), then the text
+  that is grabbed at or near point is read as a Lisp sexp and
+  evaluated, and the value is inserted instead of the grabbed text.
+
+  Yes, this means you need to know when the particular ALTERNATIVES
+  function that you want is coming up next, and use, say, `C-9' just
+  before hitting `M-.' for that alternative.  So if, e.g., you want to
+  evaluate the active region and insert the value, then you use
+  `M-. C-9 M-.', since it is the second `M-.' that grabs the region.
+
+* If the FORWARD-THING is being used, then the prefix arg determines
+  the number of things to grab, and the direction of grabbing.: A
+  negative argument grabs text to the left of the cursor; a positive
+  argument grabs text to the right.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-insert-string-at-point]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (when (consp icicle-thing-at-point-functions) ; Option should always be a cons cell.
+    (unless (eq last-command this-command) (setq icicle-default-thing-insertion-flipped-p  nil))
+    (let ((alt-fns       (car icicle-thing-at-point-functions))
+          (fwd-thing-fn  (cdr icicle-thing-at-point-functions))
+          (flipped       (or icicle-default-thing-insertion-flipped-p ; Already flipped.
+                             (setq icicle-default-thing-insertion-flipped-p  (consp arg)))))
+      (cond
+        ;; Use alternative text-grabbing functions successively.
+        ((and alt-fns (or (if (eq 'alternatives icicle-default-thing-insertion)
+                              (not flipped) ; Normal behavior for `alternatives'.
+                            flipped)    ; Flipped behavior for `more-of-the-same'.
+                          (not fwd-thing-fn))) ; No alternative.
+         (setq icicle-successive-grab-count  1 ; In this mode, reset other mode's accumulator.
+               icicle-thing-at-pt-fns-pointer
+               (if (eq last-command this-command) ; If repeated, get next text-grabbing function.
+                   (mod (1+ icicle-thing-at-pt-fns-pointer) (length alt-fns))
+                 0))
+         (let ((thing   "")
+               (alt-fn  (nth icicle-thing-at-pt-fns-pointer alt-fns)))
+           (save-excursion (with-current-buffer icicle-pre-minibuffer-buffer
+                             (setq thing  (funcall alt-fn))))
+           (setq thing  (or thing "nil"))
+           (when (and arg (atom arg))   ; Numeric prefix arg.
+             (setq thing  (condition-case err
+                              (format "%s" (eval (car (read-from-string thing))))
+                            (error thing))))
+           (icicle-insert-thing thing)
+           (icicle-msg-maybe-in-minibuffer (format "`%s'" alt-fn))))
+
+        ;; Use same text-grabbing function successively.
+        ((and fwd-thing-fn (or (if (eq 'alternatives icicle-default-thing-insertion)
+                                   flipped ; Flipped behavior for `alternatives'.
+                                 (not flipped)) ; Normal behavior for `more-of-the-same'.
+                               (not alt-fns))) ; No alternative.
+         (if (and arg (atom arg))
+
+             ;; Explicit numeric arg.  If it doesn't change direction, then increment
+             ;; existing count.  Otherwise, set count absolutely.
+             (if (eq last-command this-command)
+                 (if (= (icicle-signum icicle-successive-grab-count) ; Repeated `M-.'.
+                        (icicle-signum (prefix-numeric-value arg)))
+                     (setq icicle-successive-grab-count ; Same direction - increment count.
+                           (* (icicle-signum icicle-successive-grab-count)
+                              (+ (abs icicle-successive-grab-count)
+                                 (abs (prefix-numeric-value arg)))))
+                   (setq icicle-successive-grab-count  (prefix-numeric-value arg))) ; New dir - set.
+               (setq icicle-successive-grab-count  (prefix-numeric-value arg))) ; First `M-.' - set.
+
+           ;; No explicit numeric arg.
+           ;; If first `M-.' or plain `C-u', set count. Otherwise, increment count.
+           (if (eq last-command this-command)
+               (setq icicle-successive-grab-count ; Repeated `M-.'.
+                     (if (consp arg)
+                         ;; We're here from plain `C-u' with `alternatives' - use 1, not 4.
+                         (if (wholenump icicle-successive-grab-count) 1 -1)
+                       (if (wholenump icicle-successive-grab-count) ; Increment count.
+                           (+ icicle-successive-grab-count (abs (prefix-numeric-value arg)))
+                         (- icicle-successive-grab-count (abs (prefix-numeric-value arg))))))
+             (setq icicle-successive-grab-count  1))) ; First `M-.' - reset count.
+         (let ((things  ""))
+           (save-excursion
+             (with-current-buffer (cadr (buffer-list))
+               (setq things  (buffer-substring-no-properties
+                              (point)
+                              (save-excursion (funcall fwd-thing-fn icicle-successive-grab-count)
+                                              (point))))))
+           (icicle-insert-thing things)))))))
+
+(defun icicle-signum (num)
+  "Return 1 if NUM is positive, -1 if negative, 0 if zero."
+  (cond ((< num 0) -1) ((> num 0) 1) (t 0)))
+
+(defun icicle-insert-thing (text &optional no-replace-p)
+  "Insert TEXT in the minibuffer.
+TEXT replaces the last text that was inserted, if this command repeats
+the last and NO-REPLACE-P is nil."
+  (when (and (stringp text) (not (string= "" text)))
+    (remove-text-properties 0 (length text) '(face nil) text)
+    (when (and (eq last-command this-command) (not no-replace-p)
+               icicle-insert-string-at-pt-start) ; Ensure that we've defined the ends.
+      (delete-region icicle-insert-string-at-pt-start icicle-insert-string-at-pt-end))
+    (setq icicle-insert-string-at-pt-start  (point))
+    (insert text)
+    (setq icicle-insert-string-at-pt-end  (point))))
+
+;;;###autoload
+(defun icicle-insert-string-from-variable (askp) ; Bound to `C-=' in minibuffer.
+  "Insert text into the minibuffer from a variable.
+By default, the variable is user option `icicle-input-string'.  To
+insert from a different variable, use a prefix argument.  You are then
+prompted for the variable to use.  Completion candidates for this
+include all string-valued variables.
+
+You can use command `icicle-save-string-to-variable' to save a string
+to a variable.  Typically, you store a regexp or part of a regexp in
+the variable.  This command is bound in the minibuffer to `C-=', by
+default.  This is especially useful when used with command
+`icicle-search'.
+
+Some regexps that you might want to assign to variables:
+
+ \"[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+\"          ; Email address
+ \"\\\\([0-9]+\\\.[0-9]+\\\.[0-9]+\\\.[0-9]+\\\\)\"     ; IP address
+ \"[0-9]\\\\\\\={4\\\\}-[0-9]\\\\\\\={2\\\\}-[0-9]\\\\\\\={2\\\\}\"   ; Date: 2006-04-14, Time:
+ \"^[ \\\=\\t]*[0-9]?[0-9]\\\\([:.]?[0-9][0-9]\\\\)?\\\\(am\\\\|pm\\\\|AM\\\\|PM\\\\)?\"
+ \"`\\\\(\\\\sw\\\\sw+\\\\)'\"                        ; Words inside `_'
+ \"\\\\*.*\\\\*\"                                 ; Special buffer name: *_*
+
+Standard Emacs Lisp libraries are full of regexps that you can assign
+to variables for use with `C-='.
+ See `align.el' for regexps for programming languages.
+ See `url-dav.el' for regexps matching iso8601 dates.
+ See `rmail.el', `sendmail.el', and `mh-show.el' for regexps matching
+ mail-header fields.
+
+Imenu regexps occurring as parts of different values of
+`imenu-generic-expression' for different buffer types can be used as
+variable values for `C-='.  They all work fine with `icicle-search',
+turning it into a browser or navigator for the given mode.
+
+See, for example, `generic-x.el' and `lisp-mode.el'.  Here is a regexp
+for Javascript function definitions from `generic-x.el':
+
+ \"^function\\\\s-+\\\\([A-Za-z0-9_]+\\\\)\"
+
+And `lisp-imenu-generic-expression' (in `lisp-mode.el') provides
+regexps for Lisp function, variable, and type definitions.  Here is
+the variable-definition regexp:
+
+ \"^\\\\s-*(\\\\(def\\\\(c\\\\(onst\\\\(ant\\\\)?\\\\|ustom\\\\)\\\\|ine-symbol-macro\\\\|
+ parameter\\\\|var\\\\)\\\\)\\\\s-+\\\\(\\\\(\\\\sw\\\\|\\\\s_\\\\)+\\\\)\"
+
+Command `icicle-imenu' exploits this to automatically let you browse
+definitions.  It is a specialization of `icicle-search' for Imenu.
+
+For more useful regexps, grep for `font-lock-keywords' in Emacs `lisp'
+directory and subdirs.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-insert-string-from-variable]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (save-selected-window
+    (select-window (minibuffer-window))
+    (if askp
+        (let* ((icicle-whole-candidate-as-text-prop-p   nil)
+               ;; If we didn't use this here we'd at least have to bind it to
+               ;; `orig-must-pass-after-match-predicate', because of `icicle-execute-extended-command'.
+               (icicle-must-pass-after-match-predicate  #'(lambda (s)
+                                                            (let ((sym  (intern-soft s)))
+                                                              (and sym  (boundp (intern s))
+                                                                   (condition-case nil
+                                                                       (icicle-var-is-of-type-p
+                                                                        sym '(string color regexp)
+                                                                        'inherit-or-value)
+                                                                     (error nil))))))
+               (enable-recursive-minibuffers            t)
+               (var
+                (intern (completing-read "Insert text from variable: " obarray  nil  nil nil
+                                         (if (boundp 'variable-name-history)
+                                             'variable-name-history
+                                           'icicle-variable-name-history))))
+               ;; Make sure we use the buffer-local value of the variable, if there is one.
+               (text
+                (with-current-buffer (cadr (buffer-list)) (symbol-value var))))
+          (icicle-insert-thing text 'no-replace))
+      (icicle-insert-thing icicle-input-string 'no-replace))))
+
+;;;###autoload
+(defun icicle-insert-list-join-string () ; Bound to `C-M-j' in minibuffer during completion.
+  "Insert `icicle-list-join-string' in the minibuffer.
+Then, if `1on1-fit-minibuffer-frame-flag' is defined and non-nil, fit
+a standalone minibuffer frame to the new minibuffer contents.
+You need library `fit-frame.el' for the frame-fitting part."
+  (interactive)
+  (icicle-insert-thing icicle-list-join-string 'no-replace)
+  (let ((len  (length icicle-list-join-string)))
+    (when (and (string= "\C-j" (substring icicle-list-join-string (1- len) len))
+               (boundp '1on1-fit-minibuffer-frame-flag) ; In `oneonone.el'.
+               1on1-fit-minibuffer-frame-flag
+               (require 'fit-frame nil t))
+      (1on1-fit-minibuffer-frame))))
+
+;;;###autoload
+(defun icicle-dispatch-M-q (&optional arg) ; Bound to `M-q' in minibuffer.
+  "Do the right thing for `M-q'.
+If searching, call `icicle-toggle-search-whole-word'.
+Otherwise, call `icicle-insert-key-description'.
+Bound to `M-q' in the minibuffer."
+  (interactive "P") ; Argument is ignored for `icicle-toggle-search-whole-word'.
+  (cond (icicle-searching-p (icicle-toggle-search-whole-word))
+        (t (icicle-insert-key-description arg))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-search-whole-word 'icicle-toggle-search-whole-word)
+;;;###autoload
+(defun icicle-toggle-search-whole-word () ; Bound to `M-q' in minibuffer during Icicles search.
+  "Toggle the value of `icicle-search-whole-word-flag'.
+The new value takes effect for the next Icicles search command.
+Bound to `M-q' in the minibuffer when searching."
+  (interactive)
+  (setq icicle-search-whole-word-flag  (not icicle-search-whole-word-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-search-whole-word-flag
+                                      "Whole-word searching is now ON, starting with next search"
+                                    "Whole-word searching is now OFF, starting with next search")))
+
+;;;###autoload
+(defun icicle-insert-key-description (toggle-angle-brackets-p) ; Bound to `M-q' in minibuffer.
+  "Read key and insert its description.
+For example, if the key read is ^F, then \"C-f\" is inserted.
+
+`icicle-key-descriptions-use-<>-flag' determines whether angle
+brackets (`<', `>') are used for named keys, such as function
+keys, but a prefix argument reverses the meaning of
+`icicle-key-descriptions-use-<>-flag'.
+
+Bound to `M-q' in the minibuffer during key completion."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (let* ((enable-recursive-minibuffers  t)
+         (key
+          (progn (minibuffer-message " [Quoting key]") (read-event))))
+    (insert (single-key-description key (if toggle-angle-brackets-p
+                                            icicle-key-descriptions-use-<>-flag
+                                          (not icicle-key-descriptions-use-<>-flag))))))
+
+;;;###autoload
+(defun icicle-pp-eval-expression-in-minibuffer (insert-value) ; Bound to `M-:' in minibuffer.
+  "Evaluate an Emacs-Lisp expression and pretty-print its value.
+This just calls `pp-eval-expression' from a recursive minibuffer."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (let ((enable-recursive-minibuffers  t))
+    (call-interactively 'icicle-pp-eval-expression))
+  (select-window (minibuffer-window))
+  (select-frame-set-input-focus (selected-frame)))
+
+;;;###autoload
+(defun icicle-insert-newline-in-minibuffer (arg) ; Bound to `C-j' in minibuffer.
+  "Insert a newline character (`C-j'), in the minibuffer.
+Then, if `1on1-fit-minibuffer-frame-flag' is defined and non-nil, fit
+a standalone minibuffer frame to the new minibuffer contents.
+You need library `fit-frame.el' for the frame-fitting part."
+  (interactive "p")
+  (icicle-self-insert arg)
+  (when (and (boundp '1on1-fit-minibuffer-frame-flag) ; In `oneonone.el'.
+             1on1-fit-minibuffer-frame-flag
+             (require 'fit-frame nil t))
+    (1on1-fit-minibuffer-frame)))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-down-keys' (`down', `wheel-down').
+;;;###autoload
+(defun icicle-next-candidate-per-mode (&optional nth)
+  "Replace input by NTH next completion candidate.
+Default value of NTH is 1, meaning use the next candidate.
+Negative NTH means use a previous, not subsequent, candidate.
+
+Uses the next prefix or apropos completion command, depending on
+`icicle-current-completion-mode'.  If that is nil and
+`icicle-default-cycling-mode' is non-nil, uses the next history
+element instead.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-candidate-per-mode]')."
+  (interactive)
+  (unless nth (setq nth  1))
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (case icicle-current-completion-mode
+    (prefix
+     (setq this-command
+           (if (wholenump nth) 'icicle-next-prefix-candidate 'icicle-previous-prefix-candidate))
+     (icicle-next-prefix-candidate nth))
+    (apropos
+     (setq this-command
+           (if (wholenump nth) 'icicle-next-apropos-candidate 'icicle-previous-apropos-candidate))
+     (icicle-next-apropos-candidate nth))
+    ((nil)
+     (when icicle-default-cycling-mode (next-history-element (or nth 1))))))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-up-keys' (`up', `wheel-up').
+;;;###autoload
+(defun icicle-previous-candidate-per-mode (&optional nth)
+  "Replace input by NTH previous completion candidate.
+Default value of NTH is 1, meaning use the previous candidate.
+Negative NTH means use a subsequent, not previous, candidate.
+
+Uses the previous prefix or apropos completion command, depending on
+`icicle-current-completion-mode'. If that is nil and
+`icicle-default-cycling-mode' is non-nil, uses the previous history
+element instead.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-candidate-per-mode]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-next-candidate-per-mode (- (or nth 1))))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-previous-keys' (`home').
+(put 'icicle-previous-prefix-candidate 'icicle-cycling-command         'backward)
+(put 'icicle-previous-prefix-candidate 'icicle-prefix-cycling-command  'backward)
+;;;###autoload
+(defun icicle-previous-prefix-candidate (&optional nth)
+  "Replace input by NTH previous prefix completion for an input.
+Default value of NTH is 1, meaning use the previous prefix completion.
+Negative NTH means use a subsequent, not previous, prefix completion.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-prefix-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (setq nth  (or nth 1))
+  (icicle-next-prefix-candidate (- nth)))
+
+
+;; Bound in minibuffer to keys in `icicle-next-cycle-previous-keys' (`end').
+(put 'icicle-next-prefix-candidate 'icicle-cycling-command         'forward)
+(put 'icicle-next-prefix-candidate 'icicle-prefix-cycling-command  'forward)
+;;;###autoload
+(defun icicle-next-prefix-candidate (&optional nth)
+  "Replace input by NTH next prefix completion for an input.
+Default value of NTH is 1, meaning use the next prefix completion.
+Negative NTH means use a previous, not subsequent, prefix completion.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-prefix-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (setq icicle-current-completion-mode         'prefix
+        icicle-next-apropos-complete-cycles-p  nil)
+  (icicle-next-candidate nth (if (icicle-file-name-input-p)
+                                 'icicle-file-name-prefix-candidates
+                               'icicle-prefix-candidates)))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-previous-keys' (`prior').
+(put 'icicle-previous-apropos-candidate 'icicle-cycling-command         'backward)
+(put 'icicle-previous-apropos-candidate 'icicle-apropos-cycling-command 'backward)
+;;;###autoload
+(defun icicle-previous-apropos-candidate (&optional nth)
+  "Replace input by NTH previous apropos completion for an input.
+Default value of NTH is 1, meaning use the previous apropos completion.
+Negative NTH means use a subsequent, not previous, apropos completion.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-apropos-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (setq nth  (or nth 1))
+  (icicle-next-apropos-candidate (- nth)))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-next-keys' (`next').
+(put 'icicle-next-apropos-candidate 'icicle-cycling-command         'forward)
+(put 'icicle-next-apropos-candidate 'icicle-apropos-cycling-command 'forward)
+;;;###autoload
+(defun icicle-next-apropos-candidate (&optional nth)
+  "Replace input by NTH next apropos completion for an input.
+Default value of NTH is 1, meaning use the next apropos completion.
+Negative NTH means use a previous, not subsequent, apropos completion.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-apropos-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (setq icicle-current-completion-mode        'apropos
+        icicle-next-prefix-complete-cycles-p  nil)
+  (icicle-next-candidate nth (if (icicle-file-name-input-p)
+                                 'icicle-file-name-apropos-candidates
+                               'icicle-apropos-candidates)
+                         'regexp-p))
+
+;; Bound  in minibuffer to keys in `icicle-modal-cycle-up-action-keys' (`C-up').
+;;;###autoload
+(defun icicle-previous-candidate-per-mode-action (&optional nth)
+  "`icicle-previous-candidate-per-mode' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-candidate-per-mode-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-candidate-per-mode #'icicle-candidate-action nth))
+
+;; Bound  in minibuffer to keys in `icicle-modal-cycle-up-alt-action-keys' (`C-S-up').
+;;;###autoload
+(defun icicle-previous-candidate-per-mode-alt-action (&optional nth)
+  "`icicle-previous-candidate-per-mode' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-candidate-per-mode-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-candidate-per-mode #'icicle-candidate-alt-action nth))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-down-action-keys' (`C-down').
+;;;###autoload
+(defun icicle-next-candidate-per-mode-action (&optional nth)
+  "`icicle-next-candidate-per-mode' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-candidate-per-mode-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-candidate-per-mode #'icicle-candidate-action nth))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-down-alt-action-keys' (`C-S-down').
+;;;###autoload
+(defun icicle-next-candidate-per-mode-alt-action (&optional nth)
+  "`icicle-next-candidate-per-mode' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-candidate-per-mode-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-candidate-per-mode #'icicle-candidate-alt-action nth))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-up-help-keys' (`C-M-up').
+;;;###autoload
+(defun icicle-previous-candidate-per-mode-help (&optional nth)
+  "`icicle-previous-candidate-per-mode' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-candidate-per-mode-help]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-candidate-per-mode #'icicle-help-on-candidate nth))
+
+;; Bound in minibuffer to keys in `icicle-modal-cycle-down-help-keys' (`C-M-down').
+;;;###autoload
+(defun icicle-next-candidate-per-mode-help (&optional nth)
+  "`icicle-next-candidate-per-mode' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-candidate-per-mode'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-candidate-per-mode-help]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-candidate-per-mode #'icicle-help-on-candidate nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-previous-action-keys' (`C-home').
+(put 'icicle-previous-prefix-candidate-action 'icicle-cycling-command         'backward)
+(put 'icicle-previous-prefix-candidate-action 'icicle-prefix-cycling-command  'backward)
+;;;###autoload
+(defun icicle-previous-prefix-candidate-action (&optional nth)
+  "`icicle-previous-prefix-candidate' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-prefix-candidate-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-prefix-candidate #'icicle-candidate-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-next-action-keys' (`C-end').
+(put 'icicle-next-prefix-candidate-action 'icicle-cycling-command         'forward)
+(put 'icicle-next-prefix-candidate-action 'icicle-prefix-cycling-command  'forward)
+;;;###autoload
+(defun icicle-next-prefix-candidate-action (&optional nth)
+  "`icicle-next-prefix-candidate' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-prefix-candidate-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-prefix-candidate #'icicle-candidate-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-previous-action-keys' (`C-prior').
+(put 'icicle-previous-apropos-candidate-action 'icicle-cycling-command         'backward)
+(put 'icicle-previous-apropos-candidate-action 'icicle-apropos-cycling-command 'backward)
+;;;###autoload
+(defun icicle-previous-apropos-candidate-action (&optional nth)
+  "`icicle-previous-apropos-candidate' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-apropos-candidate-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-apropos-candidate #'icicle-candidate-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-next-action-keys' (`C-next').
+(put 'icicle-next-apropos-candidate-action 'icicle-cycling-command         'forward)
+(put 'icicle-next-apropos-candidate-action 'icicle-apropos-cycling-command 'forward)
+;;;###autoload
+(defun icicle-next-apropos-candidate-action (&optional nth)
+  "`icicle-next-apropos-candidate' and `icicle-candidate-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-apropos-candidate-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-apropos-candidate #'icicle-candidate-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-previous-alt-action-keys' (`C-S-home').
+(put 'icicle-previous-prefix-candidate-alt-action 'icicle-cycling-command         'backward)
+(put 'icicle-previous-prefix-candidate-alt-action 'icicle-prefix-cycling-command  'backward)
+;;;###autoload
+(defun icicle-previous-prefix-candidate-alt-action (&optional nth)
+  "`icicle-previous-prefix-candidate' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-prefix-candidate-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-prefix-candidate #'icicle-candidate-alt-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-next-alt-action-keys' (`C-S-end').
+(put 'icicle-next-prefix-candidate-alt-action 'icicle-cycling-command         'forward)
+(put 'icicle-next-prefix-candidate-alt-action 'icicle-prefix-cycling-command  'forward)
+;;;###autoload
+(defun icicle-next-prefix-candidate-alt-action (&optional nth)
+  "`icicle-next-prefix-candidate' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-prefix-candidate-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-prefix-candidate #'icicle-candidate-alt-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-previous-alt-action-keys' (`C-S-prior').
+(put 'icicle-previous-apropos-candidate-alt-action 'icicle-cycling-command         'backward)
+(put 'icicle-previous-apropos-candidate-alt-action 'icicle-apropos-cycling-command 'backward)
+;;;###autoload
+(defun icicle-previous-apropos-candidate-alt-action (&optional nth)
+  "`icicle-previous-apropos-candidate' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-previous-apropos-candidate-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-apropos-candidate #'icicle-candidate-alt-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-next-alt-action-keys' (`C-S-next').
+(put 'icicle-next-apropos-candidate-alt-action 'icicle-cycling-command         'forward)
+(put 'icicle-next-apropos-candidate-alt-action 'icicle-apropos-cycling-command 'forward)
+;;;###autoload
+(defun icicle-next-apropos-candidate-alt-action (&optional nth)
+  "`icicle-next-apropos-candidate' and `icicle-candidate-alt-action'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-next-apropos-candidate-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-apropos-candidate #'icicle-candidate-alt-action nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-previous-help-keys' (`C-M-home').
+(put 'icicle-help-on-previous-prefix-candidate 'icicle-cycling-command         'backward)
+(put 'icicle-help-on-previous-prefix-candidate 'icicle-prefix-cycling-command  'backward)
+;;;###autoload
+(defun icicle-help-on-previous-prefix-candidate (&optional nth)
+  "`icicle-previous-prefix-candidate' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-help-on-previous-prefix-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-prefix-candidate #'icicle-help-on-candidate nth))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-cycle-next-help-keys' (`C-M-end').
+(put 'icicle-help-on-next-prefix-candidate 'icicle-cycling-command         'forward)
+(put 'icicle-help-on-next-prefix-candidate 'icicle-prefix-cycling-command  'forward)
+;;;###autoload
+(defun icicle-help-on-next-prefix-candidate (&optional nth)
+  "`icicle-next-prefix-candidate' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-prefix-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-help-on-next-prefix-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-prefix-candidate #'icicle-help-on-candidate nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-previous-help-keys' (`C-M-prior').
+(put 'icicle-help-on-previous-apropos-candidate 'icicle-cycling-command         'backward)
+(put 'icicle-help-on-previous-apropos-candidate 'icicle-apropos-cycling-command 'backward)
+;;;###autoload
+(defun icicle-help-on-previous-apropos-candidate (&optional nth)
+  "`icicle-previous-apropos-candidate' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-previous-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-help-on-previous-apropos-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-previous-apropos-candidate #'icicle-help-on-candidate nth))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-cycle-previous-help-keys' (`C-M-next').
+(put 'icicle-help-on-next-apropos-candidate 'icicle-cycling-command         'forward)
+(put 'icicle-help-on-next-apropos-candidate 'icicle-apropos-cycling-command 'forward)
+;;;###autoload
+(defun icicle-help-on-next-apropos-candidate (&optional nth)
+  "`icicle-next-apropos-candidate' and `icicle-help-on-candidate'.
+Option `icicle-act-before-cycle-flag' determines which occurs first.
+
+Optional argument NTH is as for `icicle-next-apropos-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-help-on-next-apropos-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-successive-action #'icicle-next-apropos-candidate #'icicle-help-on-candidate nth))
+
+(defun icicle-successive-action (nav-fn action-fn nth)
+  "Call NAV-FN and ACTION-FN.  Pass argument NTH to NAV-FN.
+Set `icicle-current-completion-mode'.
+The order between NAV-FN and ACTION-FN respects the value of
+`icicle-act-before-cycle-flag'."
+  ;; Set mode only if known.  Otherwise, leave it alone (e.g. for per-mode functions).
+  (cond ((get nav-fn 'icicle-apropos-cycling-command)
+         (setq icicle-current-completion-mode        'apropos
+               icicle-next-prefix-complete-cycles-p  nil))
+        ((get nav-fn 'icicle-prefix-cycling-command)
+         (setq icicle-current-completion-mode         'prefix
+               icicle-next-apropos-complete-cycles-p  nil)))
+
+  ;; We bind `icicle-acting-on-next/prev' to non-nil (and the direction) while calling the action
+  ;; function.  This is used by Icicles search-and-replace (`icicle-search-highlight-and-maybe-replace')
+  ;; to ensure the correct candidate number for a series of replacements.
+  ;; (Not currently used for the `icicle-act-before-cycle-flag' case, but we do it there also, anyway.)
+  (cond (icicle-act-before-cycle-flag
+         (let ((icicle-acting-on-next/prev  (get nav-fn 'icicle-cycling-command)))
+           (save-excursion (save-selected-window (funcall action-fn))))
+         (funcall nav-fn nth))
+        (t
+         ;; Inhibit showing help in mode-line while moving to next/previous candidate
+         ;; in `*Completions*', because help sits for `icicle-help-in-mode-line-delay' sec.
+         ;; Display the help after we do the action.
+         (let ((icicle-help-in-mode-line-delay  0)) (funcall nav-fn nth))
+         (let ((icicle-acting-on-next/prev  (get nav-fn 'icicle-cycling-command)))
+           (save-excursion (save-selected-window (funcall action-fn))))
+         (when (stringp icicle-last-completion-candidate)
+           (icicle-show-help-in-mode-line icicle-last-completion-candidate)))))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-complete-keys' (`TAB').
+(put 'icicle-prefix-complete 'icicle-cycling-command t)
+(put 'icicle-prefix-complete 'icicle-prefix-cycling-command t)
+(put 'icicle-prefix-complete 'icicle-completing-command t)
+(put 'icicle-prefix-complete 'icicle-prefix-completing-command t)
+;;;###autoload
+(defun icicle-prefix-complete ()
+  "Complete the minibuffer contents as far as possible, as a prefix.
+Repeat this to cycle among candidate completions.
+If no characters can be completed, display the possible completions.
+Candidate completions are appropriate names whose prefix is the
+minibuffer input, where appropriateness is determined by the context
+\(command, variable, and so on).
+Return nil if there is no valid completion.
+Otherwise, return the list of completion candidates.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-prefix-complete]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (unless (string= icicle-dot-string-internal ".")
+    (icicle-convert-dots t t)
+    (setq icicle-dot-string-internal  "."))
+  (icicle-prefix-complete-1))
+
+
+;; Bound in minibuffer to keys in `icicle-prefix-complete-no-display-keys' (`C-M-TAB').
+(put 'icicle-prefix-complete-no-display 'icicle-cycling-command t)
+(put 'icicle-prefix-complete-no-display 'icicle-prefix-cycling-command t)
+(put 'icicle-prefix-complete-no-display 'icicle-completing-command t)
+(put 'icicle-prefix-complete-no-display 'icicle-prefix-completing-command t)
+;;;###autoload
+(defun icicle-prefix-complete-no-display (&optional no-msg-p) ; Bound to `C-M-TAB' in minibuffer.
+  "Like `icicle-prefix-complete', but without displaying `*Completions*'.
+Optional arg NO-MSG-P non-nil means do not show a minibuffer message
+indicating that candidates were updated.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-prefix-complete-no-display]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-prefix-complete-1 (if no-msg-p 'no-msg 'no-display)))
+
+
+;; Bound in minibuffer to keys in `icicle-word-completion-keys' (`M-SPC').
+(put 'icicle-prefix-word-complete 'icicle-cycling-command t)
+(put 'icicle-prefix-word-complete 'icicle-prefix-cycling-command t)
+(put 'icicle-prefix-word-complete 'icicle-completing-command t)
+(put 'icicle-prefix-word-complete 'icicle-prefix-completing-command t)
+;;;###autoload
+(defun icicle-prefix-word-complete ()
+  "Complete the minibuffer contents at most a single word.
+Repeating this completes additional words.
+Spaces and hyphens in candidates are considered word separators.
+If only a single candidate matches, the input is completed entirely.
+Return nil if there is no valid completion, else t.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-prefix-word-complete]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-prefix-complete-1 nil t))
+
+(defun icicle-prefix-complete-1 (&optional no-display-p word-p)
+  "Helper function for `icicle-prefix-complete(-no-display)'.
+Return the list of completion candidates.
+Optional argument NO-DISPLAY-P non-nil means do not display buffer
+ `*Completions*'.  If the value is `no-msg', then do not show any
+  message either.  NO-DISPLAY-P is passed to
+ `icicle-display-candidates-in-Completions' as its second arg.
+Optional argument WORD-P non-nil means complete only a word at a time."
+  (let ((ipc1-was-cycling-p  icicle-cycling-p)
+        (mode-line-help      nil))
+    (setq icicle-current-input                   (if (and icicle-last-input
+                                                          icicle-cycling-p
+                                                          (not icicle-edit-update-p)
+                                                          (eq icicle-current-completion-mode 'prefix)
+                                                          (or (not word-p)
+                                                              (eq this-command last-command))
+                                                          (symbolp last-command)
+                                                          (or (get last-command 'icicle-cycling-command)
+                                                              (get last-command 'icicle-action-command))
+                                                          icicle-completion-candidates)
+                                                     icicle-last-input
+                                                   (if (icicle-file-name-input-p)
+                                                       (abbreviate-file-name
+                                                        (icicle-input-from-minibuffer 'leave-envar))
+                                                     (icicle-input-from-minibuffer)))
+          icicle-current-completion-mode         'prefix
+          icicle-next-apropos-complete-cycles-p  nil
+          icicle-input-fail-pos                  nil
+          icicle-cycling-p                       nil)
+    (when icicle-edit-update-p (setq icicle-next-prefix-complete-cycles-p  nil))
+    (let ((word-complete-input      "")
+          (input-before-completion  icicle-current-input)
+          return-value)
+      (unless (and (stringp icicle-current-input) (stringp icicle-last-input)
+                   (string= icicle-current-input icicle-last-input)
+                   (or (get last-command 'icicle-prefix-completing-command)
+                       (get last-command 'icicle-action-command))
+                   (not word-p))
+        (unless (or icicle-edit-update-p (get-buffer-window "*Completions*" 0) no-display-p)
+          (message "Computing completion candidates..."))
+        (if (not word-p)
+            (setq icicle-completion-candidates
+                  (icicle-condition-case-no-debug nil
+                      (if (icicle-file-name-input-p)
+                          (icicle-file-name-prefix-candidates icicle-current-input)
+                        (icicle-prefix-candidates icicle-current-input))
+                    (error icicle-completion-candidates))) ; No change if completion error.
+          ;; Complete a word.  Save input before trying to complete.
+          ;; Update `icicle-current-input': `minibuffer-complete-word' might have completed the input
+          ;; beyond a complete candidate - e.g. `forwar-char' to `forward-char-'.
+          (setq word-complete-input   (icicle-input-from-minibuffer)
+                return-value
+                (let ((temp-buffer-show-hook       nil) ; Don't let it fit frame here.
+                      (completion-auto-help        nil) ; Don't show `*Completions*'.
+                      (minibuffer-message-timeout  0)) ; No timeout.
+                  (icicle-clear-minibuffer)
+                  (insert icicle-current-input)
+                  (save-selected-window (minibuffer-complete-word)))
+                icicle-current-input  (icicle-input-from-minibuffer)) ; Update input.
+          ;; If incremental compl., or completed some, or not repeated, then update input and recompute.
+          (when (or icicle-edit-update-p
+                    (> (length icicle-current-input) (length word-complete-input))
+                    (not (eq this-command last-command)))
+            (setq word-complete-input           icicle-current-input
+                  icicle-completion-candidates  (icicle-condition-case-no-debug nil
+                                                    (if (icicle-file-name-input-p)
+                                                        (icicle-file-name-prefix-candidates
+                                                         icicle-current-input)
+                                                      (icicle-prefix-candidates icicle-current-input))
+                                                  (error icicle-completion-candidates)))))
+        (message nil))                  ; Clear out "Computing completion candidates..." message.
+      (unless word-p (setq return-value  icicle-completion-candidates)) ; Word returns special value.
+      (icicle-save-or-restore-input)
+      (cond ((null icicle-completion-candidates)
+             (setq icicle-nb-of-other-cycle-candidates  0)
+             (let ((icicle-incremental-completion-flag ; Upgrade if OK for explicit.
+                    (or (memq icicle-highlight-input-completion-failure
+                              '(explicit-strict explicit explicit-remote))
+                        icicle-incremental-completion-flag)))
+               (icicle-highlight-input-noncompletion))
+             (save-selected-window (icicle-remove-Completions-window))
+             (run-hooks 'icicle-no-match-hook)
+             (unless (eq no-display-p 'no-msg)
+               (minibuffer-message (case (icicle-current-TAB-method)
+                                     (fuzzy        "  [No fuzzy completions]")
+                                     (vanilla      "  [No vanilla completions]")
+                                     (swank        "  [No swank (fuzzy symbol) completions]")
+                                     (t            "  [No prefix completions]")))))
+            ((null (cdr icicle-completion-candidates)) ; Single candidate.  Update minibuffer.
+             ;; When `icicle-whole-candidate-as-text-prop-p' is t and
+             ;; `icicle-expand-input-to-common-match-flag' is nil, we need to expand the input anyway.
+             ;; That transfers any `icicle-whole-candidate' property from the candidate to
+             ;; `icicle-current-input', so things that use `icicle-candidates-alist' will work.
+             (when (and icicle-whole-candidate-as-text-prop-p
+                        (not icicle-expand-input-to-common-match-flag))
+               (setq icicle-common-match-string  (icicle-expanded-common-match
+                                                  icicle-current-input icicle-completion-candidates))
+               (when icicle-common-match-string
+                 (let ((common  (if (and (icicle-file-name-input-p) insert-default-directory)
+                                    (if (string= "" icicle-common-match-string)
+                                        (or (icicle-file-name-directory icicle-current-input) "")
+                                      (directory-file-name (icicle-abbreviate-or-expand-file-name
+                                                            icicle-common-match-string
+                                                            (icicle-file-name-directory
+                                                             icicle-current-input))))
+                                  icicle-common-match-string)))
+                   ;; Save as current input, unless input is a directory.
+                   (unless (and (icicle-file-name-input-p)  (file-directory-p icicle-current-input))
+                     (setq icicle-current-input  common)))))
+             ;; Expand file-name input to the common match for the current candidate.
+             (when (icicle-file-name-input-p)
+               (setq icicle-common-match-string  (icicle-expanded-common-match
+                                                  (car icicle-completion-candidates)
+                                                  icicle-completion-candidates))
+               (when icicle-common-match-string
+                 (let ((common  (if (and (icicle-file-name-input-p) insert-default-directory)
+                                    (if (string= "" icicle-common-match-string)
+                                        (or (icicle-file-name-directory icicle-current-input) "")
+                                      (directory-file-name (icicle-abbreviate-or-expand-file-name
+                                                            icicle-common-match-string
+                                                            (icicle-file-name-directory
+                                                             icicle-current-input))))
+                                  icicle-common-match-string)))
+                   (setq icicle-current-input  common))))
+             (setq icicle-nb-of-other-cycle-candidates  0)
+             (unless icicle-edit-update-p
+               (icicle-clear-minibuffer)
+               (let ((cand  (car icicle-completion-candidates)))
+                 (if (icicle-file-name-input-p)
+                     (cond ((string= "" cand) ; This indicates an empty dir.
+                            (setq icicle-last-completion-candidate  icicle-current-input))
+                           ((eq ?\/  (aref cand (1- (length cand)))) ; Add `/', so cycling expands dir.
+                            (setq icicle-current-input (concat icicle-current-input "/")
+                                  icicle-last-completion-candidate  icicle-current-input))
+                           (t           ; Non-dir - use the candidate file, but without any dir.
+                            (setq icicle-last-completion-candidate
+                                  (icicle-file-name-nondirectory cand))))
+                   (setq icicle-last-completion-candidate  cand)))
+               (let ((inserted  (if (and (icicle-file-name-input-p) insert-default-directory
+                                         (or (not (member icicle-last-completion-candidate
+                                                          icicle-extra-candidates))
+                                             icicle-extra-candidates-dir-insert-p))
+                                    (icicle-abbreviate-or-expand-file-name
+                                     icicle-last-completion-candidate
+                                     (icicle-file-name-directory-w-default icicle-current-input))
+                                  icicle-last-completion-candidate)))
+                 (insert inserted)
+                 (when (and (icicle-file-name-input-p)
+                            (icicle-file-directory-p (icicle-abbreviate-or-expand-file-name inserted)))
+                   (setq icicle-default-directory  (icicle-abbreviate-or-expand-file-name inserted)))))
+             (save-selected-window (icicle-remove-Completions-window))
+             (icicle-transform-sole-candidate)
+             (unless (boundp 'icicle-prefix-complete-and-exit-p)
+               (icicle-highlight-complete-input)
+               (cond ((and icicle-top-level-when-sole-completion-flag
+                           (sit-for icicle-top-level-when-sole-completion-delay))
+                      (set minibuffer-history-variable
+                           (cons icicle-current-input
+                                 (symbol-value minibuffer-history-variable)))
+                      (icicle-condition-case-no-debug icicle-prefix-complete-1
+                          (throw 'icicle-read-top
+                            (if (and (icicle-file-name-input-p) insert-default-directory
+                                     (or (not (member icicle-current-input
+                                                      icicle-extra-candidates))
+                                         icicle-extra-candidates-dir-insert-p))
+                                (expand-file-name icicle-current-input)
+                              icicle-current-input))
+                        (no-catch
+                         (icicle-retrieve-last-input)
+                         icicle-current-input)
+                        (error (message "%s" (error-message-string icicle-prefix-complete-1)))))
+                     ((and icicle-edit-update-p (not (eq no-display-p 'no-msg)))
+                      (minibuffer-message
+                       (format (case (icicle-current-TAB-method)
+                                 (fuzzy        "  [One fuzzy completion: %s]")
+                                 (vanilla      "  [One vanilla completion: %s]")
+                                 (swank        "  [One swank (fuzzy symbol) completion: %s]")
+                                 (t            "  [One prefix completion: %s]"))
+                               icicle-current-input))
+                      (setq mode-line-help  icicle-current-input))
+                     ((not (eq no-display-p 'no-msg))
+                      (minibuffer-message (case (icicle-current-TAB-method)
+                                            (fuzzy        "  [Sole fuzzy completion]")
+                                            (vanilla      "  [Sole vanilla completion]")
+                                            (swank        "  [Sole swank (fuzzy symbol) completion]")
+                                            (t            "  [Sole prefix completion]")))
+                      (setq mode-line-help  icicle-current-input)))))
+            (t                          ; Multiple candidates.
+             (if icicle-edit-update-p
+                 (icicle-display-candidates-in-Completions nil no-display-p)
+               (unless word-p
+                 (icicle-clear-minibuffer)
+                 (save-window-excursion
+                   ;; Shouldn't need to explicitly select minibuffer like this, since `*Completions*'
+                   ;; input is directed there.  But there seems to be an Emacs bug somewhere, because
+                   ;; although using just `insert' inserts the input in the minibuffer OK, in some
+                   ;; cases the cursor might not follow the insertion.
+                   (select-window (active-minibuffer-window))
+                   (insert icicle-current-input))
+                 ;; Shouldn't need to do this if it is on `post-command-hook', but it seems we need to.
+                 (when (and (boundp '1on1-fit-minibuffer-frame-flag) 1on1-fit-minibuffer-frame-flag
+                            (require 'fit-frame nil t))
+                   (1on1-fit-minibuffer-frame))) ; In `oneonone.el'.
+               (deactivate-mark)
+               (icicle-highlight-initial-whitespace icicle-current-input)
+               (when (and (icicle-file-name-input-p)
+                          (icicle-file-directory-p icicle-last-completion-candidate))
+                 (setq icicle-default-directory  (icicle-abbreviate-or-expand-file-name
+                                                  icicle-last-completion-candidate)))
+               (when (and (icicle-input-is-a-completion-p icicle-current-input)
+                          (not (boundp 'icicle-prefix-complete-and-exit-p)))
+                 (icicle-highlight-complete-input)
+                 (setq mode-line-help  (icicle-minibuf-input-sans-dir icicle-current-input)))
+               (cond (;; Candidates visible.  If second prefix complete, cycle, else update candidates.
+                      (get-buffer-window "*Completions*" 0)
+                      (if (and (or ipc1-was-cycling-p icicle-next-prefix-complete-cycles-p)
+                               (get icicle-last-completion-command 'icicle-prefix-completing-command)
+                               (if word-p
+                                   ;; Word completion cycles only if both of these are true:
+                                   ;; * Input is not yet complete (null `return-value').
+                                   ;; * Either last command was an edit and input does not end in `-',
+                                   ;;          or the current input is from cycling.
+                                   ;; E.g. `M-x fo M-SPC r M-SPC' cycles among foreground-color etc.
+                                   (and (not return-value)
+                                        (or (and (not (or (get last-command
+                                                               'icicle-prefix-completing-command)
+                                                          (get last-command 'icicle-action-command)))
+                                                 (not (eq (aref icicle-current-input
+                                                                (1- (length icicle-current-input)))
+                                                          ?-)))
+                                            (not (string= icicle-last-input word-complete-input))))
+                                 (or (get last-command 'icicle-prefix-completing-command)
+                                     (get last-command 'icicle-action-command))))
+                          ;; Second prefix complete in a row.  Cycle down.
+                          (icicle-next-candidate 1 (if (icicle-file-name-input-p)
+                                                       'icicle-file-name-prefix-candidates
+                                                     'icicle-prefix-candidates))
+                        ;; User did something else (e.g. changed input).  Update the candidates.
+                        (icicle-display-candidates-in-Completions nil no-display-p)))
+                     (;; No candidates shown.  Could be first completion or could follow `C-M-(S-)TAB'.
+                      icicle-TAB-shows-candidates-flag
+                      (if (not (and (or ipc1-was-cycling-p icicle-next-prefix-complete-cycles-p)
+                                    (get icicle-last-completion-command
+                                         'icicle-prefix-completing-command)
+                                    (or (get last-command 'icicle-prefix-completing-command)
+                                        (get last-command 'icicle-action-command))
+                                    (not word-p)))
+                          ;; First prefix complete is enough to update candidates.
+                          (icicle-display-candidates-in-Completions nil no-display-p)
+                        ;; Second prefix complete.  If `TAB', then it follows `C-M-TAB', so show window.
+                        (unless no-display-p (icicle-display-candidates-in-Completions nil))
+                        (icicle-next-candidate 1 (if (icicle-file-name-input-p)
+                                                     'icicle-file-name-prefix-candidates
+                                                   'icicle-prefix-candidates))))
+                     (;; No candidates shown.  Second prefix complete.
+                      ;; If NO-DISPLAY-P and either not WORD-P or input is complete, then cycle down.
+                      ;; Else, vanilla Emacs: second `TAB' shows candidates.
+                      (and (get icicle-last-completion-command 'icicle-prefix-completing-command)
+                           (or (get last-command 'icicle-prefix-completing-command)
+                               (get last-command 'icicle-action-command))
+                           completion-auto-help)
+                      (if (or (not no-display-p) (and word-p (not return-value)))
+                          (icicle-display-candidates-in-Completions nil)
+                        (icicle-next-candidate 1 (if (icicle-file-name-input-p)
+                                                     'icicle-file-name-prefix-candidates
+                                                   'icicle-prefix-candidates))))
+                     ;; Input is complete, but exist other candidates with same prefix.
+                     ((and (member icicle-current-input icicle-completion-candidates)
+                           (not (eq no-display-p 'no-msg)))
+                      (minibuffer-message "  [Complete, but not unique]"))))))
+      (setq icicle-last-completion-command        (if word-p
+                                                      'icicle-prefix-word-complete
+                                                    (if no-display-p
+                                                        'icicle-prefix-complete-no-display
+                                                      'icicle-prefix-complete))
+            icicle-next-prefix-complete-cycles-p  (equal input-before-completion
+                                                         (icicle-input-from-minibuffer 'leave-envvars)))
+      (when mode-line-help (icicle-show-help-in-mode-line mode-line-help))
+      return-value)))
+
+(defun icicle-input-is-a-completion-p (&optional input)
+  "Return non-nil if the input is a valid completion.
+Optional arg INPUT is passed to `icicle-minibuffer-input-sans-dir'.
+This is essentially a `member' test, except for environment vars, for
+which the initial `$' is ignored."
+  (let* ((input-sans-dir  (icicle-minibuf-input-sans-dir input))
+         (env-var-name    (and (icicle-not-basic-prefix-completion-p)
+                               (> (length input-sans-dir) 0)
+                               (eq ?\$ (aref input-sans-dir 0))
+                               (substring input-sans-dir 1))))
+    (member (icicle-upcase-if-ignore-case (or env-var-name input-sans-dir))
+            (mapcar #'icicle-upcase-if-ignore-case icicle-completion-candidates))))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-complete-keys' (`S-TAB').
+(put 'icicle-apropos-complete 'icicle-cycling-command t)
+(put 'icicle-apropos-complete 'icicle-apropos-cycling-command t)
+(put 'icicle-apropos-complete 'icicle-completing-command t)
+(put 'icicle-apropos-complete 'icicle-apropos-completing-command t)
+;;;###autoload
+(defun icicle-apropos-complete ()
+  "Complete the minibuffer contents as far as possible.
+Repeat this to cycle among candidate completions.
+This uses \"apropos completion\", defined as follows:
+A completion contains the minibuffer input somewhere, as a substring.
+Display a list of possible completions in buffer `*Completions*'.
+Candidate completions are appropriate names that match the current
+input, taken as a regular expression, where appropriateness is
+determined by the context (command, variable, and so on).
+Return nil if there is no valid completion.
+Otherwise, return the list of completion candidates.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-apropos-complete]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (when (and (string= icicle-dot-string icicle-anychar-regexp)
+             (not (string= icicle-dot-string-internal icicle-anychar-regexp)))
+    (icicle-convert-dots (equal icicle-current-input icicle-last-input)) ; No confirm if same input.
+    (setq icicle-dot-string-internal  (icicle-anychar-regexp)))
+  (let* ((error-msg  nil)               ; Apropos complete.
+         (candidates
+          (icicle-condition-case-no-debug lossage
+              (icicle-apropos-complete-1)
+            (invalid-regexp
+             (setq error-msg  (cadr lossage))
+             (when (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid " error-msg)
+               (setq error-msg  "incomplete input")))
+            (error (setq error-msg  (error-message-string lossage))))))
+    (when error-msg (minibuffer-message (concat "  " error-msg)))
+    candidates))
+
+
+;; Bound in minibuffer to keys in `icicle-apropos-complete-no-display-keys' (`C-M-S-TAB').
+(put 'icicle-apropos-complete-no-display 'icicle-cycling-command t)
+(put 'icicle-apropos-complete-no-display 'icicle-apropos-cycling-command t)
+(put 'icicle-apropos-complete-no-display 'icicle-completing-command t)
+(put 'icicle-apropos-complete-no-display 'icicle-apropos-completing-command t)
+;;;###autoload
+(defun icicle-apropos-complete-no-display (&optional no-msg-p)
+  "Like `icicle-apropos-complete', but without displaying `*Completions*'.
+Optional arg NO-MSG-P non-nil means do not show a minibuffer message
+indicating that candidates were updated.
+You can use this command only from the minibuffer (`\\\
+\\[icicle-apropos-complete-no-display]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (let* ((error-msg  nil)
+         (candidates
+          (icicle-condition-case-no-debug lossage
+              (icicle-apropos-complete-1 (if no-msg-p 'no-msg 'no-display))
+            (invalid-regexp
+             (setq error-msg  (cadr lossage))
+             (when (string-match "\\`Premature \\|\\`Unmatched \\|\\`Invalid " error-msg)
+               (setq error-msg  "incomplete input")))
+            (error (setq error-msg  (error-message-string lossage))))))
+    (when error-msg (minibuffer-message (concat "  " error-msg)))
+    candidates))
+
+(defun icicle-apropos-complete-1 (&optional no-display-p)
+  "Helper function for `icicle-apropos-complete(-no-display)'.
+This does everything except deal with regexp-match errors.
+Return the list of completion candidates.
+
+Optional argument NO-DISPLAY-P non-nil means do not display buffer
+`*Completions*'.  If the value is `no-msg', then do not show any
+message either.  NO-DISPLAY-P is passed to
+`icicle-display-candidates-in-Completions' as its second arg."
+  (let ((iac1-was-cycling-p  icicle-cycling-p)
+        (mode-line-help      nil)
+        input-before-completion)
+    (setq icicle-current-input                  (if (and icicle-last-input
+                                                         icicle-cycling-p
+                                                         (not icicle-edit-update-p)
+                                                         (eq icicle-current-completion-mode 'apropos)
+                                                         (symbolp last-command)
+                                                         (or (get last-command 'icicle-cycling-command)
+                                                             (get last-command 'icicle-action-command))
+                                                         icicle-completion-candidates)
+                                                    icicle-last-input
+                                                  (icicle-input-from-minibuffer))
+          icicle-current-completion-mode        'apropos
+          icicle-next-prefix-complete-cycles-p  nil
+          icicle-input-fail-pos                 nil
+          icicle-cycling-p                      nil)
+    (when icicle-edit-update-p (setq icicle-next-apropos-complete-cycles-p  nil))
+    (when (icicle-file-name-input-p)
+      (setq icicle-current-input  (abbreviate-file-name
+                                   (if icicle-regexp-quote-flag
+                                       (substitute-in-file-name icicle-current-input)
+                                     icicle-current-input))))
+    (setq input-before-completion  icicle-current-input)
+    (unless (or icicle-edit-update-p (get-buffer-window "*Completions*" 0) no-display-p)
+      (message "Computing completion candidates..."))
+    (unless (and (stringp icicle-current-input) (stringp icicle-last-input)
+                 (string= icicle-current-input icicle-last-input)
+                 (or (get last-command 'icicle-apropos-completing-command)
+                     (get last-command 'icicle-action-command)))
+      (setq icicle-completion-candidates
+            (icicle-condition-case-no-debug nil
+                (if (icicle-file-name-input-p)
+                    (icicle-file-name-apropos-candidates icicle-current-input)
+                  (icicle-apropos-candidates icicle-current-input))
+              (error icicle-completion-candidates)))) ; No change if completion error.
+    (icicle-save-or-restore-input)
+    (cond ((null icicle-completion-candidates)
+           (setq icicle-nb-of-other-cycle-candidates  0)
+           (let ((icicle-incremental-completion-flag ; Upgrade if OK for explicit.
+                  (or (memq icicle-highlight-input-completion-failure
+                            '(explicit-strict explicit explicit-remote))
+                      icicle-incremental-completion-flag)))
+             (icicle-highlight-input-noncompletion))
+           (save-selected-window (icicle-remove-Completions-window))
+           (run-hooks 'icicle-no-match-hook)
+           (unless (eq no-display-p 'no-msg)
+             (minibuffer-message (let ((typ  (car (rassq icicle-apropos-complete-match-fn
+                                                         icicle-S-TAB-completion-methods-alist))))
+                                   (concat "  [No " typ (and typ " ") "completion]")))))
+          ((null (cdr icicle-completion-candidates)) ; Single candidate. Update minibuffer.
+           ;; When `icicle-whole-candidate-as-text-prop-p' is t
+           ;; and `icicle-expand-input-to-common-match-flag' is nil, we need to expand the input anyway.
+           ;; That transfers any `icicle-whole-candidate' property from the candidate to
+           ;; `icicle-current-input', so things that use `icicle-candidates-alist' will work.
+           (when (and icicle-whole-candidate-as-text-prop-p
+                      (not icicle-expand-input-to-common-match-flag))
+             (setq icicle-common-match-string  (icicle-expanded-common-match
+                                                icicle-current-input icicle-completion-candidates))
+             (when icicle-common-match-string
+               (let ((common  (if (and (icicle-file-name-input-p) insert-default-directory)
+                                  (if (string= "" icicle-common-match-string)
+                                      (or (icicle-file-name-directory icicle-current-input) "")
+                                    (directory-file-name (icicle-abbreviate-or-expand-file-name
+                                                          icicle-common-match-string
+                                                          (icicle-file-name-directory
+                                                           icicle-current-input))))
+                                icicle-common-match-string)))
+                 ;; Save as current input, unless input is a directory.
+                 (unless (and (icicle-file-name-input-p)  (file-directory-p icicle-current-input))
+                   (setq icicle-current-input  common)))))
+           ;; Expand file-name input to the common match for the current candidate.
+           (when (icicle-file-name-input-p)
+             (setq icicle-common-match-string  (icicle-expanded-common-match
+                                                (car icicle-completion-candidates)
+                                                icicle-completion-candidates))
+             (when icicle-common-match-string
+               (let ((common  (if (and (icicle-file-name-input-p) insert-default-directory)
+                                  (if (string= "" icicle-common-match-string)
+                                      (or (icicle-file-name-directory icicle-current-input) "")
+                                    (directory-file-name (icicle-abbreviate-or-expand-file-name
+                                                          icicle-common-match-string
+                                                          (icicle-file-name-directory
+                                                           icicle-current-input))))
+                                icicle-common-match-string)))
+                 (setq icicle-current-input  common))))
+           (setq icicle-nb-of-other-cycle-candidates  0)
+           (unless icicle-edit-update-p
+             (icicle-clear-minibuffer)
+             (if (icicle-file-name-input-p)
+                 (let ((cand  (car icicle-completion-candidates)))
+                   (cond ((string= "" cand) ; This indicates an empty dir.
+                          (setq icicle-last-completion-candidate  icicle-current-input))
+                         ((eq ?\/  (aref cand (1- (length cand)))) ; Add `/', so cycling expands dir.
+                          (setq icicle-current-input              (concat icicle-current-input "/")
+                                icicle-last-completion-candidate  icicle-current-input))
+                         (t             ; Non-dir - use the candidate file.
+                          (setq icicle-last-completion-candidate  (car icicle-completion-candidates)))))
+               (setq icicle-last-completion-candidate  (car icicle-completion-candidates)))
+             (let ((inserted  (if (and (icicle-file-name-input-p) insert-default-directory
+                                       (or (not (member icicle-last-completion-candidate
+                                                        icicle-extra-candidates))
+                                           icicle-extra-candidates-dir-insert-p))
+                                  (icicle-abbreviate-or-expand-file-name
+                                   icicle-last-completion-candidate
+                                   (icicle-file-name-directory-w-default icicle-current-input))
+                                icicle-last-completion-candidate)))
+               (insert inserted)
+               (when (and (icicle-file-name-input-p)
+                          (icicle-file-directory-p (icicle-abbreviate-or-expand-file-name inserted)))
+                 (setq icicle-default-directory  (icicle-abbreviate-or-expand-file-name inserted)))))
+           (save-selected-window (icicle-remove-Completions-window))
+           (icicle-transform-sole-candidate)
+           (unless (boundp 'icicle-apropos-complete-and-exit-p)
+             (icicle-highlight-complete-input)
+             (cond ((and icicle-top-level-when-sole-completion-flag
+                         (sit-for icicle-top-level-when-sole-completion-delay))
+                    (set minibuffer-history-variable (cons (car icicle-completion-candidates)
+                                                           (symbol-value minibuffer-history-variable)))
+                    (icicle-condition-case-no-debug icicle-apropos-complete-1
+                        (throw 'icicle-read-top
+                          (if (and (icicle-file-name-input-p) insert-default-directory
+                                   (or (not (member (car icicle-completion-candidates)
+                                                    icicle-extra-candidates))
+                                       icicle-extra-candidates-dir-insert-p))
+                              (expand-file-name (car icicle-completion-candidates))
+                            (car icicle-completion-candidates)))
+                      (no-catch (setq icicle-current-input  (car icicle-completion-candidates))
+                                (icicle-retrieve-last-input)
+                                icicle-current-input)
+                      (error (message "%s" (error-message-string icicle-apropos-complete-1)))))
+                   ((and icicle-edit-update-p (not (eq no-display-p 'no-msg)))
+                    (minibuffer-message (format "  [One apropos completion: %s]"
+                                                (car icicle-completion-candidates)))
+                    (setq mode-line-help  (car icicle-completion-candidates)))
+                   ((not (eq no-display-p 'no-msg))
+                    (minibuffer-message "  [Sole apropos completion]")
+                    (setq mode-line-help  (car icicle-completion-candidates))))))
+          (t                            ; Multiple candidates.
+           (if icicle-edit-update-p
+               (icicle-display-candidates-in-Completions nil no-display-p)
+             (icicle-clear-minibuffer)
+             (insert icicle-current-input) ; Update minibuffer.
+             ;; Shouldn't need to do this if it is on `post-command-hook', but it seems we need to.
+             (when (and (boundp '1on1-fit-minibuffer-frame-flag) 1on1-fit-minibuffer-frame-flag
+                        (require 'fit-frame nil t))
+               (1on1-fit-minibuffer-frame)) ; In `oneonone.el'.
+             (deactivate-mark)
+             (icicle-highlight-initial-whitespace icicle-current-input)
+             (when (and (icicle-file-name-input-p)
+                        (icicle-file-directory-p icicle-last-completion-candidate))
+               (setq icicle-default-directory  (icicle-abbreviate-or-expand-file-name
+                                                icicle-last-completion-candidate)))
+             (let ((input-sans-dir  (icicle-minibuf-input-sans-dir icicle-current-input)))
+               (when (and (member (icicle-upcase-if-ignore-case input-sans-dir)
+                                  (mapcar #'icicle-upcase-if-ignore-case icicle-completion-candidates))
+                          (not (boundp 'icicle-apropos-complete-and-exit-p)))
+                 (icicle-highlight-complete-input)
+                 (setq mode-line-help  input-sans-dir)))
+             (cond (;; Candidates already displayed.  If second `S-TAB', cycle, else update candidates.
+                    (get-buffer-window "*Completions*" 0)
+                    (if (and (or iac1-was-cycling-p icicle-next-apropos-complete-cycles-p)
+                             (get icicle-last-completion-command 'icicle-apropos-completing-command)
+                             (or (get last-command 'icicle-apropos-completing-command)
+                                 (get last-command 'icicle-action-command)))
+                        ;; Second `S-TAB' in a row.  Cycle down.
+                        (icicle-next-candidate 1 (if (icicle-file-name-input-p)
+                                                     'icicle-file-name-apropos-candidates
+                                                   'icicle-apropos-candidates)
+                                               'regexp-p)
+                      ;; User did something else (e.g. changed input).  (Possibly) update the display.
+                      (icicle-display-candidates-in-Completions nil no-display-p)))
+                   (t
+                    (if (not (and (or iac1-was-cycling-p icicle-next-apropos-complete-cycles-p)
+                                  (get icicle-last-completion-command
+                                       'icicle-apropos-completing-command)
+                                  (or (get last-command 'icicle-apropos-completing-command)
+                                      (get last-command 'icicle-action-command))))
+                        (icicle-display-candidates-in-Completions nil no-display-p)
+                      ;; Second apropos complete.  If `S-TAB', it follows `C-M-S-TAB', so show window.
+                      (unless no-display-p (icicle-display-candidates-in-Completions nil))
+                      (icicle-next-candidate 1 (if (icicle-file-name-input-p)
+                                                   'icicle-file-name-apropos-candidates
+                                                 'icicle-apropos-candidates)
+                                             'regexp-p)))))))
+    (setq icicle-last-completion-command         (if no-display-p
+                                                     'icicle-apropos-complete-no-display
+                                                   'icicle-apropos-complete)
+          icicle-next-apropos-complete-cycles-p  (equal input-before-completion
+                                                        (icicle-input-from-minibuffer)))
+    (when mode-line-help (icicle-show-help-in-mode-line mode-line-help))
+    icicle-completion-candidates))
+
+(defun icicle-transform-sole-candidate ()
+  "Transform matching candidate according to `icicle-list-use-nth-parts'."
+  (when (and icicle-list-use-nth-parts icicle-current-input)
+    ;; $$$$$$ (let ((newcand  (icicle-transform-multi-completion (car icicle-completion-candidates))))
+    (let ((newcand  (icicle-transform-multi-completion icicle-current-input)))
+      (icicle-clear-minibuffer)
+      (insert newcand)
+      (setq icicle-completion-candidates      (list newcand)
+            icicle-last-completion-candidate  newcand))))
+
+;;;###autoload
+(defun icicle-switch-to-Completions-buf () ; Bound to `C-insert' in minibuffer.
+  "Select the completion list window.
+The cursor is placed on the first occurrence of the current minibuffer
+content.  You can use \\\
+`\\[icicle-insert-completion]' to get back to the minibuffer.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-switch-to-Completions-buf]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (let ((window     (get-buffer-window "*Completions*" 0))
+        (search-fn  'search-forward))
+    (unless window                      ; Make sure we have a completions window.
+      (icicle-apropos-complete)
+      (setq window     (get-buffer-window "*Completions*" 0)
+            search-fn  're-search-forward)) ; Use regexp search: input is not yet complete.
+    (when window
+      (select-window window)
+      (let ((case-fold-search
+             ;; Don't bother to detect buffer completion and check `read-buffer-completion-ignore-case'.
+             (if (and (icicle-file-name-input-p)
+                      (boundp 'read-file-name-completion-ignore-case))
+                 read-file-name-completion-ignore-case
+               completion-ignore-case)))
+        (goto-char (icicle-start-of-candidates-in-Completions))
+        (cond (icicle-candidate-nb
+               (icicle-move-to-next-completion icicle-candidate-nb 'NO-MINIBUFFER-FOLLOW-P))
+              (t
+               (let ((inp  (icicle-minibuf-input-sans-dir icicle-current-input)))
+                 (when (and (get icicle-last-completion-command 'icicle-apropos-completing-command)
+                            ;; $$ Previously allowed the -action's.
+                            (not (and (symbolp last-command) (get last-command 'icicle-cycling-command))))
+                   (setq search-fn  're-search-forward)) ; Use regexp search: input is not yet complete.
+                 (while (and (not (eobp))
+                             (save-restriction
+                               (narrow-to-region (point) (next-single-property-change (point) 'mouse-face
+                                                                                      nil (point-max)))
+                               (not (funcall search-fn inp nil 'leave-at-end))))))))
+        (unless (eobp)
+          (unless icicle-candidate-nb (goto-char (match-beginning 0)))
+          (let ((prop  (get-text-property (1- (point)) 'mouse-face)))
+            ;; If in a completion, move to the start of it.
+            (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
+              (goto-char (previous-single-property-change (point) 'mouse-face nil (point-min)))))
+          (icicle-place-overlay
+           (point) (next-single-property-change (point) 'mouse-face nil (point-max))
+           'icicle-current-completion-candidate-overlay 'icicle-current-candidate-highlight
+           100 (current-buffer)))))))
+
+;;;###autoload
+(defun icicle-insert-completion (&optional completion) ; Bound to `C-insert' in `*Completions*'.
+  "Select the active minibuffer window.  Insert current completion.
+The current candidate in `*Completions*' (under the cursor) is
+inserted into the minibuffer as the current input.  You can use \\\
+`\\[icicle-switch-to-Completions-buf]'
+to switch to the `*Completions*' window.
+
+You can use this command only from buffer `*Completions*' (`\\\
+\\[icicle-insert-completion]').
+
+Non-interactively, optional arg COMPLETION is the completion to insert."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions))
+  (when (active-minibuffer-window)
+    (unwind-protect                     ; If no current completion, return to minibuffer anyway.
+         (progn
+           (setq completion                        (or completion
+                                                       (icicle-current-completion-in-Completions))
+                 icicle-last-completion-candidate  completion
+                 icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos (point)))
+           (select-window (active-minibuffer-window))
+           (with-current-buffer (window-buffer) ; Needed if `*Completions*' is redirected to minibuffer.
+             (goto-char (icicle-minibuffer-prompt-end))
+             (icicle-clear-minibuffer)
+             (icicle-insert-cand-in-minibuffer completion
+                                               (not (eq icicle-current-completion-mode 'prefix)))
+             (setq icicle-last-input  icicle-current-input
+                   icicle-cycling-p   t)
+             (icicle-show-help-in-mode-line icicle-last-completion-candidate)))
+      (select-window (active-minibuffer-window)))))
+
+(defun icicle-current-completion-in-Completions ()
+  "The completion candidate under the cursor in buffer `*Completions*'.
+Return the name as a string." ; See also `choose-completion' and `mouse-choose-completion'.
+  (let ((buffer          completion-reference-buffer)
+        (base-size       completion-base-size)
+        (start-of-cands  (icicle-start-of-candidates-in-Completions))
+        beg end)
+    (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+      (setq end  (point)
+            beg  (1+ (point))))
+    (when (and (> (point) start-of-cands) (get-text-property (1- (point)) 'mouse-face))
+      (setq end  (1- (point))
+            beg  (point)))
+    (setq beg  (previous-single-property-change (or beg (point)) 'mouse-face nil start-of-cands)
+          end  (next-single-property-change (or end (point)) 'mouse-face nil (point-max)))
+    (unless beg (error "No completion here"))
+    ;; `icicle-insert-candidates' doesn't put `mouse-face' on the final \n of a candidate
+    ;; in `*Completions*'. Add the newline back. `icicle-insert-candidates' puts property
+    ;; `icicle-keep-newline' on the newline if it is part of the candidate, as opposed to
+    ;; being just part of the display in columns.
+    (when (and (eq ?\n (char-after end)) (get-text-property end 'icicle-keep-newline))
+      (setq end  (1+ end)))
+    ;; $$$$ (buffer-substring-no-properties beg end)))
+    (buffer-substring beg end)))
+
+;;;###autoload
+(defun icicle-switch-to/from-minibuffer () ; Bound to `pause' in Icicle mode.
+  "Switch to minibuffer or previous buffer, in other window.
+If current buffer is the minibuffer, then switch to the buffer that
+was previously current.  Otherwise, switch to the minibuffer."
+  (interactive)
+  (unless (active-minibuffer-window) (error "Minibuffer is not active"))
+  (if (eq (selected-window) (active-minibuffer-window))
+      (switch-to-buffer-other-window icicle-pre-minibuffer-buffer)
+    (select-window (active-minibuffer-window))))
+
+
+;; Replaces `previous-completion' (defined in `simple.el').
+;;;###autoload
+(defun icicle-move-to-previous-completion (n) ; Bound to `left', `S-TAB' in `*Completions*'.
+  "Move to the previous item in the completion list.
+
+You can use this command only from buffer `*Completions*' (`\\\
+\\[icicle-move-to-previous-completion]')."
+  (interactive "p")
+  (when (interactive-p) (icicle-barf-if-outside-Completions))
+  (setq n  (or n 0))
+  (icicle-move-to-next-completion (- n)))
+
+
+;; Replaces `next-completion' (defined in `simple.el').
+;; This is similar, except:
+;; 1. This highlights the current candidate.
+;; 2. This wraps around from first to last and last to first.
+;; 3. Properly handles completions laid out vertically.
+;;
+;;;###autoload
+(defun icicle-move-to-next-completion (n ; Bound to `right', `TAB' in `*Completions*'.
+                                       &optional no-minibuffer-follow-p)
+  "Move to the next item in the completion list.
+With prefix argument N, move N items (negative N means move backward).
+Optional second argument, if non-nil, means do not copy the completion
+back to the minibuffer.
+
+You can use this command only from buffer `*Completions*' (`\\\
+\\[icicle-move-to-next-completion]')."
+  (interactive "p")
+  (when (interactive-p) (icicle-barf-if-outside-Completions))
+  (setq n  (or n 0))
+  (when (eq icicle-completions-format 'vertical)
+    (let* ((cols      (icicle-nb-Completions-cols))
+           (nb-cands  (length icicle-completion-candidates))
+           (rows      (/ nb-cands cols)))
+      (unless (zerop (% nb-cands cols)) (setq rows  (1+ rows)))
+      (setq n  (icicle-row-wise-cand-nb n nb-cands rows cols))))
+  (let ((beg  (icicle-start-of-candidates-in-Completions))
+        (end  (point-max)))
+ 
+    ;; Forward: n > 0.
+    (while (and (> n 0) (not (eobp)))
+      (when (get-text-property (point) 'mouse-face) ; If in a candidate, move to its end.
+        (goto-char (next-single-property-change (point) 'mouse-face nil end)))
+      (unless (get-text-property (point) 'mouse-face) ; Move to start of next candidate.
+        (goto-char (or (next-single-property-change (point) 'mouse-face)
+                       beg)))           ; Wrap back to first candidate.
+      (setq n  (1- n)))
+
+    ;; Backward: n < 0.
+    (while (and (< n 0) (>= (count-lines 1 (point)) (if icicle-show-Completions-help-flag 3 2)))
+      (let ((prop  (get-text-property (1- (point)) 'mouse-face)))
+        (when (and prop (eq prop (get-text-property (point) 'mouse-face))) ; If in cand, move to start.
+          (goto-char (previous-single-property-change (point) 'mouse-face nil beg))))
+      (unless (or (< (count-lines 1 (point)) ; Move to end of previous candidate.
+                     (if icicle-show-Completions-help-flag 3 2))
+                  (get-text-property (1- (point)) 'mouse-face))
+        (goto-char (or (previous-single-property-change (point) 'mouse-face)
+                       end)))           ; Wrap back to last candidate.
+
+      ;; Move to the start of that candidate.
+      (goto-char (previous-single-property-change (point) 'mouse-face nil beg))
+      (setq n  (1+ n)))
+
+    (icicle-place-overlay
+     (point) (next-single-property-change (point) 'mouse-face nil end)
+     'icicle-current-completion-candidate-overlay 'icicle-current-candidate-highlight
+     100 (current-buffer)))
+  (unless no-minibuffer-follow-p (save-excursion (save-window-excursion (icicle-insert-completion)))))
+
+;;;###autoload
+(defun icicle-previous-line ()          ; Bound to `up' in `*Completions*'.
+  "Move up a line, in `*Completions*' buffer.  Wrap around first to last.
+You can use this command only from buffer `*Completions*' (`\\\
+\\[icicle-previous-line]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions))
+  (let ((opoint          (point))
+        (curr-col        1)
+        (next-line-cols  1)
+        (eol             (save-excursion (end-of-line) (point))))
+    (save-excursion
+      (beginning-of-line)
+      (while (and (< (point) opoint) (re-search-forward "[^ ] +" eol t))
+        (setq curr-col  (1+ curr-col))))
+    (forward-line -1)
+    (when (< (point) (icicle-start-of-candidates-in-Completions))
+      (goto-char (point-max)) (beginning-of-line)) ; Wrap around
+    (let ((eol  (save-excursion (end-of-line) (point))))
+      (save-excursion
+        (beginning-of-line)
+        (while (re-search-forward "[^ ] +[^ ]" eol t) (setq next-line-cols  (1+ next-line-cols)))))
+    (if (> curr-col next-line-cols)
+        (icicle-move-to-next-completion (1- next-line-cols))
+      (icicle-move-to-next-completion (1- curr-col)))))
+
+;;;###autoload
+(defun icicle-next-line ()              ; Bound to `down' in `*Completions*'.
+  "Move down a line, in `*Completions*' buffer.  Wrap around last to first.
+You can use this command only from buffer `*Completions*' (`\\\
+\\[icicle-next-line]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions))
+  (let ((opoint          (point))
+        (curr-col        1)
+        (next-line-cols  1)
+        (eol             (save-excursion (end-of-line) (point))))
+    (save-excursion
+      (beginning-of-line)
+      (while (and (< (point) opoint) (re-search-forward "[^ ] +" eol t))
+        (setq curr-col  (1+ curr-col))))
+    (forward-line 1)
+    (when (eobp) (goto-char (icicle-start-of-candidates-in-Completions))) ; Wrap around
+    (let ((eol  (save-excursion (end-of-line) (point))))
+      (save-excursion
+        (beginning-of-line)
+        (while (re-search-forward "[^ ] +[^ ]" eol t) (setq next-line-cols  (1+ next-line-cols)))))
+    (if (> curr-col next-line-cols)
+        (icicle-move-to-next-completion (1- next-line-cols))
+      (icicle-move-to-next-completion (1- curr-col)))))
+
+;; Same as `end-of-line+' in `misc-cmds.el'.
+;;;###autoload
+(defun icicle-end-of-line+ (&optional n) ; Bound to `C-e' in minibuffer and in `*Completions*'.
+  "Move cursor to end of current line or end of next line if repeated.
+This is similar to `end-of-line', but:
+  If called interactively with no prefix arg:
+     If the previous command was also `end-of-line+', then move to the
+     end of the next line.  Else, move to the end of the current line.
+  Otherwise, move to the end of the Nth next line (Nth previous line
+     if N<0).  Command `end-of-line', by contrast, moves to the end of
+     the (N-1)th next line."
+  (interactive
+   (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 0)))
+  (unless n (setq n  0))                ; non-interactive with no arg
+  (if (and (eq this-command last-command) (not current-prefix-arg))
+      (forward-line 1)
+    (forward-line n))
+  (let ((inhibit-field-text-motion  t)) ; Emacs 22+, so we get past the end of the prompt field.
+    (end-of-line)))
+
+;; Same as `beginning-of-line+' in `misc-cmds.el'.
+;;;###autoload
+(defun icicle-beginning-of-line+ (&optional n) ; Bound to `C-a' in minibuffer and in `*Completions*'.
+  "Move cursor to beginning of current line or next line if repeated.
+This is the similar to `beginning-of-line', but:
+1. With arg N, the direction is the opposite: this command moves
+   backward, not forward, N lines.
+2. If called interactively with no prefix arg:
+      If the previous command was also `beginning-of-line+', then move
+      to the beginning of the previous line.  Else, move to the
+      beginning of the current line.
+   Otherwise, move to the beginning of the Nth previous line (Nth next
+      line if N<0).  Command `beginning-of-line', by contrast, moves to
+      the beginning of the (N-1)th next line."
+  (interactive
+   (list (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 0)))
+  (unless n (setq n  0))                ; non-interactive with no arg
+  (if (and (eq this-command last-command) (not current-prefix-arg))
+      (forward-line -1)
+    (forward-line (- n)))
+  (when (bobp) (goto-char (icicle-minibuffer-prompt-end))))
+
+;; Same as `resolve-file-name' in `misc-cmds.el'.
+;;;###autoload
+(defun icicle-resolve-file-name (bounds &optional killp) ; Bound to `C-x C-f' in minibuffer.
+  "Replace the file name at/near point by its absolute, true file name.
+If the region is active, replace its content instead, treating it as a
+file name.
+
+If library `thingatpt+.el' is available then use the file name
+*nearest* point.  Otherwise, use the file name *at* point.
+
+With a prefix arg, add both the original file name and the true name
+to the kill ring.  Otherwise, add neither to the kill ring.  (If the
+region was active then its content was already added to the ring.)"
+  (interactive
+   (let* ((regionp   (and transient-mark-mode mark-active))
+          (thg+bnds  (and (not regionp)
+                          (require 'thingatpt+ nil t)
+                          (thing-nearest-point-with-bounds 'filename)))
+          (bnds      (if regionp
+                         (cons (region-beginning) (region-end))
+                       (if thg+bnds
+                           (cdr thg+bnds)
+                         (bounds-of-thing-at-point 'filename))))
+          (fname     (if bnds
+                         (buffer-substring (car bnds) (cdr bnds))
+                       (message "No file name at point"))))
+     (list bnds current-prefix-arg)))
+  (when bounds
+    (let* ((file       (buffer-substring (car bounds) (cdr bounds)))
+           (absfile    (expand-file-name (buffer-substring (car bounds) (cdr bounds))))
+           (dir        (or (file-name-directory absfile) default-directory))
+           (true-dir   (file-truename dir))
+           (relfile    (file-name-nondirectory absfile))
+           (true-file  (concat true-dir relfile)))
+      (unless (equal file true-file)
+        (cond (killp
+               (if (and transient-mark-mode mark-active)
+                   (delete-region (car bounds) (cdr bounds)) ; Don't add it twice.
+                 (kill-region (car bounds) (cdr bounds)))
+               (insert (kill-new true-file)))
+              (t
+               (delete-region (car bounds) (cdr bounds))
+               (insert true-file)))))))
+
+
+(put 'icicle-all-candidates-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-all-candidates-action ()  ; Bound to `C-!' in minibuffer.
+  "Take action on each completion candidate, in turn.
+Apply `icicle-candidate-action-fn' successively to each saved
+completion candidate (if any) or each candidate that matches the
+current input (a regular expression).  The candidates that were not
+successfully acted upon are listed in buffer *Help*.
+
+If there are saved completion candidates, then they are acted on;
+if not, then all current matching candidates are acted on.
+
+If `icicle-candidate-action-fn' is nil but
+`icicle-all-candidates-list-action-fn' is not, then apply the latter
+to the list of candidates as a whole, instead.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-all-candidates-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (unless (or icicle-all-candidates-list-action-fn icicle-candidate-action-fn)
+    (error "No action defined"))
+  (if icicle-candidate-action-fn
+      (icicle-all-candidates-action-1 icicle-candidate-action-fn nil)
+    (icicle-all-candidates-action-1 icicle-all-candidates-list-action-fn t)))
+
+
+(put 'icicle-all-candidates-alt-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-all-candidates-alt-action () ; Bound to `C-|' in minibuffer.
+  "Take alternative action on each completion candidate, in turn.
+Apply `icicle-candidate-alt-action-fn' successively to each saved
+completion candidate (if any) or each candidate that matches the
+current input (a regular expression).  The candidates that were not
+successfully acted upon are listed in buffer *Help*.
+
+If there are saved completion candidates, then they are acted on; if
+not, then all current matching candidates are acted on.
+
+If `icicle-candidate-alt-action-fn' is nil but
+`icicle-all-candidates-list-alt-action-fn' is not, then apply the
+latter to the list of candidates as a whole, instead.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-all-candidates-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (unless (or icicle-all-candidates-list-alt-action-fn icicle-candidate-alt-action-fn)
+    (error "No alternative action defined"))
+  (if icicle-candidate-alt-action-fn
+      (icicle-all-candidates-action-1 icicle-candidate-alt-action-fn nil t) ; ALTP flag
+    (icicle-all-candidates-action-1 icicle-all-candidates-list-alt-action-fn t)))
+
+
+(put 'icicle-all-candidates-list-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-all-candidates-list-action () ; Bound to `M-!' in minibuffer.
+  "Take action on the list of all completion candidates.
+Apply `icicle-all-candidates-list-action-fn' to the list of saved
+completion candidates or the list of candidates that match the current
+input (a regular expression).
+
+If there are saved completion candidates, then they are acted on; if
+not, then all current matching candidates are acted on.
+
+If `icicle-all-candidates-list-action-fn' is nil but
+`icicle-candidate-action-fn' is not, then apply the latter to each
+matching candidate in turn, and print the candidates that were not
+successfully acted upon in buffer *Help*.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-all-candidates-list-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (unless (or icicle-all-candidates-list-action-fn icicle-candidate-action-fn)
+    (error "No action defined"))
+  (if icicle-all-candidates-list-action-fn
+      (icicle-all-candidates-action-1 icicle-all-candidates-list-action-fn t)
+    (icicle-all-candidates-action-1 icicle-candidate-action-fn nil)))
+
+
+(put 'icicle-all-candidates-list-alt-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-all-candidates-list-alt-action () ; Bound to `M-|' in minibuffer.
+  "Take alternative action on the list of all completion candidates.
+Apply `icicle-all-candidates-list-alt-action-fn' to the list of saved
+completion candidates or the list of completion candidates that match
+the current input (a regular expression).
+
+If there are saved completion candidates, then they are acted on;
+if not, then all current matching candidates are acted on.
+
+If `icicle-all-candidates-list-alt-action-fn' is nil but
+`icicle-candidate-alt-action-fn' is not, then apply the latter to each
+matching candidate in turn, and print the candidates that were not
+successfully acted upon in buffer *Help*.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-all-candidates-list-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (unless (or icicle-all-candidates-list-alt-action-fn icicle-candidate-alt-action-fn)
+    (error "No alternative action defined"))
+  (unless icicle-completion-candidates
+    (error "No completion candidates.  Did you use `TAB' or `S-TAB'?"))
+  (if icicle-all-candidates-list-alt-action-fn
+      (icicle-all-candidates-action-1 icicle-all-candidates-list-alt-action-fn t)
+    (icicle-all-candidates-action-1 icicle-candidate-alt-action-fn nil t))) ; ALTP flag
+
+(defun icicle-all-candidates-action-1 (fn-var listp &optional altp)
+  "Helper function for `icicle-all-candidates(-alt)-action'.
+ALTP is used only if LISTP is nil.
+ALTP is passed to `icicle-candidate-action-1'."
+  (let* ((local-saved
+          (catch 'i-a-c-a-1
+            (dolist (cand  icicle-saved-completion-candidates  icicle-saved-completion-candidates)
+              (unless (member cand icicle-completion-candidates) (throw 'i-a-c-a-1 nil)))))
+         (candidates                      (or local-saved icicle-completion-candidates))
+         (failures                        nil)
+         (icicle-minibuffer-message-ok-p  nil) ; Avoid delays from `icicle-msg-maybe-in-minibuffer'.
+         (icicle-help-in-mode-line-delay  0) ; Avoid delays for individual candidate help.
+         (icicle-all-candidates-action    t))
+    (when local-saved (setq icicle-completion-candidates  local-saved))
+    (if listp
+        (funcall fn-var candidates)
+      (while candidates
+        (let ((error-msg  (icicle-condition-case-no-debug act-on-each
+                              (icicle-candidate-action-1 fn-var altp (car candidates))
+                            (error (error-message-string act-on-each)))))
+          (when error-msg (setq failures  (cons (cons (car candidates) error-msg) failures)))
+          (setq candidates  (cdr candidates))))
+      (when failures
+        (with-output-to-temp-buffer "*Help*"
+          (princ "Action failures:")(terpri)(terpri)
+          (mapcar (lambda (entry)
+                    (princ (car entry)) (princ ":") (terpri) (princ "  ")
+                    (princ (cdr entry)) (terpri))
+                  failures))))))
+;; $$$$$$ (icicle-abort-recursive-edit))
+
+
+(put 'icicle-candidate-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-candidate-action ()       ; Bound to `C-RET' in minibuffer.
+  "Take action on the current minibuffer-completion candidate.
+If `icicle-candidate-action-fn' is non-nil, it is a function to apply
+to the current candidate, to perform the action.
+
+If no action is available in the current context, help on the
+candidate is shown - see `icicle-help-on-candidate'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-candidate-action-1 icicle-candidate-action-fn))
+
+
+(put 'icicle-candidate-alt-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-candidate-alt-action ()   ; Bound to `C-S-RET' in minibuffer.
+  "Take alternative action on the current completion candidate.
+If `icicle-candidate-alt-action-fn' is non-nil, it is a
+function to apply to the current candidate, to perform the action.
+
+For many Icicles commands, if `icicle-candidate-alt-action-fn' is nil,
+you are prompted to choose an alternative action, using completion.
+
+In any case, any alternative action defined for the current context by
+user option `icicle-alternative-actions-alist' always overrides
+`icicle-candidate-alt-action'.  That is, if
+`icicle-alternative-actions-alist' says to use function `foo', then
+Icicles uses `foo' as the alternative action, regardless of the value
+of `icicle-candidate-alt-action'.
+
+If no alternative action is available in the current context, help on
+the candidate is shown - see `icicle-help-on-candidate'.  
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-alt-action]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (let ((alt-fn  (or (cdr (assq icicle-cmd-reading-input icicle-alternative-actions-alist))
+                     icicle-candidate-alt-action-fn)))
+    (icicle-candidate-action-1 alt-fn 'alternative-p)))
+
+(defun icicle-candidate-action-1 (fn-var &optional altp cand)
+  "Helper function for `icicle-candidate(-alt)-action'.
+FN-VAR is an Icicles action function or alternative action function.
+Optional arg ALTP non-nil means FN-VAR is alternative action function.
+Optional arg CAND non-nil means it is the candidate to act on."
+  (when cand (setq icicle-last-completion-candidate  cand))
+  (cond ((not fn-var) (icicle-help-on-candidate cand)) ; It doesn't `icicle-raise-Completions-frame'.
+        ((icicle-require-match-p)
+         ;; If no last candidate, then reset to first candidate matching input.
+         (unless (stringp icicle-last-completion-candidate)
+           (setq icicle-last-completion-candidate  icicle-current-input
+                 last-command                      (if altp
+                                                       'icicle-candidate-alt-action
+                                                     'icicle-candidate-action))
+           (let ((icicle-help-in-mode-line-delay  0)) ; Avoid delay for candidate help.
+             (icicle-next-candidate 1 (if (eq icicle-current-completion-mode 'prefix)
+                                          'icicle-prefix-candidates
+                                        'icicle-apropos-candidates)
+                                    (not (eq icicle-current-completion-mode 'prefix)))))
+
+         ;; NOTE: We no longer save and restore these things here.
+         ;; We purposely allow an action function to modify these for subsequent actions.
+         ;; If you need to save and restore these for a particular action function you define,
+         ;; then you must do so in the action function itself.  This might be the case, for instance,
+         ;; if your action function does its own completion (e.g. calls `completing-read'), that is, if
+         ;; it uses a recursive minibuffer.  (But do not save and restore if you want the side effect.)
+         (let (;; (icicle-candidate-nb               icicle-candidate-nb)              ; $$$$$$
+               ;; (icicle-last-completion-candidate  icicle-last-completion-candidate) ; $$$$$$
+               ;; (icicle-completion-candidates  icicle-completion-candidates)         ; $$$$$$
+               )
+           (when icicle-completion-candidates (funcall fn-var icicle-last-completion-candidate)))
+         (when (or icicle-use-candidates-only-once-flag
+                   (and altp icicle-use-candidates-only-once-alt-p))
+           (icicle-remove-candidate-display-others 'all))
+         (icicle-raise-Completions-frame))
+        (t
+         (let ((icicle-last-input         (or cand (icicle-input-from-minibuffer)))
+               (icicle-default-directory  icicle-default-directory))
+           (when (and (icicle-file-name-input-p) (icicle-file-directory-p icicle-last-input))
+             (setq icicle-default-directory  icicle-last-input))
+           ;; NOTE: We no longer save and restore these things here.
+           ;; We purposely allow an action function to modify these for subsequent actions.
+           ;; If you need to save and restore these for a particular action function you define,
+           ;; then you must do so in the action function itself.  This might be the case, for instance,
+           ;; if your action function does its own completion (e.g. calls `completing-read'), that is,
+           ;; uses a recursive minibuffer.  (But do not save and restore if you want the side effect.)
+           (let (;; (icicle-candidate-nb               icicle-candidate-nb)              ; $$$$$$
+                 ;; (icicle-last-completion-candidate  icicle-last-completion-candidate) ; $$$$$$
+                 ;; (icicle-completion-candidates      icicle-completion-candidates)     ; $$$$$$
+                 )
+             (funcall fn-var icicle-last-input))
+           (when (and (or icicle-use-candidates-only-once-flag
+                          (and altp icicle-use-candidates-only-once-alt-p))
+                      (equal icicle-last-input
+                             (if (icicle-file-name-input-p)
+                                 (expand-file-name icicle-last-completion-candidate
+                                                   (icicle-file-name-directory icicle-last-input))
+                               icicle-last-completion-candidate)))
+             (icicle-remove-candidate-display-others 'all))
+           (icicle-raise-Completions-frame)))))
+
+
+;; Bound to `C-down-mouse-2' (`C-mouse-2') in `*Completions*'.
+(put 'icicle-mouse-candidate-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-mouse-candidate-action (event) ; `C-mouse-2'
+  "Take action on the completion candidate clicked by `mouse-2'.
+If `icicle-candidate-action-fn' is non-nil, it is a function to apply
+to the clicked candidate, to perform the action.
+
+If `icicle-candidate-action-fn' is nil, the default action is
+performed: display help on the candidate - see
+`icicle-help-on-candidate'."
+  (interactive "e")
+  (icicle-mouse-candidate-action-1 event icicle-candidate-action-fn))
+
+
+; Bound to `C-S-down-mouse-2' (`C-S-mouse-2') in `*Completions*'.
+(put 'icicle-mouse-candidate-alt-action 'icicle-action-command t)
+;;;###autoload
+(defun icicle-mouse-candidate-alt-action (event) ; `C-S-mouse-2'
+  "Take alternative action on the candidate clicked by `mouse-2'.
+If `icicle-candidate-alt-action-fn' is non-nil, it is a
+function to apply to the clicked candidate, to perform the action.
+
+If `icicle-candidate-action-fn' is nil, the default action is
+performed: display help on the candidate - see
+`icicle-help-on-candidate'."
+  (interactive "e")
+  (icicle-mouse-candidate-action-1 event icicle-candidate-alt-action-fn))
+
+(defun icicle-mouse-candidate-action-1 (event fn-var)
+  "Helper function for `icicle-mouse-candidate(-alt)-action'."
+  (run-hooks 'mouse-leave-buffer-hook)  ; Give temp modes such as isearch a chance to turn off.
+  (let ((posn-buf  (window-buffer (posn-window (event-start event))))
+        (posn-pt   (posn-point (event-start event)))
+        (posn-col  (car (posn-col-row (event-start event))))
+        (posn-row  (cdr (posn-col-row (event-start event))))
+        choice)
+    (read-event)                        ; Swallow mouse up event.
+    (with-current-buffer posn-buf
+      (save-excursion
+        (goto-char posn-pt)
+        (let (beg end)
+          (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+            (setq end  (point)
+                  beg  (1+ (point))))
+          (unless beg (error "No completion here"))
+          (setq beg  (previous-single-property-change beg 'mouse-face)
+                end  (or (next-single-property-change end 'mouse-face) (point-max)))
+          ;; `icicle-insert-candidates' doesn't put `mouse-face' on the final \n of a candidate
+          ;; in `*Completions*'. Add the newline back. `icicle-insert-candidates' puts property
+          ;; `icicle-keep-newline' on the newline if it is part of the candidate, as opposed to
+          ;; being just part of the display in columns.
+          (when (and (eq ?\n (char-after end)) (get-text-property end 'icicle-keep-newline))
+            (setq end  (1+ end)))
+          (setq choice  (if (and (icicle-file-name-input-p) insert-default-directory
+                                 (or (not (member (buffer-substring-no-properties beg end)
+                                                  icicle-extra-candidates))
+                                     icicle-extra-candidates-dir-insert-p))
+                            (concat default-directory (buffer-substring-no-properties beg end))
+                          ;; $$$$$$ (buffer-substring-no-properties beg end))))))
+                          (buffer-substring beg end)))
+          (remove-text-properties 0 (length choice) '(mouse-face nil) choice))))
+    (save-window-excursion
+      (select-window (active-minibuffer-window))
+      (delete-region (icicle-minibuffer-prompt-end) (point-max))
+      (insert choice))
+    (setq icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos posn-pt)
+          icicle-last-completion-candidate  choice)
+    (if (not fn-var)
+        (icicle-help-on-candidate)      ; Doesn't `icicle-raise-Completions-frame'.
+
+      ;; NOTE: We no longer save and restore these things here.
+      ;; We purposely allow an action function to modify these for subsequent actions.
+      ;; If you need to save and restore these for a particular action function you define,
+      ;; then you must do so in the action function itself.  This might be the case, for instance,
+      ;; if your action function does its own completion (e.g. calls `completing-read'), that is, if
+      ;; it uses a recursive minibuffer.  (But do not save and restore if you want the side effect.)
+      (let (;; (icicle-candidate-nb               icicle-candidate-nb)              ; $$$$$$
+            ;; (icicle-last-completion-candidate  icicle-last-completion-candidate) ; $$$$$$
+            ;; (icicle-completion-candidates      icicle-completion-candidates)     ; $$$$$$
+            )
+        (funcall fn-var icicle-last-completion-candidate))
+      (when icicle-use-candidates-only-once-flag (icicle-remove-candidate-display-others 'all))
+      (when icicle-completion-candidates (icicle-update-and-next))
+      (icicle-raise-Completions-frame posn-col posn-row))))
+
+
+;; $$$$$ ??? (put 'icicle-remove-candidate 'icicle-action-command t)
+;;;###autoload
+(defun icicle-remove-candidate ()       ; Bound to `delete' in minibuffer during completion.
+  "Remove current completion candidate from the set of candidates.
+This has no effect on the object, if any, represented by the
+candidate; in particular, that object is not deleted.
+
+Note: For Emacs versions prior to 22, this does not really remove a
+file-name candidate as a possible candidate.  If you use \\\
+\\[icicle-prefix-complete] or \\[icicle-apropos-complete],
+it will reappear as a possible candidate.
+
+You can use this command only from the minibuffer (`\\[icicle-remove-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (icicle-remove-candidate-display-others))
+
+
+;; $$$$$ ??? (put 'icicle-mouse-remove-candidate 'icicle-action-command t)
+;;;###autoload
+(defun icicle-mouse-remove-candidate (event) ; Bound to `S-mouse-2' in `*Completions*'.
+  "Remove clicked completion candidate from the set of candidates.
+This has no effect on the object, if any, represented by the
+candidate; in particular, that object is not deleted.
+
+See `icicle-remove-candidate' for more information."
+  (interactive "e")
+  (run-hooks 'mouse-leave-buffer-hook)  ; Give temp modes such as isearch a chance to turn off.
+  (let ((posn-buf  (window-buffer (posn-window (event-start event))))
+        (posn-pt   (posn-point (event-start event)))
+        beg end)
+    (read-event)                        ; Swallow mouse up event.
+    (with-current-buffer posn-buf
+      (save-excursion
+        (goto-char posn-pt)
+        (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+          (setq end  (point)
+                beg  (1+ (point))))
+        (unless beg (error "No completion here"))
+        (setq beg  (previous-single-property-change beg 'mouse-face)
+              end  (or (next-single-property-change end 'mouse-face) (point-max)))
+        ;; `icicle-insert-candidates' doesn't put `mouse-face' on the final \n of a candidate
+        ;; in `*Completions*'. Add the newline back. `icicle-insert-candidates' puts property
+        ;; `icicle-keep-newline' on the newline if it is part of the candidate, as opposed to
+        ;; being just part of the display in columns.
+        (when (and (eq ?\n (char-after end)) (get-text-property end 'icicle-keep-newline))
+          (setq end  (1+ end)))
+        (setq icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos posn-pt)
+              icicle-last-completion-candidate  (buffer-substring beg end)))))
+  (icicle-remove-candidate-display-others))
+
+(defun icicle-remove-candidate-display-others (&optional allp)
+  "Remove current completion candidate from list of possible candidates.
+Redisplay `*Completions*', unless there is only one candidate left.
+Non-nil optional argument ALLP means remove all occurrences of the
+current candidate.  Otherwise (nil) means remove only the current
+occurrence."
+  (unless (stringp icicle-last-completion-candidate)
+    (setq icicle-last-completion-candidate  icicle-current-input
+          last-command                      'icicle-delete-candidate-object)
+    (let ((icicle-help-in-mode-line-delay  0)) ; Avoid delay for candidate help.
+      (icicle-next-candidate 1 (if (eq icicle-current-completion-mode 'prefix)
+                                   'icicle-prefix-candidates
+                                 'icicle-apropos-candidates)
+                             (not (eq icicle-current-completion-mode 'prefix)))))
+  (let ((maybe-mct-cand  (cond ((consp minibuffer-completion-table)
+                                (icicle-mctized-display-candidate icicle-last-completion-candidate))
+                               ((arrayp minibuffer-completion-table)
+                                (intern icicle-last-completion-candidate))
+                               (t
+                                icicle-last-completion-candidate))))
+    (icicle-remove-cand-from-lists icicle-last-completion-candidate maybe-mct-cand allp))
+  (icicle-update-and-next))
+
+
+(put 'icicle-delete-candidate-object 'icicle-action-command t)
+;;;###autoload
+(defun icicle-delete-candidate-object (&optional allp) ; Bound to `S-delete' in minibuffer.
+  "Delete the object named by the current completion candidate.
+With a prefix argument, delete *ALL* objects named by the current set
+of candidates, after confirmation.
+
+Do nothing if `icicle-deletion-action-flag' is nil.
+
+Otherwise:
+
+* If the value of variable `icicle-delete-candidate-object' is a
+  function, then apply it to the current completion candidate.  This
+  should delete some object named by the completion candidate.
+
+* If `icicle-delete-candidate-object' is not a function, then it
+  should be a symbol bound to an alist.  In this case, invoke
+  `icicle-delete-candidate-object' to delete the object named by the
+  current completion candidate from that alist.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-delete-candidate-object]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (when icicle-deletion-action-flag
+    (if (null icicle-completion-candidates)
+        (message "Nothing to delete - use `S-TAB', `TAB', or a cycle key")
+      (if allp
+          (if (not (let ((icicle-completion-candidates  icicle-completion-candidates))
+                     (yes-or-no-p "Are you SURE you want to DELETE ALL of the matching objects? ")))
+              (message "OK, nothing deleted")
+            (dolist (cand icicle-completion-candidates) (icicle-delete-candidate-object-1 cand t))
+            (icicle-erase-minibuffer))
+        ;; If no last candidate, then reset to first candidate matching input.
+        (unless (stringp icicle-last-completion-candidate)
+          (setq icicle-last-completion-candidate  icicle-current-input
+                last-command                      'icicle-delete-candidate-object)
+          (let ((icicle-help-in-mode-line-delay  0)) ; Avoid delay for candidate help.
+            (icicle-next-candidate 1 (if (eq icicle-current-completion-mode 'prefix)
+                                         'icicle-prefix-candidates
+                                       'icicle-apropos-candidates)
+                                   (not (eq icicle-current-completion-mode 'prefix)))))
+        (icicle-delete-candidate-object-1 icicle-last-completion-candidate)))))
+
+(defun icicle-delete-candidate-object-1 (cand &optional no-display-p)
+  "Helper function for `icicle-delete-candidate-object'.
+Delete object named CAND.
+Optional arg NO-DISPLAY-P non-nil means don't update `*Completions*'."
+  (let ((display-cand  cand)            ; Use local vars: values might change.
+        (maybe-mct-cand
+         (cond ((consp minibuffer-completion-table) (icicle-mctized-display-candidate cand))
+               ((arrayp minibuffer-completion-table) (intern cand))
+               (t cand))))
+    (save-selected-window
+      (let ((icicle-completion-candidates  icicle-completion-candidates)) ; In case recursive minibuf.
+        (if (functionp icicle-delete-candidate-object)
+            (funcall icicle-delete-candidate-object cand)
+          (icicle-delete-current-candidate-object cand))))
+    (icicle-remove-cand-from-lists display-cand maybe-mct-cand nil) ; Use local vars.
+    (unless no-display-p (message "Deleted object named: `%s'" display-cand) (sit-for 1.0)))
+  (unless no-display-p (icicle-update-and-next))
+  (select-window (minibuffer-window))
+  (select-frame-set-input-focus (selected-frame)))
+
+(defun icicle-delete-current-candidate-object (&optional cand)
+  "Delete the object(s) corresponding to the current completion candidate.
+The value of `icicle-delete-candidate-object' must be a symbol
+\(variable) that is bound to a list of completion-candidate objects.
+
+The entries in the list must be completion candidates for the current
+call to `completing-read', but the list itself need not be the
+COLLECTION argument to `completing-read'.  For example, the list might
+be a list of symbols, and the COLLECTION argument might be an obarray
+that contains those symbols.
+
+The list can be an alist, a list of strings, or a list of symbols.
+Delete, from this list, the objects that correspond to the current
+completion candidate.  If the variable is also a user option, then
+save the option, after deleting the candidate object.
+
+The full candidate object is what is deleted.  If the list contains
+multiple identical objects that correspond to the current completion
+candidate, they are all deleted."
+  (setq cand  (or cand icicle-last-completion-candidate))
+  (let ((val  (and (symbolp icicle-delete-candidate-object)
+                   (symbol-value icicle-delete-candidate-object))))
+    ;; The message could more accurately say "Value of `icicle-delete-candidate-object' must be
+    ;; a symbol bound to a list", but this makes more sense.
+    (unless (and val (consp val)) (error "Cannot delete candidate objects now"))
+    (set icicle-delete-candidate-object ; Update the variable.
+         (cond ((or icicle-whole-candidate-as-text-prop-p icicle-candidates-alist)
+                (delete (funcall icicle-get-alist-candidate-function cand) val))
+               ((consp (car val))
+                (icicle-assoc-delete-all cand val))
+               ((stringp (car val)) (delete cand val))
+               ((symbolp (car val)) (delete (intern cand) val))
+               (t (error "Entry in list value of `icicle-delete-candidate-object' is \
+not a cons, string, or symbol")))))
+  (when (user-variable-p icicle-delete-candidate-object) ; Save the new user-option value.
+    (funcall icicle-customize-save-variable-function
+             icicle-delete-candidate-object
+             (symbol-value icicle-delete-candidate-object))))
+
+(defun icicle-remove-cand-from-lists (disp-cand mct-cand allp)
+  "Delete first occurence or all occurences of candidate.
+The appropriate form of the candidate is removed from each of these:
+ `icicle-candidates-alist'
+ `icicle-completion-candidates'
+ `minibuffer-completion-table' (if it is an alist)
+DISP-CAND is the display form of the candidate to delete.
+MCT-CAND is the MCT alist candidate that corresponds to DISP-CAND.
+If any of these conditions is true, remove all occurrences of CAND:
+ * ALLP is non-nil
+ * `icicle-transform-function' is `icicle-remove-duplicates'
+ * `icicle-transform-function' is `icicle-remove-dups-if-extras'
+   and `icicle-extra-candidates' is non-nil"
+  (setq allp  (or allp (eq icicle-transform-function 'icicle-remove-duplicates)
+                  (and (eq icicle-transform-function 'icicle-remove-dups-if-extras)
+                       icicle-extra-candidates)))
+  (when icicle-candidates-alist
+    (setq icicle-candidates-alist
+          (if allp
+              (icicle-assoc-delete-all disp-cand icicle-candidates-alist)
+            (delete (funcall icicle-get-alist-candidate-function disp-cand) icicle-candidates-alist))))
+  (when (consp icicle-completion-candidates)
+    (setq icicle-completion-candidates
+          (if allp                      ; Delete only the first occurrence, or all if ALLP.
+              (delete disp-cand icicle-completion-candidates)
+            (icicle-delete-count disp-cand icicle-completion-candidates 1))))
+
+  ;; Update `minibuffer-completion-predicate' or `read-file-name-predicate'
+  ;; to effectively remove this candidate.
+  ;; The logic here is the same as for `icicle-narrow-candidates-with-predicate'.
+  (cond (;; File name input, Emacs 22+.  Update `read-file-name-predicate'.
+         (and (icicle-file-name-input-p) (> emacs-major-version 21))
+         (setq read-file-name-predicate
+               (if read-file-name-predicate
+                   (lexical-let ((curr-pred  read-file-name-predicate))
+                     `(lambda (file-cand)
+                       (and (not (equal ',disp-cand file-cand)) (funcall ',curr-pred file-cand))))
+                 `(lambda (file-cand) (not (equal ',disp-cand file-cand))))))
+
+        ;; File name input, Emacs 20 or 21.  We can do nothing for file name.
+        ;; `TAB' or `S-TAB' will bring it back as a candidate.
+        ((icicle-file-name-input-p))
+
+        (t;; Non-file name input, all Emacs versions.  Update `minibuffer-completion-predicate'.
+         (setq minibuffer-completion-predicate
+               (if minibuffer-completion-predicate
+                   ;; Add excluding of candidate to the existing predicate.
+                   (lexical-let ((curr-pred  minibuffer-completion-predicate))
+                     `(lambda (cand)    ; This corresponds to what we do in `icicle-mctize-all'.
+                       (and (not (equal cand ',(if (and (consp mct-cand) (stringp (car mct-cand)))
+                                                   (cdr mct-cand)
+                                                   mct-cand)))
+                        (funcall ',curr-pred cand))))
+                 ;; Set predicate to excluding the candidate.
+                 `(lambda (cand) (not (equal cand ',(if (and (consp mct-cand) (stringp (car mct-cand)))
+                                                        (cdr mct-cand)
+                                                        mct-cand)))))))))
+
+;; $$$$$$$$$$$$ COULD USE THIS INSTEAD of updating the predicate,
+;; but it works only when `minibuffer-completion-table' is an alist.
+;;   (when (consp minibuffer-completion-table)
+;;     (setq minibuffer-completion-table
+;;           (if allp
+;;               (delete mct-cand minibuffer-completion-table)
+;;             (icicle-delete-count mct-cand minibuffer-completion-table 1)))))
+
+(defun icicle-update-and-next ()
+  "Update `*Completions*' and make next candidate current.
+If we don't know which candidate number this is, just display."
+  (cond ((and icicle-completion-candidates (cdr icicle-completion-candidates) ; > 1 candidates left.
+              (not (input-pending-p)))  ; Do nothing if user hit another key.
+         (icicle-maybe-sort-and-strip-candidates)
+         (message "Displaying completion candidates...")
+         (save-selected-window (icicle-display-candidates-in-Completions))
+         (when (wholenump icicle-candidate-nb)
+           (with-current-buffer "*Completions*"
+             (goto-char (icicle-start-of-candidates-in-Completions))
+             (icicle-move-to-next-completion
+              (mod icicle-candidate-nb (length icicle-completion-candidates)))
+             (set-window-point (get-buffer-window "*Completions*" 0) (point))
+             (setq icicle-last-completion-candidate  (icicle-current-completion-in-Completions))
+             (set-buffer-modified-p nil))))
+        (icicle-completion-candidates   ; Single candidate left
+         (save-selected-window (icicle-remove-Completions-window))
+         (let ((completion  (icicle-transform-multi-completion (car icicle-completion-candidates))))
+           (select-window (active-minibuffer-window))
+           (with-current-buffer (window-buffer) ; Needed if `*Completions*' redirected to minibuffer.
+             (goto-char (icicle-minibuffer-prompt-end))
+             (icicle-clear-minibuffer)
+             (insert (if (and (icicle-file-name-input-p) insert-default-directory
+                              (or (not (member icicle-current-input icicle-extra-candidates))
+                                  icicle-extra-candidates-dir-insert-p))
+                         (icicle-file-name-directory-w-default icicle-current-input)
+                       "")
+                     completion))))
+        (t                              ; No candidates left
+         ;; $$$$$$$$ `icicle-abort-recursive-edit' and `exit-recursive-edit' don't work,
+         ;; because they take us back to top level.
+         ;; $$$$ DO NOTHING? Do (icicle-remove-Completions-window)? Do (icicle-erase-minibuffer)?
+         (icicle-erase-minibuffer))))
+
+(defun icicle-add/remove-tags-and-refresh (add/remove)
+  "Prompt for tags to add/remove, then add/remove them.
+If ADD/REMOVE is `add', then add tags to the current candidate.
+Otherwise, remove them.
+
+If `icicle-full-cand-fn' is non-nil and `icicle-file-name-input-p' is
+nil, then update the current candidate to reflect the tag changes.
+Then update `*Completions*' and make the next candidate current.
+
+The candidate is updated as follows:
+1. Apply `icicle-transform-multi-completion' to it.
+2. Apply `icicle-full-cand-fn' to the result of #1.
+3. Mctize the result of #2.  That is, make it usable for
+   `minibuffer-completion-table'."
+  `(lambda ()
+    (interactive)
+    (let ((mct-cand  (icicle-mctized-display-candidate icicle-last-completion-candidate))
+          (cand      (icicle-transform-multi-completion icicle-last-completion-candidate))
+          (tags      (let ((enable-recursive-minibuffers  t)) (bmkp-read-tags-completing))))
+      (funcall ',(if (eq 'add add/remove) 'bmkp-autofile-add-tags 'bmkp-autofile-remove-tags)
+               cand tags nil nil 'MSG)
+      (when (and icicle-full-cand-fn  (not (icicle-file-name-input-p)))
+        (icicle-replace-mct-cand-in-mct
+         mct-cand
+         (icicle-mctized-full-candidate (funcall icicle-full-cand-fn cand)))
+        (icicle-update-and-next)))))
+
+
+(put 'icicle-mouse-help-on-candidate 'icicle-action-command t)
+;;;###autoload
+(defun icicle-mouse-help-on-candidate (event) ; Bound to `C-M-mouse-2' in minibuffer.
+  "Display help on the minibuffer-completion candidate clicked by mouse."
+  (interactive "e")
+  (let ((icicle-candidate-action-fn  nil)) (icicle-mouse-candidate-action event)))
+
+
+;; Free vars here: `icicle-orig-buff' is bound in `icicle-complete-keys'.
+;;                 `icicle-complete-keys-alist' is bound in `icicles-var.el'.
+(put 'icicle-help-on-candidate 'icicle-action-command t)
+;;;###autoload
+(defun icicle-help-on-candidate (&optional cand) ; Bound to `C-M-RET', `C-help', `C-f1' in minibuffer,
+                                        ; and to `C-M-RET' in *Completions.
+  "Display help on the current minibuffer-completion candidate.
+The help displayed depends on the type of candidate, as follows:
+
+ menu item - the corresponding command is described using
+             `describe-function' (only if `lacarte.el' is loaded)
+ command or other function - described using `describe-function'
+ keymap variable - described using `describe-keymap'
+                   (if available - see library `help-fns+.el')
+ user option or other variable - described using `describe-variable'
+ face - described using `describe-face'
+ command abbreviation - described using `apropos-command' for matches
+ property list - described using `apropos-describe-plist'
+ buffer name - modes described using `describe-mode' (Emacs > 20)
+ file name - file properties described
+
+If the same candidate names a function, a variable, and a face, or any
+two of these, then all such documentation is shown (Emacs 22+).
+
+In the minibuffer, you can also use `C-M-down', `C-M-up',
+`C-M-wheel-down', `C-M-wheel-up', `C-M-next', `C-M-prior', `C-M-end',
+and `C-M-home', to display help on the candidate and then move to the
+next or previous candidate.  See, for example,
+`icicle-help-on-next-apropos-candidate'.
+
+You can use this command only from the minibuffer or `*Completions*'
+\(`\\[icicle-help-on-candidate]')."
+  (interactive)                         ; Interactively, just describes itself.
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (let ((frame-with-focus  (selected-frame))
+        (cand-symb         nil)
+        transformed-cand)
+    (cond (cand (setq icicle-last-completion-candidate  cand))
+          ((eq (current-buffer) (get-buffer "*Completions*"))
+           (setq icicle-last-completion-candidate  (icicle-current-completion-in-Completions)))
+          ;; If no last candidate, then reset to first candidate matching input.
+          ((not (stringp icicle-last-completion-candidate))
+           (setq icicle-last-completion-candidate  icicle-current-input
+                 last-command                      'icicle-help-on-candidate)
+           (let ((icicle-help-in-mode-line-delay  0)) ; Avoid delay for candidate help.
+             (icicle-next-candidate 1 (if (eq icicle-current-completion-mode 'prefix)
+                                          'icicle-prefix-candidates
+                                        'icicle-apropos-candidates)
+                                    (not (eq icicle-current-completion-mode 'prefix))))))
+    (cond (;; Use special help function.
+           icicle-candidate-help-fn
+           ;; Transform candidate, in case it's a multi-completion.
+           (funcall icicle-candidate-help-fn
+                    (icicle-transform-multi-completion icicle-last-completion-candidate)))
+
+          (;; Call to `lacarte-execute(-menu)-command' (defined in `lacarte.el').
+           ;; Use command associated with menu item.
+           (consp lacarte-menu-items-alist) ; `lacarte-menu-items-alist' is in `lacarte.el'.
+           (setq cand-symb  (cdr (assoc icicle-last-completion-candidate lacarte-menu-items-alist)))
+           (if cand-symb
+               (icicle-help-on-candidate-symbol cand-symb)
+             (icicle-msg-maybe-in-minibuffer "No help"))) ; Menu item with lambda definition.
+
+          (;; A key-completion candidate.  Get the true command from the candidate.
+           icicle-completing-keys-p
+           (save-match-data
+             (string-match "\\(.+\\)  =  \\(.+\\)" icicle-last-completion-candidate)
+             (setq cand-symb  (intern-soft (substring icicle-last-completion-candidate
+                                                      (match-beginning 2) (match-end 2))))
+             (cond ((eq '\.\.\. cand-symb) ; Prefix key - describe its binding.
+                    (with-current-buffer icicle-orig-buff
+                      (describe-key (car-safe
+                                     (cdr-safe
+                                      (assq (intern-soft
+                                             (substring icicle-last-completion-candidate
+                                                        (match-beginning 0) (match-end 0)))
+                                            icicle-complete-keys-alist))))))
+                   (cand-symb (icicle-help-on-candidate-symbol cand-symb)) ; Describe key's command.
+                   (t (icicle-msg-maybe-in-minibuffer "No help")))))
+
+          (t;; Transform candidate, in case it's a multi-completion.
+           (setq transformed-cand  (icicle-transform-multi-completion icicle-last-completion-candidate))
+           ;; If buffer or file, describe its properties.  Otherwise, create symbol and get its help.
+           (cond ((and (bufferp (get-buffer transformed-cand))
+                       (with-current-buffer transformed-cand (describe-mode) t)))
+                 ((file-exists-p transformed-cand) (icicle-describe-file transformed-cand
+                                                                         current-prefix-arg))
+                 (t (icicle-help-on-candidate-symbol (intern transformed-cand))))))
+    ;;$$$ (icicle-raise-Completions-frame)
+
+    ;; This is a hack for MS Windows - otherwise, we can't continue to get more candidates,
+    ;; because the *Help* frame takes the focus away from the minibuffer frame.
+    ;; MS Windows always gives focus to a newly created frame - in this case, *Help*.
+    (let* ((help-window  (get-buffer-window "*Help*" 0))
+           (help-frame   (and help-window (window-frame help-window))))
+      (when help-frame (redirect-frame-focus help-frame frame-with-focus))))
+  (message nil))                        ; Let minibuffer contents show immediately.
+
+(defun icicle-help-on-candidate-symbol (symb)
+  "Helper function for `icicle-help-on-candidate'.  The arg is a symbol."
+  (cond ((and (fboundp 'describe-keymap) (boundp symb) (keymapp (symbol-value symb)))
+         (describe-keymap symb))
+        ((and (fboundp 'help-follow-symbol) ; Emacs 22+
+              (or (fboundp symb) (boundp symb) (facep symb)))
+         (with-current-buffer (get-buffer-create "*Help*")
+           ;; $$$$$$ (let ((help-xref-following  t)) (help-xref-interned symb)))
+           (help-xref-interned symb))
+         (when (fboundp 'fit-frame-if-one-window)
+           (save-selected-window (select-window (get-buffer-window "*Help*" 'visible))
+                                 (fit-frame-if-one-window))))
+        ((fboundp symb) (describe-function symb))
+        ((boundp symb) (describe-variable symb))
+        ((facep symb) (describe-face symb))
+        ((assq symb (mapcar #'cdr icicle-command-abbrev-alist))
+         (let ((regexp  (icicle-command-abbrev-regexp symb))) (apropos-command regexp)))
+        ((symbol-plist symb) (apropos-describe-plist symb))
+        (t
+         (setq symb  (symbol-name symb)) ; Convert symbol to string, and try some more.
+         (cond ((and (bufferp (get-buffer symb))
+                     (with-current-buffer (get-buffer symb) (describe-mode) t)))
+               ((file-exists-p symb) (icicle-describe-file symb current-prefix-arg))
+               (t (icicle-msg-maybe-in-minibuffer "No help"))))))
+
+;; This is the same as `describe-file' in `help-fns+.el', but we avoid requiring that library.
+;; This is a top-level command, but we put it here to avoid library require cycles.
+(if (and (not (fboundp 'icicle-describe-file)) (fboundp 'describe-file))
+    (defalias 'icicle-describe-file (symbol-function 'describe-file))
+  (defun icicle-describe-file (filename &optional internal-form-p) ; Suggestion: bind to `C-h M-f'.
+    "Describe the file named FILENAME.
+If FILENAME is nil, describe current directory (`default-directory').
+
+Starting with Emacs 22, if the file is an image file then:
+ * Show a thumbnail of the image as well.
+ * If you have command-line tool `exiftool' installed and in your
+   `$PATH' or `exec-path', then show EXIF data (metadata) about the
+   image.  See standard Emacs library `image-dired.el' for more
+   information about `exiftool'.
+
+If FILENAME is the name of an autofile bookmark and you use library
+`Bookmark+', then show also the bookmark information (tags etc.).  In
+this case, a prefix arg shows the internal form of the bookmark."
+    (interactive "FDescribe file: \nP")
+    (unless filename (setq filename default-directory))
+    (help-setup-xref `(icicle-describe-file ,filename ,internal-form-p) (interactive-p))
+    (let ((attrs (file-attributes filename))
+          ;; Functions `bmkp-*' are defined in `bookmark+.el'.
+          (bmk   (and (fboundp 'bmkp-get-autofile-bookmark)  (bmkp-get-autofile-bookmark filename))))
+      (unless attrs (error "Cannot open file `%s'" filename))
+      (let* ((type            (nth 0 attrs))
+             (numlinks        (nth 1 attrs))
+             (uid             (nth 2 attrs))
+             (gid             (nth 3 attrs))
+             (last-access     (nth 4 attrs))
+             (last-mod        (nth 5 attrs))
+             (last-status-chg (nth 6 attrs))
+             (size            (nth 7 attrs))
+             (permissions     (nth 8 attrs))
+             ;; Skip 9: t iff file's gid would change if file were deleted and recreated.
+             (inode           (nth 10 attrs))
+             (device          (nth 11 attrs))
+             (thumb-string    (and (fboundp 'image-file-name-regexp) ; In `image-file.el' (Emacs 22+).
+                                   (if (fboundp 'string-match-p)
+                                       (string-match-p (image-file-name-regexp) filename)
+                                     (save-match-data
+                                       (string-match (image-file-name-regexp) filename)))
+                                   (if (fboundp 'display-graphic-p) (display-graphic-p) window-system)
+                                   (require 'image-dired nil t)
+                                   (image-dired-get-thumbnail-image filename)
+                                   (apply #'propertize "XXXX"
+                                          `(display ,(append (image-dired-get-thumbnail-image filename)
+                                                             '(:margin 10))
+                                            rear-nonsticky (display)
+                                            mouse-face highlight
+                                            follow-link t
+                                            help-echo "`mouse-2' or `RET': Show full image"
+                                            keymap
+                                            (keymap
+                                             (mouse-2 . (lambda (e) (interactive "e")
+                                                                (find-file ,filename)))
+                                             (13 . (lambda () (interactive)
+                                                           (find-file ,filename))))))))
+             (image-info      (and (require 'image-dired nil t)
+                                   (fboundp 'image-file-name-regexp)
+                                   (if (fboundp 'string-match-p)
+                                       (string-match-p (image-file-name-regexp) filename)
+                                     (save-match-data
+                                       (string-match (image-file-name-regexp) filename)))
+                                   (progn (message "Gathering image data...") t)
+                                   (icicle-condition-case-no-debug nil
+                                       (let ((all  (icicle-all-exif-data (expand-file-name filename))))
+                                         (concat
+                                          (and all (not (zerop (length all)))
+                                               (format "\nImage Data (EXIF)\n-----------------\n%s"
+                                                       all))))
+                                     (error nil))))
+             (help-text
+              (concat
+               (format "`%s'\n%s\n\n" filename (make-string (+ 2 (length filename)) ?-))
+               (format "File Type:                       %s\n"
+                       (cond ((eq t type) "Directory")
+                             ((stringp type) (format "Symbolic link to `%s'" type))
+                             (t "Normal file")))
+               (format "Permissions:                %s\n" permissions)
+               (and (not (eq t type)) (format "Size in bytes:              %g\n" size))
+               (format-time-string
+                "Time of last access:        %a %b %e %T %Y (%Z)\n" last-access)
+               (format-time-string
+                "Time of last modification:  %a %b %e %T %Y (%Z)\n" last-mod)
+               (format-time-string
+                "Time of last status change: %a %b %e %T %Y (%Z)\n" last-status-chg)
+               (format "Number of links:            %d\n" numlinks)
+               (format "User ID (UID):              %s\n" uid)
+               (format "Group ID (GID):             %s\n" gid)
+               (format "Inode:                      %S\n" inode)
+               (format "Device number:              %s\n" device)
+               image-info)))
+        (with-output-to-temp-buffer "*Help*"
+          (when bmk (if internal-form-p
+              (let* ((bname     (bookmark-name-from-full-record bmk))
+                     (bmk-defn  (format "Bookmark `%s'\n%s\n\n%s"
+                                        bname   (make-string (+ 11 (length bname)) ?-)
+                                        (pp-to-string bmk))))
+                (princ bmk-defn) (terpri) (terpri))
+            (princ (bmkp-bookmark-description bmk 'NO-IMAGE)) (terpri) (terpri)))
+        (princ help-text))
+      (when thumb-string
+        (with-current-buffer "*Help*"
+          (save-excursion
+            (goto-char (point-min))
+            (let ((buffer-read-only  nil))
+              (when (re-search-forward "Device number:.+\n" nil t) (insert thumb-string))))))
+      help-text))))                   ; Return displayed text.
+
+;; This is the same as `help-all-exif-data' in `help-fns+.el', but we avoid requiring that library.
+(defun icicle-all-exif-data (file)
+  "Return all EXIF data from FILE, using command-line tool `exiftool'."
+  (with-temp-buffer
+    (delete-region (point-min) (point-max))
+    (unless (eq 0 (call-process shell-file-name nil t nil shell-command-switch
+                                (format "exiftool -All \"%s\"" file)))
+      (error "Could not get EXIF data"))
+    (buffer-substring (point-min) (point-max))))
+
+;;;###autoload
+(defun icicle-candidate-read-fn-invoke () ; Bound to `M-RET' in minibuffer.
+  "Read function name.  Invoke function on current completion candidate.
+Set `icicle-candidate-action-fn' to the interned name.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-read-fn-invoke]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  ;; If no last candidate, then reset to first candidate matching input.
+  (unless (stringp icicle-last-completion-candidate)
+    (setq icicle-last-completion-candidate  icicle-current-input
+          last-command                      'icicle-candidate-action)
+    (let ((icicle-help-in-mode-line-delay  0)) ; Avoid delay for candidate help.
+      (icicle-next-candidate 1 (if (eq icicle-current-completion-mode 'prefix)
+                                   'icicle-prefix-candidates
+                                 'icicle-apropos-candidates)
+                             (not (eq icicle-current-completion-mode 'prefix)))))
+  (let ((icicle-whole-candidate-as-text-prop-p  nil)
+        (enable-recursive-minibuffers            t)
+        (icicle-must-pass-after-match-predicate  #'(lambda (s) (functionp (intern s))))
+        (icicle-saved-completion-candidate       icicle-last-completion-candidate)
+        (icicle-candidate-action-fn              'icicle-apply-to-saved-candidate))
+    (icicle-apply-to-saved-candidate
+     (completing-read (format "Function to apply to `%s': " icicle-saved-completion-candidate)
+                      obarray))))
+
+;;;###autoload
+(defun icicle-mouse-candidate-read-fn-invoke (event) ; Bound to `M-mouse-2' in `*Completions*'.
+  "Read function name.  Invoke function on candidate clicked by mouse."
+  (interactive "e")
+  (run-hooks 'mouse-leave-buffer-hook)  ; Give temp modes such as isearch a chance to turn off.
+  (let (;;$$$$$$ (buffer    (window-buffer))
+        (posn-win  (posn-window (event-start event)))
+        (posn-col  (car (posn-col-row (event-start event))))
+        (posn-row  (cdr (posn-col-row (event-start event))))
+        choice base-size)
+    ;; (read-event)                 ; Swallow mouse up event. $$ Not needed if bound to up event.
+    (with-current-buffer (window-buffer posn-win)
+      (save-excursion
+        ;; $$$$$$ (when completion-reference-buffer (setq buffer  completion-reference-buffer))
+        (setq base-size  completion-base-size)
+        (goto-char (posn-point (event-start event)))
+        (let (beg end)
+          (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+            (setq end  (point)
+                  beg  (1+ (point))))
+          (unless beg (error "No completion here"))
+          (setq beg     (previous-single-property-change beg 'mouse-face)
+                end     (or (next-single-property-change end 'mouse-face)(point-max))
+                choice  (buffer-substring-no-properties beg end)))))
+    (setq icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos
+                                             (posn-point (event-start event)))
+          icicle-last-completion-candidate  choice)
+    (let ((icicle-whole-candidate-as-text-prop-p  nil)
+          (enable-recursive-minibuffers            t)
+          (icicle-must-pass-after-match-predicate  #'(lambda (s) (functionp (intern s))))
+          (icicle-saved-completion-candidate       icicle-last-completion-candidate)
+          (icicle-candidate-action-fn              'icicle-apply-to-saved-candidate))
+      (icicle-apply-to-saved-candidate
+       (completing-read (format "Function to apply to `%s': " icicle-saved-completion-candidate)
+                        obarray)))))
+
+(defun icicle-apply-to-saved-candidate (function &optional use-icicle-candidates-alist-p type)
+  "Apply FUNCTION to `icicle-saved-completion-candidate'.
+If `current-prefix-arg' is non-nil, then pretty-print the result using
+`icicle-pp-eval-expression'.
+The string FUNCTION is read to obtain the real function to apply.
+If optional arg USE-ICICLE-CANDIDATES-ALIST-P is non-nil, then try to
+get the real function using `icicle-get-alist-candidate-function'.
+If that returns nil, then read string FUNCTION.
+Optional arg TYPE is the type of object that FUNCTION applies to."
+  (let ((real-fn   (or (and use-icicle-candidates-alist-p
+                            (cdr (funcall icicle-get-alist-candidate-function
+                                          function 'no-error-no-msg)))
+                       (car (read-from-string function))))
+        (real-obj  (if (equal type "buffer") ; $$$$$$$ Eventually, perhaps look up TYPE in a list etc.
+                       (get-buffer icicle-saved-completion-candidate)
+                     icicle-saved-completion-candidate)))
+    ;; Actually, we should test more than `functionp', to rule out macros and special forms.
+    (unless (functionp real-fn) (error "Not a function: `%S'" real-fn))
+    (icicle-condition-case-no-debug icicle-apply-to-saved-candidate
+        (if current-prefix-arg
+            (icicle-pp-eval-expression '(funcall real-fn real-obj))
+          (funcall real-fn real-obj)
+          (when (and (not icicle-all-candidates-action) (current-message))
+            (sit-for 3)))               ; In case the function displays a message.
+      (error (message  "ERROR invoking `%S' on `%s': %s" real-fn icicle-saved-completion-candidate
+                       (error-message-string icicle-apply-to-saved-candidate))
+             (sleep-for 6)))
+    (select-window (minibuffer-window))
+    (select-frame-set-input-focus (selected-frame))
+    (icicle-raise-Completions-frame)))
+
+(defun icicle-raise-Completions-frame (&optional mouse-col mouse-row)
+  "Raise `*Completions*' frame, if displayed.
+This helps keep `*Completions*' on top.
+
+If `icicle-move-Completions-frame' is non-nil and `*Completions*' is
+in its own frame, then move that frame to the display edge, out of the
+way.
+
+Non-nil optional args MOUSE-COL and MOUSE-ROW move the mouse pointer
+to column MOUSE-COL and row MOUSE-ROW.  Do this because
+`icicle-candidate-action-fn' can call `select-frame-set-input-focus',
+which can position mouse pointer on a standalone minibuffer frame."
+  ;; Raise `*Completions*' frame, if displayed.  This helps keep `*Completions*' on top.
+  (let ((compl-win  (get-buffer-window "*Completions*" 'visible)))
+    (when compl-win
+      (save-window-excursion
+        (select-window compl-win)
+        ;; Move frame to the right, out of the way.
+        (when (and (one-window-p t) icicle-move-Completions-frame)
+          (modify-frame-parameters
+           (selected-frame)             ; Hard-code 7 here - what does it depend on?
+           (if (eq icicle-move-Completions-frame 'left)
+               '((left . 0))
+             `((left . ,(- (x-display-pixel-width) (+ (frame-pixel-width) 7))))))
+          (raise-frame)
+          (when (and (integerp mouse-col) (integerp mouse-row))
+            (set-mouse-position (selected-frame) mouse-col mouse-row)))))))
+
+;;;###autoload
+(defun icicle-Completions-mouse-3-menu (event) ; Bound to `C-mouse-3' in `*Completions*'.
+  "Pop-up menu on `C-mouse-3' for the current candidate in `*Completions*'."
+  (interactive "e")
+  (run-hooks 'mouse-leave-buffer-hook)  ; Give temp modes such as isearch a chance to turn off.
+  (let (;; $$$$$$ (buffer    (window-buffer))
+        (posn-win  (posn-window (event-start event)))
+        (posn-col  (car (posn-col-row (event-start event))))
+        (posn-row  (cdr (posn-col-row (event-start event))))
+        candidate base-size)
+    ;; (read-event)                 ; Swallow mouse up event. $$ Not needed if bound to up event.
+    (with-current-buffer (window-buffer posn-win)
+      (save-excursion
+        ;; $$$$$$ (when completion-reference-buffer (setq buffer  completion-reference-buffer))
+        (setq base-size  completion-base-size)
+        (goto-char (posn-point (event-start event)))
+        (let (beg end)
+          (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+            (setq end  (point)
+                  beg  (1+ (point))))
+          (unless beg (error "No completion here"))
+          (setq beg       (previous-single-property-change beg 'mouse-face)
+                end       (or (next-single-property-change end 'mouse-face)(point-max))
+                candidate (buffer-substring-no-properties beg end)))))
+    (setq icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos
+                                             (posn-point (event-start event)))
+          icicle-last-completion-candidate  candidate)
+    (let* ((menus   `((keymap "Completion" ,@(icicle-substitute-keymap-vars
+                                              icicle-Completions-mouse-3-menu-entries))))
+           (choice  (x-popup-menu event menus)))
+      (icicle-Completions-popup-choice menus choice))))
+
+(defun icicle-substitute-keymap-vars (menu-entries)
+  "In MENU-ENTRIES, replace keymap vars by their values."
+  (let ((new  ()))
+    (dolist (jj  menu-entries)
+      (cond ((and (symbolp jj) (keymapp (symbol-value jj))) ; Just a keymap var.
+             (setq jj  (symbol-value jj))
+             (dolist (ii  jj) (push ii new)))
+            ;; (SYMBOL menu-item NAME MENU-KEYMAP . KEYWORDS), with a keymap var.
+            ((and (consp jj) (symbolp (car jj)) (eq 'menu-item (cadr jj))
+                  (stringp (car (cddr jj))) (symbolp (car (cdr (cddr jj))))
+                  (not (commandp (car (cdr (cddr jj))))) (boundp (car (cdr (cddr jj))))
+                  (keymapp (symbol-value (car (cdr (cddr jj))))))
+             (setq jj  `(,(car jj) menu-item ,(car (cddr jj))
+                         ,(symbol-value (car (cdr (cddr jj)))) ; Replace keymap var by its value.
+                         ,@(cdr (cdr (cddr jj))))) ; Keywords.
+             (push jj new))
+            ((and (consp jj) (symbolp (car jj)) (stringp (cadr jj)) ; (SYMBOL NAME . MENU-KEYMAP)
+                  (symbolp (cddr jj)) (boundp (cddr jj)) (keymapp (symbol-value (cddr jj))))
+             (setq jj  `(,(car jj) ,(cadr jj) ,@(symbol-value (cddr jj)))) ; Replace keymap var by val.
+             (push jj new))
+            (t (push jj new))))
+    (nreverse new)))
+
+;; This is the same as `mouse3-region-popup-choice' in `mouse3.el'.
+(if (require 'mouse3 nil t)
+    (defalias 'icicle-Completions-popup-choice 'mouse3-region-popup-choice)
+  (defun icicle-Completions-popup-choice (menus choice)
+    "Invoke the command from MENUS that is represented by user's CHOICE.
+MENUS is a list that is acceptable as the second argument for
+`x-popup-menu'.  That is, it is one of the following, where MENU-TITLE
+is the menu title and PANE-TITLE is a submenu title.
+
+* a keymap - MENU-TITLE is its `keymap-prompt'
+* a list of keymaps - MENU-TITLE is the first keymap's `keymap-prompt'
+* a menu of multiple panes, which has this form: (MENU-TITLE PANE...),
+  where each PANE has this form: (PANE-TITLE ITEM...),
+  where each ITEM has one of these forms:
+  - STRING - an unselectable menu item
+  - (STRING . COMMAND) - a selectable item that invokes COMMAND"
+    (catch 'icicle-Completions-popup-choice (icicle-Completions-popup-choice-1 menus choice))))
+
+;; This is the same as `mouse3-region-popup-choice-1' in `mouse3.el'.
+(if (require 'mouse3 nil t)
+    (defalias 'icicle-Completions-popup-choice-1 'mouse3-region-popup-choice-1)
+  (defun icicle-Completions-popup-choice-1 (menus choice)
+    "Helper function for `icicle-Completions-popup-choice'."
+    (cond((keymapp menus)
+          ;; Look up each ITEM-LIST entry in keymap MENUS.
+          ;;   If what is found is a keymap, use that as MENUS for next iteration.
+          ;;   If what is found is a command, invoke it (done).
+          (let (binding)
+            (while choice
+              (setq binding  (lookup-key menus (vector (car choice))))
+              (cond ((keymapp binding)
+                     (setq menus   binding
+                           choice  (cdr choice)))
+                    ((commandp binding)
+                     ;; You get only one.
+                     (throw 'icicle-Completions-popup-choice (call-interactively binding)))
+                    (t (error "`icicle-Completions-popup-choice', binding: %s" binding))))))
+         ((consp menus)                 ; A list of keymaps or panes.
+          (dolist (menu  menus)
+            (if (keymapp menu)
+                (icicle-Completions-popup-choice-1 menu choice)
+              (when choice              ; MENU is a pane.
+                (throw 'icicle-Completions-popup-choice (call-interactively choice)))))))))
+
+;;;###autoload
+(defun icicle-widen-candidates ()       ; Bound to `M-+' in minibuffer.
+  "Complete, allowing also candidates that match an alternative regexp.
+You are prompted for the alternative input pattern.  Use `RET' to
+enter it.
+
+To (apropos) complete using a wider set of candidates, you use this
+command after you have completed (`TAB' or `S-TAB').  A shortcut is to
+use `\\\\[icicle-apropos-complete-and-widen]' - \
+it is the same as `S-TAB' followed by `\\[icicle-widen-candidates]'.
+
+This command turns off `icicle-expand-input-to-common-match-flag', for
+clarity.  You can use `\\[icicle-toggle-expand-to-common-match]' \
+to toggle that option."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (unless icicle-completion-candidates
+    (error "No completion candidates.  Did you use `TAB' or `S-TAB'?"))
+  (let* ((raw-input                     icicle-current-raw-input)
+         (enable-recursive-minibuffers  t)
+         (new-regexp                    (icicle-read-string "Or match alternative (use RET): "
+                                                            nil regexp-history)))
+    (setq icicle-current-raw-input
+          (concat (if (< emacs-major-version 22) "\\(" "\\(?:") raw-input "\\|" new-regexp "\\)")
+          icicle-expand-input-to-common-match-flag  nil))
+  (icicle-clear-minibuffer)
+  (insert icicle-current-raw-input)
+  (let ((icicle-edit-update-p  t)) (icicle-apropos-complete))
+  (icicle-msg-maybe-in-minibuffer "Expansion to common match is OFF. \
+`\\\\[icicle-toggle-expand-to-common-match]' to toggle"))
+
+;;;###autoload
+(defun icicle-narrow-candidates ()      ; Bound to `M-*' in minibuffer.
+  "Narrow the set of completion candidates using another input regexp.
+This, in effect, performs a set intersection operation on 1) the set
+of candidates in effect before the operation and 2) the set of
+candidates that match the current input.  You can repeatedly use this
+command to continue intersecting candidate sets, progressively
+narrowing the set of matches.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-narrow-candidates]')."
+  ;; We handle `no-catch' errors here because `old-completing-read' and
+  ;; `old-read-file-file-name' can still be called in Icicle mode by, for instance, an
+  ;; `interactive' spec (e.g. (interactive "bBuffer: ")).  In that case, we throw to a
+  ;; non-existant catch.  After doing that, we just insert the result, to pass it to the
+  ;; next-higher recursive minibuffer.
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (setq icicle-current-completion-mode  'apropos)
+  (let (;; Restore match function, in case it was bound to nil, e.g., by `C-h C-o'.
+        (icicle-apropos-complete-match-fn  icicle-last-apropos-complete-match-fn)
+        (icicle-progressive-completing-p   t) ; Inhibit completion by `icicle-minibuffer-setup'.
+        (enable-recursive-minibuffers      t))
+    (cond ((and icicle-completion-candidates  (null (cdr icicle-completion-candidates)))
+           (if (not (and icicle-top-level-when-sole-completion-flag
+                         (sit-for icicle-top-level-when-sole-completion-delay)))
+               (minibuffer-message "  [Sole completion]")
+             (set minibuffer-history-variable (cons (car icicle-completion-candidates)
+                                                    (symbol-value minibuffer-history-variable)))
+             ;; $$$$$$ Should this now use `icicle-current-input'
+             ;;        instead of (car icicle-completion-candidates), for PCM?
+             (icicle-condition-case-no-debug i-narrow-candidates
+                 (throw 'icicle-read-top
+                   (if (and (icicle-file-name-input-p) insert-default-directory
+                            (or (not (member (car icicle-completion-candidates)
+                                             icicle-extra-candidates))
+                                icicle-extra-candidates-dir-insert-p))
+                       (expand-file-name (car icicle-completion-candidates))
+                     (car icicle-completion-candidates)))
+               (no-catch (setq icicle-current-input  (car icicle-completion-candidates))
+                         (icicle-retrieve-last-input)
+                         icicle-current-input)
+               (error (message "%s" (error-message-string i-narrow-candidates))))))
+          (t
+           (let* (;; $$$$$$$$$$$$$ (icicle-whole-candidate-as-text-prop-p  nil)
+                  (minibuffer-setup-hook ; Make sure the new minibuffer is the reference buffer.
+                   (cons
+                    (lambda ()
+                      (with-current-buffer (get-buffer-create "*Completions*")
+                        (set (make-local-variable 'completion-reference-buffer)
+                             (window-buffer (active-minibuffer-window)))))
+                    minibuffer-setup-hook))
+                  (current-candidates  icicle-completion-candidates)
+                  (result
+                   (cond ((and (icicle-file-name-input-p)
+                               (or (= emacs-major-version 22) ; Emacs 22 or 23.1
+                                   (and (= emacs-major-version 23) (= emacs-minor-version 1))))
+                          (read-file-name "Match also (regexp): "
+                                          (icicle-file-name-directory-w-default icicle-current-input)
+                                          nil icicle-require-match-p nil
+                                          (lambda (file-cand) (member file-cand current-candidates))))
+                         ((and (icicle-file-name-input-p) (> emacs-major-version 22)) ; Emacs 23.2+
+                          (let ((icicle-must-pass-after-match-predicate
+                                 #'(lambda (c) (member c current-candidates))))
+                            (completing-read "Match also (regexp): " 'read-file-name-internal nil
+                                             icicle-require-match-p nil minibuffer-history-variable)))
+                         (t             ; Emacs 20, 21
+                          ;; In Emacs < 22, there is no PREDICATE arg to `read-file-name', so
+                          ;; we use `completing-read' even for file-name completion.  In that case, we
+                          ;; tack the `default-directory' onto each candidate, unless it is already an
+                          ;; absolute file name.  We also let completion functions (e.g. `S-TAB') know
+                          ;; that this is not really file-name completion.
+                          (completing-read
+                           "Match also (regexp): "
+                           (cond ((icicle-file-name-input-p)
+                                  (setq minibuffer-completing-file-name  nil) ; Disavow completing file.
+                                  (let ((dir  (icicle-file-name-directory-w-default
+                                               icicle-current-input)))
+                                    (mapcar (lambda (file)
+                                              (list (if (file-name-absolute-p file)
+                                                        file
+                                                      (concat dir file))))
+                                            icicle-completion-candidates)))
+                                 (icicle-whole-candidate-as-text-prop-p
+                                  (mapcar (lambda (cand)
+                                            (funcall icicle-get-alist-candidate-function (car cand)))
+                                          (icicle-filter-alist minibuffer-completion-table
+                                                               icicle-completion-candidates)))
+                                 (t
+                                  (mapcar #'list icicle-completion-candidates)))
+                           nil icicle-require-match-p nil minibuffer-history-variable)))))
+             ;; Normally, `icicle-narrow-candidates' is called from the minibuffer.
+             ;; If not, just return the result read.
+             (if (> (minibuffer-depth) 0)
+                 (icicle-condition-case-no-debug i-narrow-candidates
+                     (throw 'icicle-read-top result)
+                   (no-catch (setq icicle-current-input  result)
+                             (icicle-retrieve-last-input)
+                             icicle-current-input)
+                   (error (message "%s" (error-message-string i-narrow-candidates))))
+               result))))))
+
+;;;###autoload
+(defun icicle-apropos-complete-and-widen () ; Bound to `S-DEL' in minibuffer.
+  "Apropos complete, then `icicle-widen-candidates'.
+You must enter the new, alternative input pattern using `RET'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-apropos-complete-and-widen]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  ;; $$$$$ (let ((icicle-top-level-when-sole-completion-flag  t))
+  (when (eq icicle-current-completion-mode 'prefix)
+    (let ((icicle-incremental-completion-p  nil)
+          (regexp-quoted-input              (regexp-quote icicle-last-input)))
+      (setq regexp-quoted-input  (if (icicle-file-name-input-p)
+                                     (concat (icicle-file-name-directory regexp-quoted-input) "^"
+                                             (file-name-nondirectory regexp-quoted-input))
+                                   (concat "^" regexp-quoted-input)))
+      (icicle-erase-minibuffer)
+      (insert regexp-quoted-input)))
+  (if (eq icicle-last-completion-command 'icicle-apropos-complete-no-display)
+      (icicle-apropos-complete-no-display)
+    (icicle-apropos-complete))
+  (icicle-widen-candidates))
+
+;;;###autoload
+(defun icicle-apropos-complete-and-narrow () ; Bound to `S-SPC' in minibuffer.
+  "Apropos complete, then `icicle-narrow-candidates'.
+You can use this command only from the minibuffer (`\\\
+\\[icicle-apropos-complete-and-narrow]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  ;; $$$$$ (let ((icicle-top-level-when-sole-completion-flag  t))
+  (when (and (eq icicle-current-completion-mode 'prefix)
+             (eq icicle-current-TAB-method 'basic)
+             icicle-last-input)
+    (let ((icicle-incremental-completion-p  nil)
+          (regexp-quoted-input              (regexp-quote icicle-last-input)))
+      (setq regexp-quoted-input  (if (icicle-file-name-input-p)
+                                     (concat (icicle-file-name-directory regexp-quoted-input) "^"
+                                             (file-name-nondirectory regexp-quoted-input))
+                                   (concat "^" regexp-quoted-input)))
+      (icicle-erase-minibuffer)
+      (insert regexp-quoted-input)))
+  (setq icicle-next-apropos-complete-cycles-p  nil)
+  (if (eq icicle-last-completion-command 'icicle-apropos-complete-no-display)
+      (icicle-apropos-complete-no-display)
+    (icicle-apropos-complete))
+  (icicle-narrow-candidates))
+
+;;;###autoload
+(defun icicle-narrow-candidates-with-predicate (&optional predicate) ; Bound to `M-&' in minibuffer.
+  "Narrow the set of completion candidates by applying a predicate.
+You can repeatedly use this command to apply additional predicates,
+progressively narrowing the set of candidates.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-narrow-candidates-with-predicate]').
+
+When called from Lisp with non-nil arg PREDICATE, use that to narrow."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (let (;; Restore match function, in case it was bound to nil, e.g., by `C-h C-o'.
+        (icicle-apropos-complete-match-fn  icicle-last-apropos-complete-match-fn)
+        (icicle-progressive-completing-p   t) ; Inhibit completion by `icicle-minibuffer-setup'.
+        (last-completion-cmd               (or icicle-last-completion-command 'icicle-apropos-complete))
+        (enable-recursive-minibuffers      t))
+    (cond ((null icicle-completion-candidates)
+           (error "No completion candidates.  Did you use `TAB' or `S-TAB'?"))
+          ((null (cdr icicle-completion-candidates))
+           (if (not (and icicle-top-level-when-sole-completion-flag
+                         (sit-for icicle-top-level-when-sole-completion-delay)))
+               (minibuffer-message "  [Sole completion]")
+             (set minibuffer-history-variable (cons (car icicle-completion-candidates)
+                                                    (symbol-value minibuffer-history-variable)))
+             ;; $$$$$$ Should this now use `icicle-current-input'
+             ;;        instead of (car icicle-completion-candidates), for PCM?
+             (icicle-condition-case-no-debug i-narrow-candidates
+                 (throw 'icicle-read-top
+                   (if (and (icicle-file-name-input-p) insert-default-directory
+                            (or (not (member (car icicle-completion-candidates)
+                                             icicle-extra-candidates))
+                                icicle-extra-candidates-dir-insert-p))
+                       (expand-file-name (car icicle-completion-candidates))
+                     (car icicle-completion-candidates)))
+               (no-catch (setq icicle-current-input  (car icicle-completion-candidates))
+                         (icicle-retrieve-last-input)
+                         icicle-current-input)
+               (error (message "%s" (error-message-string i-narrow-candidates))))))
+          (t                            ; Read new predicate and incorporate it.
+           (let ((pred  (or predicate
+                            (icicle-read-from-minibuf-nil-default
+                             "Additional predicate to apply: "
+                             nil read-expression-map t (if (boundp 'function-name-history)
+                                                           'function-name-history
+                                                         'icicle-function-name-history)))))
+             ;; Update `read-file-name-predicate' or `minibuffer-completion-predicate'
+             ;; to also use new predicate, PRED.
+             ;; The logic here is the same as for `icicle-remove-cand-from-lists'.
+             (cond (;; File name input, Emacs 22+.  Update `read-file-name-predicate'.
+                    (and (icicle-file-name-input-p) (> emacs-major-version 21))
+                    (setq read-file-name-predicate
+                          (if read-file-name-predicate
+                              (lexical-let ((curr-pred  read-file-name-predicate))
+                                `(lambda (file-cand)
+                                  (and (funcall ',curr-pred file-cand) (funcall ',pred file-cand))))
+                            pred)))
+
+                   ;; File name input, Emacs 20 or 21.  We can do nothing for file name.
+                   ;; `TAB' or `S-TAB' will unfortunately bring it back as a candidate.
+                   ((icicle-file-name-input-p))
+
+                   (t;; Non-file name input, all versions.  Update `minibuffer-completion-predicate'.
+                    (setq minibuffer-completion-predicate
+                          (if minibuffer-completion-predicate
+                              ;; Add PRED to the existing predicate.
+                              (lexical-let ((curr-pred  minibuffer-completion-predicate))
+                                `(lambda (cand)
+                                  (and (funcall ',curr-pred cand) (funcall ',pred cand))))
+                            ;; Set predicate to PRED.
+                            pred)))))))
+    (funcall last-completion-cmd)))
+
+;;;###autoload
+(defun icicle-save-predicate-to-variable (askp) ; Bound to `C-M-&' in minibuffer.
+  "Save the current completion predicate to a variable.
+By default, the variable is `icicle-input-string'.  If you use a
+prefix argument, then you are prompted for the variable to use.
+
+You can retrieve the saved predicate as a string using `\\\
+\\[icicle-insert-string-from-variable]'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-save-predicate-to-variable]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (let* ((pred                                    minibuffer-completion-predicate)
+         (icicle-whole-candidate-as-text-prop-p   nil)
+         (enable-recursive-minibuffers            t)
+         (icicle-must-pass-after-match-predicate  #'(lambda (s) (boundp (intern s))))
+         (var                                     (if askp
+                                                      (intern
+                                                       (completing-read
+                                                        "Save candidates in variable: " obarray nil
+                                                        nil nil (if (boundp 'variable-name-history)
+                                                                    'variable-name-history
+                                                                  'icicle-variable-name-history)))
+                                                    'icicle-input-string)))
+    (set var (prin1-to-string pred))
+    (save-selected-window (select-window (minibuffer-window))
+                          (minibuffer-message (format "  [Predicate SAVED to `%s']" var)))))
+
+;;;###autoload
+(defun icicle-completing-read+insert () ; Bound to `C-M-S-c' (`C-M-C') in minibuffer.
+  "Read something with completion, and insert it.
+Be sure to bind `icicle-completing-read+insert-candidates' to the set
+of candidates.
+Option `icicle-completing-read+insert-keys' controls which keys are
+bound to this command.
+Return the string that was inserted."
+  (interactive)
+  (if icicle-completing-read+insert-candidates
+      (let ((enable-recursive-minibuffers  t)
+            (use-dialog-box                nil)
+            (result
+             (icicle-completing-read "Choose: " icicle-completing-read+insert-candidates)))
+        (insert result)
+        result)
+    (icicle-msg-maybe-in-minibuffer "On-demand completion not available")))
+
+;;;###autoload
+(defun icicle-read+insert-file-name (dir-too-p) ; Bound to `C-M-S-f' (`C-M-F') in minibuffer.
+  "Read a file name and insert it, without its directory, by default.
+With a prefix argument, insert its directory also.
+Option `icicle-read+insert-file-name-keys' controls which keys are
+ bound to this command.
+Return the string that was inserted."
+  (interactive "P")
+  (let ((completion-ignore-case                  (memq system-type '(ms-dos windows-nt cygwin)))
+        (enable-recursive-minibuffers            t)
+        (use-dialog-box                          nil)
+        (minibuffer-local-completion-map
+         (let ((map  (make-sparse-keymap)))
+           (set-keymap-parent map minibuffer-local-completion-map)
+           (define-key map [(control backspace)] 'icicle-up-directory)
+           (define-key map "\C-c+"               'icicle-make-directory)
+           map))
+        (minibuffer-local-must-match-map
+         (let ((map  (make-sparse-keymap)))
+           (set-keymap-parent map minibuffer-local-must-match-map)
+           (define-key map [(control backspace)] 'icicle-up-directory)
+           (define-key map "\C-c+"               'icicle-make-directory)
+           map))
+        (icicle-must-pass-after-match-predicate  nil)
+        result)
+    (setq result  (icicle-read-file-name "Choose file: "))
+    (unless dir-too-p                   ; Remove parent dir.
+      (setq result  (if (file-directory-p result)
+                        (file-name-as-directory (file-name-nondirectory (directory-file-name result)))
+                      (file-name-nondirectory result))))
+    (insert result)
+    result))
+
+;; `minibuffer-local-filename-completion-map' and `minibuffer-local-must-match-filename-map'
+;; were introduced in Emacs 22, and they inherit from `minibuffer-local-completion' and
+;; `minibuffer-local-must-match-map', respectively.  For Emacs 23.1,
+;; `minibuffer-local-must-match-filename-map' is an alias for
+;; `minibuffer-local-filename-must-match-map'.  But for Emacs 23.2, there is no such alias!
+;; And for Emacs 24+, there is no longer a `minibuffer-local-filename-must-match-map'.
+;;;###autoload
+(defun icicle-bind-file-candidate-keys ()
+  "Bind specific keys for acting on the current file candidate."
+  (cond ((boundp 'minibuffer-local-filename-completion-map)
+         (define-key minibuffer-local-filename-completion-map [(control backspace)]
+           'icicle-up-directory)
+         (define-key minibuffer-local-filename-completion-map "\C-c+"
+           'icicle-make-directory))
+        (t
+         (define-key minibuffer-local-completion-map [(control backspace)]
+           'icicle-up-directory)
+         (define-key minibuffer-local-completion-map "\C-c+"
+           'icicle-make-directory)))
+  (cond ((boundp 'minibuffer-local-filename-must-match-map)
+         (define-key minibuffer-local-filename-must-match-map [(control backspace)]
+           'icicle-up-directory)
+         (define-key minibuffer-local-filename-must-match-map "\C-c+"
+           'icicle-make-directory))
+        ((boundp 'minibuffer-local-must-match-filename-map)
+         (define-key minibuffer-local-must-match-filename-map [(control backspace)]
+           'icicle-up-directory)
+         (define-key minibuffer-local-must-match-filename-map "\C-c+"
+           'icicle-make-directory))
+        (t
+         (define-key minibuffer-local-must-match-map [(control backspace)]
+           'icicle-up-directory)
+         (define-key minibuffer-local-must-match-map "\C-c+"
+           'icicle-make-directory)))
+  (when (require 'bookmark+ nil t)
+    (cond ((boundp 'minibuffer-local-filename-completion-map)
+           (define-key minibuffer-local-filename-completion-map "\C-xm"
+             'icicle-bookmark-file-other-window)
+           (define-key minibuffer-local-filename-completion-map "\C-xa+"
+             (icicle-add/remove-tags-and-refresh 'add))
+           (define-key minibuffer-local-filename-completion-map "\C-xa-"
+             (icicle-add/remove-tags-and-refresh 'remove)))
+          (t
+           (define-key minibuffer-local-completion-map "\C-xm"
+             'icicle-bookmark-file-other-window)
+           (define-key minibuffer-local-completion-map "\C-xa+"
+             (icicle-add/remove-tags-and-refresh 'add))
+           (define-key minibuffer-local-completion-map "\C-xa-"
+             (icicle-add/remove-tags-and-refresh 'remove))))
+    (cond ((boundp 'minibuffer-local-filename-must-match-map)
+           (define-key minibuffer-local-filename-must-match-map "\C-xm"
+             'icicle-bookmark-file-other-window)
+           (define-key minibuffer-local-filename-must-match-map "\C-xa+"
+             (icicle-add/remove-tags-and-refresh 'add))
+           (define-key minibuffer-local-filename-must-match-map "\C-xa-"
+             (icicle-add/remove-tags-and-refresh 'remove)))
+          ((boundp 'minibuffer-local-must-match-filename-map)
+           (define-key minibuffer-local-must-match-filename-map "\C-xm"
+             'icicle-bookmark-file-other-window)
+           (define-key minibuffer-local-must-match-filename-map "\C-xa+"
+             (icicle-add/remove-tags-and-refresh 'add))
+           (define-key minibuffer-local-must-match-filename-map "\C-xa-"
+             (icicle-add/remove-tags-and-refresh 'remove)))
+          (t
+           (define-key minibuffer-local-completion-map "\C-xm"
+             'icicle-bookmark-file-other-window)
+           (define-key minibuffer-local-completion-map "\C-xa+"
+             (icicle-add/remove-tags-and-refresh 'add))
+           (define-key minibuffer-local-completion-map "\C-xa-"
+             (icicle-add/remove-tags-and-refresh 'remove)))))
+  ;; When using `completing-read', not `read-file-name', regardless of the Emacs version.
+  (when (not (icicle-file-name-input-p))
+    (define-key minibuffer-local-completion-map [(control backspace)]
+      'icicle-up-directory)
+    (define-key minibuffer-local-completion-map "\C-c+"
+      'icicle-make-directory)
+    (define-key minibuffer-local-completion-map "\C-xm"
+      'icicle-bookmark-file-other-window)
+    (define-key minibuffer-local-completion-map "\C-xa+"
+      (icicle-add/remove-tags-and-refresh 'add))
+    (define-key minibuffer-local-completion-map "\C-xa-"
+      (icicle-add/remove-tags-and-refresh 'remove))))
+
+;;;###autoload
+(defun icicle-unbind-file-candidate-keys ()
+  "Unbind specific keys for acting on the current file candidate."
+  (when (boundp 'minibuffer-local-filename-completion-map)
+    (define-key minibuffer-local-filename-completion-map [(control backspace)] nil)
+    (define-key minibuffer-local-filename-completion-map "\C-c+"               nil)
+    (define-key minibuffer-local-filename-completion-map "\C-xm"               nil)
+    (define-key minibuffer-local-filename-completion-map "\C-xa+"              nil)
+    (define-key minibuffer-local-filename-completion-map "\C-xa-"              nil)
+    (define-key minibuffer-local-filename-completion-map "\C-xa"               nil))
+  (when (boundp 'minibuffer-local-filename-must-match-map)
+    (define-key minibuffer-local-filename-must-match-map [(control backspace)] nil)
+    (define-key minibuffer-local-filename-must-match-map "\C-c+"               nil)
+    (define-key minibuffer-local-filename-must-match-map "\C-xm"               nil)
+    (define-key minibuffer-local-filename-must-match-map "\C-xa+"              nil)
+    (define-key minibuffer-local-filename-must-match-map "\C-xa-"              nil)
+    (define-key minibuffer-local-filename-must-match-map "\C-xa"               nil))
+  (when (boundp 'minibuffer-local-must-match-filename-map)
+    (define-key minibuffer-local-must-match-filename-map [(control backspace)] nil)
+    (define-key minibuffer-local-must-match-filename-map "\C-c+"               nil)
+    (define-key minibuffer-local-must-match-filename-map "\C-xm"               nil)
+    (define-key minibuffer-local-must-match-filename-map "\C-xa+"              nil)
+    (define-key minibuffer-local-must-match-filename-map "\C-xa-"              nil)
+    (define-key minibuffer-local-must-match-filename-map "\C-xa"               nil))
+  (define-key minibuffer-local-completion-map [(control backspace)]            nil)
+  (define-key minibuffer-local-completion-map "\C-c+"                          nil)
+  (define-key minibuffer-local-completion-map "\C-xm"                          nil)
+  (define-key minibuffer-local-completion-map "\C-xa+"                         nil)
+  (define-key minibuffer-local-completion-map "\C-xa-"                         nil)
+  (define-key minibuffer-local-completion-map "\C-xa"                          nil))
+
+
+;;;###autoload
+(defun icicle-candidate-set-swap ()     ; Bound to `C-%' in minibuffer.
+  "Swap the saved set and current sets of completion candidates.
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-swap]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (setq icicle-saved-completion-candidates
+        (prog1 icicle-completion-candidates
+          (setq icicle-completion-candidates  icicle-saved-completion-candidates)))
+  (minibuffer-message "  [Saved set of candidates SWAPPED with current]"))
+
+;;;###autoload
+(defun icicle-candidate-set-define ()   ; Bound to `C-:' in minibuffer.
+  "Define the set of current completion candidates by evaluating a sexp.
+The Lisp sexp must evaluate to a list of strings, such as is returned
+by `all-completions'.
+
+You can use this command at top level or from the minibuffer (`\\\
+\\[icicle-candidate-set-define]')."
+  (interactive)
+  (let* ((enable-recursive-minibuffers  t)
+         (evald-sexp                    (eval-minibuffer
+                                         "Set the completion candidates to sexp (eval): ")))
+    (when (and evald-sexp (or (atom evald-sexp) (not (stringp (car evald-sexp)))))
+      (error "Sexp did not evaluate to a list of strings: %S" evald-sexp))
+    (setq icicle-completion-candidates  evald-sexp))
+  (icicle-maybe-sort-and-strip-candidates)
+  (message "List of completion candidates DEFINED: %S" icicle-completion-candidates)
+  (when (> (minibuffer-depth) 0)
+    (message "Displaying completion candidates...")
+    (with-output-to-temp-buffer "*Completions*"
+      (display-completion-list icicle-completion-candidates))
+    (icicle-narrow-candidates)))
+
+;;;###autoload
+(defun icicle-candidate-set-difference () ; Bound to `C--' in minibuffer.
+  "Take the set difference between the current and saved candidates.
+The new set of candidates is the set of candidates prior to executing
+this command minus the saved set of candidates.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-difference]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (message "Computing set difference: current minus saved candidates...")
+  (icicle-candidate-set-1 'icicle-set-difference "  [saved set of candidates SUBTRACTED]"))
+
+;;;###autoload
+(defun icicle-candidate-set-union ()    ; Bound to `C-+' in minibuffer.
+  "Take the set union between the current and saved candidates.
+The new set of candidates is the union of the saved set of candidates
+and the set of candidates prior to executing this command.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-union]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (message "Computing set union: current plus saved candidates...")
+  (icicle-candidate-set-1 'icicle-set-union "  [saved set of candidates ADDED]"))
+
+;;;###autoload
+(defun icicle-candidate-set-intersection () ; Bound to `C-*' in minibuffer.
+  "Take the set intersection between the current and saved candidates.
+The new set of candidates is the intersection of the saved set of
+candidates and the set of candidates prior to executing this command.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-intersection]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (message "Computing set intersection: current and saved candidates...")
+  (icicle-candidate-set-1 'icicle-set-intersection
+                          "  [INTERSECTION of saved and current sets of candidates]"))
+
+;;;###autoload
+(defun icicle-candidate-set-complement () ; Bound to `C-~' in minibuffer.
+  "Complement the set of current completion candidates.
+The new set of candidates is the set of all candidates in the initial
+completion domain minus the set of matching candidates prior to
+executing this command - that is, all possible completions of the
+appropriate type, except for those that are in the current set of
+completions.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-complement]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (message "Complementing current set of candidates...")
+  (let ((initial-cands  (icicle-all-completions "" minibuffer-completion-table
+                                                minibuffer-completion-predicate
+                                                icicle-ignore-space-prefix-flag)))
+    (setq icicle-completion-candidates  (icicle-set-difference
+                                         (if icicle-must-pass-after-match-predicate
+                                             (icicle-remove-if-not
+                                              icicle-must-pass-after-match-predicate initial-cands)
+                                           initial-cands)
+                                         icicle-completion-candidates)))
+  (icicle-maybe-sort-and-strip-candidates)
+  (message "Displaying completion candidates...")
+  (with-output-to-temp-buffer "*Completions*" (display-completion-list icicle-completion-candidates))
+  (minibuffer-message "  [Set of candidates COMPLEMENTED]")
+  (icicle-narrow-candidates))
+
+(defun icicle-candidate-set-truncate (n) ; Bound to `M-$' in minibuffer.
+  "Trim the set of current completion candidates at the end.
+The first N candidates are kept.  N is read."
+  ;; Ugly hack: `icicle-saved-completion-candidates-internal'.  No way to bind a variable
+  ;; in `interactive' and have the binding be active in the function body.
+  (interactive
+   (list (let ((enable-recursive-minibuffers  t))
+           (setq icicle-saved-completion-candidates-internal  icicle-completion-candidates)
+           (if current-prefix-arg
+               (prefix-numeric-value current-prefix-arg)
+             (read-number "Number of candidates to keep: ")))))
+  (setq icicle-completion-candidates  icicle-saved-completion-candidates-internal)
+  (setcdr (nthcdr (1- n) icicle-completion-candidates) nil)
+  (icicle-maybe-sort-and-strip-candidates)
+  (message "Displaying completion candidates...")
+  (with-output-to-temp-buffer "*Completions*" (display-completion-list icicle-completion-candidates))
+  (message (format "  [Set of candidates TRUNCATED to %d]" n))
+  (icicle-narrow-candidates))
+
+;;;###autoload
+(defun icicle-candidate-set-retrieve (&optional arg) ; Bound to `C-M-<' in minibuffer.
+  "Retrieve a saved set of completion candidates, making it current.
+This retrieves candidates saved with `\\\
+\\[icicle-save/unsave-candidate]', `M-S-mouse-2',
+`\\\\[icicle-candidate-set-save]', \
+`\\[icicle-candidate-set-save-to-variable]', or `\\[icicle-candidate-set-save-persistently]'.
+
+With no prefix arg, retrieve candidates from variable
+ `icicle-saved-completion-candidates'.
+With a numeric prefix arg, retrieve candidates from another variable.
+With a plain prefix arg (`C-u'), retrieve candidates from a cache file
+ or, if option `icicle-filesets-as-saved-completion-sets-flag' is
+ non-nil, an Emacs fileset name (Emacs 22 or later).  To use filesets,
+ you must also load library `filesets' and use `(filesets-init)'.
+
+Completion is available when you are prompted for a cache file,
+fileset, or variable name.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-retrieve]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (icicle-candidate-set-retrieve-1 arg))
+
+;;;###autoload
+(defun icicle-candidate-set-retrieve-1 (arg &optional morep)
+  "Helper function for `icicle-candidate-set-retrieve(-more)'.
+ARG is the same as the raw prefix arg for `icicle-candidate-set-retrieve'.
+MOREP non-nil means add the saved candidates, don't replace existing."
+  (let ((name        nil)
+        (variablep   (and arg (atom arg)))
+        (curr-cands  icicle-completion-candidates)
+        saved-cands)
+    (if arg
+        (let ((icicle-whole-candidate-as-text-prop-p  nil)
+              (enable-recursive-minibuffers           t))
+          (if variablep
+              ;; Retrieve from a variable.  Prompt user for the variable to use.
+              (setq saved-cands
+                    (append (and morep curr-cands)
+                            (symbol-value
+                             (setq name  (intern
+                                          (completing-read ; Variable name.
+                                           "Retrieve candidates from variable: "
+                                           icicle-saved-candidates-variables-obarray
+                                           nil nil nil (if (boundp 'variable-name-history)
+                                                           'variable-name-history
+                                                         'icicle-variable-name-history)))))))
+            ;; Retrieve from a persistent set (and save to `icicle-saved-completion-candidates').
+            (setq name  (completing-read "Retrieve candidates from persistent set: "
+                                         (if (and icicle-filesets-as-saved-completion-sets-flag
+                                                  (featurep 'filesets) filesets-data)
+                                             (append filesets-data icicle-saved-completion-sets)
+                                           icicle-saved-completion-sets)
+                                         nil nil nil 'icicle-completion-set-history))
+            (icicle-retrieve-candidates-from-set name)
+            (setq saved-cands  (append (and morep curr-cands) icicle-saved-completion-candidates))))
+      ;; Retrieve from the default variable, `icicle-saved-completion-candidates'.
+      (setq saved-cands  (append (and morep curr-cands)
+                                 icicle-saved-completion-candidates)))
+    (cond ((null saved-cands)
+           (deactivate-mark)
+           (icicle-display-candidates-in-Completions)
+           (message "No saved candidates to restore") (sit-for 2))
+          (t
+           (setq icicle-completion-candidates ; Remove directories if completing file names
+                 (if (icicle-file-name-input-p) ; using `read-file-name'.
+                     (mapcar #'file-name-nondirectory saved-cands)
+                   saved-cands))
+           (cond ((and (consp icicle-completion-candidates) (null (cdr icicle-completion-candidates)))
+                  ;; $$$$$$ Should this now use `icicle-current-input'
+                  ;;        instead of (car icicle-completion-candidates), for PCM?
+                  (icicle-remove-Completions-window)
+                  (icicle-insert-completion (car icicle-completion-candidates)) ; Insert sole cand.
+                  (minibuffer-message "  [Sole candidate restored]")
+                  (save-selected-window (select-window (minibuffer-window))
+                                        (icicle-highlight-complete-input))
+                  (icicle-show-help-in-mode-line (car icicle-completion-candidates)))
+                 ((consp icicle-completion-candidates)
+                  (deactivate-mark)
+                  (icicle-display-candidates-in-Completions)
+                  (save-selected-window
+                    (select-window (minibuffer-window))
+                    (minibuffer-message (if name
+                                            (format "  [Saved candidates RESTORED from %s `%s']"
+                                                    (if variablep "variable" "cache file") name)
+                                          "  [Saved candidates RESTORED]")))
+                  (let ((icicle-minibuffer-setup-hook ; Pre-complete
+                         (cons (if (eq icicle-last-completion-command
+                                       'icicle-apropos-complete-no-display)
+                                   'icicle-apropos-complete-no-display
+                                 'icicle-apropos-complete)
+                               icicle-minibuffer-setup-hook)))
+                    (icicle-narrow-candidates))))))))
+
+;;;###autoload
+(defun icicle-candidate-set-retrieve-more (&optional arg) ; Bound to `C-<' in minibuffer.
+  "Retrieve a saved set of completion candidates, adding it current.
+The saved candidates are added to those already current.
+A prefix argument acts as for `icicle-candidate-set-retrieve'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-retrieve-more]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (icicle-candidate-set-retrieve-1 arg t))
+
+;;;###autoload
+(defun icicle-candidate-set-retrieve-from-variable () ; Bound to `C-M-{' in minibuffer.
+  "Retrieve a saved set of completion candidates, making it current.
+This retrieves candidates saved with `\\\
+\\[icicle-save/unsave-candidate]', `M-S-mouse-2', or
+`\\[icicle-candidate-set-save-to-variable]' (or `\\[icicle-candidate-set-save]' with a numeric \
+prefix arg).
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-retrieve-from-variable]')."
+  (interactive)
+  (icicle-candidate-set-retrieve 99))
+
+;;;###autoload
+(defun icicle-candidate-set-retrieve-persistent () ; Bound to `C-{' in minibuffer.
+  "Retrieve a saved set of completion candidates, making it current.
+This retrieves candidates saved with `\\\
+\\[icicle-candidate-set-save-persistently]' or `C-u \\[icicle-candidate-set-save]'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-retrieve-persistent]')."
+  (interactive)
+  (icicle-candidate-set-retrieve '(1)))
+
+(defun icicle-retrieve-candidates-from-set (set-name)
+  "Retrieve the saved set of completion candidates named SET-NAME.
+SET-NAME names an Icicles saved completion set or, if
+ `icicle-filesets-as-saved-completion-sets-flag' is non-nil, an Emacs
+ fileset.  If that option is non-nil and SET-NAME names a saved
+ completion set that contains Emacs filesets, then the files specified
+ for the filesets are also retrieved. 
+The candidates are retrieved to `icicle-saved-completion-candidates',
+and `icicle-candidates-alist' is updated."
+  (setq icicle-saved-completion-candidates  (icicle-get-candidates-from-saved-set set-name))
+  (when icicle-candidates-alist         ; Redefine `icicle-candidates-alist'.
+    (let ((icicle-whole-candidate-as-text-prop-p  t))
+      (setq icicle-candidates-alist  (mapcar icicle-get-alist-candidate-function
+                                             icicle-saved-completion-candidates)))))
+
+;;;###autoload
+(defun icicle-save/unsave-candidate ()  ; Bound to `insert' in minibuffer.
+  "Add/remove current candidate to/from `icicle-saved-completion-candidates'.
+If the candidate is already saved, then unsave it; otherwise, save it.
+You can use this command only from the minibuffer (`\\\
+\\[icicle-save/unsave-candidate]')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (if (not (wholenump icicle-candidate-nb))
+      (save-selected-window (select-window (minibuffer-window))
+                            (minibuffer-message "  [No current candidate]"))
+    (let ((cand  (elt icicle-completion-candidates icicle-candidate-nb)))
+      (cond ((member cand icicle-saved-completion-candidates)
+             (setq icicle-saved-completion-candidates
+                   (delete icicle-last-completion-candidate icicle-saved-completion-candidates))
+             (save-selected-window (select-window (minibuffer-window))
+                                   (minibuffer-message "  [Candidate UNsaved]")))
+            (t
+             (push cand icicle-saved-completion-candidates)
+             (save-selected-window (select-window (minibuffer-window))
+                                   (minibuffer-message "  [Candidate SAVED]")))))))
+;;;###autoload
+(defun icicle-mouse-save/unsave-candidate (event) ; Bound to `M-S-mouse-2' in *Completions.
+  "Add/remove clicked candidate to/from `icicle-saved-completion-candidates'.
+If the candidate is already saved, then unsave it; otherwise, save it."
+  (interactive "e")
+  (run-hooks 'mouse-leave-buffer-hook)  ; Give temp modes such as isearch a chance to turn off.
+  (let (;; $$$$$$ (buffer    (window-buffer))
+        (posn-win  (posn-window (event-start event)))
+        (posn-col  (car (posn-col-row (event-start event))))
+        (posn-row  (cdr (posn-col-row (event-start event))))
+        choice base-size)
+    (read-event)                        ; Swallow mouse up event.
+    (with-current-buffer (window-buffer posn-win)
+      (save-excursion
+        ;; $$$$$$ (when completion-reference-buffer (setq buffer  completion-reference-buffer))
+        (setq base-size  completion-base-size)
+        (goto-char (posn-point (event-start event)))
+        (let (beg end)
+          (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+            (setq end  (point)
+                  beg  (1+ (point))))
+          (unless beg (error "No completion here"))
+          (setq beg     (previous-single-property-change beg 'mouse-face)
+                end     (or (next-single-property-change end 'mouse-face)(point-max))
+                choice  (buffer-substring-no-properties beg end)))))
+    (setq icicle-candidate-nb               (icicle-nb-of-cand-at-Completions-pos
+                                             (posn-point (event-start event)))
+          icicle-last-completion-candidate  choice)
+    (cond ((member icicle-last-completion-candidate icicle-saved-completion-candidates)
+           (setq icicle-saved-completion-candidates
+                 (delete icicle-last-completion-candidate icicle-saved-completion-candidates))
+           (save-selected-window (select-window (minibuffer-window))
+                                 (minibuffer-message "  [Candidate UNsaved]")))
+          (t
+           (push icicle-last-completion-candidate icicle-saved-completion-candidates)
+           (save-selected-window (select-window (minibuffer-window))
+                                 (minibuffer-message "  [Candidate SAVED]"))))
+    (deactivate-mark)
+    (icicle-display-candidates-in-Completions)
+    (icicle-raise-Completions-frame posn-col posn-row)))
+
+;;;###autoload
+(defun icicle-mouse-candidate-set-save (ignore &optional arg) ; `M-S-mouse-3' in `*Completions*'.
+  "`icicle-candidate-set-save(-selected)'.
+If the region is active in `*Completions*', then
+`icicle-candidate-set-save-selected'.  Otherwise,
+`icicle-candidate-set-save'."
+  (interactive "e\nP")
+  (if (and (get-buffer "*Completions*")
+           (save-current-buffer
+             (set-buffer (get-buffer "*Completions*"))
+             (and mark-active (mark) (/= (point) (mark)))))
+      (icicle-candidate-set-save-selected arg)
+    (icicle-candidate-set-save arg)))
+
+;;;###autoload
+(defun icicle-mouse-candidate-set-save-more (ignore &optional arg) ; `M-mouse-3' in `*Completions*'.
+  "`icicle-candidate-set-save-more(-selected)'.
+If the region is active in `*Completions*', then
+`icicle-candidate-set-save-more-selected'.  Otherwise,
+`icicle-candidate-set-save-more'."
+  (interactive "e\nP")
+  (if (and (get-buffer "*Completions*")
+           (save-current-buffer
+             (set-buffer (get-buffer "*Completions*"))
+             (and mark-active (mark) (/= (point) (mark)))))
+      (icicle-candidate-set-save-more-selected arg)
+    (icicle-candidate-set-save-more arg)))
+
+;;; `mouse-3' in `*Completions*'.
+(cond ((require 'mouse3 nil t)
+       (defun icicle-mouse-save-then-kill (click &optional arg)
+         "`mouse-save-then-kill', but click same place saves selected candidates."
+         (interactive "e\nP")
+         (let ((mouse3-save-then-kill-command  `(lambda (event prefix-arg)
+                                                 (icicle-mouse-candidate-set-save-more nil ,arg))))
+           (mouse-save-then-kill click))
+         (setq this-command  'mouse-save-then-kill)))
+
+      ((< emacs-major-version 24)
+       (defun icicle-mouse-save-then-kill (click &optional arg)
+         "`mouse-save-then-kill', but click same place saves selected candidates."
+         (interactive "e\nP")
+         (flet ((mouse-save-then-kill-delete-region (beg end)
+                  (icicle-mouse-candidate-set-save-more nil arg)))
+           (mouse-save-then-kill click))
+         (setq this-command  'mouse-save-then-kill)))
+
+      (t
+       ;; The only thing Icicles-specific here is replacing killing or deleting the region by a call to
+       ;; `icicle-mouse-candidate-set-save-more'.  Otherwise, this is just `mouse-save-then-kill'.
+       (defun icicle-mouse-save-then-kill (click &optional arg) ; `mouse-3' in `*Completions*'.
+         "`mouse-save-then-kill', but click same place saves selected candidates."
+         (interactive "e\nP")
+         (mouse-minibuffer-check click)
+         (let* ((posn          (event-start click))
+                (click-pt      (posn-point posn))
+                (window        (posn-window posn))
+                (buf           (window-buffer window))
+                (this-command  this-command) ; Don't let subsequent kill cmd append to this one.
+                ;; Check if the user has multi-clicked to select words/lines.
+                (click-count   (if (and (eq mouse-selection-click-count-buffer buf)
+                                        (with-current-buffer buf (mark t)))
+                                   mouse-selection-click-count
+                                 0)))
+           (cond ((not (numberp click-pt)) nil)
+                 ((and (eq last-command 'icicle-mouse-save-then-kill) ; User clicked at same position.
+                       (eq click-pt mouse-save-then-kill-posn)
+                       (eq window (selected-window)))
+                  ;; Here is the Icicles difference from vanilla `mouse-save-then-kill'.
+                  ;; Instead of killing/deleting the region, save the selected candidates.
+                  (icicle-mouse-candidate-set-save-more nil arg)
+                  (setq mouse-selection-click-count  0
+                        mouse-save-then-kill-posn    nil))
+                 ;; If there is a suitable region, adjust it by moving the closest end to CLICK-PT.
+                 ((or (with-current-buffer buf (region-active-p))
+                      (and (eq window (selected-window))
+                           (mark t)
+                           (or (and (eq last-command 'icicle-mouse-save-then-kill)
+                                    mouse-save-then-kill-posn)
+                               (and (memq last-command '(mouse-drag-region mouse-set-region))
+                                    (or mark-even-if-inactive (not transient-mark-mode))))))
+                  (select-window window)
+                  (let* ((range  (mouse-start-end click-pt click-pt click-count)))
+                    (if (< (abs (- click-pt (mark t))) (abs (- click-pt (point))))
+                        (set-mark (car range))
+                      (goto-char (nth 1 range)))
+                    (setq deactivate-mark  nil)
+                    (mouse-set-region-1)
+                    (when mouse-drag-copy-region
+                      ;; Previous region was copied to kill-ring, so replace with adjusted region.
+                      (kill-new (filter-buffer-substring (mark t) (point)) t))
+                    (setq mouse-save-then-kill-posn  click-pt))) ; Repeated `mouse-3' kills region.
+                 (t                     ; Set the mark where point is and move to CLICK-PT.
+                  (select-window window)
+                  (mouse-set-mark-fast click)
+                  (let ((before-scroll (with-current-buffer buf point-before-scroll)))
+                    (when before-scroll (goto-char before-scroll)))
+                  (exchange-point-and-mark)
+                  (mouse-set-region-1)
+                  (when mouse-drag-copy-region (kill-new (filter-buffer-substring (mark t) (point))))
+                  (setq mouse-save-then-kill-posn  click-pt)))))))
+
+;;;###autoload
+(defun icicle-candidate-set-save (&optional arg) ; Bound to `C-M->' in minibuffer.
+  "Save the set of current completion candidates, for later recall.
+Saves candidates in variable `icicle-saved-completion-candidates', by
+default.
+With a plain prefix arg (`C-u'), save candidates in a cache file.
+With a non-zero numeric prefix arg (`C-u N'), save candidates in a
+ variable for which you are prompted.
+With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
+ or later).  Use this only for file-name candidates, obviously.  To
+ subsequently use a fileset for candidate retrieval, option
+ `icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
+
+You can retrieve the saved set of candidates with `\\\
+\\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (icicle-candidate-set-save-1 icicle-completion-candidates arg))
+
+;;;###autoload
+(defun icicle-candidate-set-save-more (&optional arg) ; Bound to `C->' in minibuffer.
+  "Add current completion candidates to saved candidates set.
+The current candidates are added to those already saved.
+A prefix argument acts the same as for `icicle-candidate-set-save'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save-more]')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (icicle-candidate-set-save-1 icicle-completion-candidates arg t))
+
+;;;###autoload
+(defun icicle-candidate-set-save-selected (&optional arg) ; Bound to `C-M-)' in minibuffer.
+  "`icicle-candidate-set-save', but only for the selected candidates.
+Candidates at least partially in the region are saved.
+A prefix argument acts the same as for `icicle-candidate-set-save'.
+
+As a special case, if no candidates are selected, then this empties
+the current set of saved candidates.  That is, it UNsaves all saved
+candidates.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save-selected]')."
+  (interactive "P")
+  (icicle-candidate-set-save-selected-1 arg nil 'no-error))
+
+;;;###autoload
+(defun icicle-candidate-set-save-more-selected (&optional arg) ; Bound to `C-)' in minibuffer.
+  "`icicle-candidate-set-save-more', but only for the selected candidates.
+Candidates at least partially in the region are added to those saved.
+A prefix argument acts the same as for `icicle-candidate-set-save'.
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save-more-selected]')."
+  (interactive "P")
+  (icicle-candidate-set-save-selected-1 arg t))
+
+;; $$$$$$$ Maybe should also allow rectangle selection.
+(defun icicle-candidate-set-save-selected-1 (arg &optional morep no-error-p)
+  "Helper function for `icicle-candidate-set-save(-more)(-region)'."
+  (when (or (get-buffer-window "*Completions*" 0) no-error-p)
+    (let ((beg-cand-nb       0)
+          (end-cand-nb       0)
+          (candidates        ())
+          (icicle-orig-buff  (current-buffer)))
+      (when (get-buffer-window "*Completions*" 0) ; Do nothing if not displayed.
+        (with-current-buffer "*Completions*"
+          (when (and mark-active (mark) (/= (point) (mark)) icicle-completion-candidates)
+            (let ((bob  (icicle-start-of-candidates-in-Completions))
+                  (eob  (point-max))
+                  (beg  (region-beginning))
+                  (end  (region-end))
+                  temp)
+
+              ;; Extend region ends to include all of first and last selected candidates.
+              (unless (get-text-property beg 'mouse-face)
+                (if (setq temp  (next-single-property-change beg 'mouse-face))
+                    (setq beg  temp)
+                  (setq beg  (next-single-property-change temp 'mouse-face))))
+
+              (when (> beg end)
+                (error "No candidates selected")) ; Active region but none selected.
+
+              (unless (get-text-property end 'mouse-face)
+                (if (setq temp  (previous-single-property-change end 'mouse-face))
+                    (setq end  temp)
+                  (setq end  (previous-single-property-change temp 'mouse-face))))
+              (when (> beg end) (setq beg  (prog1 end (setq end  beg)))) ; Swap them.
+              (while (and (>= beg bob) (get-text-property beg 'mouse-face)) (setq beg  (1- beg)))
+              (while (and (<= end eob) (get-text-property end 'mouse-face)) (setq end  (1+ end)))
+              (setq beg          (1+ beg)
+                    end          (1- end)
+                    beg-cand-nb  (icicle-nb-of-cand-at-Completions-pos beg)
+                    end-cand-nb  (icicle-nb-of-cand-at-Completions-pos end))
+              (when (> beg-cand-nb end-cand-nb) ; Swap them
+                (setq beg-cand-nb  (prog1 end-cand-nb (setq end-cand-nb  beg-cand-nb))))
+              (while (<= beg-cand-nb end-cand-nb)
+                (push (elt icicle-completion-candidates beg-cand-nb) candidates)
+                (setq beg-cand-nb  (1+ beg-cand-nb)))))))
+      (when (and morep (null candidates)) (error "No candidates selected")) ; Need selection for MOREP.
+      (setq candidates  (nreverse candidates))
+      (icicle-candidate-set-save-1 candidates arg morep t no-error-p)
+      (let ((win  (get-buffer-window icicle-orig-buff 'visible)))
+        (when win (select-window win))))))
+
+(defun icicle-candidate-set-save-1 (new-cands arg &optional morep only-selected-p no-error-p)
+  "Helper function for `icicle-candidate-set-save*' functions.
+NEW-CANDS are the candidates to save.
+ARG is the same as the raw prefix arg for `icicle-candidate-set-save'.
+MOREP non-nil means add the candidates, do not replace existing set.
+ONLY-SELECTED-P non-nil means NEW-CANDS are those selected in
+ `*Completions*'.
+NO-ERROR-P non-nil means don't raise an error if NEW-CANDS is nil."
+  (unless (or new-cands no-error-p)
+    (error "Cannot save empty candidates set - did you use `S-TAB' or `TAB'?"))
+  (let (where)
+    (if arg
+        (let ((enable-recursive-minibuffers  t))
+          (cond ((consp arg)
+                 ;; Save to cache file (and to `icicle-saved-completion-candidates').
+                 (let* ((file-name
+                         (prog1 (let ((icicle-completion-candidates  icicle-completion-candidates))
+                                  (icicle-add/update-saved-completion-set))
+                           (when (minibuffer-window-active-p (minibuffer-window))
+                             (with-output-to-temp-buffer "*Completions*" ; Redisplay.
+                               (display-completion-list icicle-completion-candidates)))
+                           (select-window (minibuffer-window))))
+                        (list-buf   (and morep (find-file-noselect file-name 'nowarn 'raw)))
+                        (old-cands  ()))
+                   (when morep
+                     (unwind-protect
+                          (condition-case nil
+                              (setq old-cands  (read list-buf))
+                            (end-of-file
+                             (save-selected-window
+                               (select-window (minibuffer-window))
+                               (minibuffer-message (format "  [No completion candidates in file `%s']"
+                                                           file-name)))))
+                       (kill-buffer list-buf)))
+                   ;; Convert to readable alist form, from propertized text.  Convert any markers
+                   ;; to the form (icicle-file-marker FILE POS) or (icicle-marker BUFFER POS).
+                   (when (and new-cands (get-text-property 0 'icicle-whole-candidate (car new-cands)))
+                     (setq new-cands
+                           (mapcar (lambda (cand)
+                                     (icicle-markers-to-readable
+                                      (or (funcall icicle-get-alist-candidate-function cand) cand)))
+                                   new-cands)))
+                   (setq icicle-saved-completion-candidates  (append new-cands old-cands)
+                         where                               (format "cache file `%s'" file-name))
+                   (with-temp-message (format "Writing candidates to cache file `%s'..." file-name)
+                     (condition-case err
+                         (with-temp-file file-name
+                           (prin1 icicle-saved-completion-candidates (current-buffer)))
+                       (error (error "Could not write to cache file.  %s"
+                                     (error-message-string err)))))))
+                ((zerop (prefix-numeric-value arg))
+                 ;; Save to a fileset (and to `icicle-saved-completion-candidates').
+                 (unless (require 'filesets nil t)
+                   (error "Cannot save to a fileset - feature `filesets' not provided"))
+                 (filesets-init)
+                 (let ((icicle-completion-candidates  icicle-completion-candidates))
+                   (setq where  (completing-read "Save to fileset: " filesets-data)))
+                 (dolist (cand  new-cands) (icicle-add-file-to-fileset cand where))
+                 (when (minibuffer-window-active-p (minibuffer-window))
+                   (with-output-to-temp-buffer "*Completions*" ; Redisplay.
+                     (display-completion-list icicle-completion-candidates)))
+                 (select-window (minibuffer-window))
+                 (setq where  (format "`%s'" where)))
+                (t                      ; Save to a variable.  Prompt for the variable to use.
+                 (let* ((varname
+                         (prog1 (let ((icicle-completion-candidates
+                                       icicle-completion-candidates)
+                                      (icicle-whole-candidate-as-text-prop-p  nil))
+                                  (completing-read (if morep
+                                                       "Add candidates to variable: "
+                                                     "Save candidates in variable: ")
+                                                   icicle-saved-candidates-variables-obarray
+                                                   nil nil nil (if (boundp 'variable-name-history)
+                                                                   'variable-name-history
+                                                                 'icicle-variable-name-history)))
+                           (when (minibuffer-window-active-p (minibuffer-window))
+                             (with-output-to-temp-buffer "*Completions*"
+                               (display-completion-list icicle-completion-candidates)))
+                           (select-window (minibuffer-window))))
+                        (var  (intern varname))) ; Intern in standard `obarray'.
+                   (intern varname icicle-saved-candidates-variables-obarray) ; For completion.
+                   (set var (if (and morep (boundp var) (listp (symbol-value var)))
+                                (append new-cands (symbol-value var))
+                              new-cands))
+                   (setq where  (format "`%s'" var))))))
+      ;; Save to default variable, `icicle-saved-completion-candidates'.
+      (setq where  "`icicle-saved-completion-candidates'"
+            icicle-saved-completion-candidates
+            (if (and morep (listp icicle-saved-completion-candidates))
+                (append new-cands icicle-saved-completion-candidates)
+              new-cands)))
+    (deactivate-mark)
+    (when (and (minibuffer-window-active-p (minibuffer-window))
+               (get-buffer-window "*Completions*" 'visible))
+      (icicle-display-candidates-in-Completions))
+    (save-selected-window
+      (select-window (minibuffer-window))
+      (minibuffer-message
+       (if morep
+           (if new-cands
+               (format "  [%sandidates ADDED to %s]" (if only-selected-p "Selected c" "C") where)
+             "  [NO candidates selected to add]")
+         (if new-cands
+             (format "  [%sandidates SAVED to %s]" (if only-selected-p "Selected c" "C") where)
+           "  [Saved candidates reset to NONE]"))))))
+
+;; This is actually a top-level command, but it is in this file because it is used by
+;; `icicle-candidate-set-save-1'.
+;;
+;; We don't define this using `icicle-define-add-to-alist-command', because we want to
+;; return the cache-file name.
+;;;###autoload
+(defun icicle-add/update-saved-completion-set ()
+  "Add or update an entry in `icicle-saved-completion-sets'.
+That is, create a new saved completion set or update an existing one.
+You are prompted for the name of a set of completion candidates and
+its cache file.  By default, the cache file name is the set name
+without spaces, and with file extension `icy'.  List
+`icicle-saved-completion-sets' is updated to have an entry with these
+set and file names.  Return the cache-file name."
+  (interactive)
+  (let* ((icicle-whole-candidate-as-text-prop-p  nil)
+         (set-name                               (icicle-substring-no-properties
+                                                  (completing-read
+                                                   "Saved completion set: "
+                                                   icicle-saved-completion-sets nil nil nil
+                                                   'icicle-completion-set-history)))
+         (file-name                              ""))
+    (setq file-name  (expand-file-name
+                      (read-file-name "Cache file for the set: " default-directory nil nil
+                                      (concat (icicle-delete-whitespace-from-string set-name) ".icy"))))
+    (while (not (icicle-file-writable-p file-name))
+      (setq file-name  (expand-file-name
+                        (read-file-name
+                         "Cannot write to that file. Cache file: " default-directory nil nil
+                         (concat (icicle-delete-whitespace-from-string set-name) ".icy")))))
+    (setq icicle-saved-completion-sets  ; Remove any old definition of this set.
+          (icicle-assoc-delete-all set-name icicle-saved-completion-sets))
+    (push (cons set-name file-name) icicle-saved-completion-sets) ; Add new set definition.
+    (funcall icicle-customize-save-variable-function
+             'icicle-saved-completion-sets
+             icicle-saved-completion-sets)
+    (message "Added set to `icicle-saved-completion-sets': `%s'" set-name)
+    file-name))                         ; Return cache-file name.
+
+;; Similar to `filesets-add-buffer', but that insists on a buffer.  This is actually a top-level
+;; command, but it is in this file because it is used by `icicle-candidate-set-save-1'.
+;;;###autoload
+(defun icicle-add-file-to-fileset (&optional file name)
+  "Add FILE to the fileset called NAME.
+If FILE is nil, use file of current buffer.
+If NAME is nil, prompt for the fileset."
+  (interactive)
+  (unless (require 'filesets nil t) (error "Cannot find library `filesets'"))
+  (setq file  (or file (buffer-file-name) (and (interactive-p) (read-file-name "File to add: "
+                                                                               nil nil t))
+                  (error "Current buffer has no associated file"))
+        name  (or name (and (interactive-p) (completing-read (format "Add `%s' to fileset: " file)
+                                                             filesets-data))
+                  (error "No fileset")))
+  (let ((entry  (or (assoc name filesets-data)
+                    (and (interactive-p)
+                         (when (y-or-n-p (format "Fileset `%s' does not exist. Create it? " name))
+                           (add-to-list 'filesets-data (list name '(:files)))
+                           (message "Fileset created.  Use `M-x filesets-save-config' to save it.")
+                           (car filesets-data))))))
+    (if (not entry)
+        (when (interactive-p) (message "Operation cancelled - no fileset"))
+      (let* ((files  (filesets-entry-get-files entry)))
+        (cond ((filesets-member file files :test 'filesets-files-equalp)
+               (message "`%s' is already in fileset `%s'" file name))
+              ((and file (eq (filesets-entry-mode entry) ':files))
+               (filesets-entry-set-files entry (cons file files) t)
+               (filesets-set-config name 'filesets-data filesets-data))
+              (t (error "Cannot add file. Fileset `%s' is not of type Files (:files)" name)))))))
+
+(defun icicle-markers-to-readable (cand)
+  "Convert (serialize) candidate CAND to Lisp-readable representation.
+CAND is a full completion candidate (collection alist entry).
+A Lisp-readable candidate uses one of the following forms to represent
+a marker:
+  (icicle-file-marker  FILE-NAME    MARKER-POSITION)
+  (icicle-marker       BUFFER-NAME  MARKER-POSITION)"
+  (if (atom cand)
+      (if (markerp cand)
+          (let ((buf  (marker-buffer cand)))
+            (unless buf (error "Marker in no buffer"))
+            (list (if (buffer-file-name buf) 'icicle-file-marker 'icicle-marker)
+                  (or (buffer-file-name buf) (buffer-name buf))
+                  (marker-position cand)))
+        cand)
+    (cons (icicle-markers-to-readable (car cand)) (icicle-markers-to-readable (cdr cand)))))
+
+;;;###autoload
+(defun icicle-candidate-set-save-to-variable () ; Bound to `C-M-}' in minibuffer.
+  "Save the set of current completion candidates in a variable you choose.
+You can retrieve the saved set of candidates with `\\\
+\\[icicle-candidate-set-retrieve-from-variable]' (or `\\[icicle-candidate-set-retrieve]'
+with a numeric prefix arg).
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save-to-variable]')."
+  (interactive)
+  (icicle-candidate-set-save 99))
+
+;;;###autoload
+(defun icicle-candidate-set-save-persistently (filesetp) ; Bound to `C-}' in minibuffer.
+  "Save the set of current completion candidates persistently.
+With no prefix arg, save in a cache file.
+With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
+
+You can retrieve the saved set of candidates with `\\\
+\\[icicle-candidate-set-retrieve-persistent]' or `C-u \\[icicle-candidate-set-retrieve]'.
+You can use the saved set of candidates for operations such as
+\\
+`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
+`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
+`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
+
+You can use this command only from the minibuffer (`\\\
+\\[icicle-candidate-set-save-persistently]')."
+  (interactive "P")
+  (icicle-candidate-set-save (if filesetp 0 '(1))))
+
+;;;###autoload
+(defun icicle-keep-only-past-inputs (&optional recent-first) ; Bound to`M-pause' in minibuffer.
+  "Narrow completion candidates to those that have been used previously.
+This filters the set of current completion candidates, keeping only
+those that have been used before.  (You must first use `TAB' or
+`S-TAB' to establish an explicit candidate set.)
+
+With a prefix arg, the previous inputs are sorted chronologically,
+most recent first.
+
+Note that whatever completion mode (prefix or apropos) was in effect
+before you use `\\\
+\\[icicle-keep-only-past-inputs]' remains in \ effect for
+`icicle-keep-only-past-inputs'.  This command does not use a recursive
+minibuffer; it simply co-opts the current completion, changing it to
+completion against the history.
+
+You can use this command only from the minibuffer \
+\(`\\[icicle-keep-only-past-inputs]').
+
+See also `\\[icicle-history]' (`icicle-history')."
+  (interactive "P")
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (if (and recent-first (interactive-p) icicle-inhibit-sort-p)
+      (icicle-msg-maybe-in-minibuffer "Cannot sort candidates now")
+    (let ((icicle-sort-comparer  (if recent-first 'icicle-most-recent-first-p icicle-sort-comparer)))
+      (when (or recent-first (eq icicle-last-completion-command 'icicle-keep-only-past-inputs))
+        (icicle-complete-again-update 'no-display))
+      (if (null icicle-completion-candidates)
+          (minibuffer-message "  [No completion candidates to filter]")
+        (unless (boundp minibuffer-history-variable) (set minibuffer-history-variable nil))
+        (when (consp (symbol-value minibuffer-history-variable))
+          (setq icicle-completion-candidates
+                (icicle-remove-if-not
+                 (lambda (candidate)
+                   (when (icicle-file-name-input-p)
+                     (setq candidate  (expand-file-name
+                                       candidate (icicle-file-name-directory icicle-last-input))))
+                   (member candidate (symbol-value minibuffer-history-variable)))
+                 icicle-completion-candidates))
+          (cond ((null icicle-completion-candidates)
+                 (save-selected-window (icicle-remove-Completions-window))
+                 (minibuffer-message "  [None of the completions have been used before]"))
+                (t
+                 (cond ((and (symbolp last-command) (get last-command 'icicle-cycling-command))
+                        (setq icicle-current-input  icicle-last-input)
+                        (icicle-retrieve-last-input))
+                       (t
+                        (setq icicle-current-input  (icicle-input-from-minibuffer))))
+                 (cond ((null icicle-completion-candidates)
+                        (setq icicle-nb-of-other-cycle-candidates  0)
+                        (save-selected-window (icicle-remove-Completions-window))
+                        (minibuffer-message "  [No matching history element]"))
+                       ((null (cdr icicle-completion-candidates)) ; Single cand. Update minibuffer.
+                        (setq icicle-nb-of-other-cycle-candidates  0)
+                        (icicle-clear-minibuffer)
+                        (setq icicle-last-completion-candidate  (car icicle-completion-candidates))
+                        (let ((inserted  (if (and (icicle-file-name-input-p) insert-default-directory
+                                                  (or (not (member icicle-last-completion-candidate
+                                                                   icicle-extra-candidates))
+                                                      icicle-extra-candidates-dir-insert-p))
+                                             (icicle-abbreviate-or-expand-file-name
+                                              icicle-last-completion-candidate
+                                              (icicle-file-name-directory-w-default
+                                               icicle-current-input))
+                                           icicle-last-completion-candidate)))
+                          (insert inserted))
+                        (save-selected-window (icicle-remove-Completions-window))
+                        (icicle-highlight-complete-input)
+                        (icicle-show-help-in-mode-line icicle-last-completion-candidate)
+                        (minibuffer-message (format "  [One matching history element]")))
+                       (t
+                        (when (member icicle-current-input icicle-completion-candidates)
+                          (icicle-highlight-complete-input)
+                          (icicle-show-help-in-mode-line icicle-current-input))
+                        (icicle-display-candidates-in-Completions)
+                        (save-window-excursion
+                          (select-window (active-minibuffer-window))
+                          (minibuffer-message
+                           (concat "  [Filtered to (matching) historical candidates"
+                                   (and recent-first ", most recent first")
+                                   "]")))))
+                 (setq icicle-last-completion-command  'icicle-keep-only-past-inputs)))))
+      icicle-completion-candidates)))
+
+;;;###autoload
+(defun icicle-other-history (arg)       ; Bound to `C-M-pause' in minibuffer.
+  "Choose a history, or complete against `icicle-interactive-history'.
+For Emacs 23 or later, if no prefix arg and you are completing a
+  command, abbrev, or keyboard macro name, then complete against
+  (non-nil) `icicle-interactive-history'.
+Otherwise, prompt with completion for a minibuffer history to use.
+  The history choice lasts only for the current (main) completion.
+  (To then complete against this history, use `M-h'.)"
+  (interactive "P")
+  (if (and (> emacs-major-version 22)
+           (memq minibuffer-history-variable
+                 '(extended-command-history icicle-command-abbrev-history icicle-kmacro-history))
+           (not arg)
+           icicle-interactive-history)
+      (icicle-use-interactive-command-history)
+    (call-interactively #'icicle-change-history-variable)))
+
+;;;###autoload
+(defun icicle-use-interactive-command-history ()
+  "Complete input against `icicle-interactive-history'.
+This is a history of all Emacs commands called interactively.
+This history is available only for Emacs 23 and later, and only if
+option `icicle-populate-interactive-history-flag' is not nil."
+  (interactive)
+  (icicle-change-history-variable "icicle-interactive-history")
+  (icicle-history))
+
+;;;###autoload
+(defun icicle-change-history-variable (hist-var)
+  "Choose a history variable to use now for `minibuffer-history-variable'.
+Use completion to choose the history to use.
+The choice lasts only for the current (main) completion.
+Non-interactively, arg HIST-VAR is the (string) name of a history var."
+  (interactive
+   (let ((enable-recursive-minibuffers  t)
+         (icicle-hist-vars              `((,(symbol-name minibuffer-history-variable))
+                                          (,(symbol-name 'icicle-previous-raw-file-name-inputs))
+                                          (,(symbol-name 'icicle-previous-raw-non-file-name-inputs)))))
+     (when (and (boundp 'icicle-populate-interactive-history-flag) ; Emacs 23+.
+                icicle-populate-interactive-history-flag)
+       (push (symbol-name 'icicle-interactive-history)  icicle-hist-vars))
+     (mapatoms (lambda (x) (when (and (boundp x) (consp (symbol-value x))
+                                      (stringp (car (symbol-value x)))
+                                      (string-match "-\\(history\\|ring\\)\\'" (symbol-name x)))
+                             (push (list (symbol-name x)) icicle-hist-vars))))
+     (list (completing-read "Use history: " icicle-hist-vars nil t nil nil nil))))
+  (when (interactive-p) (icicle-barf-if-outside-Completions-and-minibuffer))
+  (setq minibuffer-history-variable  (intern hist-var)))
+
+;;;###autoload
+(defun icicle-scroll-forward (&optional arg) ; `C-M-v' in minibuffer.
+  "Scroll `icicle-other-window' forward."
+  (interactive "P")
+  (let ((win  (if (window-live-p icicle-other-window)
+                  icicle-other-window
+                (if (window-live-p icicle-orig-window)
+                    icicle-orig-window
+                  (get-buffer-window "*Completions*" 0)))))
+    (when win (save-selected-window (select-window win) (scroll-up arg)))))
+
+;;;###autoload
+(defun icicle-scroll-backward (&optional arg) ; `C-M-S-v' (aka `C-M-V') in minibuffer.
+  "Scroll `icicle-other-window' backward."
+  (interactive "P")
+  (let ((win  (if (window-live-p icicle-other-window)
+                  icicle-other-window
+                (if (window-live-p icicle-orig-window)
+                    icicle-orig-window
+                  (get-buffer-window "*Completions*" 0)))))
+    (when win (save-selected-window (select-window win) (scroll-down arg)))))
+
+;;;###autoload
+(defun icicle-scroll-Completions-forward (&optional reverse) ; `C-v' minib; `wheel-down' *Completions*.
+  "Scroll the `*Completions*' window forward.
+With a prefix argument, or if `icicle-scroll-Completions-reverse-p' is
+non-nil, scroll backward."
+  (interactive "P")
+  (when (get-buffer-window "*Completions*" 0)
+    (save-selected-window
+      (select-window (get-buffer-window "*Completions*" 0))
+      (when (if (interactive-p) reverse current-prefix-arg) ; Non-interactive use is for `TAB', `S-TAB'.
+        (setq icicle-scroll-Completions-reverse-p  (not icicle-scroll-Completions-reverse-p)))
+      (cond (icicle-scroll-Completions-reverse-p
+             (if (not (= (window-start) (point-min)))
+                 (scroll-down nil)
+               (unless (= (window-end) (point-max))
+                 (goto-char (point-max))
+                 (scroll-down (1- (/ (window-height) 2)))
+                 (beginning-of-line))))
+            (t
+             (if (not (= (window-end) (point-max)))
+                 (scroll-up nil)
+               (unless (= (window-start) (point-min))
+                 (goto-char (icicle-start-of-candidates-in-Completions)))))))))
+
+;;;###autoload
+(defun icicle-scroll-Completions-backward () ; `M-v' in minibuf; `wheel-up' in `*Completions*'.
+  "Scroll the `*Completions*' window backward.
+If `icicle-scroll-Completions-reverse-p' is non-nil, scroll forward."
+  (interactive)
+  (let ((icicle-scroll-Completions-reverse-p  (not icicle-scroll-Completions-reverse-p)))
+    (icicle-scroll-Completions-forward)))
+
+;;;###autoload
+(defun icicle-history ()                ; Bound to `M-h' in minibuffer.
+  "Access the appropriate history list using completion or cycling.
+Complete the current minibuffer input against items in the history
+list that is in use for the current command.
+
+NOTE:
+
+1. If the required input is a file or directory name, then the entire
+minibuffer input is what is matched against the history list.  The
+reason for this is that file names in the history list are usually
+absolute.  This is unlike the case for normal file-name completion,
+which assumes the default directory.
+
+Keep this in mind for apropos (regexp) completion; it means that to
+match a file-name using a substring you must, in the minibuffer,
+either not specify a directory or explicitly use \".*\" before the
+file-name substring.
+
+For example, `/foo/bar/lph' will not apropos-match the previously
+input file name `/foo/bar/alphabet-soup.el'; you should use either
+`/foo/bar/.*lph' or `lph' (no directory).
+
+2. This also represents a difference in behavior compared to the
+similar command `icicle-keep-only-past-inputs' \
+\(`\\\
+\\[icicle-keep-only-past-inputs]' in the
+minibuffer).  That command simply filters the current set of
+completion candidates, which in the case of file-name completion is a
+set of relative file names.
+
+3. Whatever completion mode (prefix or apropos) was in effect before
+you use `\\\ \\[icicle-history]' remains in \
+effect for `icicle-history'.  This command
+does not use a recursive minibuffer; it simply co-opts the current
+completion, changing it to completion against the history.
+
+You can use this command only from the minibuffer \
+\(`\\[icicle-history]').
+
+See also `\\[icicle-keep-only-past-inputs]' (`icicle-keep-only-past-inputs')."
+  (interactive)
+  (when (interactive-p) (icicle-barf-if-outside-minibuffer))
+  (when (icicle-file-name-input-p)
+    (setq minibuffer-completion-predicate  nil
+          minibuffer-completing-file-name  nil))
+  (when (and (arrayp minibuffer-completion-table) minibuffer-completion-predicate)
+    (setq minibuffer-completion-predicate
+          `(lambda (elt) (funcall ',minibuffer-completion-predicate
+                          (intern (if (consp elt) (car elt) elt))))))
+  (when (and (boundp minibuffer-history-variable) (consp (symbol-value minibuffer-history-variable)))
+    (setq minibuffer-completion-table
+          (mapcar #'list (icicle-remove-duplicates
+                          ;; `command-history' is an exception: its entries are not strings.
+                          (if (eq 'command-history minibuffer-history-variable)
+                              (mapcar #'prin1-to-string (symbol-value minibuffer-history-variable))
+                            (symbol-value minibuffer-history-variable))))))
+  (save-selected-window (unless icicle-last-completion-command (icicle-apropos-complete)))
+  (cond (icicle-cycling-p ;; $$$ (and (symbolp last-command) (get last-command 'icicle-cycling-command))
+         (setq icicle-current-input  icicle-last-input)
+         (icicle-retrieve-last-input))
+        (t
+         (setq icicle-current-input  (icicle-input-from-minibuffer)
+               icicle-last-input     nil ; So `icicle-save-or-restore-input' thinks input has changed.
+               last-command          'icicle-history)
+         (funcall (or icicle-last-completion-command 'icicle-apropos-complete)))))
+
+;; Not actually a minibuffer command, since `isearch' technically uses the echo area.  This is not
+;; shadowed by any `icicle-mode-map' binding, since `isearch-mode-map' is also a minor mode map.
+;;;###autoload
+(defun icicle-isearch-complete ()       ; Bound to `M-TAB' and `M-o' in `isearch-mode-map'.
+  "Complete the search string using candidates from the search ring."
+  (interactive)
+  (cond ((icicle-completing-p)          ; Cannot use the var here, since not sure to be in minibuf.
+         (setq isearch-string  (if (fboundp 'field-string) (field-string) (buffer-string)))
+         (when (icicle-isearch-complete-past-string)
+           (if (fboundp 'delete-field) (delete-field) (erase-buffer))
+           (insert isearch-string)))
+        (t
+         (icicle-isearch-complete-past-string)
+         (setq isearch-message  (mapconcat 'isearch-text-char-description isearch-string ""))
+         (isearch-edit-string))))
+
+(when (fboundp 'text-scale-increase)    ; Bound to `C-x -' in the minibuffer (Emacs 23+).
+  (defun icicle-doremi-zoom-Completions+ (&optional increment)
+    "Zoom the text in buffer `*Completions*' incrementally.
+Use `=', `-', or the mouse wheel to increase or decrease text
+size.  You can use the `Meta' key (`M-=' or `M--') to increment in
+larger steps."
+    (interactive "p")
+    (unless (require 'doremi-frm nil t) (error "This command needs library `doremi-frm.el'."))
+    (unless (get-buffer-window "*Completions*" 'visible)
+      (if icicle-completion-candidates
+          (icicle-display-candidates-in-Completions)
+        (icicle-msg-maybe-in-minibuffer "Did you hit `TAB' or `S-TAB'?")))
+    (let ((mini  (active-minibuffer-window)))
+      (unwind-protect
+           (save-selected-window
+             (select-window (get-buffer-window "*Completions*" 'visible))
+             (let ((enable-recursive-minibuffers  t)
+                   (doremi-up-keys                '(?=))
+                   (doremi-down-keys              '(?-))
+                   (doremi-boost-up-keys          '(?\M-=))
+                   (doremi-boost-down-keys        '(?\M--)))
+               (doremi-buffer-font-size+ increment))
+             (setq unread-command-events  ()))
+        (unless mini (icicle-remove-Completions-window))))))
+
+;;;###autoload
+(defun icicle-doremi-candidate-width-factor+ (&optional increment) ; Bound to `C-x w' in minibuffer.
+  "Change `icicle-candidate-width-factor' incrementally.
+Use `right', `left' or mouse wheel to increase or decrease.  You can
+use the `Meta' key (e.g. `M-right') to increment in larger steps.
+
+Use `up', `down', or the mouse wheel to adjust
+`icicle-inter-candidates-min-spaces'."
+  (interactive "p")
+  (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))
+  (let ((mini  (active-minibuffer-window)))
+    (unwind-protect
+         (save-selected-window
+           (select-window (minibuffer-window))
+           (unless icicle-completion-candidates (message "Hit `TAB' or `S-TAB'"))
+           (let ((enable-recursive-minibuffers  t)
+                 (doremi-up-keys                '(left)) ; Rebind, so more intuitive for width.
+                 (doremi-boost-up-keys          '(M-left))
+                 (doremi-down-keys              '(right))
+                 (doremi-boost-down-keys        '(M-right)))
+             (doremi (lambda (new-val)
+                       (setq new-val                        (doremi-wrap new-val 1 100)
+                             icicle-candidate-width-factor  new-val)
+                       (icicle-display-candidates-in-Completions)
+                       new-val)
+                     icicle-candidate-width-factor
+                     (- increment)))    ; Reverse, so arrows correspond.
+           (when (member (car unread-command-events)
+                         (append doremi-up-keys   doremi-boost-up-keys 
+                                 doremi-down-keys doremi-boost-down-keys))
+             (icicle-doremi-inter-candidates-min-spaces+ increment))
+           (setq unread-command-events  ()))
+      (unless mini (icicle-remove-Completions-window)))))
+
+;;;###autoload
+(defun icicle-doremi-inter-candidates-min-spaces+ (&optional increment) ; Bound to `C-x |' in minibuf.
+  "Change `icicle-inter-candidates-min-spaces' incrementally.
+Use `up', `down' or the mouse wheel to increase or decrease.  You can
+ use the `Meta' key (e.g. `M-right') to increment in larger steps.
+Use `left', `right', or the mouse wheel to adjust
+`icicle-candidate-width-factor'."
+  (interactive "p")
+  (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))
+  (let ((mini  (active-minibuffer-window)))
+    (unwind-protect
+         (save-selected-window
+           (select-window (minibuffer-window))
+           (unless icicle-completion-candidates (message "Hit `TAB' or `S-TAB'"))
+           (let* ((enable-recursive-minibuffers  t))
+             (doremi (lambda (new-val)
+                       (setq new-val                             (doremi-limit new-val 1 nil)
+                             icicle-inter-candidates-min-spaces  new-val)
+                       (icicle-display-candidates-in-Completions)
+                       new-val)
+                     icicle-inter-candidates-min-spaces
+                     increment))
+           (when (member (car unread-command-events)'(left right M-left M-right))
+             (icicle-doremi-candidate-width-factor+ increment))
+           (setq unread-command-events  ()))
+      (unless mini (icicle-remove-Completions-window)))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-WYSIWYG-Completions 'icicle-toggle-WYSIWYG-Completions)
+;;;###autoload
+(defun icicle-toggle-WYSIWYG-Completions ()
+  "Toggle the value of option `icicle-WYSIWYG-Completions-flag'."
+  (interactive)
+  (setq icicle-WYSIWYG-Completions-flag  (not icicle-WYSIWYG-Completions-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-WYSIWYG-Completions-flag
+                                      "Using WYSIWYG for `*Completions*' display is now ON"
+                                    "Using WYSIWYG for `*Completions*' display is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-~-for-home-dir 'icicle-toggle-~-for-home-dir)
+;;;###autoload
+(defun icicle-toggle-~-for-home-dir ()  ; Bound to `M-~' in minibuffer.
+  "Toggle the value of option `icicle-use-~-for-home-dir-flag'.
+Bound to `M-~' in the minibuffer."
+  (interactive)
+  (setq icicle-use-~-for-home-dir-flag  (not icicle-use-~-for-home-dir-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-use-~-for-home-dir-flag
+                                      "Using `~' for home directory is now ON"
+                                    "Using `~' for home directory is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-C-for-actions 'icicle-toggle-C-for-actions)
+;;;###autoload
+(defun icicle-toggle-C-for-actions ()   ; Bound to `M-g' in minibuffer.
+  "Toggle the value of option `icicle-use-C-for-actions-flag'.
+Bound to `M-g' in the minibuffer."
+  (interactive)
+  (setq icicle-use-C-for-actions-flag  (not icicle-use-C-for-actions-flag))
+  (icicle-toggle-icicle-mode-twice)
+  (icicle-msg-maybe-in-minibuffer (if icicle-use-C-for-actions-flag
+                                      "Using `C-' prefix for multi-command actions is now ON"
+                                    "Using `C-' prefix for multi-command actions is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-alternative-sorting 'icicle-toggle-alternative-sorting)
+;;;###autoload
+(defun icicle-toggle-alternative-sorting () ; Bound to `C-M-,' in minibuffer.
+  "Toggle alternative sorting of minibuffer completion candidates.
+This swaps `icicle-alternative-sort-comparer' and `icicle-sort-comparer'.
+Bound to `C-M-,' in the minibuffer."
+  (interactive)
+  (let ((alt-sort-fn  icicle-alternative-sort-comparer))
+    (setq icicle-alternative-sort-comparer  (or icicle-sort-comparer icicle-last-sort-comparer)
+          icicle-sort-comparer              (or alt-sort-fn icicle-last-sort-comparer))
+    (icicle-complete-again-update)
+    (icicle-msg-maybe-in-minibuffer
+     (format "Sorting: `%s', Alternative: `%s'"
+             icicle-sort-comparer icicle-alternative-sort-comparer))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-sorting 'icicle-toggle-sorting)
+;;;###autoload
+(defun icicle-toggle-sorting ()         ; Not bound to a key.
+  "Toggle sorting of minibuffer completion candidates.
+When sorting is active, comparison is done by `icicle-sort-comparer'."
+  (interactive)
+  (if (and (interactive-p) icicle-inhibit-sort-p)
+      (icicle-msg-maybe-in-minibuffer "Cannot sort candidates now")
+    (if icicle-sort-comparer
+        (setq icicle-last-sort-comparer  icicle-sort-comparer ; Save it, for restoring.
+              icicle-sort-comparer       nil)
+      (setq icicle-sort-comparer  icicle-last-sort-comparer)) ; Restore it.
+    (icicle-complete-again-update)
+    (icicle-msg-maybe-in-minibuffer (if icicle-sort-comparer
+                                        "Completion-candidate sorting is now ON"
+                                      "Completion-candidate sorting is now OFF"))))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-angle-brackets 'icicle-toggle-angle-brackets)
+;;;###autoload
+(defun icicle-toggle-angle-brackets ()
+  "Toggle `icicle-key-descriptions-use-<>-flag'."
+  (interactive)
+  (setq icicle-key-descriptions-use-<>-flag  (not icicle-key-descriptions-use-<>-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-key-descriptions-use-<>-flag
+                                      "Displaying <...> in key descriptions is now ON"
+                                    "Displaying <...> in key descriptions is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-proxy-candidates 'icicle-toggle-proxy-candidates)
+;;;###autoload
+(defun icicle-toggle-proxy-candidates () ; Bound to `C-M-_' in minibuffer.
+  "Toggle `icicle-add-proxy-candidates-flag'.
+Bound to `\\\\[icicle-toggle-proxy-candidates]' in the minibuffer.
+With some commands, you must re-invoke the command for the new value
+to take effect.  (This is for performance reasons.)"
+  (interactive)
+  (setq icicle-add-proxy-candidates-flag  (not icicle-add-proxy-candidates-flag)
+        icicle-saved-proxy-candidates     (prog1 icicle-proxy-candidates
+                                            (setq icicle-proxy-candidates
+                                                  icicle-saved-proxy-candidates)))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-add-proxy-candidates-flag
+                                      "Including proxy candidates is now ON"
+                                    "Including proxy candidates is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-transforming 'icicle-toggle-transforming)
+;;;###autoload
+(defun icicle-toggle-transforming ()    ; Bound to `C-$' in minibuffer.
+  "Toggle transforming of minibuffer completion candidates.
+When transforming is active, it is done by `icicle-transform-function'.
+
+By default, transformation, if active, simply removes duplicate
+candidates.  Icicles commands already \"do the right thing\" when it
+comes to duplicate removal, so you might never need this command.
+
+Bound to `C-$' in the minibuffer."
+  (interactive)
+  (if icicle-transform-function
+      (setq icicle-last-transform-function  icicle-transform-function ; Save it, for restoring.
+            icicle-transform-function       nil)
+    (setq icicle-transform-function  icicle-last-transform-function)) ; Restore it.
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-transform-function
+                                      "Completion-candidate transformation is now ON"
+                                    "Completion-candidate transformation is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-incremental-completion 'icicle-toggle-incremental-completion)
+;;;###autoload
+(defun icicle-toggle-incremental-completion () ; Bound to `C-#' in minibuffer.
+  "Toggle the value of option `icicle-incremental-completion-flag'.
+If the current value is t or `always', then it is set to nil.
+If the current value is nil, then it is set to t.
+This command never sets the value to non-nil and non-t.
+
+Bound to `C-#' in the minibuffer."
+  (interactive)
+  (setq icicle-incremental-completion-flag  (not icicle-incremental-completion-flag)
+        icicle-incremental-completion-p     icicle-incremental-completion-flag)
+  (icicle-msg-maybe-in-minibuffer (if icicle-incremental-completion-flag
+                                      "Incremental completion is now ON"
+                                    "Incremental completion is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-expand-to-common-match 'icicle-toggle-expand-to-common-match)
+;;;###autoload
+(defun icicle-toggle-expand-to-common-match () ; Bound to `C-;' in minibuffer.
+  "Toggle the value of `icicle-expand-input-to-common-match-flag'.
+Bound to `C-;' in the minibuffer."
+  (interactive)
+  (setq icicle-expand-input-to-common-match-flag  (not icicle-expand-input-to-common-match-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-expand-input-to-common-match-flag
+                                      "Expanding input to common match is now ON"
+                                    "Expanding input to common match is now OFF")))
+
+;;;###autoload
+(defun icicle-dispatch-C-^ ()           ; Bound to `C-^' in minibuffer.
+  "Do the right thing for `C-^'
+When Icicles searching, call `icicle-toggle-highlight-all-current'.
+Otherwise, call `icicle-toggle-remote-file-testing'.
+Bound to `C-^' in the minibuffer."
+  (interactive)
+  (if icicle-searching-p (icicle-toggle-highlight-all-current) (icicle-toggle-remote-file-testing)))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-remote-file-testing 'icicle-toggle-remote-file-testing)
+;;;###autoload
+(defun icicle-toggle-remote-file-testing () ; Bound to `C-^' in minibuffer.
+  "Toggle `icicle-test-for-remote-files-flag'.
+If you use Tramp for accessing remote files, then turning this off
+also turns off Tramp file-name completion.  Therefore, if you use this
+command to turn off testing of remote file names, then use it also to
+turn testing back on (instead of just setting the option to non-nil).
+
+Bound to `C-^' in the minibuffer, except during Icicles searching."
+  (interactive)
+  (setq icicle-test-for-remote-files-flag  (not icicle-test-for-remote-files-flag))
+  (when (require 'tramp nil t)
+    (if (not icicle-test-for-remote-files-flag)
+        (tramp-unload-file-name-handlers) ; Turn off Tramp remote file-name completion.
+      ;; Bind `partial-completion-mode' to force Tramp file-name handlers unconditionally, for older
+      ;; Tramp versions than 2.1 (ugly HACK).  This code should work for all Tramp versions.
+      (let ((non-essential            t) ; Emacs 23.2+
+            (partial-completion-mode  t))
+        (condition-case nil
+            (tramp-register-file-name-handlers) ; Emacs 22+
+          (void-function
+           (tramp-register-file-name-handler) ; The order of these two matters.
+           (tramp-register-completion-file-name-handler))))))
+  (message "Updating completions...")
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-test-for-remote-files-flag
+                                      "Testing remote file names is now ON"
+                                    "Testing remote file names is now OFF")))
+
+;; NOT a top-level command (most toggle commands can be used at top-level).
+;;;###autoload
+(defalias 'toggle-icicle-highlight-all-current 'icicle-toggle-highlight-all-current)
+;;;###autoload
+(defun icicle-toggle-highlight-all-current () ; Bound to `C-^' in minibuffer.
+  "Toggle `icicle-search-highlight-all-current-flag'.
+Bound to `C-^' in the minibuffer during Icicles searching (only)."
+  (interactive)
+  (icicle-barf-if-outside-Completions-and-minibuffer)
+  (setq icicle-search-highlight-all-current-flag  (not icicle-search-highlight-all-current-flag))
+  ;; Rehighlight to see effect of toggle.
+  (let ((icicle-candidate-nb  icicle-candidate-nb))
+    (let ((icicle-current-input             icicle-current-input)
+          (icicle-incremental-completion-p  nil))
+      (icicle-erase-minibuffer))
+    (icicle-retrieve-last-input)
+    (funcall (or icicle-last-completion-command  (if (eq icicle-current-completion-mode 'prefix)
+                                                     #'icicle-prefix-complete
+                                                   #'icicle-apropos-complete))))
+  (icicle-search-highlight-all-input-matches icicle-current-input)
+  (when icicle-candidate-nb (icicle-search-action "DUMMY")) ; Get back to current.
+  (select-window (minibuffer-window))
+  (select-frame-set-input-focus (selected-frame))
+  (icicle-msg-maybe-in-minibuffer
+   (if icicle-search-highlight-all-current-flag
+       "Highlighting current input match in each main search hit is now ON"
+     "Highlighting current input match in each main search hit is now OFF")))
+
+;;;###autoload
+(defun icicle-dispatch-C-x. (arg)       ; Bound to `C-x .' in minibuffer.
+  "Do the right thing for `C-x .'.
+With a prefix arg, call `icicle-toggle-hiding-non-matching-lines'.
+With no prefix arg, call `icicle-toggle-hiding-common-match'.
+Bound to `C-x .' in the minibuffer."
+  (interactive "P")
+  (if arg (icicle-toggle-hiding-non-matching-lines) (icicle-toggle-hiding-common-match)))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-hiding-common-match 'icicle-toggle-hiding-common-match)
+;;;###autoload
+(defun icicle-toggle-hiding-common-match () ; Bound to `C-x .' in minibuffer.
+  "Toggle `icicle-hide-common-match-in-Completions-flag'.
+Bound to `C-x .' (no prefix arg) in the minibuffer.
+See also option `icicle-hide-non-matching-lines-flag'."
+  (interactive)
+  (setq icicle-hide-common-match-in-Completions-flag
+        (not icicle-hide-common-match-in-Completions-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-hide-common-match-in-Completions-flag
+                                      "Hiding common match in `*Completions*' is now ON"
+                                    "Hiding common match in `*Completions*' is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-hiding-non-matching-lines 'icicle-toggle-hiding-non-matching-lines)
+;;;###autoload
+(defun icicle-toggle-hiding-non-matching-lines () ; Bound to `C-u C-x .' in minibuffer.
+  "Toggle `icicle-hide-non-matching-lines-flag'.
+Bound to `C-u C-x .' in the minibuffer.
+See also option `icicle-hide-common-match-in-Completions-flag'."
+  (interactive)
+  (setq icicle-hide-non-matching-lines-flag  (not icicle-hide-non-matching-lines-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer
+   (if icicle-hide-non-matching-lines-flag
+       "Hiding non-matching candidate lines in `*Completions*' is now ON"
+     "Hiding non-matching candidate lines in `*Completions*' is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-show-multi-completion 'icicle-toggle-show-multi-completion)
+;;;###autoload
+(defun icicle-toggle-show-multi-completion () ; Bound to `M-m' in minibuffer.
+  "Toggle `icicle-show-multi-completion-flag'.
+Bound to `M-m' in the minibuffer."
+  (interactive)
+  (setq icicle-show-multi-completion-flag  (not icicle-show-multi-completion-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer
+   (if icicle-show-multi-completion-flag
+       "Showing multi-completions (when available) is now ON"
+     "Showing multi-completions (when available) is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-ignored-space-prefix 'icicle-toggle-ignored-space-prefix)
+;;;###autoload
+(defun icicle-toggle-ignored-space-prefix () ; Bound to `M-_' in minibuffer, except when searching.
+  "Toggle `icicle-ignore-space-prefix-flag'.
+Bound to `M-_' in the minibuffer, except during Icicles searching.
+
+Note: If the current command binds `icicle-ignore-space-prefix-flag'
+locally, then it is the local, not the global, value that is changed.
+For example, `icicle-buffer' binds it to the value of
+`icicle-buffer-ignore-space-prefix-flag'.  If that is non-nil, then
+\\`\\[icicle-toggle-ignored-space-prefix]' toggles \
+`icicle-ignore-space-prefix-flag' to nil only for the
+duration of `icicle-buffer'."
+  (interactive)
+  (setq icicle-ignore-space-prefix-flag  (not icicle-ignore-space-prefix-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-ignore-space-prefix-flag
+                                      "Ignoring space prefix is now ON"
+                                    "Ignoring space prefix is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-highlight-historical-candidates
+    'icicle-toggle-highlight-historical-candidates)
+;;;###autoload
+(defun icicle-toggle-highlight-historical-candidates () ; Bound to `C-pause' in minibuffer.
+  "Toggle `icicle-highlight-historical-candidates-flag'.
+Bound to `C-pause' in the minibuffer."
+  (interactive)
+  (setq icicle-highlight-historical-candidates-flag  (not icicle-highlight-historical-candidates-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer
+   (if icicle-highlight-historical-candidates-flag
+       "Highlighting previously used inputs in `*Completions*' is now ON"
+     "Highlighting previously used inputs in `*Completions*' is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-highlight-saved-candidates
+    'icicle-toggle-highlight-saved-candidates)
+;;;###autoload
+(defun icicle-toggle-highlight-saved-candidates () ; Bound to `S-pause' in minibuffer.
+  "Toggle `icicle-highlight-saved-candidates-flag'.
+Bound to `S-pause' in the minibuffer."
+  (interactive)
+  (setq icicle-highlight-saved-candidates-flag  (not icicle-highlight-saved-candidates-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer
+   (if icicle-highlight-saved-candidates-flag
+       "Highlighting saved candidates in `*Completions*' is now ON"
+     "Highlighting saved candidates in `*Completions*' is now OFF")))
+
+;;;###autoload
+(defun icicle-dispatch-C-. ()           ; Bound to `C-.' in minibuffer.
+  "Do the right thing for `C-.'.
+When using Icicles search (`icicle-search' and similar commands), call
+ `icicle-toggle-search-cleanup'.
+Otherwise, call `icicle-toggle-ignored-extensions'.
+
+Bound to `C-.' in the minibuffer."
+  (interactive)
+  (if icicle-searching-p (icicle-toggle-search-cleanup) (icicle-toggle-ignored-extensions)))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-ignored-extensions 'icicle-toggle-ignored-extensions)
+;;;###autoload
+(defun icicle-toggle-ignored-extensions () ; Bound to `C-.' in minibuffer except in Icicles search.
+  "Toggle respect of `completion-ignored-extensions'.
+Bound to `C-.' in minibuffer during file-name input."
+  (interactive)
+  (if (consp completion-ignored-extensions)
+      (setq icicle-saved-ignored-extensions   completion-ignored-extensions ; Save it.
+            completion-ignored-extensions     ()
+            icicle-ignored-extensions-regexp  nil)
+    (setq completion-ignored-extensions  icicle-saved-ignored-extensions ; Restore it.
+          icicle-ignored-extensions-regexp ; Make regexp for ignored file extensions.
+          (concat "\\(" (mapconcat #'regexp-quote completion-ignored-extensions "$\\|") "$\\)\\'")))
+  ;; Flag to prevent updating `icicle-ignored-extensions-regexp' unless
+  ;; `completion-ignored-extensions' changes.
+  (setq icicle-ignored-extensions  completion-ignored-extensions)
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if completion-ignored-extensions
+                                      "Ignoring selected file extensions is now ON"
+                                    "Ignoring selected file extensions is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-search-cleanup 'icicle-toggle-search-cleanup)
+;;;###autoload
+(defun icicle-toggle-search-cleanup ()  ; Bound to `C-.' in minibuffer during Icicles search.
+  "Toggle removal of `icicle-search' highlighting after a search.
+This toggles option `icicle-search-cleanup-flag'.
+Bound to `C-.' in the minibuffer during Icicles search."
+  (interactive)
+  (setq icicle-search-cleanup-flag  (not icicle-search-cleanup-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-search-cleanup-flag
+                                      "Removal of Icicles search highlighting is now ON"
+                                    "Removal of Icicles search highlighting is now OFF")))
+
+;;;###autoload
+(defalias 'toggle-icicle-search-complementing-domain 'icicle-toggle-search-complementing-domain)
+;;;###autoload
+(defun icicle-toggle-search-complementing-domain () ; Bound to `C-M-~' in minibuffer.
+  "Toggle searching the complements of the normal search contexts.
+This toggles internal variable `icicle-search-complement-domain-p'.
+If toggled during search it affects the next, not the current, search.
+Bound to `C-M-~' in the minibuffer."
+  (interactive)
+  (setq icicle-search-complement-domain-p  (not icicle-search-complement-domain-p))
+  (icicle-msg-maybe-in-minibuffer
+   (format "Future Icicles searches %suse the COMPLEMENT of the search domain"
+           (if icicle-search-complement-domain-p "" "do NOT "))))
+
+;;$$$ (defun icicle-dispatch-C-backquote ()   ; Bound to `C-`' in minibuffer.
+;;   "Do the right thing for `C-`'.
+;; When searching, call `icicle-toggle-literal-replacement'.
+;; Otherwise, call `icicle-toggle-regexp-quote'.
+
+;; Bound to `C-`' in the minibuffer."
+;;   (interactive)
+;;   (if icicle-searching-p (icicle-toggle-literal-replacement) (icicle-toggle-regexp-quote)))
+
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-regexp-quote 'icicle-toggle-regexp-quote)
+;;;###autoload
+(defun icicle-toggle-regexp-quote ()    ; Bound to `C-`' in minibuffer.
+  "Toggle escaping of regexp special chars (`icicle-regexp-quote-flag').
+Bound to `C-`' in the minibuffer."
+  (interactive)
+  (setq icicle-regexp-quote-flag  (not icicle-regexp-quote-flag))
+  (icicle-complete-again-update)
+  (icicle-msg-maybe-in-minibuffer (if icicle-regexp-quote-flag
+                                      "Escaping of regexp special characters is now ON"
+                                    "Escaping of regexp special characters is now OFF")))
+
+;;;###autoload
+(defun icicle-regexp-quote-input (beg end) ; Bound to `M-%' in minibuffer.
+  "Regexp quote current input or its active region, then apropos-complete.
+Use this if you want to literally match all of what is currently in
+the minibuffer or selected text there, but you also want to use that
+literal text as part of a regexp for apropos completion.
+
+This turns off `icicle-expand-input-to-common-match-flag'.
+You can toggle that option using `C-;'.
+
+Bound to `M-%' in the minibuffer."
+  (interactive (if (and mark-active (mark))
+                   (list (region-beginning) (region-end))
+                 (list (point-max) (point-max))))
+  (icicle-barf-if-outside-Completions-and-minibuffer)
+  (let ((regionp  (and mark-active (mark) (/= (point) (mark))))
+        quoted-part)
+    (save-excursion
+      (save-restriction
+        (narrow-to-region (if regionp beg (icicle-minibuffer-prompt-end)) (if regionp end (point-max)))
+        (setq quoted-part  (regexp-quote (icicle-input-from-minibuffer)))
+        (delete-region (icicle-minibuffer-prompt-end) (point-max))
+        (insert quoted-part))))
+  (setq icicle-current-input                      (icicle-input-from-minibuffer)
+        icicle-expand-input-to-common-match-flag  nil)
+  (icicle-apropos-complete)
+  (icicle-msg-maybe-in-minibuffer (substitute-command-keys "Expansion to common match is OFF. \
+`\\\\[icicle-toggle-expand-to-common-match]' to toggle")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-literal-replacement 'icicle-toggle-literal-replacement)
+;;;###autoload
+(defun icicle-toggle-literal-replacement () ; Bound to `C-M-`' in minibuffer.
+  "Toggle escaping of regexp special chars in replacement text.
+This toggles option `icicle-search-replace-literally-flag'.
+
+Bound to `C-M-`' in the minibuffer."
+  (interactive)
+  (setq icicle-search-replace-literally-flag  (not icicle-search-replace-literally-flag))
+  (icicle-msg-maybe-in-minibuffer (if icicle-search-replace-literally-flag
+                                      "Replacement of text literally is now ON"
+                                    "Replacement of text literally is now OFF")))
+
+;; Top-level commands.  Could instead be in `icicles-cmd2.el'.
+;;;###autoload
+(defalias 'toggle-icicle-case-sensitivity 'icicle-toggle-case-sensitivity)
+;;;###autoload
+(defun icicle-toggle-case-sensitivity (file+buff-p) ; Bound to `C-S-a' in minibuffer, i.e., `C-A'.
+  "Toggle case sensitivity.
+
+This toggles `case-fold-search' and `completion-ignore-case'.  With a
+prefix arg, it also toggles `read-file-name-completion-ignore-case'
+\(Emacs 22 and later) and `read-buffer-completion-ignore-case' (Emacs
+23 and later).
+
+More precisely, this command first toggles the default value of
+`case-fold-search', and then it sets the other variables to the value
+of `case-fold-search'.
+
+Note:
+1. This toggles the default value of `case-fold-search'.  This means
+that it does not matter which buffer is current when you call this
+command - all buffers are affected henceforth.
+
+2. Some Icicles commands bind one or more of these variables, so
+invoking this command during command execution will not necessarily
+toggle the global values of all of the variables.
+
+Bound to `C-A' in the minibuffer, that is, `C-S-a'."
+  (interactive "P")
+  (setq-default case-fold-search        (not case-fold-search)
+                completion-ignore-case  case-fold-search)
+  (when file+buff-p
+    (when (boundp 'read-file-name-completion-ignore-case) ; Emacs 22+
+      (setq read-file-name-completion-ignore-case  case-fold-search))
+    (when (boundp 'read-buffer-completion-ignore-case) ; Emacs 23+
+      (setq read-buffer-completion-ignore-case  case-fold-search)))
+  (icicle-complete-again-update)
+  (icicle-highlight-lighter)
+  (icicle-msg-maybe-in-minibuffer
+   (cond ((and case-fold-search
+               (or (not (boundp 'read-file-name-completion-ignore-case))
+                   read-file-name-completion-ignore-case)
+               (or (not (boundp 'read-buffer-completion-ignore-case))
+                   read-buffer-completion-ignore-case))
+          "Case-sensitive comparison is now OFF, everywhere")
+         (case-fold-search "Case-sensitive comparison is now OFF, except for files and buffers")
+         (t "Case-sensitive comparison is now ON, everywhere"))))
+
+;; `icicle-delete-window' (`C-x 0') does this in minibuffer.
+;; `icicle-abort-recursive-edit' call this with non-nil FORCE.
+;;;###autoload
+(defun icicle-remove-Completions-window (&optional force)
+  "Remove the `*Completions*' window.
+If not called interactively and `*Completions*' is the selected
+window, then do not remove it unless optional arg FORCE is non-nil."
+  (interactive)
+  ;; We do nothing if `*Completions*' is the selected window
+  ;; or the minibuffer window is selected and `*Completions*' window was selected just before.
+  (let ((swin  (selected-window)))
+    ;; Emacs 20-21 has no `minibuffer-selected-window' function, but we just ignore that.
+    (when (and (window-minibuffer-p swin) (fboundp 'minibuffer-selected-window))
+      (setq swin  (minibuffer-selected-window)))
+    (cond (;; `*Completions*' is shown in the selected frame.
+           (and (get-buffer-window "*Completions*")
+                (or force               ; Let user use `C-g' to get rid of it even if selected.
+                    (and (window-live-p swin) ; Not sure needed.
+                         (not (eq (window-buffer swin) (get-buffer "*Completions*"))))
+                    (interactive-p)))
+           ;; Ignore error, in particular, "Attempt to delete the sole visible or iconified frame".
+           (condition-case nil (delete-window (get-buffer-window "*Completions*")) (error nil))
+           (bury-buffer (get-buffer "*Completions*")))
+          (;; `*Completions*' is shown in a different frame.
+           (and (get-buffer-window "*Completions*" 'visible)
+                (or force               ; Let user use `C-g' to get rid of it even if selected.
+                    (and (window-live-p swin)
+                         (not (eq (window-buffer swin) (get-buffer "*Completions*"))))
+                    (interactive-p)))
+           ;; Ignore error, in particular, "Attempt to delete the sole visible or iconified frame".
+           (when (window-dedicated-p (get-buffer-window "*Completions*" 'visible))
+             (condition-case nil (icicle-delete-windows-on "*Completions*")  (error nil)))
+           (bury-buffer (get-buffer "*Completions*"))))))
+
+;; This is actually a top-level command, but it is in this file because it is used by
+;; `icicle-remove-Completions-window'.
+;;;###autoload
+(defun icicle-delete-windows-on (buffer)
+  "Delete all windows showing BUFFER.
+If such a window is alone in its frame, then delete the frame - unless
+it is the only frame or a standalone minibuffer frame."
+  (interactive
+   (list (let ((enable-recursive-minibuffers  t))
+           (read-buffer "Remove all windows showing buffer: " (current-buffer) 'existing))))
+  (setq buffer  (get-buffer buffer))    ; Convert to buffer.
+  (when buffer                          ; Do nothing if null BUFFER.
+    ;; Avoid error message "Attempt to delete minibuffer or sole ordinary window".
+    (let* ((this-buffer-frames  (icicle-frames-on buffer t))
+           (this-frame          (car this-buffer-frames)))
+      (unless (and this-frame (frame-visible-p this-frame)
+                   (null (cdr this-buffer-frames)) ; Only one frame shows BUFFER.
+                   (eq (cdr (assoc 'minibuffer (frame-parameters this-frame)))
+                       (active-minibuffer-window)) ; Has an active minibuffer.
+                   (save-window-excursion
+                     (select-frame this-frame)
+                     (one-window-p t 'SELECTED-FRAME-ONLY))) ; Only one window.
+        (let (win)
+          (dolist (fr  this-buffer-frames)
+            (setq win  (get-buffer-window buffer fr))
+            (select-window win)
+            (if (and (one-window-p t) (cdr (visible-frame-list))) ; Sole window but not sole frame.
+                (delete-frame)
+              (delete-window (selected-window)))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-mcmd)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-mcmd.el ends here
diff --git a/auto-install/icicles-mode.el b/auto-install/icicles-mode.el
new file mode 100644
index 0000000..52a4eda
--- /dev/null
+++ b/auto-install/icicles-mode.el
@@ -0,0 +1,4115 @@
+;;; icicles-mode.el --- Icicle Mode definition for Icicles
+;;
+;; Filename: icicles-mode.el
+;; Description: Icicle Mode definition for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 10:21:10 2006
+;; Version: 22.0
+;; Last-Updated: Thu Sep  8 14:32:31 2011 (-0700)
+;;           By: dradams
+;;     Update #: 7595
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-mode.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `advice', `advice-preload', `apropos', `apropos+',
+;;   `apropos-fn+var', `avoid', `backquote', `bookmark', `bookmark+',
+;;   `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
+;;   `bookmark+-lit', `bookmark+-mac', `bytecomp', `cl', `cus-edit',
+;;   `cus-face', `cus-load', `cus-start', `custom', `dired',
+;;   `dired+', `dired-aux', `dired-x', `doremi', `easymenu',
+;;   `ediff-diff', `ediff-help', `ediff-init', `ediff-merg',
+;;   `ediff-mult', `ediff-util', `ediff-wind', `el-swank-fuzzy',
+;;   `ffap', `ffap-', `fit-frame', `frame-cmds', `frame-fns',
+;;   `fuzzy', `fuzzy-match', `help+20', `hexrgb', `icicles-cmd1',
+;;   `icicles-cmd2', `icicles-face', `icicles-fn', `icicles-mac',
+;;   `icicles-mcmd', `icicles-opt', `icicles-var', `image-dired',
+;;   `info', `info+', `kmacro', `levenshtein', `menu-bar',
+;;   `menu-bar+', `misc-cmds', `misc-fns', `mkhtml',
+;;   `mkhtml-htmlize', `mouse3', `mwheel', `pp', `pp+', `regexp-opt',
+;;   `ring', `ring+', `second-sel', `strings', `thingatpt',
+;;   `thingatpt+', `unaccent', `w32-browser', `w32browser-dlgopen',
+;;   `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines the
+;;  command `icicle-mode'.  For Icicles documentation, see
+;;  `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Commands defined here:
+;;
+;;    `icicle-handle-switch-frame', `icicle-mode', `icy-mode',
+;;    `icicle-skip-this-command', `old-bbdb-complete-name',
+;;    `old-comint-dynamic-complete',
+;;    `old-comint-dynamic-complete-filename',
+;;    `old-comint-replace-by-expanded-filename',
+;;    `old-dired-read-shell-command', `old-ess-complete-object-name',
+;;    `old-gud-gdb-complete-command', `old-read-shell-command',
+;;    `orig-read-file-name'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `icicle-activate-mark', `icicle-add-menu-item-to-cmd-history',
+;;    `icicle-bind-completion-keys', `icicle-bind-isearch-keys',
+;;    `icicle-bind-key-completion-keys-for-map-var',
+;;    `icicle-bind-key-completion-keys-in-keymaps-from',
+;;    `icicle-bind-other-keymap-keys',
+;;    `icicle-cancel-Help-redirection', `icicle-define-cycling-keys',
+;;    `icicle-define-icicle-maps', `icicle-define-minibuffer-maps',
+;;    `icicle-minibuffer-setup', `icicle-rebind-global',
+;;    `icicle-redefine-standard-functions',
+;;    `icicle-redefine-standard-options',
+;;    `icicle-redefine-std-completion-fns',
+;;    `icicle-restore-completion-keys',
+;;    `icicle-restore-other-keymap-keys',
+;;    `icicle-restore-region-face',
+;;    `icicle-restore-standard-functions',
+;;    `icicle-restore-standard-options',
+;;    `icicle-restore-std-completion-fns',
+;;    `icicle-run-icicle-post-command-hook',
+;;    `icicle-run-icicle-pre-command-hook',
+;;    `icicle-select-minibuffer-contents', `icicle-set-calling-cmd',
+;;    `icicle-S-iso-lefttab-to-S-TAB', `icicle-top-level-prep',
+;;    `icicle-unbind-isearch-keys',
+;;    `icicle-unbind-key-completion-keys-for-map-var',
+;;    `icicle-unbind-key-completion-keys-in-keymaps-from',
+;;    `icicle-undo-std-completion-faces', `icicle-unmap',
+;;    `icicle-update-ignored-extensions-regexp'.
+;;
+;;  User options defined here (in Custom group `Icicles'):
+;;
+;;    `icicle-mode', `icicle-mode-hook'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `icicle-bookmark-menu-map', `icicle-custom-menu-map',
+;;    `icicle-describe-menu-map', `icicle-edit-menu-map',
+;;    `icicle-file-menu-map', `icicle-frames-menu-map',
+;;    `icicle-info-menu-map', `icicle-mode-map',
+;;    `icicle-options-menu-map', `icicle-search-menu-map',
+;;    `icicle-search-tags-menu-map'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "User Options (alphabetical)")
+;;  (@> "Internal variables (alphabetical)")
+;;  (@> "Icicle mode command")
+;;  (@> "Other Icicles functions that define Icicle mode")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; ;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;;###autoload (autoload 'icicle-mode "icicles" "Toggle Icicle mode." t nil)
+;;;###autoload (autoload 'icy-mode    "icicles" "Toggle Icicle mode." t nil)
+
+(eval-when-compile (require 'cl)) ;; pushnew, case
+                                  ;; plus, for Emacs < 21: push, dolist
+
+(require 'advice)
+  ;; ad-activate, ad-copy-advice-info, ad-deactivate, ad-disable-advice, ad-enable-advice,
+  ;; ad-find-some-advice, ad-get-arg, ad-is-active, ad-set-advice-info
+
+(require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
+  ;; icicle-buffer-configs, icicle-buffer-extras, icicle-change-region-background-flag,
+  ;; icicle-default-cycling-mode, icicle-incremental-completion-flag,
+  ;; icicle-default-value, icicle-kmacro-ring-max, icicle-minibuffer-setup-hook,
+  ;; icicle-modal-cycle-down-keys, icicle-modal-cycle-up-keys,
+  ;; icicle-functions-to-redefine, icicle-regexp-search-ring-max,
+  ;; icicle-region-background, icicle-search-ring-max, icicle-show-Completions-initially-flag,
+  ;; icicle-top-level-key-bindings, icicle-touche-pas-aux-menus-flag,
+  ;; icicle-word-completion-keys, icicle-yank-function
+(require 'icicles-fn)                   ; (This is required anyway by `icicles-cmd1.el'.)
+  ;; assq-delete-all, icicle-completing-p, icicle-isearch-complete-past-string,
+  ;; icicle-toggle-icicle-mode-twice, icicle-unhighlight-lighter
+(require 'icicles-var)                  ; (This is required anyway by `icicles-fn.el'.)
+  ;; icicle-candidate-action-fn, icicle-candidate-nb, icicle-cmd-calling-for-completion,
+  ;; icicle-completing-p, icicle-completion-candidates,
+  ;; icicle-current-completion-mode, icicle-default-directory, icicle-ignored-extensions,
+  ;; icicle-ignored-extensions-regexp, icicle-incremental-completion-p, icicle-initial-value,
+  ;; icicle-last-completion-candidate, icicle-last-completion-command, icicle-last-input,
+  ;; icicle-menu-map, icicle-pre-minibuffer-buffer, icicle-minor-mode-map-entry,
+  ;; icicle-saved-completion-candidates, icicle-saved-kmacro-ring-max,
+  ;; icicle-saved-regexp-search-ring-max, icicle-saved-region-background,
+  ;; icicle-saved-search-ring-max, icicle-search-current-overlay, icicle-search-overlays,
+  ;; icicle-search-refined-overlays
+(require 'icicles-cmd1)                 ; (This is required anyway by `icicles-cmd2.el'.)
+  ;; icicle-add-buffer-candidate, icicle-add-buffer-config, icicle-bbdb-complete-name,
+  ;; icicle-customize-face, icicle-customize-face-other-window, icicle-dabbrev-completion,
+  ;; icicle-select-bookmarked-region
+(require 'icicles-cmd2)
+  ;; icicle-imenu, icicle-occur, icicle-search, icicle-search-bookmark,
+  ;; icicle-search-bookmarks-together, icicle-search-buffer, icicle-search-file,
+  ;; icicle-search-w-isearch-string
+
+;; Use `condition-case' because if `mb-depth.el' can't be found, `mb-depth+.el' is not provided.
+(when (>= emacs-major-version 22) (condition-case nil (require 'mb-depth+ nil t) (error nil)))
+  ;; (no error if not found): minibuffer-depth-indicate-mode
+
+(require 'dired+ nil t) ;; (no error if not found):
+                        ;; diredp-menu-bar-operate-menu, diredp-menu-bar-subdir-menu
+(require 'dired) ;; dired-mode-map
+(require 'menu-bar+ nil t) ;; (no error if not found):
+  ;; menu-bar-apropos-menu, menu-bar-describe-menu, menu-bar-edit-menu,
+  ;; menu-bar-file-menu, menu-bar-frames-menu, menu-bar-options-menu, menu-bar-search-tags-menu
+
+;; `icicle-apropos-complete' is used here.  It is defined in `icicles-mcmd.el'.
+;; `icicle-file-name-input-p' is used here.  It is defined in `icicles-fn.el'.
+
+;;; Defvars to quiet byte-compiler:
+(when (< emacs-major-version 22)
+  (defvar kmacro-ring-max)
+  (defvar minibuffer-local-filename-completion-map)
+  (defvar minibuffer-local-must-match-filename-map)
+  (defvar minibuffer-local-filename-must-match-map)
+  (defvar mouse-wheel-down-event)
+  (defvar mouse-wheel-up-event)
+  (defvar read-file-name-function))
+
+(defvar Buffer-menu-mode-map)           ; In `buff-menu.el'.
+(defvar comint-mode-map)                ; In `comint.el'.
+(defvar crm-local-completion-map)       ; In `crm.el'.
+(defvar crm-local-must-match-map)       ; In `crm.el'.
+(defvar dired-mode-map)                 ; In `dired.el'.
+(defvar gud-minibuffer-local-map)       ; In `gud.el'.
+(defvar ibuffer-mode-map)               ; In `ibuffer.el'.
+(defvar ibuffer-mode-operate-map)       ; In `ibuffer.el'.
+(defvar icicle-crm-local-completion-map) ; In `icicles-fn.el' after load `crm.el'.
+(defvar icicle-crm-local-must-match-map) ; In `icicles-fn.el' after load `crm.el'.
+(defvar icicle-kmacro-ring-max)         ; In `icicles-opt.el' for Emacs 22+.
+(defvar icicle-saved-kmacro-ring-max)   ; In `icicles-var.el' for Emacs 22+.
+(defvar ielm-map)                       ; In `ielm.el'.
+(defvar inferior-tcl-mode-map)          ; In `tcl.el'.
+(defvar Info-mode-map)                  ; In `info.el'.
+(defvar isearch-mode-map)               ; In `isearch.el'.
+(defvar old-crm-local-completion-map)   ; In `icicles-fn.el' after load `crm.el'.
+(defvar old-crm-local-must-match-map)   ; In `icicles-fn.el' after load `crm.el'.
+(defvar savehist-minibuffer-history-variables) ; In `savehist.el'
+(defvar shell-mode-map)                 ; In `shell.el'.
+(defvar sh-mode-map)                    ; In `sh-script.el'.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "User Options (alphabetical)")
+
+;;; User Options (alphabetical) --------------------------------------
+
+;; Emacs 20 only
+(unless (fboundp 'define-minor-mode)
+  (defcustom icicle-mode nil
+    "*Toggle minibuffer input completion and cycling.
+Setting this variable directly does not take effect;
+use either \\[customize] or command `icy-mode' (aka `icicle-mode')."
+    :set (lambda (symbol value) (icicle-mode (if value 1 -1)))
+    :initialize 'custom-initialize-default
+    :type 'boolean :group 'Icicles-Miscellaneous :require 'icicles))
+
+;;;###autoload
+(defcustom icicle-mode-hook nil
+  "*Functions run after entering and exiting Icicle mode."
+  :type 'hook :group 'Icicles-Miscellaneous)
+ 
+;;(@* "Internal variables (alphabetical)")
+
+;;; Internal variables (alphabetical) --------------------------------
+
+(defvar icicle-mode-map nil
+  "Keymap for Icicle mode.  These are top-level key bindings.
+See also `icicle-define-minibuffer-maps' for minibuffer bindings and
+bindings in `*Completions*'.")
+ 
+;;(@* "Icicle mode command")
+
+;;; Icicle mode command ----------------------------------------------
+
+;; Main command.  Inspired from `icomplete-mode'.
+;;;###autoload
+(defalias 'icy-mode 'icicle-mode)
+(when (fboundp 'define-minor-mode)      ; Emacs 21+ ------------
+  (when (> emacs-major-version 22)
+    (defadvice call-interactively (after icicle-save-to-history disable activate)
+      "Save command to `icicle-interactive-history'."
+      ;; If command's input is not a parameterized (e.g. mouse) event, record it.
+      (let* ((fn   (ad-get-arg 0))
+             (int  (interactive-form fn)))
+        (when (and (symbolp fn) (consp int) (or (not (stringp (cadr int)))
+                                                (string= (cadr int) "")
+                                                (not (eq ?e (aref (cadr int) 0)))))
+          (pushnew (symbol-name fn) icicle-interactive-history))))
+    (when (boundp 'savehist-save-hook)  ; Do not save `icicle-interactive-history' (too large).
+      (add-hook 'savehist-save-hook
+                (lambda () (setq savehist-minibuffer-history-variables
+                                 (delq 'icicle-interactive-history
+                                       savehist-minibuffer-history-variables))))))
+  (when (> emacs-major-version 21)
+    (defadvice describe-face (before icicle-respect-WYSIWYG activate)
+      "`read-face-name' respects `icicle-WYSIWYG-Completions-flag'.
+If non-nil, then it does not use `completing-read-multiple' (which
+cannot take advantage of WYSIWYG)."
+      (interactive (list (read-face-name "Describe face" "= `default' face"
+                                         (not icicle-WYSIWYG-Completions-flag))))))
+
+  (eval '(define-minor-mode icicle-mode
+          "Icicle mode: Toggle minibuffer input completion and cycling.
+Non-nil prefix ARG turns mode on if ARG > 0, else turns it off.
+Icicle mode is a global minor mode.  It binds keys in the minibuffer.
+
+The following top-level commands are also available in Icicle mode.
+In many cases there are also `other-window' versions.
+
+`clear-option' (alias)                 - Set binary option(s) to nil
+`icicle-add-buffer-candidate'          - Add always-candidate buffer
+`icicle-add-buffer-config'             - To `icicle-buffer-configs'
+`icicle-add-entry-to-saved-completion-set' - Add completion to a set
+`icicle-add/update-saved-completion-set' - To
+                                        `icicle-saved-completion-sets'
+`icicle-apply'                         - Apply function to alist items
+`icicle-apropos'                       - `apropos', but shows matches
+`icicle-apropos-command'               - Enhanced `apropos-command'
+`icicle-apropos-variable'              - Enhanced `apropos-variable'
+`icicle-apropos-zippy'                 - Show matching Zippy quotes
+`icicle-bookmark'                      - Jump to a bookmark
+`icicle-bookmark-all-tags'             - Jump to tagged bookmark
+`icicle-bookmark-all-tags-regexp'      - Jump to tagged bookmark
+`icicle-bookmark-bookmark-list'        - Jump to a bookmark list
+`icicle-bookmark-desktop'              - Jump to a desktop bookmark
+`icicle-bookmark-dired'                - Jump to a Dired bookmark
+`icicle-bookmark-file'                 - Jump to a file bookmark
+`icicle-bookmark-file-all-tags'        - Jump to tagged file bookmark
+`icicle-bookmark-file-all-tags-regexp'
+`icicle-bookmark-file-some-tags'
+`icicle-bookmark-file-some-tags-regexp'
+`icicle-bookmark-file-this-dir-all-tags'
+`icicle-bookmark-file-this-dir-all-tags-regexp'
+`icicle-bookmark-file-this-dir-some-tags'
+`icicle-bookmark-file-this-dir-some-tags-regexp'
+`icicle-bookmark-gnus'                 - Jump to a Gnus bookmark
+`icicle-bookmark-info'                 - Jump to an Info bookmark
+`icicle-bookmark-local-file'           - Jump to local-file bookmark
+`icicle-bookmark-man'                  - Jump to a `man'-page bookmark
+`icicle-bookmark-non-file'             - Jump to a buffer bookmark
+`icicle-bookmark-region'               - Jump to a region bookmark
+`icicle-bookmark-remote-file'          - Jump to a remote file
+`icicle-bookmark-some-tags'            - Jump to tagged bookmark
+`icicle-bookmark-some-tags-regexp'     - Jump to tagged bookmark
+`icicle-bookmark-specific-buffers'     - Jump to a bookmarked buffer
+`icicle-bookmark-specific-files'       - Jump to a bookmarked file
+`icicle-bookmark-this-buffer'          - Jump to bookmark for this buf
+`icicle-bookmark-url'                  - Jump to a URL bookmark
+`icicle-bookmark-w3m'                  - Jump to a W3M (URL) bookmark
+`icicle-buffer'                        - Switch to buffer
+`icicle-buffer-config'                 - Pick `icicle-buffer' options
+`icicle-buffer-list'                   - Choose a list of buffer names
+`icicle-change-alternative-sort-order' - Choose an alternative sort
+`icicle-change-sort-order'             - Choose a sort order
+`icicle-clear-current-history'         - Clear current history entries
+`icicle-clear-history'                 - Clear entries from a history
+`icicle-color-theme'                   - Change color theme
+`icicle-comint-command'                - Reuse shell etc. command
+`icicle-comint-dynamic-complete'       - Text completion in shell
+`icicle-comint-search'                 - Reuse shell etc. command
+`icicle-command-abbrev'                - Multi-command `M-x' + abbrevs
+`icicle-compilation-search'            - `icicle-search' and show hits
+`icicle-complete-keys'                 - Complete keys
+`icicle-complete-thesaurus-entry'      - Complete word using thesaurus
+`icicle-completing-yank'               - `yank' using completion
+`icicle-customize-face'                - Multi-`customize-face'
+`icicle-customize-icicles-group'       - Customize options and faces
+`icicle-delete-file'                   - Delete file/directory
+`icicle-delete-window'                 - Delete window (`C-u': buffer)
+`icicle-delete-windows'                - Delete all windows for buffer
+`icicle-dired'                         - Multi-command Dired
+`icicle-doc'                           - Show doc for fn, var, or face
+`icicle-doremi-candidate-width-factor+' - +/- candidate column width
+`icicle-doremi-increment-max-candidates+' - +/- max number candidates
+`icicle-doremi-increment-swank-prefix-length+' - +/- swank prefix
+`icicle-doremi-increment-swank-timeout+' - +/- swank completion msec
+`icicle-doremi-increment-variable+'    - Increment var using Do Re Mi
+`icicle-doremi-inter-candidates-min-spaces+' - +/- candidate spacing
+`icicle-doremi-zoom-Completions+'      - +/- `*Completions*' text size
+`icicle-execute-extended-command'      - Multi-command `M-x'
+`icicle-execute-named-keyboard-macro'  - Execute named keyboard macro
+`icicle-face-list'                     - Choose a list of face names
+`icicle-file-list'                     - Choose a list of file names
+`icicle-file'                          - Visit file/directory
+`icicle-find-file'                     -       same: relative only
+`icicle-find-file-absolute'            -       same: absolute only
+`icicle-find-file-all-tags'            - Visit tagged file
+`icicle-find-file-all-tags-regexp'
+`icicle-find-file-some-tags'
+`icicle-find-file-some-tags-regexp'
+`icicle-find-file-in-tags-table'       - File in Emacs tags table
+`icicle-find-file-tagged'              - Visit tagged file
+`icicle-find-first-tag'                - Visit definition with tag
+`icicle-find-tag'                      - Visit definition with tag
+`icicle-font'                          - Change font of frame
+`icicle-frame-bg'                      - Change background of frame
+`icicle-frame-fg'                      - Change foreground of frame
+`icicle-fundoc'                        - Show function description
+`icicle-goto-global-marker'            - Go to a global marker
+`icicle-goto-marker'                   - Go to a marker in this buffer
+`icicle-imenu*'                        - Navigate among Imenu entries
+`icicle-increment-option'              - Increment numeric option
+`icicle-increment-variable'            - Increment numeric variable
+`icicle-Info-goto-node'                - Multi-cmd `Info-goto-node'
+`icicle-Info-index'                    - Multi-command `Info-index'
+`icicle-Info-menu'                     - Multi-command `Info-menu'
+`icicle-Info-virtual-book'             - Open a virtual Info book
+`icicle-insert-buffer'                 - Multi-command `insert-buffer'
+`icicle-insert-thesaurus-entry'        - Insert thesaurus entry(s)
+`icicle-keyword-list'                  - Choose a list of keywords
+`icicle-kill-buffer'                   - Kill buffer
+`icicle-kmacro'                        - Execute a keyboard macro
+`icicle-locate-file'                   - Visit file(s) in a directory
+`icicle-minibuffer-help'               - Show Icicles minibuffer help
+`icicle-mode' or `icy-mode'            - Toggle Icicle mode
+`icicle-next-S-TAB-completion-method'  - Next S-TAB completion method
+`icicle-next-TAB-completion-method'    - Next TAB completion method
+`icicle-occur'                         - Incremental `occur'
+`icicle-other-window-or-frame'         - Other window/frame or select
+`icicle-plist'                         - Show symbols, property lists
+`icicle-recent-file'                   - Open recently used file(s)
+`icicle-recompute-shell-command-candidates' - Update from search path
+`icicle-remove-buffer-candidate'       - Remove always-candidate buf
+`icicle-remove-buffer-config'          - From `icicle-buffer-configs'
+`icicle-remove-entry-from-saved-completion-set' - From a saved set
+`icicle-remove-file-from-recentf-list' - Remove from recent files list
+`icicle-remove-saved-completion-set'   - From
+                                        `icicle-saved-completion-sets'
+`icicle-reset-option-to-nil'           - Set binary option(s) to nil
+`icicle-save-string-to-variable'       - Save text for use with `C-='
+`icicle-search'                        - Search with regexps & cycling
+`icicle-search-all-tags-bookmark'      - Search tagged bookmarks 
+`icicle-search-all-tags-regexp-bookmark'
+`icicle-search-bookmark'               - Search bookmarks separately
+`icicle-search-bookmark-list-bookmark' - Search bookmark lists
+`icicle-search-bookmarks-together'     - Search bookmarks together
+`icicle-search-char-property'          - Search for overlay/text props
+`icicle-search-dired-bookmark'         - Search Dired bookmarks
+`icicle-search-dired-marked'           - Search marked files in Dired
+`icicle-search-file'                   - Search multiple files
+`icicle-search-file-bookmark'          - Search bookmarked files
+`icicle-search-gnus-bookmark'          - Search bookmarked Gnus msgs
+`icicle-search-ibuffer-marked'         - Search marked bufs in Ibuffer
+`icicle-search-info-bookmark'          - Search bookmarked Info nodes
+`icicle-search-keywords'               - Search with regexp keywords
+`icicle-search-local-file-bookmark'    - Search bookmarked local files
+`icicle-search-man-bookmark'           - Search bookmarked `man' pages
+`icicle-search-non-file-bookmark'      - Search bookmarked buffers
+`icicle-search-overlay-property'       - Search for overlay properties
+`icicle-search-pages'                  - Search Emacs pages
+`icicle-search-paragraphs'             - Search Emacs paragraphs
+`icicle-search-region-bookmark'        - Search bookmarked regions
+`icicle-search-remote-file-bookmark'   - Search remote bookmarks
+`icicle-search-sentences'              - Search sentences as contexts
+`icicle-search-some-tags-bookmark'     - Search tagged bookmarks 
+`icicle-search-some-tags-regexp-bookmark'
+`icicle-search-text-property'          - Search for faces etc.
+`icicle-search-url-bookmark'           - Search bookmarked URLs
+`icicle-search-word'                   - Whole-word search
+`icicle-select-bookmarked-region'      - Select bookmarked regions
+`icicle-select-frame'                  - Select a frame by name
+`icicle-select-window'                 - Select window by buffer name
+`icicle-send-bug-report'               - Send Icicles bug report
+`icicle-set-option-to-t'               - Set binary option(s) to t
+`icicle-tag-a-file'                    - Tag a file a la delicious
+`icicle-toggle-~-for-home-dir'         - Toggle using `~' for $HOME
+`icicle-toggle-alternative-sorting'    - Swap alternative sort
+`icicle-toggle-angle-brackets'         - Toggle using angle brackets
+`icicle-toggle-C-for-actions'          - Toggle using `C-' for actions
+`icicle-toggle-case-sensitivity'       - Toggle case sensitivity
+`icicle-toggle-dot'                    - Toggle `.' matching newlines
+`icicle-toggle-expand-to-common-match' - Toggle input ECM expansion
+`icicle-toggle-hiding-common-match'    - Toggle match, `*Completions*'
+`icicle-toggle-hiding-non-matching-lines'- Toggle no-match lines
+`icicle-toggle-highlight-all-current'  - Toggle max search highlight
+`icicle-toggle-highlight-historical-candidates'
+                                       - Toggle past-input highlight
+`icicle-toggle-highlight-saved-candidates'
+                                       - Toggle highlighting saved
+`icicle-toggle-ignored-extensions'     - Toggle ignored files
+`icicle-toggle-ignored-space-prefix'   - Toggle ignoring space prefix
+`icicle-toggle-ignoring-comments'      - Toggle ignoring comments
+`icicle-toggle-incremental-completion' - Toggle apropos icompletion
+`icicle-toggle-option'                 - Toggle binary user option
+`icicle-toggle-proxy-candidates'       - Toggle proxy candidates
+`icicle-toggle-regexp-quote'           - Toggle regexp escaping
+`icicle-toggle-search-cleanup'         - Toggle search highlighting
+`icicle-toggle-search-complementing-domain' - Toggle complement search
+`icicle-toggle-search-replace-common-match' - Toggle ECM replacement
+`icicle-toggle-search-replace-whole'   - Toggle replacing whole hit
+`icicle-toggle-search-whole-word'      - Toggle whole-word searching
+`icicle-toggle-show-multi-completion'  - Toggle multi-completions
+`icicle-toggle-sorting'                - Toggle sorting of completions
+`icicle-toggle-transforming'           - Toggle duplicate removal
+`icicle-toggle-WYSIWYG-Completions'   - Toggle WYSIWYG `*Completions*'
+`icicle-untag-a-file'                  - Remove some tags from a file
+`icicle-vardoc'                        - Show variable description
+`icicle-where-is'                      - `where-is' multi-command
+`icicle-yank-maybe-completing'         - `yank' maybe using completion
+`toggle' (alias)                       - Toggle binary user option
+
+For more information, use `\\\\[icicle-minibuffer-help]' \
+when the minibuffer is active.
+
+Note: Depending on your platform, if you use Icicles in a text
+terminal (that is, without a window system/manager), then you might
+need to change some of the key bindings, if some of the default
+bindings are not available to you."
+          :global t :group 'Icicles-Miscellaneous :lighter " Icy" :init-value nil
+          (cond (icicle-mode
+                 ;; (when (interactive-p)
+                 ;;   (unless (or window-system (and (fboundp 'daemonp) (daemonp)))
+                 ;;     (with-output-to-temp-buffer "*Attention*"
+                 ;;       (princ "You are using Icicles in a text terminal (no window ")
+                 ;;       (princ "system/manager).\n\nIcicles makes use of many keys that are ")
+                 ;;      (princ "unavailable when running\nEmacs in a text terminal.  You will ")
+                 ;;       (princ "want to rebind those keys.\n")
+                 ;;       (princ "See the Icicles doc, section Key Bindings.\n"))
+                 ;;  (message "Icicles uses keys that might not be suitable for a text terminal")
+                 ;;     (sit-for 5)))
+                 (icicle-define-icicle-maps)
+                 (icicle-bind-other-keymap-keys)
+                 (add-hook 'minibuffer-setup-hook       'icicle-minibuffer-setup)
+                 (add-hook 'minibuffer-exit-hook        'icicle-cancel-Help-redirection)
+                 (add-hook 'minibuffer-exit-hook        'icicle-restore-region-face)
+                 (add-hook 'minibuffer-exit-hook        'icicle-unhighlight-lighter)
+                 (add-hook 'icicle-post-command-hook    'icicle-activate-mark 'append)
+                 (add-hook 'completion-setup-hook       'icicle-set-calling-cmd 'append)
+                 (when icicle-customize-save-flag
+                   (add-hook 'kill-emacs-hook           'icicle-command-abbrev-save))
+                 (add-hook 'comint-mode-hook            'icicle-comint-hook-fn)
+                 (add-hook 'compilation-mode-hook       'icicle-compilation-hook-fn)
+                 (add-hook 'compilation-minor-mode-hook 'icicle-compilation-hook-fn)
+                 ;; $$$$$$ Do this only in `icicle-display-candidates-in-Completions' now.
+                 ;; $$$$$$ (add-hook 'temp-buffer-show-hook       'icicle-fit-completions-window)
+                 (icicle-undo-std-completion-faces)
+                 (icicle-redefine-std-completion-fns)
+                 (icicle-redefine-standard-functions)
+                 (icicle-redefine-standard-options)
+                 (when (ad-find-some-advice 'describe-face 'before 'icicle-respect-WYSIWYG)
+                   (ad-enable-advice 'describe-face 'before 'icicle-respect-WYSIWYG))
+                 (when (fboundp 'minibuffer-depth-indicate-mode) ; In `mb-depth(+).el'
+                   (minibuffer-depth-indicate-mode 99))
+                 (if icicle-menu-items-to-history-flag
+                     (add-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history)
+                   (remove-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history))
+                 (when (> emacs-major-version 22)
+                   (when icicle-populate-interactive-history-flag
+                     (ad-enable-advice 'call-interactively 'after 'icicle-save-to-history))
+                   (ad-activate 'call-interactively))
+                 (dolist (fn  icicle-inhibit-advice-functions)
+                   (when (and (fboundp fn) (ad-is-active fn))
+                     (push (cons fn (ad-copy-advice-info fn)) icicle-advice-info-list)
+                     (ad-deactivate fn))))
+                (t
+                 (makunbound 'icicle-mode-map)
+                 (icicle-restore-other-keymap-keys)
+                 (remove-hook 'minibuffer-setup-hook    'icicle-minibuffer-setup)
+                 (remove-hook 'minibuffer-exit-hook     'icicle-cancel-Help-redirection)
+                 (remove-hook 'minibuffer-exit-hook     'icicle-restore-region-face)
+                 (remove-hook 'icicle-post-command-hook 'icicle-activate-mark)
+                 ;; The pre- and post-command hooks are local to the minibuffer,
+                 ;; So they are added in `icicle-minibuffer-setup', not here.
+                 ;; Nevertheless, they are removed here when Icicle mode is exited.
+                 (remove-hook 'pre-command-hook         'icicle-top-level-prep)
+                 (remove-hook 'pre-command-hook         'icicle-run-icicle-pre-command-hook t)
+                 (remove-hook 'post-command-hook        'icicle-run-icicle-post-command-hook t)
+                 (remove-hook 'completion-setup-hook    'icicle-set-calling-cmd)
+                 (remove-hook 'kill-emacs-hook          'icicle-command-abbrev-save)
+                 (remove-hook 'comint-mode-hook         'icicle-comint-hook-fn)
+                 (remove-hook 'compilation-mode-hook    'icicle-compilation-hook-fn)
+                 (remove-hook 'compilation-minor-mode-hook 'icicle-compilation-hook-fn)
+                 ;; $$$$$$ Do this only in `icicle-display-candidates-in-Completions' now.
+                 ;; $$$$$$ (remove-hook 'temp-buffer-show-hook    'icicle-fit-completions-window)
+
+                 ;; $$ Should restore standard completion faces here.
+                 (icicle-restore-std-completion-fns)
+                 (icicle-restore-standard-functions)
+                 (icicle-restore-standard-options)
+                 (when (ad-find-some-advice 'describe-face 'before 'icicle-respect-WYSIWYG)
+                   (ad-disable-advice 'describe-face 'before 'icicle-respect-WYSIWYG))
+                 (when (fboundp 'minibuffer-depth-indicate-mode)
+                   (minibuffer-depth-indicate-mode -99))
+                 (remove-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history)
+                 (when (> emacs-major-version 22)
+                   (ad-disable-advice 'call-interactively 'after 'icicle-save-to-history)
+                   (ad-activate 'call-interactively))
+                 (dolist (fn  icicle-inhibit-advice-functions)
+                   (let ((info  (memq fn icicle-advice-info-list)))
+                     (when (and (fboundp fn) info)
+                       (ad-set-advice-info fn info)
+                       (when (ad-is-active fn) (ad-activate fn)))))))
+          (unless (eq icicle-guess-commands-in-path 'load)
+            (setq icicle-shell-command-candidates-cache  ())) ; Reset - toggle Icy to update.
+          (message "Turning %s Icicle mode..." (if icicle-mode "ON" "OFF"))
+          (icicle-define-minibuffer-maps icicle-mode)
+          (run-hooks 'icicle-mode-hook)
+          (message "Turning %s Icicle mode...done" (if icicle-mode "ON" "OFF")))))
+
+(unless (fboundp 'define-minor-mode)    ; Emacs 20 ------------
+  (defun icicle-mode (&optional arg)
+    "Icicle mode: Toggle minibuffer input completion and cycling.
+Non-nil prefix ARG turns mode on if ARG > 0, else turns it off.
+Icicle mode is a global minor mode.  It binds keys in the minibuffer.
+
+The following top-level commands are also available in Icicle mode.
+In many cases there are also `other-window' versions.
+
+`clear-option' (alias)                 - Set binary option(s) to nil
+`icicle-add-buffer-candidate'          - Add always-candidate buffer
+`icicle-add-buffer-config'             - To `icicle-buffer-configs'
+`icicle-add-entry-to-saved-completion-set' - Add completion to a set
+`icicle-add/update-saved-completion-set' - To
+                                        `icicle-saved-completion-sets'
+`icicle-apply'                         - Apply function to alist items
+`icicle-apropos'                       - `apropos', but shows matches
+`icicle-apropos-command'               - Enhanced `apropos-command'
+`icicle-apropos-variable'              - Enhanced `apropos-variable'
+`icicle-apropos-zippy'                 - Show matching Zippy quotes
+`icicle-bookmark'                      - Jump to a bookmark
+`icicle-bookmark-all-tags'             - Jump to tagged bookmark
+`icicle-bookmark-all-tags-regexp'      - Jump to tagged bookmark
+`icicle-bookmark-bookmark-list'        - Jump to a bookmark list
+`icicle-bookmark-desktop'              - Jump to a desktop bookmark
+`icicle-bookmark-dired'                - Jump to a Dired bookmark
+`icicle-bookmark-file'                 - Jump to a file bookmark
+`icicle-bookmark-file-all-tags'        - Jump to tagged file bookmark
+`icicle-bookmark-file-all-tags-regexp'
+`icicle-bookmark-file-some-tags'
+`icicle-bookmark-file-some-tags-regexp'
+`icicle-bookmark-file-this-dir-all-tags'
+`icicle-bookmark-file-this-dir-all-tags-regexp'
+`icicle-bookmark-file-this-dir-some-tags'
+`icicle-bookmark-file-this-dir-some-tags-regexp'
+`icicle-bookmark-gnus'                 - Jump to a Gnus bookmark
+`icicle-bookmark-info'                 - Jump to an Info bookmark
+`icicle-bookmark-local-file'           - Jump to local-file bookmark
+`icicle-bookmark-man'                  - Jump to a `man'-page bookmark
+`icicle-bookmark-non-file'             - Jump to a buffer bookmark
+`icicle-bookmark-region'               - Jump to a region bookmark
+`icicle-bookmark-remote-file'          - Jump to a remote file
+`icicle-bookmark-some-tags'            - Jump to tagged bookmark
+`icicle-bookmark-some-tags-regexp'     - Jump to tagged bookmark
+`icicle-bookmark-specific-buffers'     - Jump to a bookmarked buffer
+`icicle-bookmark-specific-files'       - Jump to a bookmarked file
+`icicle-bookmark-this-buffer'          - Jump to bookmark for this buf
+`icicle-bookmark-url'                  - Jump to a URL bookmark
+`icicle-bookmark-w3m'                  - Jump to a W3M (URL) bookmark
+`icicle-buffer'                        - Switch to buffer
+`icicle-buffer-config'                 - Pick `icicle-buffer' options
+`icicle-buffer-list'                   - Choose a list of buffer names
+`icicle-change-alternative-sort-order' - Choose an alternative sort
+`icicle-change-sort-order'             - Choose a sort order
+`icicle-clear-current-history'         - Clear current history entries
+`icicle-clear-history'                 - Clear entries from a history
+`icicle-color-theme'                   - Change color theme
+`icicle-comint-command'                - Reuse shell etc. command
+`icicle-comint-dynamic-complete'       - Text completion in shell
+`icicle-comint-search'                 - Reuse shell etc. command
+`icicle-command-abbrev'                - Multi-command `M-x' + abbrevs
+`icicle-compilation-search'            - `icicle-search' and show hits
+`icicle-complete-thesaurus-entry'      - Complete word using thesaurus
+`icicle-completing-yank'               - `yank' using completion
+`icicle-customize-face'                - Multi-`customize-face'
+`icicle-customize-icicles-group'       - Customize options and faces
+`icicle-delete-file'                   - Delete file/directory
+`icicle-delete-window'                 - Delete window (`C-u': buffer)
+`icicle-delete-windows'                - Delete all windows for buffer
+`icicle-dired'                         - Multi-command Dired
+`icicle-doc'                           - Show doc for fn, var, or face
+`icicle-doremi-candidate-width-factor+' - +/- candidate column width
+`icicle-doremi-increment-max-candidates+' - +/- max number candidates
+`icicle-doremi-increment-swank-prefix-length+' - +/- swank prefix
+`icicle-doremi-increment-swank-timeout+' - +/- swank completion msec
+`icicle-doremi-increment-variable+'    - Increment var using Do Re Mi
+`icicle-doremi-inter-candidates-min-spaces+' - +/- candidate spacing
+`icicle-doremi-zoom-Completions+'      - +/- `*Completions*' text size
+`icicle-execute-extended-command'      - Multi-command `M-x'
+`icicle-execute-named-keyboard-macro'  - Execute named keyboard macro
+`icicle-face-list'                     - Choose a list of face names
+`icicle-file-list'                     - Choose a list of file names
+`icicle-file'                          - Visit file/directory
+`icicle-find-file'                     -       same: relative only
+`icicle-find-file-absolute'            -       same: absolute only
+`icicle-find-file-all-tags'            - Visit tagged file
+`icicle-find-file-all-tags-regexp'
+`icicle-find-file-some-tags'
+`icicle-find-file-some-tags-regexp'
+`icicle-find-file-in-tags-table'       - File in Emacs tags table
+`icicle-find-file-tagged'              - Visit tagged file
+`icicle-find-first-tag'                - Visit definition with tag
+`icicle-find-tag'                      - Visit definition with tag
+`icicle-font'                          - Change font of frame
+`icicle-frame-bg'                      - Change background of frame
+`icicle-frame-fg'                      - Change foreground of frame
+`icicle-fundoc'                        - Show function description
+`icicle-goto-global-marker'            - Go to a global marker
+`icicle-goto-marker'                   - Go to a marker in this buffer
+`icicle-imenu*'                        - Navigate among Imenu entries
+`icicle-increment-option'              - Increment numeric option
+`icicle-increment-variable'            - Increment numeric variable
+`icicle-Info-goto-node'                - Multi-cmd `Info-goto-node'
+`icicle-Info-index'                    - Multi-command `Info-index'
+`icicle-Info-menu'                     - Multi-command `Info-menu'
+`icicle-insert-buffer'                 - Multi-command `insert-buffer'
+`icicle-insert-thesaurus-entry'        - Insert thesaurus entry(s)
+`icicle-keyword-list'                  - Choose a list of keywords
+`icicle-kill-buffer'                   - Kill buffer
+`icicle-locate-file'                   - Visit file(s) in a directory
+`icicle-minibuffer-help'               - Show Icicles minibuffer help
+`icicle-mode' or `icy-mode'            - Toggle Icicle mode
+`icicle-next-S-TAB-completion-method'  - Next S-TAB completion method
+`icicle-next-TAB-completion-method'    - Next TAB completion method
+`icicle-occur'                         - Incremental `occur'
+`icicle-other-window-or-frame'         - Other window/frame or select
+`icicle-plist'                         - Show symbols, property lists
+`icicle-recent-file'                   - Open recently used file(s)
+`icicle-recompute-shell-command-candidates' - Update from search path
+`icicle-remove-buffer-candidate'       - Remove always-candidate buf
+`icicle-remove-buffer-config'          - From `icicle-buffer-configs'
+`icicle-remove-entry-from-saved-completion-set' - From a saved set
+`icicle-remove-file-from-recentf-list' - Remove from recent files list
+`icicle-remove-saved-completion-set'   - From
+                                        `icicle-saved-completion-sets'
+`icicle-reset-option-to-nil'           - Set binary option(s) to nil
+`icicle-save-string-to-variable'       - Save text for use with `C-='
+`icicle-search'                        - Search with regexps & cycling
+`icicle-search-bookmark'               - Search bookmarks separately
+`icicle-search-all-tags-bookmark'      - Search tagged bookmarks 
+`icicle-search-all-tags-regexp-bookmark'
+`icicle-search-bookmark-list-bookmark' - Search bookmark lists
+`icicle-search-bookmarks-together'     - Search bookmarks together
+`icicle-search-char-property'          - Search for overlay/text props
+`icicle-search-dired-bookmark'         - Search Dired bookmarks
+`icicle-search-dired-marked'           - Search marked files in Dired
+`icicle-search-file'                   - Search multiple files
+`icicle-search-file-bookmark'          - Search bookmarked files
+`icicle-search-gnus-bookmark'          - Search bookmarked Gnus msgs
+`icicle-search-ibuffer-marked'         - Search marked bufs in Ibuffer
+`icicle-search-info-bookmark'          - Search bookmarked Info nodes
+`icicle-search-keywords'               - Search with regexp keywords
+`icicle-search-local-file-bookmark'    - Search bookmarked local files
+`icicle-search-man-bookmark'           - Search bookmarked `man' pages
+`icicle-search-non-file-bookmark'      - Search bookmarked buffers
+`icicle-search-overlay-property'       - Search for overlay properties
+`icicle-search-pages'                  - Search Emacs pages
+`icicle-search-paragraphs'             - Search Emacs paragraphs
+`icicle-search-region-bookmark'        - Search bookmarked regions
+`icicle-search-remote-file-bookmark'   - Search remote bookmarks
+`icicle-search-sentences'              - Search sentences as contexts
+`icicle-search-some-tags-bookmark'     - Search tagged bookmarks 
+`icicle-search-some-tags-regexp-bookmark'
+`icicle-search-text-property'          - Search for faces etc.
+`icicle-search-url-bookmark'           - Search bookmarked URLs
+`icicle-search-word'                   - Whole-word search
+`icicle-select-bookmarked-region'      - Select bookmarked regions
+`icicle-select-frame'                  - Select a frame by name
+`icicle-select-window'                 - Select window by buffer name
+`icicle-send-bug-report'               - Send Icicles bug report
+`icicle-set-option-to-t'               - Set binary option(s) to t
+`icicle-tag-a-file'                    - Tag a file a la delicious
+`icicle-toggle-~-for-home-dir'         - Toggle using `~' for $HOME
+`icicle-toggle-alternative-sorting'    - Swap alternative sort
+`icicle-toggle-angle-brackets'         - Toggle using angle brackets
+`icicle-toggle-C-for-actions'          - Toggle using `C-' for actions
+`icicle-toggle-case-sensitivity'       - Toggle case sensitivity
+`icicle-toggle-dot'                    - Toggle `.' matching newlines
+`icicle-toggle-expand-to-common-match' - Toggle input ECM expansion
+`icicle-toggle-hiding-common-match'    - Toggle match, `*Completions*'
+`icicle-toggle-hiding-non-matching-lines'- Toggle no-match lines
+`icicle-toggle-highlight-all-current'  - Toggle max search highlight
+`icicle-toggle-highlight-historical-candidates'
+                                       - Toggle past-input highlight
+`icicle-toggle-highlight-saved-candidates'
+                                       - Toggle highlighting saved
+`icicle-toggle-ignored-extensions'     - Toggle ignored files
+`icicle-toggle-ignored-space-prefix'   - Toggle ignoring space prefix
+`icicle-toggle-ignoring-comments'      - Toggle ignoring comments
+`icicle-toggle-incremental-completion' - Toggle apropos icompletion
+`icicle-toggle-option'                 - Toggle binary user option
+`icicle-toggle-proxy-candidates'       - Toggle proxy candidates
+`icicle-toggle-regexp-quote'           - Toggle regexp escaping
+`icicle-toggle-search-cleanup'         - Toggle search highlighting
+`icicle-toggle-search-complementing-domain' - Toggle complement search
+`icicle-toggle-search-replace-common-match' - Toggle ECM replacement
+`icicle-toggle-search-replace-whole'   - Toggle replacing whole hit
+`icicle-toggle-search-whole-word'      - Toggle whole-word searching
+`icicle-toggle-show-multi-completion'  - Toggle multi-completions
+`icicle-toggle-sorting'                - Toggle sorting of completions
+`icicle-toggle-transforming'           - Toggle duplicate removal
+`icicle-toggle-WYSIWYG-Completions'   - Toggle WYSIWYG `*Completions*'
+`icicle-untag-a-file'                  - Remove some tags from a file
+`icicle-vardoc'                        - Show variable description
+`icicle-where-is'                      - `where-is' multi-command
+`icicle-yank-maybe-completing'         - `yank' maybe using completion
+`toggle' (alias)                       - Toggle binary user option
+
+For more information, use `\\\\[icicle-minibuffer-help]' \
+when the minibuffer is active.
+
+Note: Depending on your platform, if you use Icicles in a text
+terminal (that is, without a window system/manager), then you might
+need to change some of the key bindings, if some of the default
+bindings are not available to you."
+    (interactive "P")
+    (setq icicle-mode  (if arg (> (prefix-numeric-value arg) 0) (not icicle-mode)))
+    (icicle-define-minibuffer-maps icicle-mode)
+    (cond (icicle-mode
+           ;; (when (interactive-p)
+           ;;   (unless (or window-system (and (fboundp 'daemonp) (daemonp)))
+           ;;     (with-output-to-temp-buffer "*Attention*"
+           ;;       (princ "You are using Icicles in a text terminal (no window ")
+           ;;       (princ "system/manager).\n\nIcicles makes use of many keys that are ")
+           ;;       (princ "unavailable when running\nEmacs in a text terminal.  You will ")
+           ;;       (princ "want to rebind those keys.\n")
+           ;;       (princ "See the Icicles doc, section Key Bindings.\n"))
+           ;;     (message "Icicles uses keys that might not be suitable for a text terminal")
+           ;;     (sit-for 5)))
+           (icicle-define-icicle-maps)
+           (icicle-bind-other-keymap-keys)
+           ;; This is not really necessary after the first time - no great loss.
+           (add-hook 'minibuffer-setup-hook       'icicle-minibuffer-setup)
+           (add-hook 'minibuffer-exit-hook        'icicle-cancel-Help-redirection)
+           (add-hook 'minibuffer-exit-hook        'icicle-restore-region-face)
+           (add-hook 'minibuffer-exit-hook        'icicle-unhighlight-lighter)
+           (add-hook 'icicle-post-command-hook    'icicle-activate-mark 'append)
+           (add-hook 'completion-setup-hook       'icicle-set-calling-cmd 'append)
+           (when icicle-customize-save-flag
+             (add-hook 'kill-emacs-hook           'icicle-command-abbrev-save))
+           (add-hook 'comint-mode-hook            'icicle-comint-hook-fn)
+           (add-hook 'compilation-mode-hook       'icicle-compilation-hook-fn)
+           (add-hook 'compilation-minor-mode-hook 'icicle-compilation-hook-fn)
+           ;; $$$$$$ Do this only in `icicle-display-candidates-in-Completions' now.
+           ;; $$$$$$ (add-hook 'temp-buffer-show-hook       'icicle-fit-completions-window)
+           (icicle-redefine-std-completion-fns)
+           (icicle-redefine-standard-functions)
+           (icicle-redefine-standard-options)
+           (if icicle-menu-items-to-history-flag
+               (add-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history)
+             (remove-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history))
+           (dolist (fn  icicle-inhibit-advice-functions)
+             (when (and (fboundp fn) (ad-is-active fn))
+               (push (cons fn (ad-copy-advice-info fn)) icicle-advice-info-list)
+               (ad-deactivate fn)))
+           (run-hooks 'icicle-mode-hook)
+           (message "Icicle mode is now ON"))
+          (t
+           (makunbound 'icicle-mode-map)
+           (icicle-restore-other-keymap-keys)
+           (remove-hook 'minibuffer-setup-hook    'icicle-minibuffer-setup)
+           (remove-hook 'minibuffer-exit-hook     'icicle-cancel-Help-redirection)
+           (remove-hook 'minibuffer-exit-hook     'icicle-restore-region-face)
+           (remove-hook 'icicle-post-command-hook 'icicle-activate-mark)
+           ;; The pre- and post-command hooks are local to the minibuffer,
+           ;; So they are added in `icicle-minibuffer-setup', not here.
+           ;; Nevertheless, they are removed here when Icicle mode is exited.
+           (remove-hook 'pre-command-hook         'icicle-top-level-prep)
+           (remove-hook 'pre-command-hook         'icicle-run-icicle-pre-command-hook t)
+           (remove-hook 'post-command-hook        'icicle-run-icicle-post-command-hook t)
+           (remove-hook 'completion-setup-hook    'icicle-set-calling-cmd)
+           (remove-hook 'kill-emacs-hook          'icicle-command-abbrev-save)
+           (remove-hook 'comint-mode-hook         'icicle-comint-hook-fn)
+           (remove-hook 'compilation-mode-hook    'icicle-compilation-hook-fn)
+           (remove-hook 'compilation-minor-mode-hook 'icicle-compilation-hook-fn)
+           ;; $$$$$$ Do this only in `icicle-display-candidates-in-Completions' now.
+           ;; $$$$$$ (remove-hook 'temp-buffer-show-hook    'icicle-fit-completions-window)
+           (icicle-restore-std-completion-fns)
+           (icicle-restore-standard-functions)
+           (icicle-restore-standard-options)
+           (unless (eq icicle-guess-commands-in-path 'load)
+             (setq icicle-shell-command-candidates-cache  ())) ; Reset - toggle Icy to update.
+           (remove-hook 'pre-command-hook 'icicle-add-menu-item-to-cmd-history)
+           (dolist (fn  icicle-inhibit-advice-functions)
+             (let ((info  (memq fn icicle-advice-info-list)))
+               (when (and (fboundp fn) info)
+                 (ad-set-advice-info fn info)
+                 (when (ad-is-active fn) (ad-activate fn)))))
+           (run-hooks 'icicle-mode-hook)
+           (message "Icicle mode is now OFF")))
+
+    (add-to-list 'minor-mode-alist '(icicle-mode " Icy"))))
+
+(defun icicle-add-menu-item-to-cmd-history ()
+  "Add `this-command' to command history, if it is a menu item.
+Menu items that are not associated with a command symbol are ignored.
+Used on `pre-command-hook'."
+  (condition-case nil                   ; Just in case, since this is on `pre-command-hook'.
+      (when (and (> (length (this-command-keys-vector)) 0)
+                 (equal '(menu-bar) (elt (this-command-keys-vector) 0))
+                 ;; Exclude uninterned symbols such as `menu-function-356'.
+                 (symbolp this-command) (or (< emacs-major-version 21) (intern-soft this-command)))
+        (pushnew (symbol-name this-command) extended-command-history))
+    (error nil)))
+
+(defun icicle-top-level-prep ()
+  "Do top-level stuff.  Used in `pre-command-hook'."
+  ;; Reset `icicle-current-TAB-method' and `icicle-apropos-complete-match-fn' if temporary.
+  ;; Save this top-level command as `icicle-last-top-level-command'
+  ;; Reset `icicle-candidates-alist' to ().
+  (when (= 0 (recursion-depth))
+    (let ((TAB-method  (get 'icicle-last-top-level-command 'icicle-current-TAB-method))
+          (apropos-fn  (get 'icicle-last-top-level-command 'icicle-apropos-complete-match-fn)))
+      (when TAB-method (setq icicle-current-TAB-method  TAB-method))
+      (when apropos-fn (setq icicle-apropos-complete-match-fn apropos-fn)))
+    (setq icicle-last-top-level-command   this-command
+          icicle-candidates-alist         ())))
+
+(defun icicle-define-icicle-maps ()
+  "Define `icicle-mode-map' and `icicle-menu-map'."
+  (setq icicle-mode-map  (make-sparse-keymap)) ; Recreate it each time, to capture latest bindings.
+
+  ;; Define `Icicles' menu-bar menu.  Create it only once: sacrifice any new bindings for speed.
+  (unless icicle-menu-map
+    (setq icicle-menu-map  (make-sparse-keymap "Icicles"))
+    (define-key icicle-menu-map [icicle-mode] '(menu-item "Turn Off Icicle Mode" icicle-mode))
+    (define-key icicle-menu-map [icicle-abort]
+      '(menu-item "Cancel Minibuffer" icicle-abort-recursive-edit
+        :enable (active-minibuffer-window)))
+    (define-key icicle-menu-map [icicle-report-bug]
+      '(menu-item "Send Bug Report" icicle-send-bug-report))
+    (define-key icicle-menu-map [icicle-customize-icicles-group]
+      '(menu-item "Customize Icicles" icicle-customize-icicles-group))
+    (define-key icicle-menu-map [icicle-help]
+      '(menu-item "Help" icicle-minibuffer-help
+        :help "Display help for minibuffer input and completion"
+        :keys "C-? in minibuf"))
+    (define-key icicle-menu-map [icicle-separator-last] '("--"))
+
+    (when (and (not icicle-touche-pas-aux-menus-flag) ; `Bookmark+' menu.
+               (boundp 'bmkp-bmenu-menubar-menu)) ; In `bookmark+-bmu.el'.
+      (defvar icicle-bookmark+-menu-map (make-sparse-keymap)
+        "Icicles submenu for `Bookmark+' menu.")
+      (define-key bmkp-bmenu-menubar-menu [icicles]
+        (list 'menu-item "Icicles" icicle-bookmark+-menu-map :visible 'icicle-mode))
+      (define-key icicle-bookmark+-menu-map [icicle-search-bookmark-list-marked]
+        '(menu-item "Search & Replace in Marked Files..." icicle-search-bookmark-list-marked
+          :visible icicle-mode :enable (eq major-mode 'bookmark-bmenu-mode)))
+      (define-key icicle-bookmark+-menu-map [icicle-bookmark-save-marked-files-more]
+        '(menu-item "Saved Marked Files as More Candidates..." icicle-bookmark-save-marked-files-more
+          :visible icicle-mode :enable (eq major-mode 'bookmark-bmenu-mode)))
+      (define-key icicle-bookmark+-menu-map [icicle-bookmark-save-marked-files]
+        '(menu-item "Saved Marked Files as Candidates..." icicle-bookmark-save-marked-files
+          :visible icicle-mode :enable (eq major-mode 'bookmark-bmenu-mode)))
+      (define-key icicle-bookmark+-menu-map [icicle-bookmark-save-marked-files-as-project]
+        '(menu-item "Save Marked Files as Project" icicle-bookmark-save-marked-files-as-project
+          :visible icicle-mode :enable (eq major-mode 'bookmark-bmenu-mode))))
+
+    (unless icicle-touche-pas-aux-menus-flag ; Use Dired's `Multiple' or `Operate' menu.
+      (defvar icicle-dired-multiple-menu-map (make-sparse-keymap)
+        "Icicles submenu for Dired's `Multiple' (or `Operate') menu.")
+      (if (boundp 'diredp-menu-bar-operate-menu) ; In `dired+.el'.
+          (define-key diredp-menu-bar-operate-menu [icicles]
+            (list 'menu-item "Icicles" icicle-dired-multiple-menu-map :visible 'icicle-mode))
+        (define-key dired-mode-map [menu-bar operate icicles]
+          (list 'menu-item "Icicles" icicle-dired-multiple-menu-map :visible 'icicle-mode)))
+      (define-key icicle-dired-multiple-menu-map [icicle-search-dired-marked]
+        '(menu-item "Search (and Replace)..." icicle-search-dired-marked
+          :visible icicle-mode :enable (eq major-mode 'dired-mode)))
+      (define-key icicle-dired-multiple-menu-map [icicle-dired-save-marked-more]
+        '(menu-item "Save as More Completion Candidates" icicle-dired-save-marked-more
+          :visible icicle-mode :enable (eq major-mode 'dired-mode)))
+      (define-key icicle-dired-multiple-menu-map [icicle-dired-save-marked]
+        '(menu-item "Save as Completion Candidates" icicle-dired-save-marked
+          :visible icicle-mode :enable (eq major-mode 'dired-mode)))
+      (define-key icicle-dired-multiple-menu-map [icicle-dired-save-marked-as-project]
+        '(menu-item "Save as Project" icicle-dired-save-marked-as-project
+          :visible icicle-mode :enable (eq major-mode 'dired-mode))))
+
+    (unless icicle-touche-pas-aux-menus-flag ; Use Dired's `Dir' or `Subdir' menu.
+      (defvar icicle-dired-dir-menu-map (make-sparse-keymap)
+        "Icicles submenu for Dired's `Dir' (or `Subdir') menu.")
+      (if (boundp 'diredp-menu-bar-subdir-menu) ; In `dired+.el'.
+          (define-key diredp-menu-bar-subdir-menu [icicles]
+            (list 'menu-item "Icicles" icicle-dired-dir-menu-map :visible 'icicle-mode))
+        (define-key dired-mode-map [menu-bar subdir icicles]
+          (list 'menu-item "Icicles" icicle-dired-dir-menu-map :visible 'icicle-mode)))
+      (define-key icicle-dired-dir-menu-map [icicle-dired-saved-file-candidates-other-window]
+        '(menu-item "Open Dired for Chosen Files..."
+          icicle-dired-saved-file-candidates-other-window
+          :visible icicle-mode
+          :enable (and icicle-saved-completion-candidates (eq major-mode 'dired-mode))))
+      (define-key icicle-dired-dir-menu-map [icicle-dired-project-other-window]
+        '(menu-item "Open Dired for Project..." icicle-dired-project-other-window
+          :visible icicle-mode
+          :enable (and icicle-saved-completion-sets (eq major-mode 'dired-mode)))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'Info-mode-menu)) ; Use `Info' menu, if available.
+           (defvar icicle-info-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Info' menu.")
+           (define-key Info-mode-menu [icicles]
+             (list 'menu-item "Icicles" icicle-info-menu-map :visible 'icicle-mode))
+           (when (fboundp 'icicle-Info-virtual-book)
+             (define-key icicle-info-menu-map [icicle-Info-virtual-book]
+               '(menu-item "Virtual Book" icicle-Info-virtual-book :visible icicle-mode
+                 :enable (eq major-mode 'Info-mode))))
+           (define-key icicle-info-menu-map [icicle-Info-goto-node]
+             '(menu-item "+ Go to Node..." icicle-Info-goto-node :visible icicle-mode
+               :enable (eq major-mode 'Info-mode) :keys "g"))
+           (define-key icicle-info-menu-map [icicle-Info-menu]
+             '(menu-item "+ Go to Menu Node..." icicle-Info-menu :visible icicle-mode
+               :enable (eq major-mode 'Info-mode) :keys "m"))
+           (define-key icicle-info-menu-map [icicle-Info-index]
+             '(menu-item "+ Look Up in Index..." icicle-Info-index :visible icicle-mode
+               :enable (eq major-mode 'Info-mode) :keys "i")))
+          (t
+           (when (fboundp 'icicle-Info-virtual-book)
+             (define-key icicle-menu-map [icicle-Info-virtual-book]
+               '(menu-item "Virtual Book" icicle-Info-virtual-book
+                 :enable (eq major-mode 'Info-mode))))
+           (define-key icicle-menu-map [icicle-Info-goto-node]
+             '(menu-item "+ Go to Node..." icicle-Info-goto-node
+               :enable (eq major-mode 'Info-mode)))
+           (define-key icicle-menu-map [icicle-Info-menu]
+             '(menu-item "+ Go to Menu Node..." icicle-Info-menu
+               :enable (eq major-mode 'Info-mode)))
+           (define-key icicle-menu-map [icicle-Info-index]
+             '(menu-item "+ Look Up in Index..." icicle-Info-index
+               :enable (eq major-mode 'Info-mode)))
+           (define-key icicle-menu-map [icicle-separator-Info]
+             '(menu-item "--" icicle-separator-Info :visible icicle-mode
+               :enable (eq major-mode 'Info-mode)))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-frames-menu)) ; Use `Frames' menu, defined in `menu-bar+.el'.
+           (defvar icicle-frames-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Frames' menu.")
+           (define-key menu-bar-frames-menu [icicles]
+             (list 'menu-item "Icicles" icicle-frames-menu-map :visible 'icicle-mode))
+           (define-key icicle-frames-menu-map [icicle-font]
+             '(menu-item "+ Change Font" icicle-font :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+           (define-key icicle-frames-menu-map [icicle-frame-fg]
+             '(menu-item "+ Change Foreground..." icicle-frame-fg :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+           (define-key icicle-frames-menu-map [icicle-frame-bg]
+             '(menu-item "+ Change Background..." icicle-frame-bg :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))))
+          (t
+           (define-key icicle-menu-map [icicle-font]
+             '(menu-item "+ Change Font of Frame..." icicle-font
+               :enable (and icicle-mode
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))))
+           (define-key icicle-menu-map [icicle-frame-fg]
+             '(menu-item "+ Change Foreground of Frame..." icicle-frame-fg
+               :enable (and icicle-mode
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))))
+           (define-key icicle-menu-map [icicle-frame-bg]
+             '(menu-item "+ Change Background of Frame..." icicle-frame-bg
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+           (define-key icicle-menu-map [icicle-separator-frame] '("--"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-describe-menu)) ; Use `Describe' menu, if available.
+           (defvar icicle-describe-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Describe' menu.")
+           (define-key menu-bar-describe-menu [icicles]
+             (list 'menu-item "Icicles" icicle-describe-menu-map :visible 'icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-plist]
+             '(menu-item "+ Symbol with Property List..." icicle-plist :visible icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-doc]
+             '(menu-item "+ Doc of Fun, Var, or Face..." icicle-doc :visible icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-fundoc]
+             '(menu-item "+ Function with Name, Doc..." icicle-fundoc :visible icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-vardoc]
+             '(menu-item "+ Variable with Name, Doc..." icicle-vardoc :visible icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-describe-option-of-type]
+             '(menu-item "+ Option of Type..." icicle-describe-option-of-type
+               :visible icicle-mode))
+           (define-key icicle-describe-menu-map [icicle-where-is]
+             '(menu-item "+ Where Is..." icicle-where-is :visible icicle-mode)))
+          (t
+           (define-key icicle-menu-map [icicle-plist]
+             '(menu-item "+ Symbol with Property List..." icicle-plist))
+           (define-key icicle-menu-map [icicle-doc]
+             '(menu-item "+ Doc of Fun, Var, or Face..." icicle-doc))
+           (define-key icicle-menu-map [icicle-fundoc]
+             '(menu-item "+ Describe Function with Name, Doc..." icicle-fundoc))
+           (define-key icicle-menu-map [icicle-vardoc]
+             '(menu-item "+ Describe Variable with Name, Doc..." icicle-vardoc))
+           (define-key icicle-menu-map [icicle-describe-option-of-type]
+             '(menu-item "+ Option of Type..." icicle-describe-option-of-type))
+           (define-key icicle-menu-map [icicle-where-is]
+             '(menu-item "+ Where Is..." icicle-where-is))
+           (define-key icicle-menu-map [icicle-separator-doc] '("--"))))
+
+    (define-key icicle-menu-map [icicle-apply]
+      '(menu-item "+ Apply Function to Alist Items..." icicle-apply))
+    (define-key icicle-menu-map [icicle-save-string-to-variable]
+      '(menu-item "Save String to Variable..." icicle-save-string-to-variable))
+    (define-key icicle-menu-map [icicle-color-theme]
+      '(menu-item "+ Choose Color Theme..." icicle-color-theme
+        :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+    (define-key icicle-menu-map [icicle-remove-saved-completion-set]
+      '(menu-item "+ Remove Saved Candidate Set..." icicle-remove-saved-completion-set
+        :enable icicle-saved-completion-sets))
+    (define-key icicle-menu-map [icicle-add/update-saved-completion-set]
+      '(menu-item "Add/Update Saved Candidate Set..." icicle-add/update-saved-completion-set))
+    (when (fboundp 'icicle-kmacro)
+      (define-key icicle-menu-map [icicle-kmacro]
+        '(menu-item "+ Execute Nth Keyboard Macro..." icicle-kmacro
+          :enable (or (kmacro-ring-head) kmacro-ring))))
+    (define-key icicle-menu-map [icicle-execute-named-keyboard-macro]
+      '(menu-item "+ Execute Named Keyboard Macro..." icicle-execute-named-keyboard-macro))
+    (define-key icicle-menu-map [icicle-separator-misc] '("--"))
+    (define-key icicle-menu-map [icicle-imenu]
+      '(menu-item "+ Imenu..." icicle-imenu
+        :enable imenu-generic-expression))
+    (define-key icicle-menu-map [icicle-goto-global-marker]
+      '(menu-item "+ Go To Global Marker..." icicle-goto-global-marker
+        :enable (consp (icicle-markers global-mark-ring)) :keys "C-- C-x C-SPC"))
+    (define-key icicle-menu-map [icicle-goto-marker]
+      '(menu-item "+ Go To Marker..." icicle-goto-marker
+        :enable (mark t) :keys "C-- C-SPC"))
+    (define-key icicle-menu-map [icicle-separator-goto] '("--"))
+    (define-key icicle-menu-map [icicle-search-bookmarks-together]
+      '(menu-item "+ Search Bookmarks Together..." icicle-search-bookmarks-together
+        :enable (featurep 'bookmark+) :keys "C-u C-`"))
+    (define-key icicle-menu-map [icicle-search-bookmark]
+      '(menu-item "+ Search Bookmarks Separately..." icicle-search-bookmark
+        :enable (featurep 'bookmark+)))
+    (define-key icicle-menu-map [icicle-select-bookmarked-region]
+      '(menu-item "+ Select Bookmarked Region..." icicle-select-bookmarked-region
+        :enable (featurep 'bookmark+) :keys "C-u C-x C-x"))
+    (define-key icicle-menu-map [icicle-separator-region] '("--"))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-apropos-menu)) ; Use `Apropos' menu, if available.
+           (defvar icicle-apropos-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Apropos' menu.")
+           (define-key menu-bar-apropos-menu [icicles]
+             (list 'menu-item "Icicles" icicle-apropos-menu-map :visible 'icicle-mode))
+           (define-key icicle-apropos-menu-map [icicle-apropos-zippy]
+             '(menu-item "Zippy..." icicle-apropos-zippy :visible icicle-mode))
+           (cond ((fboundp 'apropos-option)
+                  (define-key icicle-apropos-menu-map [icicle-apropos]
+                    '(menu-item "Symbols..." icicle-apropos :visible icicle-mode))
+                  (define-key icicle-apropos-menu-map [icicle-apropos-function]
+                    '(menu-item "Functions..." icicle-apropos-function :visible icicle-mode))
+                  (define-key icicle-apropos-menu-map [icicle-apropos-variable]
+                    '(menu-item "Variables..." icicle-apropos-variable :visible icicle-mode))
+                  (define-key icicle-apropos-menu-map [icicle-apropos-option]
+                    '(menu-item "Options..." icicle-apropos-option :visible icicle-mode))
+                  (define-key icicle-apropos-menu-map [icicle-apropos-command]
+                    '(menu-item "Commands..." icicle-apropos-command :visible icicle-mode)))
+                 (t
+                  (define-key icicle-apropos-menu-map [icicle-apropos-variable]
+                    '(menu-item "Variables..." icicle-apropos-variable
+                      :visible icicle-mode))))
+           (define-key icicle-apropos-menu-map [icicle-apropos-command]
+             '(menu-item "Commands..." icicle-apropos-command :visible icicle-mode)))
+          (t
+           (define-key icicle-menu-map [icicle-apropos-zippy]
+             '(menu-item "Apropos Zippy..." icicle-apropos-zippy))
+           (cond ((fboundp 'apropos-option)
+                  (define-key icicle-menu-map [icicle-apropos]
+                    '(menu-item "Apropos..." icicle-apropos))
+                  (define-key icicle-menu-map [icicle-apropos-function]
+                    '(menu-item "Apropos Functions..." icicle-apropos-function))
+                  (define-key icicle-menu-map [icicle-apropos-variable]
+                    '(menu-item "Apropos Variables..." icicle-apropos-variable))
+                  (define-key icicle-menu-map [icicle-apropos-option]
+                    '(menu-item "Apropos Options..." icicle-apropos-option))
+                  (define-key icicle-menu-map [icicle-apropos-command]
+                    '(menu-item "Apropos Commands..." icicle-apropos-command)))
+                 (t
+                  (define-key icicle-menu-map [icicle-apropos-variable]
+                    '(menu-item "Apropos Variables..." icicle-apropos-variable))
+                  (define-key icicle-menu-map [icicle-apropos-command]
+                    '(menu-item "Apropos Commands..." icicle-apropos-command))))
+           (define-key icicle-menu-map [icicle-separator-apropos] '("--"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-options-menu)) ; Use `Options' menu, if available.
+           (defvar icicle-options-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Options' menu.")
+           (define-key menu-bar-options-menu [icicles]
+             (list 'menu-item "Icicles" icicle-options-menu-map :visible 'icicle-mode))
+           (define-key icicle-options-menu-map [icicle-set-option-to-t]
+             '(menu-item "+ Turn On Any Option..." icicle-set-option-to-t :visible icicle-mode
+               :help "Set boolean option to `t' (C-u: any user option, C--: any var)"))
+           (define-key icicle-options-menu-map [icicle-reset-option-to-nil]
+             '(menu-item "+ Turn Off Any Option..." icicle-reset-option-to-nil :visible icicle-mode
+               :help "Reset an option to `nil' (C-u: reset any variable)"))
+           (define-key icicle-options-menu-map [icicle-toggle-option]
+             '(menu-item "+ Toggle Any Option..." icicle-toggle-option :visible icicle-mode
+               :help "Toggle boolean option (C-u: any user option, C--: any var)"))
+           (define-key icicle-options-menu-map [icicle-separator-options-general] '("--"))
+           (define-key icicle-options-menu-map [icicle-toggle-search-cleanup]
+             '(menu-item "Toggle Icicle-Search Highlighting Cleanup" icicle-toggle-search-cleanup
+               :visible icicle-mode :keys "C-." :help "Toggle option `icicle-search-cleanup-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-search-replace-common-match]
+             '(menu-item "Toggle Replacing Longest Common Match"
+               icicle-toggle-search-replace-common-match :visible icicle-mode
+               :enable icicle-searching-p :keys "M-;"
+               :help "Toggle option `icicle-search-replace-common-match-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-search-replace-whole]
+             '(menu-item "Toggle Replacing Whole Search Hit"
+               icicle-toggle-search-replace-whole :visible icicle-mode
+               :enable icicle-searching-p :keys "M-_"
+               :help "Toggle option `icicle-search-replace-whole-candidate-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-search-whole-word]
+             '(menu-item "Toggle Whole-Word Searching (Icicles Search)"
+               icicle-toggle-search-whole-word :visible icicle-mode
+               :enable icicle-searching-p :keys "M-q"
+               :help "Toggle `icicle-search-whole-word-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-search-complementing-domain]
+             '(menu-item "Toggle Searching Complement"
+               icicle-toggle-search-complementing-domain :visible icicle-mode :keys "C-M-~"
+               :help "Toggle `icicle-search-complement-domain-p'"))
+           (define-key icicle-options-menu-map [icicle-toggle-highlight-all-current]
+             '(menu-item "Toggle All-Current Icicle-Search Highlighting"
+               icicle-toggle-highlight-all-current :visible icicle-mode
+               :enable icicle-searching-p :keys "C-^"
+               :help "Toggle option `icicle-search-highlight-all-current-flag'"))
+           (define-key icicle-options-menu-map [icicle-separator-options-search] '("--"))
+           (define-key icicle-options-menu-map [icicle-toggle-regexp-quote]
+             '(menu-item "Toggle Escaping Special Chars" icicle-toggle-regexp-quote
+               :visible icicle-mode :keys "C-`"
+               :help "Toggle option `icicle-regexp-quote-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-dot]
+             '(menu-item "Toggle `.' Matching Newlines Too" icicle-toggle-dot
+               :visible icicle-mode :keys "C-M-."
+               :help "Toggle `icicle-dot-string' between `.' and `icicle-anychar-regexp'"))
+           (define-key icicle-options-menu-map [icicle-toggle-incremental-completion]
+             '(menu-item "Toggle Incremental Completion"
+               icicle-toggle-incremental-completion :visible icicle-mode :keys "C-#"
+               :help "Toggle option `icicle-incremental-completion-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-show-multi-completion]
+             '(menu-item "Toggle Showing Multi-Completions"
+               icicle-toggle-show-multi-completion :visible icicle-mode
+               :help "Toggle option `icicle-show-multi-completion-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-hiding-non-matching-lines]
+             '(menu-item "Toggle Hiding Non-Matching Lines"
+               icicle-toggle-hiding-non-matching-lines :visible icicle-mode :keys "C-u C-x ."
+               :help "Toggle option `icicle-hide-non-matching-lines-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-hiding-common-match]
+             '(menu-item "Toggle Hiding Common Match"
+               icicle-toggle-hiding-common-match :visible icicle-mode :keys "C-x ."
+               :help "Toggle option `icicle-hide-common-match-in-Completions-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-expand-to-common-match]
+             '(menu-item "Toggle Longest Common Match"
+               icicle-toggle-expand-to-common-match :visible icicle-mode :keys "C-;"
+               :help "Toggle option `icicle-expand-input-to-common-match-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-ignoring-comments]
+             '(menu-item "Toggle Ignoring Comments" icicle-toggle-ignoring-comments
+               :visible icicle-mode :keys "C-M-;"
+               :help "Toggle option `icicle-ignore-comments-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-ignored-space-prefix]
+             '(menu-item "Toggle Ignoring Space Prefix" icicle-toggle-ignored-space-prefix
+               :visible icicle-mode :keys "M-_"
+               :help "Toggle option `icicle-ignore-space-prefix-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-ignored-extensions]
+             '(menu-item "Toggle Ignored File Extensions" icicle-toggle-ignored-extensions
+               :visible icicle-mode :keys "C-."
+               :help "Toggle respect of `completion-ignored-extensions'"))
+           (define-key icicle-options-menu-map [icicle-toggle-remote-file-testing]
+             '(menu-item "Toggle Remote File Handling" icicle-toggle-remote-file-testing
+               :visible icicle-mode :enable (not icicle-searching-p) :keys "C-^"
+               :help "Toggle option `icicle-test-for-remote-files-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-angle-brackets]
+             '(menu-item "Toggle Angle Brackets" icicle-toggle-angle-brackets
+               :visible icicle-mode :help "Toggle option `icicle-key-descriptions-use-<>-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-highlight-saved-candidates]
+             '(menu-item "Toggle Highlighting Saved Candidates"
+               icicle-toggle-highlight-saved-candidates :visible icicle-mode :keys "S-pause"
+               :help "Toggle option `icicle-highlight-saved-candidates-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-highlight-historical-candidates]
+             '(menu-item "Toggle Highlighting Past Inputs"
+               icicle-toggle-highlight-historical-candidates :visible icicle-mode :keys "C-pause"
+               :help "Toggle option `icicle-highlight-historical-candidates-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-case-sensitivity]
+             '(menu-item "Toggle Case Sensitivity" icicle-toggle-case-sensitivity
+               :visible icicle-mode :keys "C-A"
+               :help "Toggle `case-fold-search', `completion-ignore-case' (C-u: file & buffer too)"))
+           (define-key icicle-options-menu-map [icicle-toggle-proxy-candidates]
+             '(menu-item "Toggle Including Proxy Candidates" icicle-toggle-proxy-candidates
+               :visible icicle-mode :keys "C-M-_"
+               :help "Toggle option `icicle-add-proxy-candidates-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-transforming]
+             '(menu-item "Toggle Duplicate Removal" icicle-toggle-transforming
+               :visible icicle-mode :keys "C-$"
+               :help "Toggle use of `icicle-transform-function' (default: remove dups)"))
+           (define-key icicle-options-menu-map [icicle-toggle-C-for-actions]
+             '(menu-item "Toggle Using `C-' for Actions" icicle-toggle-C-for-actions
+               :visible icicle-mode :keys "M-g"
+               :help "Toggle option `icicle-use-C-for-actions-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-~-for-home-dir]
+             '(menu-item "Toggle Using `~' for $HOME" icicle-toggle-~-for-home-dir
+               :visible icicle-mode :keys "M-~"
+               :help "Toggle option `icicle-use-~-for-home-dir-flag'"))
+           (define-key icicle-options-menu-map [icicle-toggle-WYSIWYG-Completions]
+             '(menu-item "Toggle WYSIWYG For `*Completions*'" icicle-toggle-WYSIWYG-Completions
+               :visible icicle-mode :help "Toggle option `icicle-WYSIWYG-Completions-flag'"))
+           (define-key icicle-options-menu-map [icicle-next-TAB-completion-method]
+             '(menu-item "Next `TAB' Completion Method"
+               icicle-next-TAB-completion-method :visible icicle-mode :keys "C-("
+               :help "Cycle to the next `TAB' completion method (C-u: ONE-OFF)"))
+           (define-key icicle-options-menu-map [icicle-next-S-TAB-completion-method]
+             '(menu-item "Next `S-TAB' Completion Method" icicle-next-S-TAB-completion-method
+               :visible icicle-mode :keys "M-("
+               :help "Cycle to the next `S-TAB' completion method (C-u: ONE-OFF)"))
+           (define-key icicle-options-menu-map [icicle-separator-options-sort] '("--"))
+           (define-key icicle-options-menu-map [icicle-toggle-alternative-sorting]
+             '(menu-item "Swap Alternative Sort" icicle-toggle-alternative-sorting
+               :visible icicle-mode :keys "C-M-,"
+               :help "Swap current sort order for current alternative sort order"))
+           (define-key icicle-options-menu-map [icicle-change-alternative-sort-order]
+             '(menu-item "Change Alternative Sort Order"
+               icicle-change-alternative-sort-order :visible icicle-mode :keys "M-,"
+               :help "Choose alt sort order (C-9: reverse, C-u: cyle/complete)"))
+           (define-key icicle-options-menu-map [icicle-change-sort-order]
+             '(menu-item "Change Sort Order" icicle-change-sort-order :visible icicle-mode
+               :enable (not icicle-inhibit-sort-p) :keys "C-,"
+               :help "Choose sort order (C-9: reverse, C-u: cyle/complete)"))
+           (when (fboundp 'doremi)
+             (define-key icicle-options-menu-map [icicle-separator-options-doremi]
+               '(menu-item "--" nil :visible (or (get-buffer-window "*Completions*" 'visible)
+                                              (eq (icicle-current-TAB-method) 'swank)
+                                              (active-minibuffer-window))))
+             (when (fboundp 'text-scale-increase) ; Emacs 23+.
+               (define-key icicle-options-menu-map [icicle-doremi-zoom-Completions+]
+                 '(menu-item "`*Completions*' Zoom Factor - Do Re Mi"
+                   icicle-doremi-zoom-Completions+
+                   :visible (and icicle-mode (get-buffer-window "*Completions*" 'visible))
+                   :keys "C-x -" :help "Zoom text in `*Completions*' incrementally")))
+             (define-key icicle-options-menu-map [icicle-doremi-inter-candidates-min-spaces+]
+               '(menu-item "Inter-Candidate Spacing - Do Re Mi"
+                 icicle-doremi-inter-candidates-min-spaces+
+                 :visible (and icicle-mode (get-buffer-window "*Completions*" 'visible))
+                 :keys "C-x |" :help "Change `icicle-inter-candidates-min-spaces' incrementally"))
+             (define-key icicle-options-menu-map [icicle-doremi-candidate-width-factor+]
+               '(menu-item "Candidate Column Width - Do Re Mi"
+                 icicle-doremi-candidate-width-factor+
+                 :visible (and icicle-mode (get-buffer-window "*Completions*" 'visible))
+                 :keys "C-x w" :help "Change `icicle-candidate-width-factor' incrementally"))
+             (define-key icicle-options-menu-map [icicle-doremi-increment-swank-prefix-length+]
+               '(menu-item "Swank Min Match Chars - Do Re Mi"
+                 icicle-doremi-increment-swank-prefix-length+
+                 :visible (and icicle-mode (eq (icicle-current-TAB-method) 'swank)) :keys "C-x 2"
+                 :help "Change `icicle-swank-prefix-length' incrementally"))
+             (define-key icicle-options-menu-map [icicle-doremi-increment-swank-timeout+]
+               '(menu-item "Swank Timeout - Do Re Mi"
+                 icicle-doremi-increment-swank-timeout+
+                 :visible (and icicle-mode (eq (icicle-current-TAB-method) 'swank)) :keys "C-x 1"
+                 :help "Change `icicle-swank-timeout' incrementally"))
+             (define-key icicle-options-menu-map [icicle-doremi-increment-max-candidates+]
+               '(menu-item "Max # of Completions - Do Re Mi"
+                 icicle-doremi-increment-max-candidates+
+                 :visible (and icicle-mode (active-minibuffer-window)) :keys "C-x #"
+                 :help "Change `icicle-max-candidates' incrementally"))))
+          (t
+           (define-key icicle-menu-map [icicle-set-option-to-t]
+             '(menu-item "+ Turn On Any Option..." icicle-set-option-to-t
+               :help "Set boolean option to `t' (C-u: any user option, C--: any var)"))
+           (define-key icicle-menu-map [icicle-reset-option-to-nil]
+             '(menu-item "+ Turn Off Any Option..." icicle-reset-option-to-nil
+               :help "Reset an option to `nil' (C-u: reset any variable)"))
+           (define-key icicle-menu-map [icicle-toggle-option]
+             '(menu-item "+ Toggle Any Option..." icicle-toggle-option
+               :help "Toggle boolean option (C-u: any user option, C--: any var)"))
+           (define-key icicle-menu-map [icicle-toggle-C-for-actions]
+             '(menu-item "Toggle Using `C-' for Actions" icicle-toggle-C-for-actions :keys "M-g"
+               :help "Toggle option `icicle-use-C-for-actions-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-~-for-home-dir]
+             '(menu-item "Toggle Using `~' for $HOME" icicle-toggle-~-for-home-dir :keys "M-~"
+               :help "Toggle option `icicle-use-~-for-home-dir-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-WYSIWYG-Completions]
+             '(menu-item "Toggle WYSIWYG For `*Completions*'" icicle-toggle-WYSIWYG-Completions
+               :help "Toggle option `icicle-WYSIWYG-Completions-flag'"))
+           (define-key icicle-menu-map [icicle-next-TAB-completion-method]
+             '(menu-item "Next `TAB' Completion Method" icicle-next-TAB-completion-method
+               :keys "C-(" :help "Cycle to the next `TAB' completion method (C-u: ONE-OFF)"))
+           (define-key icicle-menu-map [icicle-next-S-TAB-completion-method]
+             '(menu-item "Next `S-TAB' Completion Method" icicle-next-S-TAB-completion-method
+               :keys "M-(" :help "Cycle to the next `S-TAB' completion method (C-u: ONE-OFF)"))
+           (define-key icicle-menu-map [icicle-toggle-search-cleanup]
+             '(menu-item "Toggle Icicle-Search Highlighting Cleanup" icicle-toggle-search-cleanup
+               :keys "C-." :help "Toggle option `icicle-search-cleanup-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-search-replace-common-match]
+             '(menu-item "Toggle Replacing Longest Common Match"
+               icicle-toggle-search-replace-common-match :enable icicle-searching-p :keys "M-;"
+               :help "Toggle option `icicle-search-replace-common-match-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-search-replace-whole]
+             '(menu-item "Toggle Replacing Whole Search Hit" icicle-toggle-search-replace-whole
+               :enable icicle-searching-p :keys "M-_"
+               :help "Toggle option `icicle-search-replace-whole-candidate-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-search-whole-word]
+             '(menu-item "Toggle Whole-Word Searching (Icicles Search)"
+               icicle-toggle-search-whole-word
+               :enable icicle-searching-p :keys "M-q"
+               :help "Toggle `icicle-search-whole-word-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-regexp-quote]
+             '(menu-item "Toggle Escaping Special Chars" icicle-toggle-regexp-quote :keys "C-`"
+               :help "Toggle option `icicle-regexp-quote-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-dot]
+             '(menu-item "Toggle `.' Matching Newlines Too" icicle-toggle-dot :keys "C-M-."
+               :help "Toggle `icicle-dot-string' between `.' and `icicle-anychar-regexp'"))
+           (define-key icicle-menu-map [icicle-toggle-incremental-completion]
+             '(menu-item "Toggle Incremental Completion" icicle-toggle-incremental-completion
+               :keys "C-#" :help "Toggle option `icicle-incremental-completion-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-show-multi-completion]
+             '(menu-item "Toggle Showing Multi-Completions" icicle-toggle-show-multi-completion
+               :help "Toggle option `icicle-show-multi-completion-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-hiding-non-matching-lines]
+             '(menu-item "Toggle Hiding Non-Matching Lines"
+               icicle-toggle-hiding-non-matching-lines
+               :keys "C-u C-x ." :help "Toggle option `icicle-hide-non-matching-lines-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-hiding-common-match]
+             '(menu-item "Toggle Hiding Common Match" icicle-toggle-hiding-common-match
+               :keys "C-x ." :help "Toggle option `icicle-hide-common-match-in-Completions-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-expand-to-common-match]
+             '(menu-item "Toggle Longest Common Match" icicle-toggle-expand-to-common-match
+               :keys "C-;" :help "Toggle option `icicle-expand-input-to-common-match-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-ignoring-comments]
+             '(menu-item "Toggle Ignoring Comments" icicle-toggle-ignoring-comments
+               :keys "C-M-;" :help "Toggle option `icicle-ignore-comments-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-ignored-space-prefix]
+             '(menu-item "Toggle Ignoring Space Prefix" icicle-toggle-ignored-space-prefix
+               :keys "M-_" :help "Toggle option `icicle-ignore-space-prefix-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-ignored-extensions]
+             '(menu-item "Toggle Ignored File Extensions" icicle-toggle-ignored-extensions
+               :keys "C-." :help "Toggle respect of `completion-ignored-extensions'"))
+           (define-key icicle-menu-map [icicle-toggle-remote-file-testing]
+             '(menu-item "Toggle Remote File Handling" icicle-toggle-remote-file-testing
+               :enable (not icicle-searching-p) :keys "C-^"
+               :help "Toggle option `icicle-test-for-remote-files-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-angle-brackets]
+             '(menu-item "Toggle Angle Brackets" icicle-toggle-angle-brackets
+               :help "Toggle option `icicle-key-descriptions-use-<>-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-highlight-saved-candidates]
+             '(menu-item "Toggle Highlighting Saved Candidates"
+               icicle-toggle-highlight-saved-candidates :keys "S-pause"
+               :help "Toggle option `icicle-highlight-saved-candidates-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-highlight-historical-candidates]
+             '(menu-item "Toggle Highlighting Past Inputs"
+               icicle-toggle-highlight-historical-candidates :keys "C-pause"
+               :help "Toggle option `icicle-highlight-historical-candidates-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-case-sensitivity]
+             '(menu-item "Toggle Case Sensitivity" icicle-toggle-case-sensitivity :keys "C-A"
+               :help "Toggle `case-fold-search', `completion-ignore-case' (C-u: file & buffer too)"))
+           (define-key icicle-menu-map [icicle-toggle-proxy-candidates]
+             '(menu-item "Toggle Including Proxy Candidates" icicle-toggle-proxy-candidates
+               :keys "C-M-_" :help "Toggle option `icicle-add-proxy-candidates-flag'"))
+           (define-key icicle-menu-map [icicle-toggle-transforming]
+             '(menu-item "Toggle Duplicate Removal" icicle-toggle-transforming :keys "C-$"
+               :help "Toggle use of `icicle-transform-function' (default: remove dups)"))
+           (define-key icicle-menu-map [icicle-toggle-alternative-sorting]
+             '(menu-item "Swap Alternative Sort" icicle-toggle-alternative-sorting :keys "C-M-,"
+               :help "Swap current sort order for current alternative sort order"))
+           (define-key icicle-menu-map [icicle-change-alternative-sort-order]
+             '(menu-item "Change Alternative Sort Order" icicle-change-alternative-sort-order
+               :keys "M-," :help "Choose alt sort order (C-9: reverse, C-u: cyle/complete)"))
+           (define-key icicle-menu-map [icicle-change-sort-order]
+             '(menu-item "Change Sort Order" icicle-change-sort-order
+               :enable (not icicle-inhibit-sort-p) :keys "C-,"
+               :help "Choose sort order (C-9: reverse, C-u: cyle/complete)"))
+           (when (fboundp 'doremi)
+             (when (fboundp 'text-scale-increase) ; Emacs 23+.
+               (define-key icicle-menu-map [icicle-doremi-zoom-Completions+]
+                 '(menu-item "`*Completions*' Zoom Factor - Do Re Mi"
+                   icicle-doremi-zoom-Completions+
+                   :visible (get-buffer-window "*Completions*" 'visible) :keys "C-x -"
+                   :help "Zoom text in `*Completions*' incrementally")))
+             (define-key icicle-menu-map [icicle-doremi-inter-candidates-min-spaces+]
+               '(menu-item "Inter-Candidate Spacing - Do Re Mi"
+                 icicle-doremi-inter-candidates-min-spaces+
+                 :visible (get-buffer-window "*Completions*" 'visible) :keys "C-x |"
+                  :help "Change `icicle-inter-candidates-min-spaces' incrementally"))
+             (define-key icicle-menu-map [icicle-doremi-candidate-width-factor+]
+               '(menu-item "Candidate Column Width - Do Re Mi"
+                 icicle-doremi-candidate-width-factor+
+                 :visible (get-buffer-window "*Completions*" 'visible) :keys "C-x w"
+                 :help "Change `icicle-candidate-width-factor' incrementally"))
+             (define-key icicle-menu-map [icicle-doremi-increment-swank-prefix-length+]
+               '(menu-item "Swank Min Match Chars - Do Re Mi"
+                 icicle-doremi-increment-swank-prefix-length+
+                 :visible (eq (icicle-current-TAB-method) 'swank) :keys "C-x 2"
+                 :help "Change `icicle-swank-prefix-length' incrementally"))
+             (define-key icicle-menu-map [icicle-doremi-increment-swank-timeout+]
+               '(menu-item "Swank Timeout - Do Re Mi"
+                 icicle-doremi-increment-swank-timeout+
+                 :visible  (eq (icicle-current-TAB-method) 'swank) :keys "C-x 1"
+                 :help "Change `icicle-swank-timeout' incrementally"))
+             (define-key icicle-menu-map [icicle-doremi-increment-max-candidates+]
+               '(menu-item "Max # of Completions - Do Re Mi"
+                 icicle-doremi-increment-max-candidates+
+                 :visible (active-minibuffer-window) :keys "C-x #"
+                 :help "Change `icicle-max-candidates' incrementally")))
+           (define-key icicle-menu-map [icicle-separator-toggle] '("--"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-custom-menu)) ; Use `Customize' menu, if available.
+           (defvar icicle-custom-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Customize' menu.")
+           (define-key menu-bar-custom-menu [icicles]
+             (list 'menu-item "Icicles" icicle-custom-menu-map :visible 'icicle-mode))
+           (define-key icicle-custom-menu-map [icicle-customize-apropos-groups]
+             '(menu-item "Groups Matching Regexp..." icicle-customize-apropos-groups
+               :visible icicle-mode :help "Customize all user groups matching a regexp"))
+           (define-key icicle-custom-menu-map [icicle-customize-apropos-faces]
+             '(menu-item "Faces Matching Regexp..." icicle-customize-apropos-faces
+               :visible icicle-mode :help "Customize all user faces matching a regexp"))
+           (define-key icicle-custom-menu-map [icicle-customize-face]
+             '(menu-item "+ Face..." icicle-customize-face :visible icicle-mode
+                :help "Customize a face"))
+           (define-key icicle-custom-menu-map [icicle-customize-apropos-options]
+             '(menu-item "Options Matching Regexp..." icicle-customize-apropos-options
+               :visible icicle-mode :help "Customize all user options matching a regexp"))
+           (define-key icicle-custom-menu-map [icicle-customize-apropos]
+             '(menu-item "Settings Matching Regexp..." icicle-customize-apropos
+               :visible icicle-mode :help "Customize all user settings matching a regexp")))
+          (t
+           (define-key icicle-menu-map [icicle-separator-customize] '("--"))
+           (define-key icicle-menu-map [icicle-customize-apropos-groups]
+             '(menu-item "Groups Matching Regexp..." icicle-customize-apropos-groups
+                :help "Customize all customization groups matching a regexp"))
+           (define-key icicle-menu-map [icicle-customize-apropos-faces]
+             '(menu-item "Faces Matching Regexp..." icicle-customize-apropos-faces
+                :help "Customize all faces matching a regexp"))
+           (define-key icicle-menu-map [icicle-customize-face]
+             '(menu-item "+ Face..." icicle-customize-face :help "Customize a face"))
+           (define-key icicle-menu-map [icicle-customize-apropos-options]
+             '(menu-item "Options Matching Regexp..." icicle-customize-apropos-options
+                :help "Customize all user options matching a regexp"))
+           (define-key icicle-menu-map [icicle-customize-apropos]
+             '(menu-item "Settings Matching Regexp..." icicle-customize-apropos
+                :help "Customize all user settings matching a regexp"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-edit-menu)) ; Use `Edit' menu, if available.
+           (defvar icicle-edit-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Edit' menu.")
+           (define-key menu-bar-edit-menu [icicles]
+             (list 'menu-item "Icicles" icicle-edit-menu-map :visible 'icicle-mode))
+           (define-key icicle-edit-menu-map [icicle-complete-thesaurus-entry]
+             '(menu-item "Complete with Thesaurus..." icicle-complete-thesaurus-entry
+               :visible icicle-mode
+               :enable (and (not buffer-read-only) (boundp 'synonyms-obarray))))
+           (define-key icicle-edit-menu-map [icicle-insert-thesaurus-entry]
+             '(menu-item "+ Insert Thesaurus Entry..." icicle-insert-thesaurus-entry
+               :visible icicle-mode
+               :enable (and (not buffer-read-only) (boundp 'synonyms-obarray))))
+           (define-key icicle-edit-menu-map [icicle-completing-yank]
+             '(menu-item "+ Paste Copied Text..." icicle-completing-yank :visible icicle-mode
+               :enable (not buffer-read-only) :keys "C-- C-y")))
+          (t
+           (define-key icicle-menu-map [icicle-separator-edit] '("--"))
+           (define-key icicle-menu-map [icicle-complete-thesaurus-entry]
+             '(menu-item "Complete with Thesaurus..." icicle-complete-thesaurus-entry
+               :enable (and (not buffer-read-only) (boundp 'synonyms-obarray))
+               :help "Complete a word to an entry from a thesaurus"))
+           (define-key icicle-menu-map [icicle-insert-thesaurus-entry]
+             '(menu-item "+ Insert Thesaurus Entry..." icicle-insert-thesaurus-entry
+               :enable (and (not buffer-read-only) (boundp 'synonyms-obarray))
+               :help "Insert an entry from a thesaurus"))
+           (define-key icicle-menu-map [icicle-completing-yank]
+             '(menu-item "+ Paste Copied Text..." icicle-completing-yank
+               :enable (not buffer-read-only) :keys "C-- C-y"
+               :help "Yank an entry from the `kill-ring', choosing it using completion"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-file-menu)) ; Use `File' menu, if available.
+           (defvar icicle-file-menu-map (make-sparse-keymap)
+             "Icicles submenu for `File' menu.")
+           (define-key menu-bar-file-menu [icicles]
+             (list 'menu-item "Icicles" icicle-file-menu-map :visible 'icicle-mode))
+           (define-key icicle-file-menu-map [icicle-kill-buffer]
+             '(menu-item "+ Kill Buffer..." icicle-kill-buffer :visible icicle-mode :keys "C-x k"
+               :help "Kill a buffer (C-0: same-mode, C-9: file, C-- this-frame"))
+           (define-key icicle-file-menu-map [icicle-delete-file]
+             '(menu-item "+ Delete File..." icicle-delete-file :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Delete a file or directory"))
+           (when (featurep 'recentf)
+             (define-key icicle-file-menu-map [icicle-remove-file-from-recentf-list]
+               '(menu-item "+ Remove from Recent Files List..."
+                 icicle-remove-file-from-recentf-list :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Remove file from `recentf-list' - the list of recently used files"))
+             (define-key icicle-file-menu-map [icicle-recent-file-other-window]
+               '(menu-item "+ Open Recent File (Other Window)..."
+                 icicle-recent-file-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Open a recently used file in another window"))
+             (define-key icicle-file-menu-map [icicle-recent-file]
+               '(menu-item "+ Open Recent File..." icicle-recent-file :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Open a recently used file")))
+           (define-key icicle-file-menu-map [icicle-dired-saved-file-candidates-other-window]
+             '(menu-item "Open Dired for Chosen Files..."
+               icicle-dired-saved-file-candidates-other-window :visible icicle-mode
+               :enable (and icicle-saved-completion-candidates
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Open Dired on a set of files & directories of your choice"))
+           (define-key icicle-file-menu-map [icicle-dired-project-other-window]
+             '(menu-item "Open Dired for Project..." icicle-dired-project-other-window
+               :visible icicle-mode
+               :enable (and icicle-saved-completion-sets
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Open Dired on a saved project in another window"))
+           (define-key icicle-file-menu-map [icicle-locate-file-other-window]
+             '(menu-item "+ Open File Under Directory (Other Window)..."
+               icicle-locate-file-other-window :visible icicle-mode
+               :help "Visit a file within a directory or its subdirectories, in another window"))
+           (define-key icicle-file-menu-map [icicle-locate-file]
+             '(menu-item "+ Open File Under Directory..." icicle-locate-file :visible icicle-mode
+               :help "Visit a file within a directory or its subdirectories"))
+           (define-key icicle-file-menu-map [icicle-file-other-window]
+             '(menu-item "+ Open File or Directory (Other Window)..." icicle-file-other-window
+               :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Visit a file or directory in another window"))
+           (define-key icicle-file-menu-map [icicle-file]
+             '(menu-item "+ Open File or Directory..." icicle-file :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Visit a file or directory (C-u absolute, C-- absolute by date)")))
+          (t
+           (define-key icicle-menu-map [icicle-kill-buffer]
+             '(menu-item "+ Kill Buffer..." icicle-kill-buffer
+               :help "Kill a buffer (C-0: same-mode, C-9: file, C-- this-frame"))
+           (define-key icicle-menu-map [icicle-delete-file]
+             '(menu-item "+ Delete File..." icicle-delete-file
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Delete a file or directory"))
+           (when (featurep 'recentf)
+             (define-key icicle-menu-map [icicle-remove-file-from-recentf-list]
+               '(menu-item "+ Remove from Recent Files List..."
+                 icicle-remove-file-from-recentf-list
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Remove file from `recentf-list' - the list of recently used files"))
+             (define-key icicle-menu-map [icicle-recent-file-other-window]
+               '(menu-item "+ Open Recent File (Other Window)..." icicle-recent-file-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Open a recently used file in another window"))
+             (define-key icicle-menu-map [icicle-recent-file]
+               '(menu-item "+ Open Recent File..." icicle-recent-file
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Open a recently used file")))
+           (define-key icicle-menu-map [icicle-dired-saved-file-candidates-other-window]
+             '(menu-item "Open Dired for Chosen Files..."
+               icicle-dired-saved-file-candidates-other-window
+               :enable (and icicle-saved-completion-candidates
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Open Dired on a set of files & directories of your choice"))
+           (define-key icicle-menu-map [icicle-dired-project-other-window]
+             '(menu-item "Open Dired for Project..." icicle-dired-project-other-window
+               :enable (and icicle-saved-completion-sets
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Open Dired on a saved project in another window"))
+           (define-key icicle-menu-map [icicle-locate-file-other-window]
+             '(menu-item "+ Open File Under Directory (Other Window)..."
+               icicle-locate-file-other-window
+               :help "Visit a file within a directory or its subdirectories, in another window"))
+           (define-key icicle-menu-map [icicle-locate-file]
+             '(menu-item "+ Open File Under Directory..." icicle-locate-file
+               :help "Visit a file within a directory or its subdirectories"))
+           (define-key icicle-menu-map [icicle-file-other-window]
+             '(menu-item "+ Open File or Directory (Other Window)..."
+               icicle-file-other-window
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Visit a file or directory in another window"))
+           (define-key icicle-menu-map [icicle-file]
+             '(menu-item "+ Open File or Directory ..." icicle-file
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Visit a file or directory (C-u absolute, C-- absolute by date)"))))
+    (define-key icicle-menu-map [icicle-buffer-list]
+      '(menu-item "+ Buffer List..." icicle-buffer-list :help "Choose a list of buffer names"))
+    (define-key icicle-menu-map [icicle-remove-buffer-config]
+      '(menu-item "+ Remove Buffer Configuration..." icicle-remove-buffer-config
+        :enable icicle-buffer-configs
+        :help "Remove buffer configuration from `icicle-buffer-configs'"))
+    (define-key icicle-menu-map [icicle-add-buffer-config]
+      '(menu-item "New Buffer Configuration..." icicle-add-buffer-config
+        :help "Add buffer configuration to `icicle-buffer-configs'"))
+    (define-key icicle-menu-map [icicle-buffer-config]
+      '(menu-item "+ Choose Buffer Configuration..." icicle-buffer-config
+        :enable icicle-buffer-configs
+        :help "Choose a configuration of user options for `icicle-buffer'"))
+    (define-key icicle-menu-map [icicle-remove-buffer-candidate]
+      '(menu-item "+ Don't Always Include Buffer..." icicle-remove-buffer-candidate
+        :enable icicle-buffer-extras :help "Remove buffer as an always-show completion candidate"))
+    (define-key icicle-menu-map [icicle-add-buffer-candidate]
+      '(menu-item "+ Always Include Buffer..." icicle-add-buffer-candidate
+        :help "Add buffer as an always-show completion candidate"))
+    (define-key icicle-menu-map [icicle-kill-buffer]
+      '(menu-item "+ Kill Buffer..." icicle-kill-buffer
+        :help "Kill a buffer (C-0: same-mode, C-9: file, C-- this-frame"))
+    (define-key icicle-menu-map [icicle-insert-buffer]
+      '(menu-item "+ Insert Buffer..." icicle-insert-buffer
+        :help "Multi-command version of `insert-buffer'"))
+    (define-key icicle-menu-map [icicle-delete-windows]
+      '(menu-item "+ Delete Windows on Buffer..." icicle-delete-windows :keys "C-u C-x 0"
+        :help "Delete windows showing a buffer, anywhere"))
+    (define-key icicle-menu-map [icicle-buffer-other-window]
+      '(menu-item "+ Switch to Buffer (Other Window)..." icicle-buffer-other-window
+        :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+    (define-key icicle-menu-map [icicle-buffer]
+      '(menu-item "+ Switch to Buffer..." icicle-buffer
+        :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+        :help "Switch to a buffer (C-0: same mode, C-9: file buffer, C--: same frame"))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-bookmark-map)) ; Use `Bookmarks' menu, if available.
+           (require 'bookmark)          ; `bookmark-buffer-name' is not autoloaded.
+           (defvar icicle-bookmark-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Bookmarks' menu.")
+           (define-key menu-bar-bookmark-map [icicles]
+             (list 'menu-item "Icicles" icicle-bookmark-menu-map :visible 'icicle-mode))
+           (define-key icicle-bookmark-menu-map [icicle-goto-global-marker]
+             '(menu-item "+ Go To Global Marker..." icicle-goto-global-marker :visible icicle-mode
+               :enable (consp (icicle-markers global-mark-ring)) :keys "C-- C-x C-SPC"
+               :help "Go to a global marker, choosing it by its line"))
+           (define-key icicle-bookmark-menu-map [icicle-goto-marker]
+             '(menu-item "+ Go To Marker..." icicle-goto-marker :visible icicle-mode
+               :enable (consp (icicle-markers mark-ring)) :keys "C-- C-SPC"
+               :help "Go to a marker in this buffer, choosing it by its line"))
+           (define-key icicle-bookmark-menu-map [icicle-separator-goto] '("--"))
+           (when (featurep 'bookmark+)
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-all-tags-regexp-other-window]
+               '(menu-item "All Tags Matching Regexp..." icicle-bookmark-all-tags-regexp-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark that has each tag matching a regexp that you enter"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-some-tags-regexp-other-window]
+               '(menu-item "Any Tag Matching Regexp..." icicle-bookmark-some-tags-regexp-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark with at least one tag matching a regexp"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-all-tags-other-window]
+               '(menu-item "All Tags in Set..." icicle-bookmark-all-tags-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark that has all of a set of tags that you enter"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-some-tags-other-window]
+               '(menu-item "Any Tag in Set..." icicle-bookmark-some-tags-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark that has some of a set of tags that you enter"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-file-all-tags-regexp-other-window]
+               '(menu-item "File, All Tags Matching Regexp..."
+                 icicle-bookmark-file-all-tags-regexp-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file or dir bookmark where each tag matches a regexp"))
+             (define-key icicle-bookmark-menu-map
+                 [icicle-bookmark-file-some-tags-regexp-other-window]
+               '(menu-item "File, Any Tag Matching Regexp..."
+                 icicle-bookmark-file-some-tags-regexp-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file or dir bookmark where at least one tag matches a regexp"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-file-all-tags-other-window]
+               '(menu-item "File, All Tags in Set..." icicle-bookmark-file-all-tags-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file or dir bookmark that has all of a set of tags"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-file-some-tags-other-window]
+               '(menu-item "File, Any Tag in Set..." icicle-bookmark-file-some-tags-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file or dir bookmark that has some of a set of tags"))
+             (define-key icicle-bookmark-menu-map [icicle-separator-bookmark-tags] '("--"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-non-file-other-window]
+               '(menu-item "+ Jump to Buffer (Non-File) Bookmark..."
+                 icicle-bookmark-non-file-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a buffer (i.e., a non-file) bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-region-other-window]
+               '(menu-item "+ Jump to Region Bookmark..." icicle-bookmark-region-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark and activate its recorded region"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-url-other-window]
+               '(menu-item "+ Jump to URL Bookmark..." icicle-bookmark-url-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a URL bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-gnus-other-window]
+               '(menu-item "+ Jump to Gnus Bookmark..." icicle-bookmark-gnus-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a Gnus bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-man-other-window]
+               '(menu-item "+ Jump to `man' Bookmark..." icicle-bookmark-man-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a `man'-page bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-info-other-window]
+               '(menu-item "+ Jump to Info Bookmark..." icicle-bookmark-info-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to an Info bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-remote-file-other-window]
+               '(menu-item "+ Jump to Remote-File Bookmark..."
+                 icicle-bookmark-remote-file-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a remote-file bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-local-file-other-window]
+               '(menu-item "+ Jump to Local-File Bookmark..."
+                 icicle-bookmark-local-file-other-window :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a local-file bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-file-other-window]
+               '(menu-item "+ Jump to File Bookmark..." icicle-bookmark-file-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-dired-other-window]
+               '(menu-item "+ Jump to Dired Bookmark..." icicle-bookmark-dired-other-window
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a Dired bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-bookmark-list]
+               '(menu-item "+ Jump to Bookmark-List Bookmark..."
+                 icicle-bookmark-bookmark-list :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark-list bookmark"))
+             (define-key icicle-bookmark-menu-map [icicle-bookmark-desktop]
+               '(menu-item "+ Jump to Desktop Bookmark..." icicle-bookmark-desktop
+                 :visible icicle-mode
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to an Emacs desktop bookmark"))
+             )
+           (define-key icicle-bookmark-menu-map [icicle-bookmark-other-window]
+             '(menu-item "+ Jump to Bookmark..." icicle-bookmark-other-window :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Jump to a bookmark (C-u: reverse `icicle-bookmark-refresh-cache-flag')"))
+           (define-key icicle-bookmark-menu-map [icicle-bookmark]
+             '(menu-item "+ Jump to Bookmark (Same Window)..." icicle-bookmark :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Jump to a bookmark (C-u: reverse `icicle-bookmark-refresh-cache-flag')")))
+          (t
+           (when (featurep 'bookmark+)
+             (define-key icicle-menu-map [icicle-bookmark-non-file-other-window]
+               '(menu-item "+ Jump to Buffer (Non-File) Bookmark..."
+                 icicle-bookmark-non-file-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a buffer (i.e., a non-file) bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-region-other-window]
+               '(menu-item "+ Jump to Region Bookmark..." icicle-bookmark-region-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark and activate its recorded region"))
+             (define-key icicle-menu-map [icicle-bookmark-url-other-window]
+               '(menu-item "+ Jump to URL Bookmark..." icicle-bookmark-url-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a URL bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-gnus-other-window]
+               '(menu-item "+ Jump to Gnus Bookmark..." icicle-bookmark-gnus-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a Gnus bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-man-other-window]
+               '(menu-item "+ Jump to `man' Bookmark..." icicle-bookmark-man-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a `man'-page bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-info-other-window]
+               '(menu-item "+ Jump to Info Bookmark..." icicle-bookmark-info-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to an Info bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-remote-file-other-window]
+               '(menu-item "+ Jump to Remote-File Bookmark..."
+                 icicle-bookmark-remote-file-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a remote-file bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-local-file-other-window]
+               '(menu-item "+ Jump to Local-File Bookmark..."
+                 icicle-bookmark-local-file-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a local-file bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-file-other-window]
+               '(menu-item "+ Jump to File Bookmark..." icicle-bookmark-file-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a file bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-dired-other-window]
+               '(menu-item "+ Jump to Dired Bookmark..." icicle-bookmark-dired-other-window
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a Dired bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-bookmark-list]
+               '(menu-item "+ Jump to Bookmark-List Bookmark..."
+                 icicle-bookmark-bookmark-list
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to a bookmark-list bookmark"))
+             (define-key icicle-menu-map [icicle-bookmark-desktop]
+               '(menu-item "+ Jump to Desktop Bookmark..." icicle-bookmark-desktop
+                 :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                 :help "Jump to an Emacs desktop bookmark"))
+             )
+           (define-key icicle-menu-map [icicle-bookmark-other-window]
+             '(menu-item "+ Jump To Bookmark..." icicle-bookmark-other-window
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Jump to a bookmark (C-u: reverse `icicle-bookmark-refresh-cache-flag')"))
+           (define-key icicle-menu-map [icicle-bookmark]
+             '(menu-item "+ Jump To Bookmark (Same Window)..." icicle-bookmark
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Jump to a bookmark (C-u: reverse `icicle-bookmark-refresh-cache-flag')"))
+           (define-key icicle-menu-map [icicle-separator-bookmark] '("--"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-search-tags-menu)) ; Use `Tags' menu, defined in `menu-bar+.el'.
+           (defvar icicle-search-tags-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Tags' submenu of `Search' menu.")
+           (define-key menu-bar-search-tags-menu [icicles]
+             (list 'menu-item "Icicles" icicle-search-tags-menu-map :visible 'icicle-mode))
+           (define-key icicle-search-tags-menu-map [icicle-tags-search]
+             '(menu-item "+ Search Tagged Files ..." icicle-tags-search :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search all source files listed in tags tables for matches for a regexp"))
+           (define-key icicle-search-tags-menu-map [icicle-pop-tag-mark]
+             '(menu-item "+ Back (Pop Tag Mark)" icicle-pop-tag-mark :visible icicle-mode
+               :enable (and (boundp 'find-tag-marker-ring)
+                        (not (ring-empty-p find-tag-marker-ring))
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Pop back to where `M-.' was last invoked"))
+           (define-key icicle-search-tags-menu-map [icicle-find-first-tag-other-window]
+             '(menu-item "+ Find First Tag ..." icicle-find-first-tag-other-window
+               :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Find first tag in current tags table whose name matches your input"))
+           (define-key icicle-search-tags-menu-map [icicle-find-tag]
+             '(menu-item "+ Find Tag ..." icicle-find-tag :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Navigate among all tags that match a regexp")))
+          ((and (not icicle-touche-pas-aux-menus-flag) ; Use `Search' menu, if no `Tags' menu.
+                (boundp 'menu-bar-search-menu))
+           (defvar icicle-search-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Search' menu.")
+           (define-key menu-bar-search-menu [icicles]
+             (list 'menu-item "Icicles" icicle-search-menu-map :visible 'icicle-mode))
+           (defvar icicle-search-tags-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Tags' submenu of `Search' menu.")
+           (define-key icicle-search-menu-map [icicles-tags]
+             (list 'menu-item "Tags" icicle-search-tags-menu-map :visible 'icicle-mode))
+           (define-key icicle-search-tags-menu-map [icicle-tags-search]
+             '(menu-item "+ Search Tagged Files ..." icicle-tags-search :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search all source files listed in tags tables for matches for a regexp"))
+           (define-key icicle-search-tags-menu-map [icicle-pop-tag-mark]
+             '(menu-item "+ Back (Pop Tag Mark)" icicle-pop-tag-mark :visible icicle-mode
+               :enable (and (boundp 'find-tag-marker-ring)
+                        (not (ring-empty-p find-tag-marker-ring))
+                        (not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+               :help "Pop back to where `M-.' was last invoked"))
+           (define-key icicle-search-tags-menu-map [icicle-find-first-tag-other-window]
+             '(menu-item "+ Find First Tag ..." icicle-find-first-tag-other-window
+               :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Find first tag in current tags table whose name matches your input"))
+           (define-key icicle-search-tags-menu-map [icicle-find-tag]
+             '(menu-item "+ Find Tag ..." icicle-find-tag :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Navigate among all tags that match a regexp")))
+          (t
+           (define-key icicle-menu-map [icicle-tags-search]
+             '(menu-item "+ Search Tagged Files ..." icicle-tags-search
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search all source files listed in tags tables for matches for a regexp"))
+           (define-key icicle-menu-map [icicle-pop-tag-mark]
+             '(menu-item "+ Back (Pop Tag Mark)" icicle-pop-tag-mark
+               :enable (and (boundp 'find-tag-marker-ring)
+                        (not (ring-empty-p find-tag-marker-ring))
+                        (not (window-minibuffer-p
+                              (frame-selected-window menu-updating-frame))))
+               :help "Pop back to where `M-.' was last invoked"))
+           (define-key icicle-menu-map [icicle-find-first-tag-other-window]
+             '(menu-item "Find First Tag ..." icicle-find-first-tag-other-window
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Find first tag in current tags table whose name matches your input"))
+           (define-key icicle-menu-map [icicle-find-tag]
+             '(menu-item "Find Tag ..." icicle-find-tag
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Navigate among all tags that match a regexp"))))
+
+    (cond ((and (not icicle-touche-pas-aux-menus-flag)
+                (boundp 'menu-bar-search-menu)) ; Use `Search' menu, if available.
+           (defvar icicle-search-menu-map (make-sparse-keymap)
+             "Icicles submenu for `Search' menu.")
+           (define-key menu-bar-search-menu [icicles]
+             (list 'menu-item "Icicles" icicle-search-menu-map :visible 'icicle-mode))
+           (define-key icicle-search-menu-map [icicle-goto-global-marker]
+             '(menu-item "+ Go To Global Marker..." icicle-goto-global-marker :visible icicle-mode
+               :enable (consp (icicle-markers global-mark-ring)) :keys "C-- C-x C-SPC"
+               :help "Go to a global marker, choosing it by its line"))
+           (define-key icicle-search-menu-map [icicle-goto-marker]
+             '(menu-item "+ Go To Marker..." icicle-goto-marker :visible icicle-mode
+               :enable (consp (icicle-markers mark-ring)) :keys "C-- C-SPC"
+               :help "Go to a marker in this buffer, choosing it by its line"))
+           (define-key icicle-search-menu-map [icicle-separator-goto] '("--"))
+           (define-key icicle-search-menu-map [icicle-search-highlight-cleanup]
+             '(menu-item "Remove Icicle-Search Highlighting..." icicle-search-highlight-cleanup
+               :visible icicle-mode
+               :enable (or icicle-search-overlays (overlayp icicle-search-current-overlay)
+                        (overlayp icicle-search-refined-overlays) icicle-search-refined-overlays)
+               :help "Remove all highlighting from the last use of `icicle-search'"))
+           (define-key icicle-search-menu-map [icicle-compilation-search]
+             '(menu-item "+ Search Compilation/Grep Hits (Regexp)..."
+               icicle-compilation-search :visible icicle-mode
+               :enable (and (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                        (condition-case nil (eq (current-buffer) (compilation-find-buffer))
+                          (error nil)))
+               :keys "C-`" :help "Icicles search, showing the matching compilation-buffer hit"))
+           (define-key icicle-search-menu-map [icicle-grep-saved-file-candidates]
+             '(menu-item "Grep Saved File-Name Candidates..."
+               icicle-grep-saved-file-candidates :visible icicle-mode
+               :enable icicle-saved-completion-candidates
+               :help "Run `grep' on the set of completion candidates saved using `C-M->'"))
+           (define-key icicle-search-menu-map [icicle-imenu-non-interactive-function]
+             '(menu-item "+ Search Non-Command Fn Definition (Regexp)..."
+               icicle-imenu-non-interactive-function :visible icicle-mode
+               :enable (eq major-mode 'emacs-lisp-mode)
+               :help "Go to an Emacs non-interactive function definition with `icicle-search'"))
+           (define-key icicle-search-menu-map [icicle-imenu-command]
+             '(menu-item "+ Search Command Definition (Regexp)..." icicle-imenu-command
+               :visible icicle-mode
+               :enable (eq major-mode 'emacs-lisp-mode)
+               :help "Go to an Emacs command definition using `icicle-search'"))
+           (define-key icicle-search-menu-map [icicle-imenu]
+             '(menu-item "+ Search Definition (Regexp)..." icicle-imenu :visible icicle-mode
+               :enable imenu-generic-expression :help "Go to an Imenu entry using `icicle-search'"))
+           (define-key icicle-search-menu-map [icicle-tags-search]
+             '(menu-item "+ Search Tagged Files ..." icicle-tags-search :visible icicle-mode
+               :help "Search all source files listed in tags tables for matches for a regexp"))
+           (define-key icicle-search-menu-map [icicle-search-bookmarks-together]
+             '(menu-item "+ Search Bookmarks Together..." icicle-search-bookmarks-together
+               :visible (and icicle-mode (featurep 'bookmark+)) :keys "C-u C-`"
+               :help "Search bookmarked regions (together)"))
+           (define-key icicle-search-menu-map [icicle-search-bookmark]
+             '(menu-item "+ Search Bookmarks Separately..." icicle-search-bookmark
+               :visible (and icicle-mode (featurep 'bookmark+))
+               :help "Search bookmarked text"))
+           (define-key icicle-search-menu-map [icicle-search-file]
+             '(menu-item "+ Search Files (Regexp)..." icicle-search-file :visible icicle-mode
+               :help "Search multiple files completely"))
+           (define-key icicle-search-menu-map [icicle-search-buffer]
+             '(menu-item "+ Search Buffers (Regexp)..." icicle-search-buffer :visible icicle-mode
+               :help "Search multiple buffers completely"))
+           (define-key icicle-search-menu-map [icicle-search-text-property]
+             '(menu-item "+ Search Text Property..." icicle-search-text-property
+               :visible icicle-mode
+               :help "Search for text that has a property with a certain value"))
+           (define-key icicle-search-menu-map [icicle-search-word]
+             '(menu-item "+ Search for Word..." icicle-search-word :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Whole-word Icicles search"))
+           (define-key icicle-search-menu-map [icicle-search-keywords]
+             '(menu-item "+ Search with Keywords (Regexps)..." icicle-search-keywords
+               :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search with one or more keywords, which can each be a regexp"))
+           (define-key icicle-search-menu-map [icicle-search]
+             '(menu-item "+ Search (Regexp)..." icicle-search :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :keys "C-`"
+               :help "Search for matches, with completion, cycling, and hit replacement"))
+           (define-key icicle-search-menu-map [icicle-occur]
+             '(menu-item "+ Occur (Regexp)..." icicle-occur :visible icicle-mode
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "`icicle-search' with a regexp of \".*\".  An `occur' with icompletion")))
+          (t
+           (define-key icicle-menu-map [icicle-search-highlight-cleanup]
+             '(menu-item "Remove Icicle-Search Highlighting..." icicle-search-highlight-cleanup
+               :enable (or icicle-search-overlays (overlayp icicle-search-current-overlay)
+                        (overlayp icicle-search-refined-overlays)
+                        icicle-search-refined-overlays)
+               :help "Remove all highlighting from the last use of `icicle-search'"))
+           (define-key icicle-menu-map [icicle-compilation-search]
+             '(menu-item "+ Search Compilation/Grep Hits (Regexp)..." icicle-compilation-search
+               :enable (and (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+                        (condition-case nil (eq (current-buffer) (compilation-find-buffer))
+                          (error nil)))
+               :help "Icicles search, showing the matching compilation-buffer hit"))
+           (define-key icicle-menu-map [icicle-grep-saved-file-candidates]
+             '(menu-item "Grep Saved File-Name Candidates..."
+               icicle-grep-saved-file-candidates :enable icicle-saved-completion-candidates
+               :help "Run `grep' on the set of completion candidates saved using `C-M->'"))
+           (define-key icicle-menu-map [icicle-imenu-non-interactive-function]
+             '(menu-item "Search Non-Command Fn Definition (Regexp)..."
+               icicle-imenu-non-interactive-function :enable (eq major-mode 'emacs-lisp-mode)
+               :help "Go to an Emacs non-interactive function definition with `icicle-search'"))
+           (define-key icicle-menu-map [icicle-imenu-command]
+             '(menu-item "Search Command Definition (Regexp)..." icicle-imenu-command
+               :enable (eq major-mode 'emacs-lisp-mode)
+               :help "Go to an Emacs command definition using `icicle-search'"))
+           (define-key icicle-menu-map [icicle-imenu]
+             '(menu-item "+ Search Definition (Regexp)..." icicle-imenu
+               :enable imenu-generic-expression :help "Go to an Imenu entry using `icicle-search'"))
+           (define-key icicle-menu-map [icicle-tags-search]
+             '(menu-item "+ Search Tagged Files ..." icicle-tags-search
+               :help "Search all source files listed in tags tables for matches for a regexp"))
+           (define-key icicle-menu-map [icicle-search-bookmarks-together]
+             '(menu-item "+ Search Bookmarks Together..." icicle-search-bookmarks-together
+               :visible (featurep 'bookmark+) :keys "C-u C-`"
+               :help "Search bookmarked regions (together)"))
+           (define-key icicle-menu-map [icicle-search-bookmark]
+             '(menu-item "+ Search Bookmarks Separately..." icicle-search-bookmark
+               :visible (featurep 'bookmark+) :help "Search bookmarked text"))
+           (define-key icicle-menu-map [icicle-search-file]
+             '(menu-item "+ Search Files (Regexp)..." icicle-search-file
+               :help "Search multiple files completely"))
+           (define-key icicle-menu-map [icicle-search-buffer]
+             '(menu-item "+ Search Buffers (Regexp)..." icicle-search-buffer
+               :help "Search multiple buffers completely"))
+           (define-key icicle-menu-map [icicle-search-text-property]
+             '(menu-item "+ Search Text Property..." icicle-search-text-property
+               :help "Search for text that has a property with a certain value"))
+           (define-key icicle-menu-map [icicle-search-word]
+             '(menu-item "+ Search for Word..." icicle-search-word
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Whole-word Icicles search"))
+           (define-key icicle-menu-map [icicle-search-keywords]
+             '(menu-item "+ Search with Keywords (Regexps)..." icicle-search-keywords
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search with one or more keywords, which can each be a regexp"))
+           (define-key icicle-menu-map [icicle-search]
+             '(menu-item "+ Search (Regexp)..." icicle-search
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "Search for matches, with completion, cycling, and hit replacement"))
+           (define-key icicle-menu-map [icicle-occur]
+             '(menu-item "+ Occur (Regexp)..." icicle-occur
+               :enable (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+               :help "`icicle-search' with a regexp of \".*\".  An `occur' with icompletion")))))
+
+  ;; Install `Icicles' menu-bar menu.
+  (define-key icicle-mode-map [menu-bar icicles] (cons "Icicles" icicle-menu-map))
+
+  ;; Optional `icicle-mode-map' bindings - governed by `icicle-top-level-key-bindings'.
+  (icicle-bind-top-level-commands)
+
+  ;; Install or update `icicle-mode-map'.
+  (if icicle-minor-mode-map-entry
+      (setcdr icicle-minor-mode-map-entry icicle-mode-map)
+    (setq icicle-minor-mode-map-entry  (cons 'icicle-mode icicle-mode-map))
+    (add-to-list 'minor-mode-map-alist icicle-minor-mode-map-entry)))
+
+(defun icicle-S-iso-lefttab-to-S-TAB (strg)
+  "Return string STRG, but with \"S-iso-lefttab\" replaced by \"S-TAB\"."
+  (replace-regexp-in-string "S-iso-lefttab" "S-TAB" strg))
+
+(defun icicle-bind-other-keymap-keys ()
+  "Bind some keys in maps other than minibuffer maps and `icicle-mode-map'"
+
+  ;; Bind Isearch keys.
+  (icicle-bind-isearch-keys)
+
+  ;; Bind keys in Comint mode.
+  (when (boundp 'comint-mode-map)
+    (define-key comint-mode-map "\C-c\C-i"         'icicle-comint-command)
+    (define-key comint-mode-map [(control ?c) tab] 'icicle-comint-command))
+
+  ;; Bind keys in Shell mode.
+  (when (and (boundp 'shell-mode-map) (memq 'comint-dynamic-complete icicle-functions-to-redefine))
+    (define-key shell-mode-map "\t" 'icicle-comint-dynamic-complete))
+
+  ;; Bind keys in Shell Script mode.
+  (when (and (boundp 'sh-mode-map) (memq 'comint-dynamic-complete icicle-functions-to-redefine))
+    (icicle-remap 'comint-dynamic-complete 'icicle-comint-dynamic-complete sh-mode-map))
+
+  ;; Bind keys in Ielm mode.
+  (when (and (boundp 'ielm-map) (memq 'comint-dynamic-complete icicle-functions-to-redefine))
+    (define-key ielm-map "\t" 'icicle-comint-dynamic-complete))
+
+  ;; Bind keys in Tcl mode.
+  (when (and (boundp 'inferior-tcl-mode-map) (memq 'comint-dynamic-complete
+                                                   icicle-functions-to-redefine))
+    (define-key inferior-tcl-mode-map "\t" 'icicle-comint-dynamic-complete))
+
+  ;; Bind keys in GUD (Debugger) mode.
+  (when (and (boundp 'gud-minibuffer-local-map) (memq 'comint-dynamic-complete-filename
+                                                      icicle-functions-to-redefine))
+    (define-key gud-minibuffer-local-map "\t" 'icicle-comint-dynamic-complete-filename))
+
+  ;; Bind some keys in `bookmark-bmenu-mode' mode (*Bookmark List*) - requires Bookmark+.
+  (when (and (featurep 'bookmark+) (boundp 'bookmark-bmenu-mode-map))
+    (unless (lookup-key bookmark-bmenu-mode-map [(control meta ?>)]) ; *Bookmark List* `C-M->'
+      (define-key bookmark-bmenu-mode-map [(control meta ?>)] 'icicle-bookmark-save-marked-files))
+    (unless (lookup-key bookmark-bmenu-mode-map [(control ?>)]) ; *Bookmark List* `C->'
+      (define-key bookmark-bmenu-mode-map [(control ?>)] 'icicle-bookmark-save-marked-files-more))
+    (unless (lookup-key bookmark-bmenu-mode-map [(control meta ?})]) ; *Bookmark List* `C-M-}'
+      (define-key bookmark-bmenu-mode-map [(control meta ?})]
+        'icicle-bookmark-save-marked-files-to-variable))
+    (unless (lookup-key bookmark-bmenu-mode-map [(control ?})]) ; *Bookmark List* `C-}'
+      (define-key bookmark-bmenu-mode-map [(control ?})]
+        'icicle-bookmark-save-marked-files-as-project))
+    (let ((defn  (lookup-key bookmark-bmenu-mode-map "\M-si"))) ; *Bookmark List* `M-s i'
+      (unless (and defn  (not (integerp defn)))
+        (define-key bookmark-bmenu-mode-map "\M-si" 'icicle-search-dired-marked))))    
+
+  ;; Bind some keys in Dired mode.
+  (when (boundp 'dired-mode-map)
+    (unless (lookup-key dired-mode-map [(control meta ?<)]) ; Dired `C-M-<'
+      (define-key dired-mode-map [(control meta ?<)]
+        'icicle-dired-saved-file-candidates-other-window))
+    (unless (lookup-key dired-mode-map [(control ?{)]) ; Dired `C-{'
+      (define-key dired-mode-map [(control ?{)] 'icicle-dired-project-other-window))
+    (unless (lookup-key dired-mode-map [(control meta ?>)]) ; Dired `C-M->'
+      (define-key dired-mode-map [(control meta ?>)] 'icicle-dired-save-marked))
+    (unless (lookup-key dired-mode-map [(control ?>)]) ; Dired `C->'
+      (define-key dired-mode-map [(control ?>)] 'icicle-dired-save-marked-more))
+    (unless (lookup-key dired-mode-map [(control meta ?})]) ; Dired `C-M-}'
+      (define-key dired-mode-map [(control meta ?})] 'icicle-dired-save-marked-to-variable))
+    (unless (lookup-key dired-mode-map [(control ?})]) ; Dired `C-}'
+      (define-key dired-mode-map [(control ?})] 'icicle-dired-save-marked-as-project))
+    (let ((defn  (lookup-key dired-mode-map "\M-si"))) ; Dired `M-s i'
+      (unless (and defn  (not (integerp defn)))
+        (define-key dired-mode-map "\M-si" 'icicle-search-dired-marked))))
+
+  ;; Bind keys in Ibuffer mode.
+  (when (boundp 'ibuffer-mode-map)
+    (let ((defn  (lookup-key ibuffer-mode-map "\M-si"))) ; Ibuffer `M-s i'
+      (unless (and defn  (not (integerp defn)))
+        (define-key ibuffer-mode-map "\M-si" 'icicle-search-ibuffer-marked))
+      (unless icicle-touche-pas-aux-menus-flag ; Use Ibuffer's `Operate' menu.
+        (define-key ibuffer-mode-operate-map [icicle-search-ibuffer-marked]
+          '(menu-item "Icicles Search (and Replace)..." icicle-search-ibuffer-marked
+            :visible icicle-mode :enable (eq major-mode 'ibuffer-mode))))))
+
+  ;; Bind keys in Buffer Menu mode.
+  (when (boundp 'Buffer-menu-mode-map)
+    (let ((defn  (lookup-key Buffer-menu-mode-map "\M-si"))) ; Buffer-Menu `M-s i'
+      (unless (and defn  (not (integerp defn)))
+        (define-key Buffer-menu-mode-map "\M-si" 'icicle-search-buff-menu-marked))))
+
+  ;; Bind `S-TAB' in major maps, for key completion.
+  (when (fboundp 'map-keymap)           ; Emacs 22+.
+    (icicle-bind-key-completion-keys-in-keymaps-from (current-global-map))
+    (mapcar #'icicle-bind-key-completion-keys-for-map-var icicle-keymaps-for-key-completion))
+
+  ;; Prevent `this-command' from being set to `handle-switch-frame'.
+  (define-key global-map [handle-switch-frame] 'icicle-skip-this-command)
+  (define-key global-map [switch-frame] 'icicle-handle-switch-frame))
+
+;;;###autoload
+(defun icicle-bind-isearch-keys ()
+  "Bind Icicles Isearch commands."
+  (dolist (key icicle-search-from-isearch-keys)
+    (define-key isearch-mode-map key 'icicle-search-w-isearch-string)) ; In `icicles-cmd2.el'.
+  (dolist (key icicle-isearch-complete-keys)
+    (define-key isearch-mode-map key 'icicle-isearch-complete))
+  (cond ((fboundp 'isearch-moccur)      ; In `moccur.el'.
+         (define-key isearch-mode-map (kbd "C-o") 'isearch-moccur))
+        ((fboundp 'isearch-occur)       ; In `occur-schroeder.el'.
+         (define-key isearch-mode-map (kbd "C-o") 'isearch-occur))))
+
+(defun icicle-bind-key-completion-keys-for-map-var (keymap-var)
+  "Bind `S-TAB' in keymaps accessible from keymap KEYMAP-VAR.
+KEYMAP-VAR should be bound to a keymap that has at least one prefix
+keymap.  If KEYMAP-VAR is not bound to a keymap, it is ignored."
+  (let ((temp  keymap-var))
+    (when (boundp temp)
+      (setq temp  (symbol-value temp))
+      (when (keymapp temp) (icicle-bind-key-completion-keys-in-keymaps-from temp)))))
+
+(defun icicle-bind-key-completion-keys-in-keymaps-from (map)
+  "Bind keys in `icicle-key-complete-keys' to `icicle-complete-keys'.
+Each key in `icicle-complete-keys' is bound in all keymaps accessible
+from keymap MAP."
+  (dolist (key+map  (accessible-keymaps map))
+    (let ((map  (cdr key+map)))
+      ;; We could try to exclude menu maps, by testing (not (keymap-prompt map)).
+      ;; But we want to include at least some menu maps - those, such as `facemenu-keymap',
+      ;; that are bound to keyboard keys. (when (and (keymapp map) (not (keymap-prompt map)))...)
+      (when (keymapp map)
+        (dolist (key  icicle-key-complete-keys)
+          (when (or icicle-complete-key-anyway-flag (not (lookup-key map key)))
+            (condition-case nil (define-key map key 'icicle-complete-keys) (error nil))))))))
+
+(defun icicle-restore-other-keymap-keys ()
+  "Restore some bindings changed by `icicle-bind-other-keymap-keys'."
+
+  ;; Unbind Isearch keys.
+  (icicle-unbind-isearch-keys)
+
+  ;; Unbind keys in Comint mode.
+  (when (boundp 'comint-mode-map)
+    (define-key comint-mode-map "\C-c\C-i"         nil)
+    (define-key comint-mode-map [(control ?c) tab] nil))
+
+  ;; Unbind keys in Shell mode.
+  (when (and (boundp 'shell-mode-map) (memq 'icicle-comint-dynamic-complete
+                                            icicle-functions-to-redefine))
+    (define-key shell-mode-map "\t" (if (> emacs-major-version 23)
+                                        'completion-at-point
+                                      'comint-dynamic-complete)))
+
+  ;; Unbind keys in Shell Script mode.
+  (when (and (boundp 'sh-mode-map) (memq 'icicle-comint-dynamic-complete
+                                         icicle-functions-to-redefine))
+    (icicle-unmap 'comint-dynamic-complete sh-mode-map 'icicle-comint-dynamic-complete))
+
+  ;; Unbind keys in Ielm mode.
+  (when (and (boundp 'ielm-map) (memq 'icicle-comint-dynamic-complete
+                                      icicle-functions-to-redefine))
+    (define-key ielm-map "\t" 'comint-dynamic-complete))
+
+  ;; Unbind keys in Tcl mode.
+  (when (and (boundp 'inferior-tcl-mode-map) (memq 'icicle-comint-dynamic-complete
+                                                   icicle-functions-to-redefine))
+    (define-key inferior-tcl-mode-map "\t" 'comint-dynamic-complete))
+
+  ;; Bind keys in GUD (Debugger) mode.
+  (when (and (boundp 'gud-minibuffer-local-map) (memq 'icicle-comint-dynamic-complete-filename
+                                                      icicle-functions-to-redefine))
+    (define-key gud-minibuffer-local-map "\t" 'comint-dynamic-complete-filename))
+
+  ;; Unbind keys in `bookmark-bmenu-mode' mode (*Bookmark List*) - requires Bookmark+.
+  (when (and (featurep 'bookmark+) (boundp 'bookmark-bmenu-mode-map))
+    (define-key bookmark-bmenu-mode-map [(control meta ?>)] nil)
+    (define-key bookmark-bmenu-mode-map [(control ?>)] nil)
+    (define-key bookmark-bmenu-mode-map [(control meta ?})] nil)
+    (define-key bookmark-bmenu-mode-map [(control ?})] nil)
+    (define-key bookmark-bmenu-mode-map "\M-si" nil))
+
+  ;; Unbind keys in Dired mode.
+  (when (boundp 'dired-mode-map)
+    (define-key dired-mode-map [(control meta ?<)] nil)
+    (define-key dired-mode-map [(control ?{)]      nil)
+    (define-key dired-mode-map [(control meta ?>)] nil)
+    (define-key dired-mode-map [(control ?>)]      nil)
+    (define-key dired-mode-map [(control meta ?})] nil)
+    (define-key dired-mode-map [(control ?})]      nil)
+    (define-key dired-mode-map "\M-si"             nil))
+
+  ;; Unbind keys in Ibuffer mode.
+  (when (boundp 'ibuffer-mode-map)
+    (define-key ibuffer-mode-map "\M-si" nil))
+
+  ;; Unbind keys in Buffer Menu mode.
+  (when (boundp 'Buffer-menu-mode-map)
+    (define-key Buffer-menu-mode-map "\M-si" nil))
+
+  ;; Unbind `S-TAB' in major maps.
+  (when (fboundp 'map-keymap)           ; Emacs 22+.
+    (icicle-unbind-key-completion-keys-in-keymaps-from (current-global-map))
+    (mapcar #'icicle-unbind-key-completion-keys-for-map-var icicle-keymaps-for-key-completion))
+
+  ;; Restore prevention of `this-command' being `handle-switch-frame'.
+  (define-key global-map [handle-switch-frame] nil)
+  (define-key global-map [switch-frame] 'handle-switch-frame))
+
+(defun icicle-unbind-isearch-keys ()
+  "Unbind Icicles Isearch commands."
+  (dolist (key icicle-search-from-isearch-keys) (define-key isearch-mode-map key nil))
+  (dolist (key icicle-isearch-complete-keys) (define-key isearch-mode-map key nil))
+  (define-key isearch-mode-map "\M-\t" 'isearch-complete)
+  (when (fboundp 'isearch-moccur)       ; Restore `moccur.el' binding.
+    (define-key isearch-mode-map (kbd "M-o") 'isearch-moccur))
+  (define-key isearch-mode-map (kbd "C-o") nil))
+
+(defun icicle-unbind-key-completion-keys-for-map-var (keymap-var)
+  "Unbind `S-TAB' in keymaps accessible from keymap KEYMAP-VAR.
+KEYMAP-VAR should be bound to a keymap that has at least one prefix
+keymap.  If KEYMAP-VAR is not bound to a keymap, it is ignored."
+  (let ((temp  keymap-var))
+    (when (boundp temp)
+      (setq temp  (symbol-value temp))
+      (when (keymapp temp) (icicle-unbind-key-completion-keys-in-keymaps-from temp)))))
+
+(defun icicle-unbind-key-completion-keys-in-keymaps-from (map)
+  "Unbind `icicle-key-complete-keys' in keymaps accessible from MAP."
+  (dolist (key+map (accessible-keymaps map))
+    (let ((map  (cdr key+map)))
+      (when (and (keymapp map) (not (stringp (car-safe (last map))))) ; Try to exclude menu maps.
+        (dolist (key icicle-key-complete-keys)
+          (when (eq (lookup-key map key) 'icicle-complete-keys)
+            (condition-case nil (define-key map key nil) (error nil))))))))
+ 
+;;(@* "Other Icicles functions that define Icicle mode")
+
+;;; Other Icicles functions that define Icicle mode ------------------
+
+;;;###autoload
+(defun icicle-skip-this-command ()
+  "Prevent `handle-switch-frame' from being added to `this-command'."
+  (interactive)
+  (setq this-command  last-command))
+
+;;;###autoload
+(defun icicle-handle-switch-frame (event)
+  "Call `handle-switch-frame', but don't add it to `this-command'."
+  (interactive "e")
+  (handle-switch-frame event)
+  (setq this-command  last-command))
+
+(defun icicle-define-minibuffer-maps (turn-on-p)
+  "Define keymaps for the minibuffer and buffer `*Completions*'."
+  (cond
+    (turn-on-p                          ; TURN IT ON ********************************
+
+     ;; `minibuffer-local-map': default minibuffer map.
+     (let ((map  minibuffer-local-map))
+
+       ;; Menu-bar `Minibuf' menu.
+       (define-key map [menu-bar minibuf quit] ; Replace `keyboard-escape-quit'
+         '(menu-item "Quit" icicle-abort-recursive-edit
+           :help "Cancel minibuffer input or recursive edit"))
+       (define-key map [menu-bar minibuf return]
+         '(menu-item "Enter" exit-minibuffer
+           :help "Terminate input and exit minibuffer" :keys "RET"))
+       (define-key map [menu-bar minibuf separator-help] '("--"))
+       (define-key map [menu-bar minibuf completion-help]
+         '(menu-item "Icicles Help" icicle-minibuffer-help
+           :help "Display help for minibuffer input and completion"))
+       (define-key map [menu-bar minibuf separator-last] '("--"))
+       (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain]
+         '(menu-item "Toggle Searching Complement"
+           icicle-toggle-search-complementing-domain
+           :help "Toggle `icicle-search-complement-domain-p'" :keys "C-M-~"))
+       (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]
+         '(menu-item "Toggle All-Current Icicle-Search Highlighting"
+           icicle-toggle-highlight-all-current :enable icicle-searching-p
+           :help "Toggle `icicle-search-highlight-all-current-flag'" :keys "C-^"))
+       (define-key map [menu-bar minibuf icicle-regexp-quote-input]
+         '(menu-item "Regexp-Quote Input" icicle-regexp-quote-input
+           :enable (with-current-buffer (window-buffer (minibuffer-window))
+                     (not (zerop (buffer-size))))
+           :help "Regexp-quote current input or its active region, then apropos-complete"
+           :keys "M-%"))
+       (define-key map [menu-bar minibuf separator-set2] '("--"))
+       (define-key map [menu-bar minibuf icicle-clear-current-history]
+         '(menu-item "Clear History Entries" icicle-clear-current-history
+           :help "Clear current minibuffer history of selected entries"))
+       (define-key map [menu-bar minibuf icicle-erase-minibuffer]
+         '(menu-item "Delete from History" icicle-erase-minibuffer-or-history-element
+           :visible (memq last-command
+                     '(previous-history-element next-history-element
+                       icicle-erase-minibuffer-or-history-element
+                       previous-matching-history-element next-matching-history-element))
+           :help "Delete current history element (in minibuffer now)" :keys "M-k"))
+       (define-key map [menu-bar minibuf icicle-delete-history-element]
+         '(menu-item "Clear (Erase) Minibuffer" icicle-erase-minibuffer-or-history-element
+           :visible (not (memq last-command
+                          '(previous-history-element next-history-element
+                            icicle-erase-minibuffer-or-history-element
+                            previous-matching-history-element next-matching-history-element)))
+           :help "Erase the Minibuffer" :keys "M-k"))
+       (define-key map [menu-bar minibuf icicle-insert-list-join-string]
+         '(menu-item "Insert Join-String" icicle-insert-list-join-string
+           :help "Insert `icicle-list-join-string' into the minibuffer"))
+       (define-key map [menu-bar minibuf icicle-insert-key-description]
+         '(menu-item "Insert Key Description" icicle-insert-key-description
+           :visible (not icicle-searching-p) :keys "M-q"
+           :help "Read key and insert its description - e.g., reading ^F inserts `C-f'"))
+       (define-key map [menu-bar minibuf icicle-insert-history-element]
+         '(menu-item "Insert Past Input using Completion" icicle-insert-history-element
+           :enable (consp (symbol-value minibuffer-history-variable))
+           :help "Use completion to insert a previous input into the minibuffer"))
+       (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]
+         '(menu-item "Insert String from a Variable..." icicle-insert-string-from-variable
+           :visible current-prefix-arg :keys "C-="
+           :help "Read a variable name and insert its string value into the minibuffer"))
+       (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]
+         '(menu-item "Insert `icicle-input-string'" icicle-insert-string-from-variable
+           :visible (not current-prefix-arg) :keys "C-="
+           :help "Insert text from variable `icicle-input-string' into the minibuffer"))
+       (define-key map [menu-bar minibuf icicle-insert-string-at-point]
+         '(menu-item "Insert Text from Point" icicle-insert-string-at-point
+           :help "Insert text at or near the cursor into the minibuffer"))
+       (define-key map [menu-bar minibuf icicle-completing-read+insert]
+         '(menu-item "Insert On-Demand Completion" icicle-completing-read+insert
+           :visible (consp icicle-completing-read+insert-candidates)
+           :help "Read and insert something using (lax) completion"))
+       (define-key map [menu-bar minibuf icicle-read+insert-file-name]
+         '(menu-item "Insert File Name" icicle-read+insert-file-name
+           :help "Read and insert a file name using (lax) completion"))
+
+       (define-key map [(control ??)]            'icicle-minibuffer-help) ; `C-?'
+       (define-key map [(control ?g)]            'icicle-abort-recursive-edit) ; `C-g'
+       (define-key map [M-S-backspace]           'icicle-erase-minibuffer) ; `M-S-backspace'
+       (define-key map [M-S-delete]              'icicle-erase-minibuffer) ; `M-S-delete'
+       (define-key map [(meta ?.)]               'icicle-insert-string-at-point) ; `M-.'
+       (define-key map "\C-x\C-f"                'icicle-resolve-file-name) ; `C-x C-f'
+       (define-key map [(control ?=)]            'icicle-insert-string-from-variable) ; `C-='
+       (define-key map [(meta ?o)]               'icicle-insert-history-element) ; `M-o'
+       (define-key map [(meta ?i)]               'icicle-clear-current-history) ; `M-i'
+       (define-key map [(meta ?k)]               'icicle-erase-minibuffer-or-history-element) ; `M-k'
+       (define-key map [(meta ?:)]               'icicle-pp-eval-expression-in-minibuffer) ; `M-:'
+       (define-key map [(control ?a)]            'icicle-beginning-of-line+) ; `C-a'
+       (define-key map [(control ?e)]            'icicle-end-of-line+) ; `C-e'
+       (define-key map [(control meta ?v)]       'icicle-scroll-forward) ; `C-M-v'
+       (define-key map [(control meta shift ?v)] 'icicle-scroll-backward) ; `C-M-S-v' (aka `C-M-V')
+       (dolist (key  icicle-completing-read+insert-keys)
+         (define-key map key 'icicle-completing-read+insert)) ; `C-M-S-c'
+       (dolist (key  icicle-read+insert-file-name-keys)
+         (define-key map key 'icicle-read+insert-file-name)) ; `C-M-S-f'
+       (define-key map "\n"                      'icicle-insert-newline-in-minibuffer) ; `C-j'
+       (when (fboundp 'yank-secondary)  ; In `second-sel.el'.
+         (define-key map "\C-\M-y" 'icicle-yank-secondary))) ; `C-M-y'
+
+     ;; `minibuffer-local-ns-map': default minibuffer map when spaces are not allowed.
+     ;; In Emacs 22+, local is parent of local-ns.
+     (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-ns-map))
+       (let ((map  minibuffer-local-ns-map))
+         (define-key map [menu-bar minibuf quit] ; Replace `keyboard-escape-quit'
+           '(menu-item "Quit" icicle-abort-recursive-edit
+             :help "Cancel minibuffer input or recursive edit"))
+         (define-key map [menu-bar minibuf return]
+           '(menu-item "Enter" exit-minibuffer
+             :help "Terminate input and exit minibuffer" :keys "RET"))
+         (define-key map [menu-bar minibuf separator-help] '("--"))
+         (define-key map [menu-bar minibuf completion-help]
+           '(menu-item "Icicles Help" icicle-minibuffer-help
+             :help "Display help for minibuffer input and completion"))
+         (define-key map [menu-bar minibuf separator-last] '("--"))
+         (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain]
+           '(menu-item "Toggle Searching Complement"
+             icicle-toggle-search-complementing-domain
+             :help "Toggle `icicle-search-complement-domain-p'" :keys "C-M-~"))
+         (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]
+           '(menu-item "Toggle All-Current Icicle-Search Highlighting"
+             icicle-toggle-highlight-all-current :enable icicle-searching-p
+             :help "Toggle `icicle-search-highlight-all-current-flag'" :keys "C-^"))
+         (define-key map [menu-bar minibuf icicle-regexp-quote-input]
+           '(menu-item "Regexp-Quote Input" icicle-regexp-quote-input
+             :enable (with-current-buffer (window-buffer (minibuffer-window))
+                       (not (zerop (buffer-size))))
+             :help "Regexp-quote current input or its active region, then apropos-complete"
+             :keys "M-%"))
+         (define-key map [menu-bar minibuf separator-set2] '("--"))
+         (define-key map [menu-bar minibuf icicle-clear-current-history]
+           '(menu-item "Clear History Entries" icicle-clear-current-history
+             :help "Clear current minibuffer history of selected entries"))
+         (define-key map [menu-bar minibuf icicle-erase-minibuffer]
+           '(menu-item "Delete from History" icicle-erase-minibuffer-or-history-element
+             :visible (memq last-command
+                       '(previous-history-element next-history-element
+                         icicle-erase-minibuffer-or-history-element
+                         previous-matching-history-element next-matching-history-element))
+             :help "Delete current history element (in minibuffer now)" :keys "M-k"))
+         (define-key map [menu-bar minibuf icicle-delete-history-element]
+           '(menu-item "Clear (Erase) Minibuffer" icicle-erase-minibuffer-or-history-element
+             :visible (not (memq last-command
+                            '(previous-history-element next-history-element
+                              icicle-erase-minibuffer-or-history-element
+                              previous-matching-history-element next-matching-history-element)))
+             :help "Erase the Minibuffer" :keys "M-k"))
+         (define-key map [menu-bar minibuf icicle-insert-list-join-string]
+           '(menu-item "Insert Join-String" icicle-insert-list-join-string
+             :help "Insert `icicle-list-join-string' into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-key-description]
+           '(menu-item "Insert Key Description" icicle-insert-key-description
+             :visible (not icicle-searching-p) :keys "M-q"
+             :help "Read key and insert its description - e.g., reading ^F inserts `C-f'"))
+         (define-key map [menu-bar minibuf icicle-insert-history-element]
+           '(menu-item "Insert Past Input using Completion" icicle-insert-history-element
+             :enable (consp (symbol-value minibuffer-history-variable))
+             :help "Use completion to insert a previous input into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]
+           '(menu-item "Insert String from a Variable..." icicle-insert-string-from-variable
+             :visible current-prefix-arg :keys "C-="
+             :help "Read a variable name and insert its string value into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]
+           '(menu-item "Insert `icicle-input-string'" icicle-insert-string-from-variable
+             :visible (not current-prefix-arg) :keys "C-="
+             :help "Insert text from variable `icicle-input-string' into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-at-point]
+           '(menu-item "Insert Text from Point" icicle-insert-string-at-point
+             :help "Insert text at or near the cursor into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-completing-read+insert]
+           '(menu-item "Insert On-Demand Completion" icicle-completing-read+insert
+             :visible (consp icicle-completing-read+insert-candidates)
+             :help "Read and insert something using (lax) completion"))
+         (define-key map [menu-bar minibuf icicle-read+insert-file-name]
+           '(menu-item "Insert File Name" icicle-read+insert-file-name
+             :help "Read and insert a file name using (lax) completion"))
+
+         (define-key map [(control ??)]            'icicle-minibuffer-help) ; `C-?'
+         (define-key map [(control ?g)]            'icicle-abort-recursive-edit) ; `C-g'
+         (define-key map [M-S-backspace]           'icicle-erase-minibuffer) ; `M-S-backspace'
+         (define-key map [M-S-delete]              'icicle-erase-minibuffer) ; `M-S-delete'
+         (define-key map [(meta ?.)]               'icicle-insert-string-at-point) ; `M-.'
+         (define-key map "\C-x\C-f"                'icicle-resolve-file-name) ; `C-x C-f'
+         (define-key map [(control ?=)]            'icicle-insert-string-from-variable) ; `C-='
+         (define-key map [(meta ?o)]               'icicle-insert-history-element) ; `M-o'
+         (define-key map [(meta ?i)]               'icicle-clear-current-history) ; `M-i'
+         (define-key map [(meta ?k)]           'icicle-erase-minibuffer-or-history-element) ; `M-k'
+         (define-key map [(meta ?:)]              'icicle-pp-eval-expression-in-minibuffer) ; `M-:'
+         (define-key map [(control ?a)]            'icicle-beginning-of-line+) ; `C-a'
+         (define-key map [(control ?e)]            'icicle-end-of-line+) ; `C-e'
+         (define-key map [(control meta ?v)]       'icicle-scroll-forward) ; `C-M-v'
+         (define-key map [(control meta shift ?v)] 'icicle-scroll-backward) ; `C-M-S-v' (aka `C-M-V')
+         (dolist (key  icicle-completing-read+insert-keys)
+           (define-key map key 'icicle-completing-read+insert)) ; `C-M-S-c'
+         (dolist (key  icicle-read+insert-file-name-keys)
+           (define-key map key 'icicle-read+insert-file-name)) ; `C-M-S-f'
+         (define-key map "\n"                      'icicle-insert-newline-in-minibuffer) ; `C-j'
+         (when (fboundp 'yank-secondary) ; In `second-sel.el'.
+           (define-key map "\C-\M-y" 'icicle-yank-secondary)))) ; `C-M-y'
+
+     ;; `minibuffer-local-isearch-map': minibuffer map for editing isearch strings.
+     ;; In Emacs 21+, local is parent of local-isearch.
+     (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-isearch-map))
+       (let ((map  minibuffer-local-isearch-map))
+         (define-key map [menu-bar minibuf quit] ; Replace `keyboard-escape-quit'
+           '(menu-item "Quit" icicle-abort-recursive-edit
+             :help "Cancel minibuffer input or recursive edit"))
+         (define-key map [menu-bar minibuf return]
+           '(menu-item "Enter" exit-minibuffer
+             :help "Terminate input and exit minibuffer" :keys "RET"))
+         (define-key map [menu-bar minibuf separator-help] '("--"))
+         (define-key map [menu-bar minibuf completion-help]
+           '(menu-item "Icicles Help" icicle-minibuffer-help
+             :help "Display help for minibuffer input and completion"))
+         (define-key map [menu-bar minibuf separator-last] '("--"))
+         (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain]
+           '(menu-item "Toggle Searching Complement"
+             icicle-toggle-search-complementing-domain
+             :help "Toggle `icicle-search-complement-domain-p'" :keys "C-M-~"))
+         (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]
+           '(menu-item "Toggle All-Current Icicle-Search Highlighting"
+             icicle-toggle-highlight-all-current :enable icicle-searching-p
+             :help "Toggle `icicle-search-highlight-all-current-flag'" :keys "C-^"))
+         (define-key map [menu-bar minibuf icicle-regexp-quote-input]
+           '(menu-item "Regexp-Quote Input" icicle-regexp-quote-input
+             :enable (with-current-buffer (window-buffer (minibuffer-window))
+                       (not (zerop (buffer-size))))
+             :help "Regexp-quote current input or its active region, then apropos-complete"
+             :keys "M-%"))
+         (define-key map [menu-bar minibuf separator-set2] '("--"))
+         (define-key map [menu-bar minibuf icicle-clear-current-history]
+           '(menu-item "Clear History Entries" icicle-clear-current-history
+             :help "Clear current minibuffer history of selected entries"))
+         (define-key map [menu-bar minibuf icicle-erase-minibuffer]
+           '(menu-item "Delete from History" icicle-erase-minibuffer-or-history-element
+             :visible (memq last-command
+                       '(previous-history-element next-history-element
+                         icicle-erase-minibuffer-or-history-element
+                         previous-matching-history-element next-matching-history-element))
+             :help "Delete current history element (in minibuffer now)" :keys "M-k"))
+         (define-key map [menu-bar minibuf icicle-delete-history-element]
+           '(menu-item "Clear (Erase) Minibuffer" icicle-erase-minibuffer-or-history-element
+             :visible (not (memq last-command
+                            '(previous-history-element next-history-element
+                              icicle-erase-minibuffer-or-history-element
+                              previous-matching-history-element next-matching-history-element)))
+             :help "Erase the Minibuffer" :keys "M-k"))
+         (define-key map [menu-bar minibuf icicle-insert-list-join-string]
+           '(menu-item "Insert Join-String" icicle-insert-list-join-string
+             :help "Insert `icicle-list-join-string' into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-key-description]
+           '(menu-item "Insert Key Description" icicle-insert-key-description
+             :visible (not icicle-searching-p) :keys "M-q"
+             :help "Read key and insert its description - e.g., reading ^F inserts `C-f'"))
+         (define-key map [menu-bar minibuf icicle-insert-history-element]
+           '(menu-item "Insert Past Input using Completion" icicle-insert-history-element
+             :enable (consp (symbol-value minibuffer-history-variable))
+             :help "Use completion to insert a previous input into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]
+           '(menu-item "Insert String from a Variable..." icicle-insert-string-from-variable
+             :visible current-prefix-arg :keys "C-="
+             :help "Read a variable name and insert its string value into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]
+           '(menu-item "Insert `icicle-input-string'" icicle-insert-string-from-variable
+             :visible (not current-prefix-arg) :keys "C-="
+             :help "Insert text from variable `icicle-input-string' into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-insert-string-at-point]
+           '(menu-item "Insert Text from Point" icicle-insert-string-at-point
+             :help "Insert text at or near the cursor into the minibuffer"))
+         (define-key map [menu-bar minibuf icicle-completing-read+insert]
+           '(menu-item "Insert On-Demand Completion" icicle-completing-read+insert
+             :visible (consp icicle-completing-read+insert-candidates)
+             :help "Read and insert something using (lax) completion"))
+         (define-key map [menu-bar minibuf icicle-read+insert-file-name]
+           '(menu-item "Insert File Name" icicle-read+insert-file-name
+             :help "Read and insert a file name using (lax) completion"))
+
+         (define-key map [(control ??)]            'icicle-minibuffer-help) ; `C-?'
+         (define-key map [(control ?g)]            'icicle-abort-recursive-edit) ; `C-g'
+         (define-key map [M-S-backspace]           'icicle-erase-minibuffer) ; `M-S-backspace'
+         (define-key map [M-S-delete]              'icicle-erase-minibuffer) ; `M-S-delete'
+         (define-key map [(meta ?.)]               'icicle-insert-string-at-point) ; `M-.'
+         (define-key map "\C-x\C-f"                'icicle-resolve-file-name) ; `C-x C-f'
+         (define-key map [(control ?=)]            'icicle-insert-string-from-variable) ; `C-='
+         (define-key map [(meta ?o)]               'icicle-insert-history-element) ; `M-o'
+         (define-key map [(meta ?i)]               'icicle-clear-current-history) ; `M-i'
+         (define-key map [(meta ?k)]           'icicle-erase-minibuffer-or-history-element) ; `M-k'
+         (define-key map [(meta ?:)]              'icicle-pp-eval-expression-in-minibuffer) ; `M-:'
+         (define-key map [(control ?a)]            'icicle-beginning-of-line+) ; `C-a'
+         (define-key map [(control ?e)]            'icicle-end-of-line+) ; `C-e'
+         (define-key map [(control meta ?v)]       'icicle-scroll-forward) ; `C-M-v'
+         (define-key map [(control meta shift ?v)] 'icicle-scroll-backward) ; `C-M-S-v' (aka `C-M-V')
+         (dolist (key  icicle-completing-read+insert-keys)
+           (define-key map key 'icicle-completing-read+insert)) ; `C-M-S-c'
+         (dolist (key  icicle-read+insert-file-name-keys)
+           (define-key map key 'icicle-read+insert-file-name)) ; `C-M-S-f'
+         (define-key map "\n"                      'icicle-insert-newline-in-minibuffer) ; `C-j'
+         (when (fboundp 'yank-secondary) ; In `second-sel.el'.
+           (define-key map "\C-\M-y" 'icicle-yank-secondary)))) ; `C-M-y'
+
+     ;; `minibuffer-local-completion-map': completion map.
+     (icicle-bind-completion-keys minibuffer-local-completion-map)
+
+     ;; `minibuffer-local-must-match-map': must-match map.
+     ;; In Emacs 22+, local-completion is parent of local-must-match
+     (if (not (eq minibuffer-local-completion-map (keymap-parent minibuffer-local-must-match-map)))
+         (icicle-bind-completion-keys minibuffer-local-must-match-map)
+       (define-key minibuffer-local-must-match-map [(control ?g)]
+         'icicle-abort-recursive-edit)  ; `C-g' - need it anyway, even if inherit completion map.
+       (dolist (key  icicle-completing-read+insert-keys)
+         (define-key minibuffer-local-must-match-map key 'icicle-completing-read+insert)) ; `C-M-S-c'
+       (dolist (key  icicle-read+insert-file-name-keys)
+         (define-key minibuffer-local-must-match-map key 'icicle-read+insert-file-name)) ; `C-M-S-f'
+       ;; Override the binding of `C-j' to `minibuffer-complete-and-exit'.
+       (define-key minibuffer-local-must-match-map "\n"
+         'icicle-insert-newline-in-minibuffer)) ; `C-j' (newline)
+     (define-key minibuffer-local-must-match-map [S-return] ; `S-RET'
+       'icicle-apropos-complete-and-exit)
+
+     ;; `completion-list-mode-map': map for `*Completions*' buffer.
+     ;; Abort on `C-g' or `q'.  Switch to minibuffer on `C-insert'.  Do not allow normal input.
+     (let ((map  completion-list-mode-map))
+       (define-key map [(control ??)]     'icicle-minibuffer-help) ; `C-?'
+       (define-key map [(control ?g)]     'icicle-abort-recursive-edit) ; `C-g'
+       (define-key map "q"                'icicle-abort-recursive-edit) ; `q'
+       (define-key map [(control insert)] 'icicle-insert-completion) ; `C-insert'
+       (define-key map [down]             'icicle-next-line) ; `down'
+       (define-key map [up]               'icicle-previous-line) ; `up'
+       (define-key map [right]            'icicle-move-to-next-completion) ; `right'
+       (define-key map [left]             'icicle-move-to-previous-completion) ; `left'
+       (dolist (key icicle-previous-candidate-keys)
+         (define-key map key 'icicle-move-to-previous-completion)) ; `S-TAB'
+       (define-key map [(control ?i)]     'icicle-move-to-next-completion) ; `TAB'
+       (define-key map [tab]              'icicle-move-to-next-completion) ; `TAB'
+       (when (boundp 'mouse-wheel-down-event) ; Emacs 22+ -  `wheel-down', `wheel-up'
+         (define-key map (vector mouse-wheel-down-event) 'icicle-scroll-Completions-backward)
+         (define-key map (vector mouse-wheel-up-event) 'icicle-scroll-Completions-forward))
+       (define-key map [S-down-mouse-2]   'icicle-mouse-remove-candidate) ; `S-mouse-2'
+       (define-key map [S-mouse-2]        'ignore)
+       (define-key map [C-S-down-mouse-2] 'icicle-mouse-candidate-alt-action) ; `C-S-mouse-2'
+       (define-key map [C-S-mouse-2]      'ignore)
+       (define-key map [C-down-mouse-2]   'icicle-mouse-candidate-action) ; `C-mouse-2'
+       (define-key map [C-mouse-2]        'ignore)
+       (define-key map [C-M-return]       'icicle-help-on-candidate) ; `C-M-RET'
+       (define-key map [C-M-down-mouse-2] 'icicle-mouse-help-on-candidate) ; `C-M-mouse-2'
+       (define-key map [C-M-mouse-2]      'ignore)
+       (define-key map [M-S-down-mouse-2] 'icicle-mouse-save/unsave-candidate) ; `M-S-mouse-2'
+       (define-key map [M-S-mouse-2]      'ignore)
+       (define-key map [M-down-mouse-2]   'icicle-mouse-candidate-read-fn-invoke) ; `M-mouse-2'
+       (define-key map [M-mouse-2]        'ignore)
+       (define-key map [C-down-mouse-3]   'icicle-Completions-mouse-3-menu) ; `C-mouse-3'
+       (define-key map [C-mouse-3]        'ignore)
+       (define-key map [M-down-mouse-3]   'icicle-mouse-candidate-set-save-more) ; `M-mouse-3'
+       (define-key map [M-mouse-3]        'ignore)
+       (define-key map [M-S-down-mouse-3] 'icicle-mouse-candidate-set-save) ; `M-S-mouse-3'
+       (define-key map [M-S-mouse-3]      'ignore)
+       (define-key map [mouse-3]          'icicle-mouse-save-then-kill) ; `mouse-3'
+       (define-key map [(control ?>)]     'icicle-candidate-set-save-more) ; `C->'
+       (define-key map [(control meta ?>)] 'icicle-candidate-set-save) ; `C-M->'
+       (define-key map [(control ?\))]    'icicle-candidate-set-save-more-selected) ; `C-)'
+       (define-key map [(control meta ?\))] 'icicle-candidate-set-save-selected) ; `C-M-)'
+       (define-key map [(control meta ?<)] 'icicle-candidate-set-retrieve) ; `C-M-<'
+       (define-key map [(control ?l)]      'icicle-retrieve-previous-input) ; `C-l'
+       (define-key map [(control ?a)]      'icicle-beginning-of-line+) ; `C-a'
+       (define-key map [(control ?e)]      'icicle-end-of-line+) ; `C-e'
+       ;; (suppress-keymap map) ; Inhibit character self-insertion.
+       ))
+
+    (t                                  ; TURN IT OFF *******************************
+
+     ;; `minibuffer-local-map': default minibuffer map.
+     (let ((map  minibuffer-local-map))
+
+       ;; Menu-bar `Minibuf' menu.
+       (define-key map [menu-bar minibuf quit]
+         '(menu-item "Quit" keyboard-escape-quit :help "Abort input and exit minibuffer"))
+       (define-key map [menu-bar minibuf return]
+         '(menu-item "Enter" exit-minibuffer
+           :help "Terminate input and exit minibuffer" :keys "RET"))
+       (define-key map [menu-bar minibuf separator-help]                            nil)
+       (define-key map [menu-bar minibuf completion-help]                           nil)
+       (define-key map [menu-bar minibuf separator-last]                            nil)
+       (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain] nil)
+       (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]       nil)
+       (define-key map [menu-bar minibuf icicle-regexp-quote-input]                 nil)
+       (define-key map [menu-bar minibuf separator-set2]                            nil)
+       (define-key map [menu-bar minibuf icicle-clear-current-history]              nil)
+       (define-key map [menu-bar minibuf icicle-erase-minibuffer]                   nil)
+       (define-key map [menu-bar minibuf icicle-delete-history-element]             nil)
+       (define-key map [menu-bar minibuf icicle-insert-list-join-string]            nil)
+       (define-key map [menu-bar minibuf icicle-insert-key-description]             nil)
+       (define-key map [menu-bar minibuf icicle-insert-history-element]             nil)
+       (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]           nil)
+       (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]         nil)
+       (define-key map [menu-bar minibuf icicle-insert-string-at-point]             nil)
+       (define-key map [menu-bar minibuf icicle-completing-read+insert]             nil)
+       (define-key map [menu-bar minibuf icicle-read+insert-file-name]              nil)
+
+       (define-key map [(control ??)]            nil) ; `C-?'
+       (define-key map [(control ?g)]            (if (and (fboundp 'minibuffer-keyboard-quit)
+                                                          delete-selection-mode)
+                                                     'minibuffer-keyboard-quit
+                                                   'abort-recursive-edit)) ; `C-g'
+       (define-key map [M-S-backspace]           nil) ; `M-S-DEL'
+       (define-key map [M-S-delete]              nil) ; `M-S-delete'
+       (define-key map [(meta ?.)]               nil) ; `M-.'
+       (define-key map "\C-x\C-f"                nil) ; `C-x C-f'
+       (define-key map [(control ?=)]            nil) ; `C-='
+       (define-key map [(meta ?o)]               nil) ; `M-o'
+       (define-key map [(meta ?i)]               nil) ; `M-i'
+       (define-key map [(meta ?k)]               nil) ; `M-k'
+       (define-key map [(meta ?:)]               nil) ; `M-:'
+       (define-key map [(control ?a)]            nil) ; `C-a'
+       (define-key map [(control ?e)]            nil) ; `C-e'
+       (define-key map [(control meta ?v)]       nil) ; `C-M-v'
+       (define-key map [(control meta shift ?v)] nil) ; `C-M-S-v' (aka `C-M-V')
+       (dolist (key  icicle-completing-read+insert-keys) (define-key map key nil)) ; `C-M-S-c'
+       (dolist (key  icicle-read+insert-file-name-keys) (define-key map key nil)) ; `C-M-S-f'
+       (define-key map "\n"                      'exit-minibuffer) ; `C-j'
+       (define-key map "\C-\M-y"                 nil)) ; `C-M-y'
+
+     ;; `minibuffer-local-ns-map': default minibuffer map when spaces are not allowed.
+     ;; In Emacs 22+, local is parent of local-ns.
+     (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-ns-map))
+       (let ((map  minibuffer-local-ns-map))
+         (define-key map [menu-bar minibuf quit]
+           '(menu-item "Quit" keyboard-escape-quit :help "Abort input and exit minibuffer"))
+         (define-key map [menu-bar minibuf return]
+           '(menu-item "Enter" exit-minibuffer
+             :help "Terminate input and exit minibuffer" :keys "RET"))
+         (define-key map [menu-bar minibuf separator-help]                            nil)
+         (define-key map [menu-bar minibuf completion-help]                           nil)
+         (define-key map [menu-bar minibuf separator-last]                            nil)
+         (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain] nil)
+         (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]       nil)
+         (define-key map [menu-bar minibuf icicle-regexp-quote-input]                 nil)
+         (define-key map [menu-bar minibuf separator-set2]                            nil)
+         (define-key map [menu-bar minibuf icicle-clear-current-history]              nil)
+         (define-key map [menu-bar minibuf icicle-erase-minibuffer]                   nil)
+         (define-key map [menu-bar minibuf icicle-delete-history-element]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-list-join-string]            nil)
+         (define-key map [menu-bar minibuf icicle-insert-key-description]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-history-element]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]           nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]         nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-at-point]             nil)
+         (define-key map [menu-bar minibuf icicle-completing-read+insert]             nil)
+         (define-key map [menu-bar minibuf icicle-read+insert-file-name]              nil)
+
+         (define-key map [(control ??)]            nil) ; `C-?'
+         (define-key map [(control ?g)]            (if (and (fboundp 'minibuffer-keyboard-quit)
+                                                            delete-selection-mode)
+                                                       'minibuffer-keyboard-quit
+                                                     'abort-recursive-edit)) ; `C-g'
+         (define-key map [M-S-backspace]           nil) ; `M-S-DEL'
+         (define-key map [M-S-delete]              nil) ; `M-S-delete'
+         (define-key map [(meta ?.)]               nil) ; `M-.'
+         (define-key map "\C-x\C-f"                nil) ; `C-x C-f'
+         (define-key map [(control ?=)]            nil) ; `C-='
+         (define-key map [(meta ?o)]               nil) ; `M-o'
+         (define-key map [(meta ?i)]               nil) ; `M-i'
+         (define-key map [(meta ?k)]               nil) ; `M-k'
+         (define-key map [(meta ?:)]               nil) ; `M-:'
+         (define-key map [(control ?a)]            nil) ; `C-a'
+         (define-key map [(control ?e)]            nil) ; `C-e'
+         (define-key map [(control meta ?v)]       nil) ; `C-M-v'
+         (define-key map [(control meta shift ?v)] nil) ; `C-M-S-v' (aka `C-M-V')
+         (dolist (key  icicle-completing-read+insert-keys) (define-key map key nil)) ; `C-M-S-c'
+         (dolist (key  icicle-read+insert-file-name-keys) (define-key map key nil)) ; `C-M-S-f'
+         (define-key map "\n"                      'exit-minibuffer) ; `C-j'
+         (define-key map "\C-\M-y"                 nil))) ; `C-M-y'
+
+     ;; `minibuffer-local-isearch-map': minibuffer map for editing isearch strings.
+     ;; In Emacs 21+, local is parent of local-isearch
+     (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-isearch-map))
+       (let ((map  minibuffer-local-isearch-map))
+         (define-key map [menu-bar minibuf quit]
+           '(menu-item "Quit" keyboard-escape-quit :help "Abort input and exit minibuffer"))
+         (define-key map [menu-bar minibuf return]
+           '(menu-item "Enter" exit-minibuffer
+             :help "Terminate input and exit minibuffer" :keys "RET"))
+         (define-key map [menu-bar minibuf separator-help]                            nil)
+         (define-key map [menu-bar minibuf completion-help]                           nil)
+         (define-key map [menu-bar minibuf separator-last]                            nil)
+         (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain] nil)
+         (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]       nil)
+         (define-key map [menu-bar minibuf icicle-regexp-quote-input]                 nil)
+         (define-key map [menu-bar minibuf separator-set2]                            nil)
+         (define-key map [menu-bar minibuf icicle-clear-current-history]              nil)
+         (define-key map [menu-bar minibuf icicle-erase-minibuffer]                   nil)
+         (define-key map [menu-bar minibuf icicle-delete-history-element]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-list-join-string]            nil)
+         (define-key map [menu-bar minibuf icicle-insert-key-description]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-history-element]             nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]           nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]         nil)
+         (define-key map [menu-bar minibuf icicle-insert-string-at-point]             nil)
+         (define-key map [menu-bar minibuf icicle-completing-read+insert]             nil)
+         (define-key map [menu-bar minibuf icicle-read+insert-file-name]              nil)
+
+         (define-key map [(control ??)]            nil) ; `C-?'
+         (define-key map [(control ?g)]            (if (and (fboundp 'minibuffer-keyboard-quit)
+                                                            delete-selection-mode)
+                                                       'minibuffer-keyboard-quit
+                                                     'abort-recursive-edit)) ; `C-g'
+         (define-key map [M-S-backspace]           nil) ; `M-S-DEL'
+         (define-key map [M-S-delete]              nil) ; `M-S-delete'
+         (define-key map [(meta ?.)]               nil) ; `M-.'
+         (define-key map "\C-x\C-f"                nil) ; `C-x C-f'
+         (define-key map [(control ?=)]            nil) ; `C-='
+         (define-key map [(meta ?o)]               nil) ; `M-o'
+         (define-key map [(meta ?i)]               nil) ; `M-i'
+         (define-key map [(meta ?k)]               nil) ; `M-k'
+         (define-key map [(meta ?:)]               nil) ; `M-:'
+         (define-key map [(control ?a)]            nil) ; `C-a'
+         (define-key map [(control ?e)]            nil) ; `C-e'
+         (define-key map [(control meta ?v)]       nil) ; `C-M-v'
+         (define-key map [(control meta shift ?v)] nil) ; `C-M-S-v' (aka `C-M-V')
+         (dolist (key  icicle-completing-read+insert-keys) (define-key map key nil)) ; `C-M-S-c'
+         (dolist (key  icicle-read+insert-file-name-keys) (define-key map key nil)) ; `C-M-S-f'
+         (define-key map "\n"                      'exit-minibuffer))) ; `C-j'
+
+     ;; `minibuffer-local-completion-map': completion map.
+     (icicle-restore-completion-keys minibuffer-local-completion-map)
+
+     ;; `minibuffer-local-must-match-map': must-match map.
+     ;; In Emacs 22+, local-completion is parent of local-must-match
+     (if (not (eq minibuffer-local-completion-map (keymap-parent minibuffer-local-must-match-map)))
+         (icicle-restore-completion-keys minibuffer-local-must-match-map)
+       (define-key minibuffer-local-must-match-map [(control ?g)]
+         (if (and (fboundp 'minibuffer-keyboard-quit)
+                  delete-selection-mode)
+             'minibuffer-keyboard-quit
+           'abort-recursive-edit))  ; `C-g' - need it anyway, even if inherit completion map.
+       (dolist (key  icicle-completing-read+insert-keys)
+         (define-key minibuffer-local-must-match-map key nil))
+       (dolist (key  icicle-read+insert-file-name-keys)
+         (define-key minibuffer-local-must-match-map key nil))
+       (define-key minibuffer-local-must-match-map "\n" 'minibuffer-complete-and-exit)) ; `C-j'
+     (define-key minibuffer-local-must-match-map [S-return] nil)
+
+     ;; `completion-list-mode-map': map for `*Completions*' buffer.
+     (let ((map  completion-list-mode-map))
+       (define-key map [(control ?g)]       nil)
+       (define-key map "q"                  nil)
+       (define-key map [(control insert)]   nil)
+       (dolist (key icicle-prefix-cycle-next-keys)     (define-key map key nil))
+       (dolist (key icicle-prefix-cycle-previous-keys) (define-key map key nil))
+       (dolist (key icicle-previous-candidate-keys)   (define-key map key nil))
+       (define-key map [(control ?i)]       nil)
+       (define-key map [tab]                nil)
+       (define-key map [S-down-mouse-2]     nil)
+       (define-key map [S-mouse-2]          nil)
+       (define-key map [C-S-down-mouse-2]   nil)
+       (define-key map [C-S-mouse-2]        nil)
+       (define-key map [C-down-mouse-2]     nil)
+       (define-key map [C-mouse-2]          nil)
+       (define-key map [C-M-return]         nil)
+       (define-key map [C-M-down-mouse-2]   nil)
+       (define-key map [C-M-mouse-2]        nil)
+       (define-key map [M-S-down-mouse-2]   nil)
+       (define-key map [M-S-mouse-2]        nil)
+       (define-key map [M-down-mouse-2]     nil)
+       (define-key map [M-mouse-2]          nil)
+       (define-key map [C-down-mouse-3]     nil)
+       (define-key map [M-down-mouse-3]     nil)
+       (define-key map [M-mouse-3]          nil)
+       (define-key map [M-S-down-mouse-3]   nil)
+       (define-key map [M-S-mouse-3]        nil)
+       (define-key map [mouse-3]            nil)
+       (define-key map [C-mouse-3]          nil)
+       (define-key map [(control ?>)]       nil)
+       (define-key map [(control meta ?>)]  nil)
+       (define-key map [(control ?\))]      nil)
+       (define-key map [(control meta ?\))] nil)
+       (define-key map [(control meta ?<)]  nil)
+       (define-key map [(control ?l)]       nil)
+       (define-key map [(control ?a)]       nil)
+       (define-key map [(control ?e)]       nil)
+       (define-key map [down]               nil)
+       (define-key map [up]                 nil)
+       ;; Do these last:
+       (define-key map [right]              'next-completion)
+       (define-key map [left]               'previous-completion))))
+  (when (and (interactive-p) turn-on-p)
+    (message (substitute-command-keys
+              "Use `\\\
+\\[icicle-minibuffer-help]' in minibuffer for help."))))
+
+(defun icicle-unmap (command map current)
+  "In MAP, unbind any keys that are bound to COMMAND.
+If command remapping is available, remap COMMAND to nil in MAP,
+unbinding it.
+Otherwise, bind COMMAND to whatever CURRENT is bound to in MAP."
+  (if (fboundp 'command-remapping)
+      (define-key map (vector 'remap command) nil)
+    (substitute-key-definition current command map)))
+
+(defun icicle-rebind-global (old new map)
+  "Bind command NEW in MAP to all keys currently bound globally to OLD."
+  (substitute-key-definition old new map (current-global-map)))
+
+(defun icicle-bind-completion-keys (map)
+  "Bind keys for minibuffer completion map MAP.
+MAP is `minibuffer-local-completion-map' or
+`minibuffer-local-must-match-map'."
+
+  ;; Menu-bar `Minibuf' menu.
+
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map [menu-bar minibuf quit] ; Replace `keyboard-escape-quit'
+      '(menu-item "Quit" icicle-abort-recursive-edit
+        :help "Cancel minibuffer input or recursive edit"))
+    (define-key map [menu-bar minibuf return]
+      '(menu-item "Enter" exit-minibuffer
+        :help "Terminate input and exit minibuffer" :keys "RET"))
+    (define-key map [menu-bar minibuf separator-help] '("--"))
+    (define-key map [menu-bar minibuf completion-help]
+      '(menu-item "Icicles Help" icicle-minibuffer-help
+        :help "Display help for minibuffer input and completion"))
+    (define-key map [menu-bar minibuf separator-last] '("--"))
+    (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain]
+        '(menu-item "Toggle Searching Complement"
+          icicle-toggle-search-complementing-domain
+          :help "Toggle `icicle-search-complement-domain-p'" :keys "C-M-~"))
+    (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]
+      '(menu-item "Toggle All-Current Icicle-Search Highlighting"
+        icicle-toggle-highlight-all-current :enable icicle-searching-p
+        :help "Toggle `icicle-search-highlight-all-current-flag'" :keys "C-^"))
+    (define-key map [menu-bar minibuf icicle-regexp-quote-input]
+      '(menu-item "Regexp-Quote Input" icicle-regexp-quote-input
+        :enable (with-current-buffer (window-buffer (minibuffer-window)) (not (zerop (buffer-size))))
+        :help "Regexp-quote current input or its active region, then apropos-complete"
+        :keys "M-%"))
+    (define-key map [menu-bar minibuf separator-set2] '("--"))
+    (define-key map [menu-bar minibuf icicle-clear-current-history]
+      '(menu-item "Clear History Entries" icicle-clear-current-history
+        :help "Clear current minibuffer history of selected entries"))
+    (define-key map [menu-bar minibuf icicle-erase-minibuffer]
+      '(menu-item "Delete from History" icicle-erase-minibuffer-or-history-element
+        :visible (memq last-command
+                  '(previous-history-element next-history-element
+                    icicle-erase-minibuffer-or-history-element
+                    previous-matching-history-element next-matching-history-element))
+        :help "Delete current history element (in minibuffer now)" :keys "M-k"))
+    (define-key map [menu-bar minibuf icicle-delete-history-element]
+      '(menu-item "Clear (Erase) Minibuffer" icicle-erase-minibuffer-or-history-element
+        :visible (not (memq last-command
+                       '(previous-history-element next-history-element
+                         icicle-erase-minibuffer-or-history-element
+                         previous-matching-history-element next-matching-history-element)))
+        :help "Erase the Minibuffer" :keys "M-k"))
+    (define-key map [menu-bar minibuf icicle-insert-list-join-string]
+      '(menu-item "Insert Join-String" icicle-insert-list-join-string
+        :help "Insert `icicle-list-join-string' into the minibuffer"))
+    (define-key map [menu-bar minibuf icicle-insert-key-description]
+      '(menu-item "Insert Key Description" icicle-insert-key-description
+        :visible (not icicle-searching-p) :keys "M-q"
+        :help "Read key and insert its description - e.g., reading ^F inserts `C-f'"))
+    (define-key map [menu-bar minibuf icicle-insert-history-element]
+      '(menu-item "Insert Past Input using Completion" icicle-insert-history-element
+        :help "Use completion to insert a previous input into the minibuffer"))
+    (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]
+      '(menu-item "Insert String from a Variable..." icicle-insert-string-from-variable
+        :visible current-prefix-arg :keys "C-="
+        :help "Read a variable name and insert its string value into the minibuffer"))
+    (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]
+      '(menu-item "Insert `icicle-input-string'" icicle-insert-string-from-variable
+        :visible (not current-prefix-arg) :keys "C-="
+        :help "Insert text from variable `icicle-input-string' into the minibuffer"))
+    (define-key map [menu-bar minibuf icicle-insert-string-at-point]
+      '(menu-item "Insert Text from Point" icicle-insert-string-at-point
+        :help "Insert text at or near the cursor into the minibuffer"))
+    (define-key map [menu-bar minibuf icicle-completing-read+insert]
+      '(menu-item "Insert On-Demand Completion" icicle-completing-read+insert
+        :visible (consp icicle-completing-read+insert-candidates)
+        :help "Read and insert something using (lax) completion"))
+    (define-key map [menu-bar minibuf icicle-read+insert-file-name]
+      '(menu-item "Insert File Name" icicle-read+insert-file-name
+        :help "Read and insert a file name using (lax) completion"))
+    )
+  (define-key map [menu-bar minibuf icicle-goto/kill-failed-input]
+    '(menu-item "Cursor to Mismatch (Repeat: Kill)" icicle-goto/kill-failed-input
+      :enable (and (overlayp icicle-input-completion-fail-overlay)
+               (overlay-start icicle-input-completion-fail-overlay))
+      :help "Put cursor where input fails to complete - repeat to kill mismatch"))
+  (define-key map [menu-bar minibuf icicle-retrieve-next-input]
+    '(menu-item "Restore Next Completion Input" icicle-retrieve-next-input
+      :enable (consp (symbol-value (if (icicle-file-name-input-p)
+                                       'icicle-previous-raw-file-name-inputs
+                                     'icicle-previous-raw-non-file-name-inputs)))
+      :help "Cycle forward to insert a previous completion input in the minibuffer (`C-u': \
+complete)"))
+  (define-key map [menu-bar minibuf icicle-retrieve-previous-input]
+    '(menu-item "Restore Previous Completion Input" icicle-retrieve-previous-input
+      :enable (consp (symbol-value (if (icicle-file-name-input-p)
+                                       'icicle-previous-raw-file-name-inputs
+                                     'icicle-previous-raw-non-file-name-inputs)))
+      :help "Cycle backward to insert a previous completion input in the minibuffer (`C-u': \
+complete)"))
+  (define-key map [menu-bar minibuf separator-C-l] '("--"))
+  (define-key map [menu-bar minibuf ?\?] nil)
+  (define-key map [menu-bar minibuf space] nil)
+  (define-key map [menu-bar minibuf tab] nil)
+  (define-key map [menu-bar minibuf alt-action-list-all]
+    '(menu-item "Alt Act on List of Candidates" icicle-all-candidates-list-alt-action
+      :help "Apply the alternative action to the list of matching completion candidates"
+      :enable icicle-all-candidates-list-alt-action-fn))
+  (define-key map [menu-bar minibuf alt-action-all]
+    '(menu-item "Alt Act on Each Candidate" icicle-all-candidates-alt-action
+      :help "Apply the alternative action to each matching completion candidates"
+      :enable icicle-candidate-alt-action-fn))
+  (define-key map [menu-bar minibuf action-list-all]
+    '(menu-item "Act on List of Candidates" icicle-all-candidates-list-action
+      :help "Apply the command action to the list of matching completion candidates"
+      :enable icicle-all-candidates-list-action-fn))
+  (define-key map [menu-bar minibuf action-all]
+    '(menu-item "Act on Each Candidate" icicle-all-candidates-action
+      :help "Apply the command action to each matching completion candidates"
+      :enable icicle-candidate-action-fn))
+  (define-key map [menu-bar minibuf separator-actions] '("--"))
+  (define-key map [menu-bar minibuf set-define]
+    '(menu-item "Define Candidates by Lisp Sexp" icicle-candidate-set-define
+      :help "Define the set of current completion candidates by evaluating a sexp"))
+  (define-key map [menu-bar minibuf icicle-keep-only-past-inputs]
+    '(menu-item "Keep Only Previously Entered" icicle-keep-only-past-inputs
+      :enable (and icicle-completion-candidates (consp (symbol-value minibuffer-history-variable)))
+      :help "Removed candidates that you have not previously chosen and entered"))
+  (define-key map [menu-bar minibuf set-union]
+    '(menu-item "Add (Union) Saved Candidate Set" icicle-candidate-set-union
+      :enable icicle-saved-completion-candidates
+      :help "Set union between the current and saved completion candidates"))
+  (define-key map [menu-bar minibuf set-difference]
+    '(menu-item "Subtract Saved Candidate Set" icicle-candidate-set-difference
+      :enable icicle-saved-completion-candidates
+      :help "Set difference between the current and saved completion candidates"))
+  (define-key map [menu-bar minibuf set-intersection]
+    '(menu-item "Intersect Saved Candidate Set" icicle-candidate-set-intersection
+      :enable icicle-saved-completion-candidates
+      :help "Set intersection between the current and saved candidates"))
+  (define-key map [menu-bar minibuf icicle-save-predicate-to-variable]
+    '(menu-item "Save Predicate to Variable" icicle-save-predicate-to-variable
+      :help "Save the current completion predicate to a variable"))
+  (define-key map [menu-bar minibuf icicle-narrow-candidates-with-predicate]
+    '(menu-item "Satisfy Also Predicate..." icicle-narrow-candidates-with-predicate
+      :help "Match another input pattern (narrow completions set)"
+      :enable icicle-completion-candidates))
+  (define-key map [menu-bar minibuf icicle-narrow-candidates]
+    '(menu-item "Match Also Regexp..." icicle-narrow-candidates
+      :enable icicle-completion-candidates
+      :help "Match another input pattern (narrow completions set)"))
+  (define-key map [menu-bar minibuf icicle-widen-candidates]
+    '(menu-item "Match Alternative..." icicle-widen-candidates
+      :enable icicle-completion-candidates
+      :help "Match alternative input pattern (widen completions set)"))
+  (define-key map [menu-bar minibuf set-complement]
+    '(menu-item "Complement Candidates" icicle-candidate-set-complement
+      :help "Complement the set of current completion candidates"))
+  (define-key map [menu-bar minibuf separator-set1] '("--"))
+  (define-key map [menu-bar minibuf set-swap]
+    '(menu-item "Swap Saved and Current Sets" icicle-candidate-set-swap
+      :enable icicle-saved-completion-candidates
+      :help "Swap the saved and current sets of completion candidates"))
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-more-selected]
+    '(menu-item "Save More Selected (Region) Candidates"
+      icicle-candidate-set-save-more-selected
+      :help "Add the candidates in the region to the saved candidates"))
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-selected]
+    '(menu-item "Save Selected (Region) Candidates"
+      icicle-candidate-set-save-selected
+      :help "Save the candidates in the region, for later recall"))
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-more]
+    '(menu-item "Save More Candidates" icicle-candidate-set-save-more
+      :help "Add current completion candidates to saved candidates set"))
+  (define-key map [menu-bar minibuf set-save-to-cache-file]
+    '(menu-item "    to Cache File..." icicle-candidate-set-save-persistently
+      :help "Save current completion candidates to a cache file, for later recall"))
+  (define-key map [menu-bar minibuf set-save-to-variable]
+    '(menu-item "    to Variable..." icicle-candidate-set-save-to-variable
+      :help "Save current completion candidates to a variable, for later recall"))
+  (define-key map [menu-bar minibuf set-save]
+    '(menu-item "Save Candidates" icicle-candidate-set-save
+      :help "Save the set of current completion candidates, for later recall"))
+  (define-key map [menu-bar minibuf icicle-candidate-set-retrieve-more]
+    '(menu-item "Retrieve More Saved Candidates"
+      icicle-candidate-set-retrieve-more
+      :help "Add saved candidates to current completion candidates"))
+  (define-key map [menu-bar minibuf set-retrieve-from-cache-file]
+    '(menu-item "    from Cache File..."
+      icicle-candidate-set-retrieve-persistent
+      :help "Retrieve saved completion candidates from a cache file, making them current"))
+  (define-key map [menu-bar minibuf set-retrieve-from-variable]
+    '(menu-item "    from Variable..." icicle-candidate-set-retrieve-from-variable
+      :help "Retrieve saved completion candidates from variable, making them current"))
+  (define-key map [menu-bar minibuf set-retrieve]
+    '(menu-item "Retrieve Saved Candidates" icicle-candidate-set-retrieve
+      :enable icicle-saved-completion-candidates
+      :help "Retrieve the saved set of completion candidates, making it current"))
+  (define-key map [menu-bar minibuf separator-complete] '("--"))
+  (define-key map [menu-bar minibuf word-complete]
+    '(menu-item "Word-Complete" icicle-prefix-word-complete
+      :help "Complete at most one word of prefix"))
+  (define-key map [menu-bar minibuf prefix-complete]
+    '(menu-item "Prefix-Complete" icicle-prefix-complete
+      :help "Complete prefix as far as possible"))
+  (define-key map [menu-bar minibuf apropos-complete]
+    '(menu-item "Apropos-Complete" icicle-apropos-complete :keys "S-TAB"
+      :help "Complete regular expression as far as possible and list completions"))
+
+  ;; Remap some commands for completion.
+  (icicle-remap 'self-insert-command           'icicle-self-insert map (current-global-map))
+  (icicle-remap 'universal-argument            'icicle-universal-argument ; `C-u'
+                map (current-global-map))
+  (icicle-remap 'negative-argument             'icicle-negative-argument ; `M--'
+                map (current-global-map))
+  (icicle-remap 'digit-argument                'icicle-digit-argument ; `C-9'
+                map (current-global-map))
+  (icicle-remap 'backward-delete-char-untabify 'icicle-backward-delete-char-untabify ; `DEL'
+                map (current-global-map))
+  (icicle-remap 'delete-backward-char          'icicle-delete-backward-char ; `DEL'
+                map (current-global-map))
+  (icicle-remap 'delete-char                   'icicle-delete-char ; `C-d', `deletechar'
+                map (current-global-map))
+  (icicle-remap 'backward-kill-word            'icicle-backward-kill-word ; `M-DEL'
+                map (current-global-map))
+  (icicle-remap 'kill-word                     'icicle-kill-word ; `M-d'
+                map (current-global-map))
+  (icicle-remap 'backward-kill-sexp            'icicle-backward-kill-sexp ; `C-M-backspace'
+                map (current-global-map))
+  (icicle-remap 'kill-sexp                     'icicle-kill-sexp ; `C-M-k', `C-M-delete'
+                map (current-global-map))
+  (icicle-remap 'backward-kill-sentence        'icicle-backward-kill-sentence ; `C-x DEL'
+                map (current-global-map))
+  (icicle-remap 'backward-kill-paragraph       'icicle-backward-kill-paragraph ; `C-backspace'
+                map (current-global-map))
+  (icicle-remap 'kill-paragraph                'icicle-kill-paragraph ; `C-delete'
+                map (current-global-map))
+  (icicle-remap 'kill-line                     'icicle-kill-line ; `C-k', `deleteline'
+                map (current-global-map))
+  (icicle-remap 'reposition-window             'icicle-goto/kill-failed-input ; `C-M-l'
+                map (current-global-map))
+  (icicle-remap 'transpose-chars               'icicle-transpose-chars ; `C-t'
+                map (current-global-map))
+  (icicle-remap 'transpose-words               'icicle-transpose-words ; `M-t'
+                map (current-global-map))
+  (icicle-remap 'transpose-sexps               'icicle-transpose-sexps ; `C-M-t'
+                map (current-global-map))
+  (icicle-remap 'yank-pop                      'icicle-yank-pop ; `M-y', `M-insert'
+                map (current-global-map))
+  (icicle-remap 'mouse-yank-secondary          'icicle-mouse-yank-secondary ; `M-mouse-2'
+                map (current-global-map))
+
+  ;; Bind additional keys.
+  (dolist (key icicle-word-completion-keys)
+    (define-key map key 'icicle-prefix-word-complete)) ; `M-SPC'
+  (dolist (key icicle-apropos-complete-keys)
+    (define-key map key 'icicle-apropos-complete)) ; `S-TAB'
+  (dolist (key icicle-prefix-complete-keys) (define-key map key 'icicle-prefix-complete)) ; `TAB'
+  (dolist (key icicle-apropos-complete-no-display-keys)
+    (define-key map key 'icicle-apropos-complete-no-display)) ; `C-M-S-TAB'
+  (dolist (key icicle-prefix-complete-no-display-keys)
+    (define-key map key 'icicle-prefix-complete-no-display)) ; `C-M-TAB'
+
+  (icicle-define-cycling-keys map)      ;     `up',     `down',     `prior',     `next',
+                                        ;   `C-up',   `C-down',   `C-prior',   `C-next',
+                                        ; `C-M-up', `C-M-down', `C-M-prior', `C-M-next',
+                                        ; `C-S-up', `C-S-down', `C-S-prior', `C-S-next',
+  (define-key map [(control help)]           'icicle-help-on-candidate) ; `C-help'
+  (define-key map [(control meta help)]      'icicle-help-on-candidate) ; `C-M-help'
+  (define-key map [(control f1)]             'icicle-help-on-candidate) ; `C-f1'
+  (define-key map [(control meta f1)]        'icicle-help-on-candidate) ; `C-M-f1'
+  (define-key map [(control meta return)]    'icicle-help-on-candidate) ; `C-M-RET'
+  (define-key map [(meta return)]            'icicle-candidate-read-fn-invoke) ;`M-RET' as `M-return'
+  (define-key map "\C-\M-m"                  'icicle-candidate-read-fn-invoke) ;`M-RET' as `ESC RET'
+  (define-key map [(control shift return)]   'icicle-candidate-alt-action) ; `C-S-RET'
+  (define-key map [delete]                   'icicle-remove-candidate) ; `delete'
+  (define-key map [(shift delete)]           'icicle-delete-candidate-object) ; `S-delete'
+  (define-key map [(control ?w)]             'icicle-kill-region) ; `C-w'
+  (define-key map [(control return)]         'icicle-candidate-action) ; `C-RET'
+  (define-key map [(control ?!)]             'icicle-all-candidates-action) ; `C-!'
+  (define-key map [(control ?|)]             'icicle-all-candidates-alt-action) ; `C-|'
+  (define-key map [(meta ?!)]                'icicle-all-candidates-list-action) ; `M-!'
+  (define-key map [(meta ?|)]                'icicle-all-candidates-list-alt-action) ; `M-|'
+  (define-key map [(control meta ?/)]        'icicle-prefix-complete) ; `C-M-/', for `dabbrev.el'.
+  (define-key map [(meta ?h)]                'icicle-history) ; `M-h'
+  (define-key map [(meta pause)]             'icicle-keep-only-past-inputs) ; `M-pause'
+  (define-key map [(control pause)]     'icicle-toggle-highlight-historical-candidates) ; `C-pause'
+  (define-key map [(shift pause)]            'icicle-toggle-highlight-saved-candidates) ; `S-pause'
+  (define-key map [(control meta pause)]     'icicle-other-history) ; `C-M-pause'
+  (define-key map [(control insert)]         'icicle-switch-to-Completions-buf) ; `C-insert'
+  (define-key map [insert]                   'icicle-save/unsave-candidate) ; `insert'
+
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    ;; Note: `setup-keys.el' binds `C-o' to `1on1-fit-minibuffer-frame' if defined.
+    (define-key map [(control ?a)]           'icicle-beginning-of-line+) ; `C-a'
+    (define-key map [(control ?e)]           'icicle-end-of-line+) ; `C-e'
+    (define-key map [(control meta ?v)]      'icicle-scroll-forward) ; `C-M-v'
+    (define-key map [(control meta shift ?v)] 'icicle-scroll-backward) ; `C-M-S-v' (aka `C-M-V')
+    (define-key map [(control ?=)]           'icicle-insert-string-from-variable) ; `C-='
+    ;; Replaces `tab-to-tab-stop':
+    (define-key map [(meta ?i)]              'icicle-clear-current-history) ; `M-i'
+    ;; Replaces `kill-sentence':
+    (define-key map [(meta ?k)]              'icicle-erase-minibuffer-or-history-element) ; `M-k'
+    (define-key map [(meta ?o)]              'icicle-insert-history-element) ; `M-o'
+    (define-key map [(meta ?.)]              'icicle-insert-string-at-point) ; `M-.'
+    (define-key map "\C-x\C-f"               'icicle-resolve-file-name) ; `C-x C-f'
+    (define-key map [(meta ?:)]              'icicle-pp-eval-expression-in-minibuffer) ; `M-:'
+    (when (fboundp 'yank-secondary)     ; In `second-sel.el'.
+      (define-key map "\C-\M-y"              'icicle-yank-secondary)) ; `C-M-y'
+    (define-key map [M-S-backspace]          'icicle-erase-minibuffer) ; `M-S-backspace'
+    (define-key map [M-S-delete]             'icicle-erase-minibuffer) ; `M-S-delete'
+    (dolist (key  icicle-completing-read+insert-keys)
+      (define-key map key 'icicle-completing-read+insert)) ; `C-M-S-c'
+    (dolist (key  icicle-read+insert-file-name-keys)
+      (define-key map key 'icicle-read+insert-file-name)) ; `C-M-S-f'
+    )
+
+  ;; Need `C-g', even if `minibuffer-local-completion-map' inherits from `minibuffer-local-map'.
+  (define-key map [(control ?g)]             'icicle-abort-recursive-edit) ; `C-g'
+  (define-key map [(meta ?q)]                'icicle-dispatch-M-q) ; `M-q'
+  (define-key map [(control ?l)]             'icicle-retrieve-previous-input) ; `C-l'
+  (define-key map [(control shift ?l)]       'icicle-retrieve-next-input) ; `C-L' (`C-S-l')
+  (define-key map [(meta ?$)]                'icicle-candidate-set-truncate) ; `M-$'
+  (define-key map [(control ?~)]             'icicle-candidate-set-complement) ; `C-~'
+  (define-key map [(control ?-)]             'icicle-candidate-set-difference) ; `C--'
+  (define-key map [(control ?+)]             'icicle-candidate-set-union) ; `C-+'
+  (define-key map [(control ?*)]             'icicle-candidate-set-intersection) ; `C-*'
+  (define-key map [(control ?>)]             'icicle-candidate-set-save-more) ; `C->'
+  (define-key map [(control meta ?>)]        'icicle-candidate-set-save) ; `C-M->'
+  (define-key map [(control ?\()]            'icicle-next-TAB-completion-method) ; `C-('
+  (define-key map [(meta ?\()]               'icicle-next-S-TAB-completion-method) ; `M-('
+  (define-key map [(control ?\))]            'icicle-candidate-set-save-more-selected) ; `C-)'
+  (define-key map [(control meta ?\))]       'icicle-candidate-set-save-selected) ; `C-M-)'
+  (define-key map [(control meta ?<)]        'icicle-candidate-set-retrieve) ; `C-M-<'
+  (define-key map [(control meta ?})]        'icicle-candidate-set-save-to-variable) ; `C-M-}'
+  (define-key map [(control meta ?{)]        'icicle-candidate-set-retrieve-from-variable) ; `C-M-{'
+  (define-key map [(control ?})]             'icicle-candidate-set-save-persistently) ; `C-}'
+  (define-key map [(control ?{)]             'icicle-candidate-set-retrieve-persistent) ; `C-{'
+  (define-key map [(control ?%)]             'icicle-candidate-set-swap) ; `C-%'
+  (define-key map [(meta ?%)]                'icicle-regexp-quote-input) ; `M-%'
+  (define-key map [(control ?:)]             'icicle-candidate-set-define) ; `C-:'
+  (define-key map [(control meta ?j)]        'icicle-insert-list-join-string) ; `C-M-j'
+  (define-key map [(control ?,)]             'icicle-change-sort-order) ; `C-,'
+  (define-key map [(control meta ?\;)]       'icicle-toggle-ignoring-comments) ; `C-M-;'
+  (define-key map [(control ?`)]             'icicle-toggle-regexp-quote) ; `C-`'
+  (define-key map [(control meta ?\.)]       'icicle-toggle-dot) ; `C-M-.'
+  (define-key map [(control meta ?`)]        'icicle-toggle-literal-replacement) ; `C-M-`'
+  (define-key map [(control ?<)]             'icicle-candidate-set-retrieve-more) ; `C-<'
+  (define-key map [(control meta ?_)]        'icicle-toggle-proxy-candidates) ; `C-M-_'
+  (define-key map [(control ?$)]             'icicle-toggle-transforming) ; `C-$'
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map [(control ??)]           'icicle-minibuffer-help)) ; `C-?'
+  (define-key map [(control ?.)]             'icicle-dispatch-C-.) ; `C-.'
+  (define-key map [(control ?#)]             'icicle-toggle-incremental-completion) ; `C-#'
+  (define-key map [(control ?\;)]            'icicle-toggle-expand-to-common-match) ; `C-;'
+  (define-key map [(meta ?\;)]               'icicle-toggle-search-replace-common-match) ; `M-;'
+  (define-key map [(control ?^)]             'icicle-dispatch-C-^) ; `C-^'
+  (define-key map [(control shift ?a)]       'icicle-toggle-case-sensitivity) ; `C-S-a' (`C-A')
+  (define-key map [(meta ?~)]                'icicle-toggle-~-for-home-dir) ; `M-~'
+  (define-key map [(control meta ?~)]        'icicle-toggle-search-complementing-domain) ; `C-M-~'
+  (define-key map [(meta ?g)]                'icicle-toggle-C-for-actions) ; `M-g'
+  (define-key map [(meta ?,)]                'icicle-dispatch-M-comma) ; `M-,'
+  (define-key map [(control meta ?,)]        'icicle-toggle-alternative-sorting) ; `C-M-,'
+  (define-key map [(control meta ?+)]        'icicle-plus-saved-sort) ; `C-M-+'
+  (define-key map [(meta ?+)]                'icicle-widen-candidates) ; `M-+'
+  (define-key map [(meta ?*)]                'icicle-narrow-candidates) ; `M-*'
+  (define-key map [(meta ?&)]                'icicle-narrow-candidates-with-predicate) ; `M-&'
+  (define-key map [(meta ?_)]                'icicle-dispatch-M-_) ; `M-_'
+  (define-key map [(control meta ?&)]        'icicle-save-predicate-to-variable) ; `C-M-&'
+  (define-key map [(shift ?\ )]              'icicle-apropos-complete-and-narrow) ; `S-SPC'
+  (define-key map [(shift backspace)]        'icicle-apropos-complete-and-widen) ; `S-DEL'
+  (define-key map "\C-v"                     'icicle-scroll-Completions-forward) ; `C-v'
+  (define-key map "\M-v"                     'icicle-scroll-Completions-backward) ; `M-v'
+  (define-key map "."                        'icicle-insert-dot-command) ; `.'
+  (define-key map "\M-m"                     'icicle-toggle-show-multi-completion) ; `M-m'
+  (define-key map "\C-x."                    'icicle-dispatch-C-x.) ; `C-x .'
+  (when (fboundp 'icicle-cycle-image-file-thumbnail) ; Emacs 23+
+    (define-key map "\C-xt"                  'icicle-cycle-image-file-thumbnail)) ; `C-x t'
+  (when (fboundp 'doremi)
+    (define-key map "\C-xw"                  'icicle-doremi-candidate-width-factor+) ; `C-x w'
+    (define-key map "\C-x|"                  'icicle-doremi-inter-candidates-min-spaces+) ; `C-x |'
+    (define-key map "\C-x#"                  'icicle-doremi-increment-max-candidates+) ; `C-x #'
+    (when (fboundp 'text-scale-increase) ; Emacs 23+.
+      (define-key map "\C-x-"                'icicle-doremi-zoom-Completions+)) ; `C-x -'
+    (when (eq (icicle-current-TAB-method) 'swank)
+      (define-key map "\C-x1"                'icicle-doremi-increment-swank-timeout+)
+      (define-key map "\C-x2"                'icicle-doremi-increment-swank-prefix-length+)))
+  ;; `minibuffer-completion-help' got wiped out by remap for self-insert.
+  (define-key map "?"                        'icicle-self-insert) ; `?'
+  (define-key map " "                        'icicle-self-insert) ; " "
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map "\n"                     'icicle-insert-newline-in-minibuffer))) ; `C-j'
+
+(defun icicle-restore-completion-keys (map)
+  "Restore standard keys for minibuffer completion map MAP.
+MAP is `minibuffer-local-completion-map',
+`minibuffer-local-filename-completion-map', or
+`minibuffer-local-must-match-map'."
+
+  ;; Menu-bar `Minibuf' menu.
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map [menu-bar minibuf quit]
+      '(menu-item "Quit" keyboard-escape-quit :help "Abort input and exit minibuffer"))
+    (define-key map [menu-bar minibuf return]
+      '(menu-item "Enter" exit-minibuffer
+        :help "Terminate input and exit minibuffer" :keys "RET"))
+    (define-key map [menu-bar minibuf separator-help]                            nil)
+    (define-key map [menu-bar minibuf completion-help]                           nil)
+    (define-key map [menu-bar minibuf separator-last]                            nil)
+    (define-key map [menu-bar minibuf icicle-clear-current-history]              nil)
+    (define-key map [menu-bar minibuf icicle-toggle-search-complementing-domain] nil)
+    (define-key map [menu-bar minibuf icicle-toggle-highlight-all-current]       nil)
+    (define-key map [menu-bar minibuf icicle-regexp-quote-input]                 nil)
+    (define-key map [menu-bar minibuf separator-set2]                            nil)
+    (define-key map [menu-bar minibuf icicle-clear-current-history]              nil)
+    (define-key map [menu-bar minibuf icicle-erase-minibuffer]                   nil)
+    (define-key map [menu-bar minibuf icicle-delete-history-element]             nil)
+    (define-key map [menu-bar minibuf icicle-insert-list-join-string]            nil)
+    (define-key map [menu-bar minibuf icicle-insert-key-description]             nil)
+    (define-key map [menu-bar minibuf icicle-insert-history-element]             nil)
+    (define-key map [menu-bar minibuf icicle-insert-string-from-a-var]           nil)
+    (define-key map [menu-bar minibuf icicle-insert-string-from-std-var]         nil)
+    (define-key map [menu-bar minibuf icicle-insert-string-at-point]             nil)
+    (define-key map [menu-bar minibuf icicle-completing-read+insert]             nil)
+    (define-key map [menu-bar minibuf icicle-read+insert-file-name]              nil)
+    )
+  (define-key map [menu-bar minibuf icicle-goto/kill-failed-input]           nil)
+  (define-key map [menu-bar minibuf icicle-retrieve-next-input]              nil)
+  (define-key map [menu-bar minibuf icicle-retrieve-previous-input]          nil)
+  (define-key map [menu-bar minibuf separator-C-l]                           nil)
+  (define-key map [menu-bar minibuf alt-action-list-all]                     nil)
+  (define-key map [menu-bar minibuf alt-action-all]                          nil)
+  (define-key map [menu-bar minibuf action-list-all]                         nil)
+  (define-key map [menu-bar minibuf action-all]                              nil)
+  (define-key map [menu-bar minibuf separator-actions]                       nil)
+  (define-key map [menu-bar minibuf set-define]                              nil)
+  (define-key map [menu-bar minibuf icicle-keep-only-past-inputs]            nil)
+  (define-key map [menu-bar minibuf set-union]                               nil)
+  (define-key map [menu-bar minibuf set-difference]                          nil)
+  (define-key map [menu-bar minibuf set-intersection]                        nil)
+  (define-key map [menu-bar minibuf icicle-save-predicate-to-variable]       nil)
+  (define-key map [menu-bar minibuf icicle-narrow-candidates-with-predicate] nil)
+  (define-key map [menu-bar minibuf icicle-narrow-candidates]                nil)
+  (define-key map [menu-bar minibuf icicle-widen-candidates]                 nil)
+  (define-key map [menu-bar minibuf set-complement]                          nil)
+  (define-key map [menu-bar minibuf separator-set1]                          nil)
+  (define-key map [menu-bar minibuf set-swap]                                nil)
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-more-selected] nil)
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-selected]      nil)
+  (define-key map [menu-bar minibuf icicle-candidate-set-save-more]          nil)
+  (define-key map [menu-bar minibuf set-retrieve-from-cache-file]            nil)
+  (define-key map [menu-bar minibuf set-retrieve-from-variable]              nil)
+  (define-key map [menu-bar minibuf set-retrieve]                            nil)
+  (define-key map [menu-bar minibuf set-save-to-cache-file]                  nil)
+  (define-key map [menu-bar minibuf set-save-to-variable]                    nil)
+  (define-key map [menu-bar minibuf set-save]                                nil)
+  (define-key map [menu-bar minibuf separator-set2]                          nil)
+  (define-key map [menu-bar minibuf word-complete]                           nil)
+  (define-key map [menu-bar minibuf prefix-complete]                         nil)
+  (define-key map [menu-bar minibuf apropos-complete]                        nil)
+  (define-key map [menu-bar minibuf ?\?]
+    '(menu-item "List Completions" minibuffer-completion-help
+      :help "Display all possible completions"))
+  (define-key map [menu-bar minibuf space]
+    '(menu-item "Complete Word" minibuffer-complete-word :help "Complete at most one word"))
+  (define-key map [menu-bar minibuf tab]
+    '(menu-item "Complete" minibuffer-complete :help "Complete as far as possible"))
+
+  ;; Unmap commands that were bound for completion.
+  (icicle-unmap 'self-insert-command           map 'icicle-self-insert)
+  (icicle-unmap 'universal-argument            map 'icicle-universal-argument)
+  (icicle-unmap 'negative-argument             map 'icicle-negative-argument)
+  (icicle-unmap 'digit-argument                map 'icicle-digit-argument)
+  (icicle-unmap 'backward-delete-char-untabify map 'icicle-backward-delete-char-untabify)
+  (icicle-unmap 'delete-backward-char          map 'icicle-delete-backward-char)
+  (icicle-unmap 'delete-char                   map 'icicle-delete-char)
+  (icicle-unmap 'backward-kill-word            map 'icicle-backward-kill-word)
+  (icicle-unmap 'kill-word                     map 'icicle-kill-word)
+  (icicle-unmap 'backward-kill-sexp            map 'icicle-backward-kill-sexp)
+  (icicle-unmap 'kill-sexp                     map 'icicle-kill-sexp)
+  (icicle-unmap 'backward-kill-sentence        map 'icicle-backward-kill-sentence)
+  (icicle-unmap 'backward-kill-paragraph       map 'icicle-backward-kill-paragraph)
+  (icicle-unmap 'kill-paragraph                map 'icicle-kill-paragraph)
+  (icicle-unmap 'kill-line                     map 'icicle-kill-line)
+  (icicle-unmap 'reposition-window             map 'icicle-goto/kill-failed-input)
+  (icicle-unmap 'transpose-chars               map 'icicle-transpose-chars)
+  (icicle-unmap 'transpose-words               map 'icicle-transpose-words)
+  (icicle-unmap 'transpose-sexps               map 'icicle-transpose-sexps)
+  (icicle-unmap 'yank-pop                      map 'icicle-yank-pop)
+  (icicle-unmap 'mouse-yank-secondary          map 'icicle-mouse-yank-secondary)
+
+  ;; Restore additional bindings.
+  ;; Do the option keys first, so they can be rebound as needed.
+  (dolist (key icicle-word-completion-keys)                   (define-key map key nil))
+  (dolist (key icicle-apropos-complete-keys)                  (define-key map key nil))
+  (dolist (key icicle-prefix-complete-keys)                   (define-key map key nil))
+  (dolist (key icicle-apropos-complete-no-display-keys)       (define-key map key nil))
+  (dolist (key icicle-prefix-complete-no-display-keys)        (define-key map key nil))
+
+  (dolist (key icicle-prefix-cycle-previous-keys)             (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-next-keys)                 (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-previous-keys)            (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-next-keys)                (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-previous-action-keys)      (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-previous-alt-action-keys)  (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-next-action-keys)          (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-next-alt-action-keys)      (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-previous-action-keys)     (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-previous-alt-action-keys) (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-next-action-keys)         (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-next-alt-action-keys)     (define-key map key nil))
+  (dolist (key icicle-modal-cycle-up-keys)                    (define-key map key nil))
+  (dolist (key icicle-modal-cycle-down-keys)                  (define-key map key nil))
+  (dolist (key icicle-modal-cycle-up-action-keys)             (define-key map key nil))
+  (dolist (key icicle-modal-cycle-up-alt-action-keys)         (define-key map key nil))
+  (dolist (key icicle-modal-cycle-down-action-keys)           (define-key map key nil))
+  (dolist (key icicle-modal-cycle-down-alt-action-keys)       (define-key map key nil))
+  (dolist (key icicle-modal-cycle-up-help-keys)               (define-key map key nil))
+  (dolist (key icicle-modal-cycle-down-help-keys)             (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-previous-help-keys)        (define-key map key nil))
+  (dolist (key icicle-prefix-cycle-next-help-keys)            (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-previous-help-keys)       (define-key map key nil))
+  (dolist (key icicle-apropos-cycle-next-help-keys)           (define-key map key nil))
+
+  (define-key map [(control help)]           nil)
+  (define-key map [(control meta help)]      nil)
+  (define-key map [(control f1)]             nil)
+  (define-key map [(control meta f1)]        nil)
+  (define-key map [(control meta return)]    nil)
+  (define-key map [(meta return)]            nil)
+  (define-key map "\C-\M-m"                  nil)
+  (define-key map [(control shift return)]   nil)
+  (define-key map [delete]                   nil)
+  (define-key map [(shift delete)]           nil)
+  (define-key map [(control ?w)]             nil)
+  (define-key map [(control return)]         nil)
+  (define-key map [(control ?!)]             nil)
+  (define-key map [(control ?!)]             nil)
+  (define-key map [(control ?|)]             nil)
+  (define-key map [(meta ?!)]                nil)
+  (define-key map [(meta ?|)]                nil)
+  (define-key map [(control meta ?/)]        nil)
+  (define-key map [(meta ?h)]                nil)
+  (define-key map [(meta pause)]             nil)
+  (define-key map [(control pause)]          nil)
+  (define-key map [(shift pause)]            nil)
+  (define-key map [(control meta pause)]     nil)
+  (define-key map [(control insert)]         nil)
+  (define-key map [insert]                   nil)
+
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map [(control ?a)]           nil)
+    (define-key map [(control ?e)]           nil)
+    (define-key map [(control ?=)]           nil)
+    (define-key map [(meta ?i)]              nil)
+    (define-key map [(meta ?k)]              nil)
+    (define-key map [(meta ?o)]              nil)
+    (define-key map [(meta ?.)]              nil)
+    (define-key map "\C-x\C-f"               nil)
+    (define-key map [(meta ?:)]              nil)
+    (define-key map "\C-\M-y"                nil)
+    (define-key map [M-S-backspace]          nil)
+    (define-key map [M-S-delete]             nil)
+    (dolist (key  icicle-completing-read+insert-keys)
+      (define-key minibuffer-local-must-match-map key nil))
+    (dolist (key  icicle-read+insert-file-name-keys)
+      (define-key minibuffer-local-must-match-map key nil))
+    )
+
+  (define-key map [(meta ?q)]                nil)
+  (define-key map [(control ?l)]             nil)
+  (define-key map [(control shift ?l)]       nil)
+  (define-key map [(meta ?$)]                nil)
+  (define-key map [(control ?~)]             nil)
+  (define-key map [(control ?-)]             nil)
+  (define-key map [(control ?+)]             nil)
+  (define-key map [(control ?*)]             nil)
+  (define-key map [(control ?>)]             nil)
+  (define-key map [(control meta ?>)]        nil)
+  (define-key map [(control ?\()]            nil)
+  (define-key map [(meta ?\()]               nil)
+  (define-key map [(control ?\))]            nil)
+  (define-key map [(control meta ?\))]       nil)
+  (define-key map [(control meta ?<)]        nil)
+  (define-key map [(control meta ?})]        nil)
+  (define-key map [(control meta ?{)]        nil)
+  (define-key map [(control ?})]             nil)
+  (define-key map [(control ?{)]             nil)
+  (define-key map [(control ?%)]             nil)
+  (define-key map [(meta ?%)]                nil)
+  (define-key map [(control ?:)]             nil)
+  (define-key map [(control meta ?j)]        nil)
+  (define-key map [(control ?,)]             nil)
+  (define-key map [(control ? )]             nil)
+  (define-key map [(control meta ?\;)]       nil)
+  (define-key map [(control ?`)]             nil)
+  (define-key map [(control meta ?`)]        nil)
+  (define-key map [(control ?<)]             nil)
+  (define-key map [(control meta ?_)]        nil)
+  (define-key map [(control ?$)]             nil)
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map [(control ??)]           nil))
+  (define-key map [(control ?.)]             nil)
+  (define-key map [(control ?#)]             nil)
+  (define-key map [(control ?\;)]            nil)
+  (define-key map [(control meta ?\.)]       nil)
+  (define-key map [(meta ?\;)]               nil)
+  (define-key map [(control ?^)]             nil)
+  (define-key map [(control shift ?a)]       nil)
+  (define-key map [(meta ?~)]                nil)
+  (define-key map [(control meta ?~)]        nil)
+  (define-key map [(meta ?g)]                nil)
+  (define-key map [(meta ?,)]                nil)
+  (define-key map [(control meta ?,)]        nil)
+  (define-key map [(control meta ?+)]        nil)
+  (define-key map [(meta ?+)]                nil)
+  (define-key map [(meta ?*)]                nil)
+  (define-key map [(meta ?&)]                nil)
+  (define-key map [(meta ?_)]                nil)
+  (define-key map [(control meta ?&)]        nil)
+  (define-key map [(shift ?\ )]              nil)
+  (define-key map [(shift backspace)]        nil)
+  (define-key map "\C-v"                     nil)
+  (define-key map "\M-v"                     nil)
+  (define-key map "."                        nil)
+  (define-key map "\M-m"                     nil)
+  (define-key map "\C-x."                    nil)
+  (when (fboundp 'icicle-cycle-image-file-thumbnail) ; Emacs 23+
+    (define-key map "\C-xt"                  nil))
+  (when (fboundp 'doremi)
+    (define-key map "\C-xw"                  nil)
+    (define-key map "\C-x|"                  nil)
+    (define-key map "\C-x#"                  nil)
+    (when (fboundp 'text-scale-increase)
+      (define-key map "\C-x-"                nil))
+    (define-key map "\C-x1"                  nil)
+    (define-key map "\C-x2"                  nil))
+  ;; Do these last. -----------------
+  (define-key map [(control ?i)]             'minibuffer-complete)
+  (define-key map [tab]                      'minibuffer-complete)
+  (define-key map "?"                        'minibuffer-completion-help)
+  (define-key map " "                        'minibuffer-complete-word)
+  (define-key map [(control ?g)]             (if (and (fboundp 'minibuffer-keyboard-quit)
+                                                      delete-selection-mode)
+                                                 'minibuffer-keyboard-quit
+                                               'abort-recursive-edit))
+  ;; In Emacs 22+, local is parent of local-completion
+  (unless (eq minibuffer-local-map (keymap-parent minibuffer-local-completion-map))
+    (define-key map "\n"                     'exit-minibuffer))
+  (define-key map [(meta ?p)]                'previous-history-element)
+  (define-key map [(meta ?n)]                'next-history-element)
+  (define-key map [up]                       'previous-history-element)
+  (define-key map [down]                     'next-history-element)
+  (define-key map [(meta ?v)]                'switch-to-completions)
+  (define-key map [prior]                    'switch-to-completions)
+  (define-key map [next]                     'next-history-element))
+
+(defun icicle-minibuffer-setup ()
+  "Run in minibuffer on activation, to enable completion cycling.
+Usually run by inclusion in `minibuffer-setup-hook'."
+  (when (and icicle-mode (window-minibuffer-p (selected-window)) (not executing-kbd-macro))
+    ;; The pre- and post-command hooks are local to the
+    ;; minibuffer, so they are added here, not in `icicle-mode'.
+    ;; They are removed in `icicle-mode' when mode is exited.
+    (unless (fboundp 'define-minor-mode) (make-local-hook 'pre-command-hook))
+    (add-hook 'pre-command-hook  'icicle-top-level-prep) ; This must not be LOCAL (nil LOCAL arg).
+    (add-hook 'pre-command-hook  'icicle-run-icicle-pre-command-hook nil t)
+    (unless (fboundp 'define-minor-mode) (make-local-hook 'post-command-hook))
+    (add-hook 'post-command-hook 'icicle-run-icicle-post-command-hook nil t)
+    ;; Change the region background here dynamically.  It would be better to
+    ;; just use a buffer-local face, but those don't yet exist.
+    (when (= 1 (recursion-depth))
+      (setq icicle-saved-region-background  (face-background 'region))
+      (when icicle-change-region-background-flag
+        (set-face-background 'region icicle-region-background)))
+    ;; Reset prompt, because some commands (e.g. `find-file') don't use `read-file-name'
+    ;; or `completing-read'.  Reset other stuff too.
+    (setq icicle-candidate-nb                    nil
+          icicle-completion-candidates           nil
+          ;; This is so that cycling works right initially, without first hitting `TAB' or `S-TAB'.
+          icicle-current-completion-mode         (and (< (minibuffer-depth) 2)
+                                                      (case icicle-default-cycling-mode
+                                                        ((nil)      nil)
+                                                        (apropos    'apropos)
+                                                        (prefix     'prefix)
+                                                        (otherwise  nil)))
+          icicle-next-apropos-complete-cycles-p  nil
+          icicle-next-prefix-complete-cycles-p   nil
+          icicle-default-directory               default-directory
+          icicle-incremental-completion-p        icicle-incremental-completion-flag
+          icicle-initial-value                   nil
+          icicle-cmd-reading-input               this-command
+          icicle-last-completion-command         nil
+          icicle-last-completion-candidate       nil
+          icicle-last-input                      nil
+          icicle-input-fail-pos                  nil
+          icicle-saved-proxy-candidates          nil
+          ;; `other-buffer' doesn't work, because it looks for a buffer only from the same frame.
+          icicle-pre-minibuffer-buffer           (cadr (buffer-list)) ; $$$$$$ (other-buffer nil t)
+          )
+    (when (and (icicle-completing-p) (> emacs-major-version 20))
+      (let ((prompt-prefix   (if icicle-candidate-action-fn "+ " ". ")))
+        (put-text-property 0 1 'face
+                           (cond ((and icicle-candidate-action-fn (icicle-require-match-p))
+                                  '(icicle-multi-command-completion icicle-mustmatch-completion))
+                                 (icicle-candidate-action-fn 'icicle-multi-command-completion)
+                                 ((icicle-require-match-p)
+                                  '(icicle-completion icicle-mustmatch-completion))
+                                 (t 'icicle-completion))
+                           prompt-prefix)
+        (if (overlayp icicle-completion-prompt-overlay)
+            (move-overlay icicle-completion-prompt-overlay (point-min) (point-min))
+          (setq icicle-completion-prompt-overlay  (make-overlay (point-min) (point-min))))
+        (overlay-put icicle-completion-prompt-overlay 'before-string prompt-prefix)))
+    (unless icicle-add-proxy-candidates-flag
+      (setq icicle-saved-proxy-candidates  (prog1 icicle-proxy-candidates
+                                             (setq icicle-proxy-candidates
+                                                   icicle-saved-proxy-candidates))))
+    (while icicle-saved-candidate-overlays
+      (delete-overlay (car icicle-saved-candidate-overlays))
+      (setq icicle-saved-candidate-overlays  (cdr icicle-saved-candidate-overlays)))
+    (icicle-update-ignored-extensions-regexp)
+    (when (memq icicle-default-value '(preselect-start preselect-end))
+      (icicle-select-minibuffer-contents))
+    (when (and icicle-show-Completions-initially-flag
+               (not icicle-progressive-completing-p) ; If narrowed, then we have already completed.
+               (icicle-completing-p)    ; Function initializes variable `icicle-completing-p'.
+               (sit-for icicle-incremental-completion-delay)) ; Let user interrupt.
+      (case icicle-default-cycling-mode
+        (apropos    (icicle-apropos-complete))
+        (otherwise  (icicle-prefix-complete)))) ; Prefix completion, by default.
+    (run-hooks 'icicle-minibuffer-setup-hook)))
+
+(defun icicle-define-cycling-keys (map)
+  "Define keys for cycling candidates.
+The modal keys are defined first, then the non-modal keys.
+That means that in case of conflict mode-specific cyling wins.
+For example, if you define both `icicle-modal-cycle-up-keys' and
+`icicle-prefix-cycle-previous-keys' as ([up]), the latter gets the
+binding."
+  (cond (icicle-use-C-for-actions-flag  ; Use `C-' for actions, no `C-' for plain cycling.
+         ;; Modal cycling keys.
+         (dolist (key icicle-modal-cycle-up-keys)
+           (define-key map key 'icicle-previous-candidate-per-mode)) ; `up'
+         (dolist (key icicle-modal-cycle-down-keys)
+           (define-key map key 'icicle-next-candidate-per-mode)) ; `down'
+         (dolist (key icicle-modal-cycle-up-action-keys)
+           (define-key map key 'icicle-previous-candidate-per-mode-action)) ; `C-up'
+         (dolist (key icicle-modal-cycle-down-action-keys)
+           (define-key map key 'icicle-next-candidate-per-mode-action)) ; `C-down'
+         ;; Non-modal cycling keys.  In case of conflict, these will prevail over modal keys.
+         (dolist (key icicle-prefix-cycle-previous-keys)
+           (define-key map key 'icicle-previous-prefix-candidate)) ; `home'
+         (dolist (key icicle-prefix-cycle-next-keys)
+           (define-key map key 'icicle-next-prefix-candidate)) ; `end'
+         (dolist (key icicle-apropos-cycle-previous-keys)
+           (define-key map key 'icicle-previous-apropos-candidate)) ; `prior'
+         (dolist (key icicle-apropos-cycle-next-keys)
+           (define-key map key 'icicle-next-apropos-candidate)) ; `next'
+         (dolist (key icicle-prefix-cycle-previous-action-keys)
+           (define-key map key 'icicle-previous-prefix-candidate-action)) ; `C-home'
+         (dolist (key icicle-prefix-cycle-next-action-keys)
+           (define-key map key 'icicle-next-prefix-candidate-action)) ; `C-end'
+         (dolist (key icicle-apropos-cycle-previous-action-keys)
+           (define-key map key 'icicle-previous-apropos-candidate-action)) ; `C-prior'
+         (dolist (key icicle-apropos-cycle-next-action-keys)
+           (define-key map key 'icicle-next-apropos-candidate-action))) ; `C-next'
+
+        (t                              ; Use `C-' for plain cycling, NO `C-' for action.
+         ;; Modal cycling keys.  At least some of these will overwrite non-modal keys.
+         (dolist (key icicle-modal-cycle-up-keys)
+           (define-key map key 'icicle-previous-candidate-per-mode-action)) ; `up'
+         (dolist (key icicle-modal-cycle-down-keys)
+           (define-key map key 'icicle-next-candidate-per-mode-action)) ; `down'
+         (dolist (key icicle-modal-cycle-up-action-keys)
+           (define-key map key 'icicle-previous-candidate-per-mode)) ; `C-up'
+         (dolist (key icicle-modal-cycle-down-action-keys)
+           (define-key map key 'icicle-next-candidate-per-mode)) ; `C-down'
+         ;; Non-modal cycling keys.  In case of conflict, these will prevail over modal keys.
+         (dolist (key icicle-prefix-cycle-previous-keys)
+           (define-key map key 'icicle-previous-prefix-candidate-action)) ; `home'
+         (dolist (key icicle-prefix-cycle-next-keys)
+           (define-key map key 'icicle-next-prefix-candidate-action)) ; `end'
+         (dolist (key icicle-apropos-cycle-previous-keys)
+           (define-key map key 'icicle-previous-apropos-candidate-action)) ; `prior'
+         (dolist (key icicle-apropos-cycle-next-keys)
+           (define-key map key 'icicle-next-apropos-candidate-action)) ; `next'
+         (dolist (key icicle-prefix-cycle-previous-action-keys)
+           (define-key map key 'icicle-previous-prefix-candidate)) ; `C-home'
+         (dolist (key icicle-prefix-cycle-next-action-keys)
+           (define-key map key 'icicle-next-prefix-candidate)) ; `C-end'
+         (dolist (key icicle-apropos-cycle-previous-action-keys)
+           (define-key map key 'icicle-previous-apropos-candidate)) ; `C-prior'
+         (dolist (key icicle-apropos-cycle-next-action-keys)
+           (define-key map key 'icicle-next-apropos-candidate))))
+
+  ;; Help and alternative-action keys are NOT controlled by `icicle-use-C-for-actions-flag'.
+  ;;
+  ;; Define modal cycling help and alternative action keys.
+  (dolist (key icicle-modal-cycle-up-help-keys)
+    (define-key map key 'icicle-previous-candidate-per-mode-help)) ; `C-M-up'
+  (dolist (key icicle-modal-cycle-down-help-keys)
+    (define-key map key 'icicle-next-candidate-per-mode-help)) ; `C-M-down'
+  (dolist (key icicle-modal-cycle-up-alt-action-keys)
+    (define-key map key 'icicle-previous-candidate-per-mode-alt-action)) ; `C-S-up'
+  (dolist (key icicle-modal-cycle-down-alt-action-keys)
+    (define-key map key 'icicle-next-candidate-per-mode-alt-action)) ; `C-S-down'
+  ;; Define non-modal cycling help and alternative action keys.
+  (dolist (key icicle-prefix-cycle-previous-help-keys)
+    (define-key map key 'icicle-help-on-previous-prefix-candidate)) ; `C-M-home'
+  (dolist (key icicle-prefix-cycle-next-help-keys)
+    (define-key map key 'icicle-help-on-next-prefix-candidate)) ; `C-M-end'
+  (dolist (key icicle-apropos-cycle-previous-help-keys)
+    (define-key map key 'icicle-help-on-previous-apropos-candidate)) ; `C-M-prior'
+  (dolist (key icicle-apropos-cycle-next-help-keys)
+    (define-key map key 'icicle-help-on-next-apropos-candidate)) ; `C-M-next'
+  (dolist (key icicle-prefix-cycle-previous-alt-action-keys)
+    (define-key map key 'icicle-previous-prefix-candidate-alt-action)) ; `C-S-home'
+  (dolist (key icicle-prefix-cycle-next-alt-action-keys)
+    (define-key map key 'icicle-next-prefix-candidate-alt-action)) ; `C-S-end'
+  (dolist (key icicle-apropos-cycle-previous-alt-action-keys)
+    (define-key map key 'icicle-previous-apropos-candidate-alt-action)) ; `C-S-prior'
+  (dolist (key icicle-apropos-cycle-next-alt-action-keys)
+    (define-key map key 'icicle-next-apropos-candidate-alt-action))) ; `C-S-next'
+
+(defun icicle-select-minibuffer-contents ()
+  "Select minibuffer contents and leave point at its beginning."
+  (let ((min  (icicle-minibuffer-prompt-end)))
+    (set-mark (if (eq 'preselect-start icicle-default-value) (point-max) min))
+    (goto-char (if (eq 'preselect-start icicle-default-value) min (point-max)))))
+
+;; $$$ (defadvice next-history-element (after icicle-select-minibuffer-contents activate)
+;;   "Select minibuffer contents and leave point at its beginning."
+;;   (when (and icicle-mode (memq icicle-default-value '(preselect-start preselect-end)))
+;;     (icicle-select-minibuffer-contents)
+;;     (setq deactivate-mark  nil)))
+
+(defun icicle-cancel-Help-redirection ()
+  "Cancel redirection of focus from *Help* buffer to minibuffer.
+Focus was redirected during `icicle-help-on-candidate'."
+  (let* ((help-window  (get-buffer-window "*Help*" 0))
+         (help-frame   (and help-window (window-frame help-window))))
+    (when help-frame (redirect-frame-focus help-frame))))
+
+(defun icicle-run-icicle-pre-command-hook ()
+  "Run `icicle-pre-command-hook' functions.
+Used in `pre-command-hook'."
+  (run-hooks 'icicle-pre-command-hook))
+
+(defun icicle-run-icicle-post-command-hook ()
+  "Run `icicle-post-command-hook' functions.
+Used in `post-command-hook'."
+  (run-hooks 'icicle-post-command-hook))
+
+(defun icicle-set-calling-cmd ()
+  "Remember last command that called for completion.
+Used in `completion-setup-hook'."
+  (setq icicle-cmd-calling-for-completion  this-command))
+
+(defun icicle-update-ignored-extensions-regexp ()
+  "Update ignored extensions if `completion-ignored-extensions' changed."
+  (when (and (icicle-file-name-input-p) ; In `icicles-fn.el'.
+             (not (equal icicle-ignored-extensions completion-ignored-extensions)))
+    (setq icicle-ignored-extensions-regexp ; Make regexp for ignored file extensions.
+          (concat "\\(" (mapconcat #'regexp-quote completion-ignored-extensions "\\|") "\\)\\'")
+
+          ;; Flag to prevent updating `icicle-ignored-extensions-regexp' unless
+          ;; `completion-ignored-extensions' changes.
+          icicle-ignored-extensions  completion-ignored-extensions)))
+
+;; We change the region background here dynamically.
+;; It would be better to just use a buffer-local face, but those don't yet exist.
+(defun icicle-restore-region-face ()
+  "Restore region face.  It was changed during minibuffer activity
+if `icicle-change-region-background-flag' is non-nil."
+  (when (and icicle-change-region-background-flag (= 1 (recursion-depth)))
+    (set-face-background 'region icicle-saved-region-background)))
+
+(defun icicle-activate-mark ()
+  "Prevent region from being deactivated.  Use in `icicle-post-command-hook'."
+  (when (and (window-minibuffer-p (selected-window))
+             icicle-completing-p
+             (not executing-kbd-macro))
+    (setq deactivate-mark  nil)))
+
+(defun icicle-redefine-standard-functions ()
+  "Alias the functions in `icicle-functions-to-redefine' to Icicles versions."
+  (when (fboundp 'icicle-completing-read)
+    (dolist (fn  icicle-functions-to-redefine)
+      (when (fboundp (intern (concat "old-" (symbol-name fn))))
+        (defalias fn (intern (concat "icicle-" (symbol-name fn))))))))
+
+(defun icicle-restore-standard-functions ()
+  "Restore original versions of functions in `icicle-functions-to-redefine'."
+  (when (fboundp 'old-completing-read)
+    (let (old-fn)
+      (dolist (fn  icicle-functions-to-redefine)
+        (when (fboundp (setq old-fn  (intern (concat "old-" (symbol-name fn)))))
+          (defalias fn old-fn))))))
+
+;;; In Emacs versions before 22:
+;;; Save original `read-file-name'.  We redefine it as `icicle-read-file-name' (which calls it).
+;;; Then we restore it when you quit Icicle mode.  (In Emacs 22+, no redefinition is needed.)
+(unless (or (boundp 'read-file-name-function) (fboundp 'orig-read-file-name))
+  (defalias 'orig-read-file-name (symbol-function 'read-file-name)))
+
+(defun icicle-redefine-std-completion-fns ()
+  "Replace some standard functions with versions for Icicle mode."
+  (when (fboundp 'icicle-completing-read)
+    (defalias 'choose-completion            'icicle-choose-completion)
+    (defalias 'choose-completion-string     'icicle-choose-completion-string)
+    (defalias 'completing-read              'icicle-completing-read)
+    (defalias 'completion-setup-function    'icicle-completion-setup-function)
+    (unless (> emacs-major-version 22)
+      (defalias 'dired-smart-shell-command  'icicle-dired-smart-shell-command))
+    (defalias 'display-completion-list      'icicle-display-completion-list)
+    (defalias 'exit-minibuffer              'icicle-exit-minibuffer)
+    (when (fboundp 'face-valid-attribute-values)
+      (defalias 'face-valid-attribute-values 'icicle-face-valid-attribute-values))
+    (defalias 'minibuffer-complete-and-exit 'icicle-minibuffer-complete-and-exit)
+    (defalias 'mouse-choose-completion      'icicle-mouse-choose-completion)
+    (defalias 'next-history-element         'icicle-next-history-element)
+    (defalias 'read-face-name               'icicle-read-face-name)
+    (if (boundp 'read-file-name-function) ; Emacs 22+
+        (setq icicle-old-read-file-name-fn  (prog1 (and (not (eq read-file-name-function
+                                                                 'icicle-read-file-name))
+                                                        read-file-name-function)
+                                              (setq read-file-name-function
+                                                    'icicle-read-file-name)))
+      (defalias 'read-file-name             'icicle-read-file-name)) ; Emacs 20, 21
+    (when (fboundp 'icicle-read-number)
+      (defalias 'read-number                'icicle-read-number))
+    (unless (> emacs-major-version 22)
+      (defalias 'shell-command              'icicle-shell-command))
+    (unless (> emacs-major-version 22)
+      (defalias 'shell-command-on-region    'icicle-shell-command-on-region))
+    (defalias 'switch-to-completions        'icicle-switch-to-completions)
+    (when (fboundp 'icicle-completing-read-multiple)
+      (defalias 'completing-read-multiple   'icicle-completing-read-multiple)
+      (setq crm-local-completion-map  icicle-crm-local-completion-map
+            crm-local-must-match-map  icicle-crm-local-must-match-map))
+    (when (> emacs-major-version 22)
+      (defalias 'sit-for                    'icicle-sit-for))
+    ))
+
+(defun icicle-restore-std-completion-fns ()
+  "Restore some standard functions that were replaced in Icicle mode."
+  (when (fboundp 'old-completing-read)
+    (defalias 'choose-completion            'old-choose-completion)
+    (defalias 'choose-completion-string     'old-choose-completion-string)
+    (defalias 'completing-read              'old-completing-read)
+    (defalias 'completion-setup-function    'old-completion-setup-function)
+    (when (fboundp 'old-dired-smart-shell-command) ; Emacs 23
+      (defalias 'dired-smart-shell-command  'old-dired-smart-shell-command))
+    (defalias 'display-completion-list      'old-display-completion-list)
+    (defalias 'exit-minibuffer              'old-exit-minibuffer)
+    (when (fboundp 'old-face-valid-attribute-values)
+      (defalias 'face-valid-attribute-values 'old-face-valid-attribute-values))
+    (defalias 'minibuffer-complete-and-exit 'old-minibuffer-complete-and-exit)
+    (defalias 'mouse-choose-completion      'old-mouse-choose-completion)
+    (defalias 'next-history-element         'old-next-history-element)
+    (defalias 'read-face-name               'old-read-face-name)
+    (if (boundp 'read-file-name-function) ; Emacs 22+
+        (setq read-file-name-function  (and (not (eq icicle-old-read-file-name-fn
+                                                     'icicle-read-file-name))
+                                            icicle-old-read-file-name-fn))
+      (defalias 'read-file-name             'orig-read-file-name)) ; Emacs 20, 21
+    (when (fboundp 'old-read-number)
+      (defalias 'read-number                'old-read-number))
+    (when (fboundp 'old-shell-command) ; Emacs 23
+      (defalias 'shell-command              'old-shell-command))
+    (when (fboundp 'old-shell-command-on-region) ; Emacs 23
+      (defalias 'shell-command-on-region    'old-shell-command-on-region))
+    (defalias 'switch-to-completions        'old-switch-to-completions)
+    (when (fboundp 'old-completing-read-multiple)
+      (defalias 'completing-read-multiple   'old-completing-read-multiple)
+      (setq crm-local-completion-map  old-crm-local-completion-map
+            crm-local-must-match-map  old-crm-local-must-match-map))
+    (when (> emacs-major-version 22)
+      (defalias 'sit-for                    'old-sit-for))
+    ))
+
+;; Free vars here: `icicle-saved-kmacro-ring-max' is bound in `icicles-var.el'.
+(defun icicle-redefine-standard-options ()
+  "Replace certain standard Emacs options with Icicles versions."
+  (when (boundp 'icicle-search-ring-max)
+    (setq icicle-saved-search-ring-max         search-ring-max ; Save it.
+          search-ring-max                      icicle-search-ring-max
+          icicle-saved-regexp-search-ring-max  regexp-search-ring-max ; Save it.
+          regexp-search-ring-max               icicle-regexp-search-ring-max))
+  (when (boundp 'icicle-kmacro-ring-max)
+    (setq icicle-saved-kmacro-ring-max  kmacro-ring-max ; Save it.
+          kmacro-ring-max               icicle-kmacro-ring-max)))
+
+(defun icicle-restore-standard-options ()
+  "Restore standard Emacs options replaced in Icicle mode."
+  (when (boundp 'icicle-saved-search-ring-max)
+    (setq search-ring-max         icicle-saved-search-ring-max
+          regexp-search-ring-max  icicle-saved-regexp-search-ring-max)))
+
+;; This is used only in Emacs 22+, but we define it always anyway.
+(defun icicle-undo-std-completion-faces ()
+  "Get rid of standard completion-root highlighting in `*Completions*'."
+  ;; Do this because the standard Emacs 22 highlighting can interfere with
+  ;; apropos-completion highlighting.
+  (when (fboundp 'face-spec-reset-face)
+    (when (facep 'completions-common-part)
+      (face-spec-reset-face 'completions-common-part)
+      (set-face-attribute 'completions-common-part nil :inherit nil))
+    (when (facep 'completions-first-difference)
+      (face-spec-reset-face 'completions-first-difference)
+      (set-face-attribute 'completions-first-difference nil :inherit nil))))
+
+
+;;; Save original functions, so they can be restored when leave Icicle mode.
+;;; Toggle Icicle mode after loading the library (and `icicles-mode.el'),
+;;; to pick up the original definition.
+;;;
+;;; Note: The `boundp' test for `icicle-mode' is just in case the form gets evaluated while
+;;; loading `icicles-mode.el' (e.g. the library gets loaded while loading `icicles-mode.el').
+
+;;; `comint.el' - `comint-dynamic-complete', `comint-replace-by-expanded-filename'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'comint-dynamic-complete)
+                          (not (fboundp 'old-comint-dynamic-complete)))
+                 (defalias 'old-comint-dynamic-complete (symbol-function 'comint-dynamic-complete)))
+               (when (and (fboundp 'comint-dynamic-complete-filename)
+                          (not (fboundp 'old-comint-dynamic-complete-filename)))
+                 (defalias 'old-comint-dynamic-complete-filename
+                     (symbol-function 'comint-dynamic-complete-filename)))
+               (when (and (fboundp 'comint-replace-by-expanded-filename)
+                          (not (fboundp 'old-comint-replace-by-expanded-filename)))
+                 (defalias 'old-comint-replace-by-expanded-filename
+                     (symbol-function 'comint-replace-by-expanded-filename)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'comint) (eval-after-load "icicles-mode" form) (eval-after-load "comint" form)))
+
+;;; `ess-site.el' - `ess-complete-object-name'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'ess-complete-object-name)
+                          (not (fboundp 'old-ess-complete-object-name)))
+                 (defalias 'old-ess-complete-object-name (symbol-function
+                                                          'ess-complete-object-name)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'ess-site) (eval-after-load "icicles-mode" form) (eval-after-load "ess-site" form)))
+
+;;; `gud.el' - `gud-gdb-complete-command'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'gud-gdb-complete-command)
+                          (not (fboundp 'old-gud-gdb-complete-command)))
+                 (defalias 'old-gud-gdb-complete-command (symbol-function
+                                                          'gud-gdb-complete-command)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'gud) (eval-after-load "icicles-mode" form) (eval-after-load "gud" form)))
+
+;;; `info.el' - `Info-goto-node', `Info-index', `Info-menu'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (featurep 'info) (not (fboundp 'old-Info-goto-node)))
+                 (defalias 'old-Info-goto-node (symbol-function 'Info-goto-node))
+                 (defalias 'old-Info-index     (symbol-function 'Info-index))
+                 (defalias 'old-Info-menu      (symbol-function 'Info-menu)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'info) (eval-after-load "icicles-mode" form) (eval-after-load "info" form)))
+
+;;; `bbdb-com.el' -  `bbdb-complete-name'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'bbdb-complete-name) (not (fboundp 'old-bbdb-complete-name)))
+                 (defalias 'old-bbdb-complete-name (symbol-function 'bbdb-complete-name)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'bbdb-com) (eval-after-load "icicles-mode" form) (eval-after-load "bbdb-com" form)))
+
+;;; `dired-aux.el' - `dired-read-shell-command'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'dired-read-shell-command)
+                          (not (fboundp 'old-dired-read-shell-command)))
+                 (defalias 'old-dired-read-shell-command (symbol-function
+                                                          'dired-read-shell-command)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'dired-aux)
+      (eval-after-load "icicles-mode" form)
+    (eval-after-load "dired-aux" form)))
+
+;;; `dired-x.el' - `dired-read-shell-command', `dired-smart-shell-command'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'dired-read-shell-command)
+                          (not (fboundp 'old-dired-read-shell-command)))
+                 (defalias 'old-dired-read-shell-command (symbol-function
+                                                          'dired-read-shell-command)))
+               (unless (fboundp 'read-shell-command) ; `dired-smart-shell-command' in Emacs < 23.
+                 (when (and (fboundp 'dired-smart-shell-command)
+                            (not (fboundp 'old-dired-smart-shell-command)))
+                   (defalias 'old-dired-smart-shell-command (symbol-function
+                                                             'dired-smart-shell-command))))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'dired-x) (eval-after-load "icicles-mode" form) (eval-after-load "dired-x" form)))
+
+;;; `simple.el' - `read-shell-command' - Emacs 23+.
+(when (> emacs-major-version 22)
+  ;; `simple.el' is preloaded for Emacs 23+, so just do it now.
+  (let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+    (when icyp (icicle-mode -1))
+    (when (and (fboundp 'read-shell-command) (not (fboundp 'old-read-shell-command)))
+      (defalias 'old-read-shell-command (symbol-function 'read-shell-command)))
+    (when icyp (icicle-mode 1))))
+
+;;; `recentf.el' - `recentf-make-menu-items'.
+(let ((form  '(let ((icyp  (and (boundp 'icicle-mode) icicle-mode)))
+               (when icyp (icicle-mode -1))
+               (when (and (fboundp 'recentf-make-menu-items)
+                          (not (fboundp 'old-recentf-make-menu-items)))
+                 (defalias 'old-recentf-make-menu-items (symbol-function 'recentf-make-menu-items)))
+               (when icyp (icicle-mode 1)))))
+  (if (featurep 'recentf) (eval-after-load "icicles-mode" form) (eval-after-load "recentf" form)))
+
+      
+;; Do this last.
+;;
+;; When these libraries are first loaded, toggle Icicle mode to pick up the definitions
+(dolist (library '("bookmark+" "buff-menu" "comint" "dired" "ess-site" "gud" "ibuffer"
+                   "idlw-shell"         ; (untested - I don't have an `idl' program)
+                   "ielm" "info" "net-utils" "rlogin" "shell" "sh-script" "tcl"))
+  (unless (if (fboundp 'load-history-regexp) ; Emacs 22+
+              (load-history-filename-element (load-history-regexp library))
+            (assoc library load-history))
+    (eval-after-load library '(icicle-toggle-icicle-mode-twice))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-mode)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-mode.el ends here
diff --git a/auto-install/icicles-opt.el b/auto-install/icicles-opt.el
new file mode 100644
index 0000000..b94a006
--- /dev/null
+++ b/auto-install/icicles-opt.el
@@ -0,0 +1,3853 @@
+;;; icicles-opt.el --- User options (variables) for Icicles
+;;
+;; Filename: icicles-opt.el
+;; Description: User options (variables) for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:22:14 2006
+;; Version: 22.0
+;; Last-Updated: Mon Sep  5 14:33:18 2011 (-0700)
+;;           By: dradams
+;;     Update #: 4465
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-opt.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `backquote', `bytecomp', `cl', `el-swank-fuzzy', `ffap',
+;;   `ffap-', `fuzzy', `fuzzy-match', `hexrgb', `icicles-face',
+;;   `icicles-mac', `kmacro', `levenshtein', `regexp-opt',
+;;   `thingatpt', `thingatpt+', `wid-edit', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  user options (variables).  For Icicles documentation, see
+;;  `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Widgets defined here:
+;;
+;;    `icicle-key-definition'.
+;;
+;;  Constants defined here:
+;;
+;;    `icicle-anychar-regexp', `icicle-Completions-misc-submenu',
+;;    `icicle-Completions-save/retrieve-submenu',
+;;    `icicle-Completions-sets-submenu',
+;;    `icicle-Completions-sorting-submenu',
+;;    `icicle-Completions-this-candidate-submenu',
+;;    `icicle-Completions-toggle-submenu'.
+;;
+;;  User options defined here (in Custom group `Icicles'):
+;;
+;;    `icicle-act-before-cycle-flag',
+;;    `icicle-add-proxy-candidates-flag',
+;;    `icicle-alternative-actions-alist',
+;;    `icicle-alternative-sort-comparer',
+;;    `icicle-apropos-complete-keys',
+;;    `icicle-apropos-complete-no-display-keys',
+;;    `icicle-apropos-cycle-next-keys',
+;;    `icicle-apropos-cycle-next-action-keys',
+;;    `icicle-apropos-cycle-next-alt-action-keys',
+;;    `icicle-apropos-cycle-next-help-keys',
+;;    `icicle-apropos-cycle-previous-keys',
+;;    `icicle-apropos-cycle-previous-action-keys',
+;;    `icicle-apropos-cycle-previous-alt-action-keys',
+;;    `icicle-apropos-cycle-previous-help-keys',
+;;    `icicle-anything-transform-candidates-flag',
+;;    `icicle-bookmark-name-length-max',
+;;    `icicle-bookmark-refresh-cache-flag', `icicle-buffer-configs',
+;;    `icicle-buffer-extras',
+;;    `icicle-buffer-ignore-space-prefix-flag',
+;;    `icicle-buffer-match-regexp', `icicle-buffer-no-match-regexp',
+;;    `icicle-buffer-predicate', `icicle-buffer-require-match-flag'
+;;    `icicle-buffer-sort', `icicle-buffers-ido-like-flag',
+;;    `icicle-candidate-width-factor',
+;;    `icicle-change-region-background-flag',
+;;    `icicle-change-sort-order-completion-flag',
+;;    `icicle-C-l-uses-completion-flag', `icicle-color-themes',
+;;    `icicle-comint-dynamic-complete-replacements',
+;;    `icicle-command-abbrev-alist',
+;;    `icicle-command-abbrev-match-all-parts-flag',
+;;    `icicle-command-abbrev-priority-flag',
+;;    `icicle-complete-key-anyway-flag',
+;;    `icicle-complete-keys-self-insert-ranges',
+;;    `icicle-completing-read+insert-keys',
+;;    `icicle-completion-history-max-length',
+;;    `icicle-Completions-display-min-input-chars',
+;;    `icicle-completions-format',
+;;    `icicle-Completions-mouse-3-menu-entries',
+;;    `icicle-Completions-text-scale-decrease',
+;;    `icicle-Completions-window-max-height',
+;;    `icicle-customize-save-flag',
+;;    `icicle-customize-save-variable-function',
+;;    `icicle-cycle-into-subdirs-flag', `icicle-default-cycling-mode',
+;;    `icicle-default-thing-insertion', `icicle-default-value',
+;;    `icicle-define-alias-commands-flag',
+;;    `icicle-deletion-action-flag', `icicle-dot-show-regexp-flag',
+;;    `icicle-dot-string', `icicle-expand-input-to-common-match-flag',
+;;    `icicle-file-extras', `icicle-file-match-regexp',
+;;    `icicle-file-no-match-regexp', `icicle-file-predicate',
+;;    `icicle-file-require-match-flag', `icicle-file-sort',
+;;    `icicle-files-ido-like-flag',
+;;    `icicle-filesets-as-saved-completion-sets-flag',
+;;    `icicle-functions-to-redefine', `icicle-guess-commands-in-path',
+;;    `icicle-help-in-mode-line-delay',
+;;    `icicle-hide-common-match-in-Completions-flag',
+;;    `icicle-hide-non-matching-lines-flag',
+;;    `icicle-highlight-historical-candidates-flag',
+;;    `icicle-highlight-input-completion-failure',
+;;    `icicle-highlight-input-completion-failure-delay',
+;;    `icicle-highlight-input-completion-failure-threshold',
+;;    `icicle-highlight-input-initial-whitespace-flag',
+;;    `icicle-highlight-lighter-flag',
+;;    `icicle-highlight-saved-candidates-flag',
+;;    `icicle-ignore-comments-flag', `icicle-ignored-directories',
+;;    `icicle-ignore-space-prefix-flag',
+;;    `icicle-image-files-in-Completions',
+;;    `icicle-incremental-completion-delay',
+;;    `icicle-incremental-completion-flag',
+;;    `icicle-incremental-completion-threshold',
+;;    `icicle-inhibit-advice-functions', `icicle-inhibit-ding-flag',
+;;    `icicle-input-string', `icicle-inter-candidates-min-spaces',
+;;    `icicle-isearch-complete-keys', `icicle-key-complete-keys',
+;;    `icicle-key-descriptions-use-<>-flag',
+;;    `icicle-key-descriptions-use-angle-brackets-flag',
+;;    `icicle-keymaps-for-key-completion', `icicle-kmacro-ring-max',
+;;    `icicle-levenshtein-distance', `icicle-list-join-string',
+;;    `icicle-list-nth-parts-join-string',
+;;    `icicle-mark-position-in-candidate', `icicle-max-candidates',
+;;    `icicle-menu-items-to-history-flag',
+;;    `icicle-minibuffer-setup-hook', `icicle-modal-cycle-down-keys',
+;;    `icicle-modal-cycle-down-action-keys',
+;;    `icicle-modal-cycle-down-alt-action-keys',
+;;    `icicle-modal-cycle-down-help-keys',
+;;    `icicle-modal-cycle-up-keys',
+;;    `icicle-modal-cycle-up-action-keys',
+;;    `icicle-modal-cycle-up-alt-action-keys',
+;;    `icicle-modal-cycle-up-help-keys',
+;;    `icicle-move-Completions-frame', `icicle-no-match-hook',
+;;    `icicle-option-type-prefix-arg-list',
+;;    `icicle-point-position-in-candidate',
+;;    `icicle-populate-interactive-history-flag',
+;;    `icicle-pp-eval-expression-print-length',
+;;    `icicle-pp-eval-expression-print-level',
+;;    `icicle-prefix-complete-keys',
+;;    `icicle-prefix-complete-no-display-keys',
+;;    `icicle-prefix-cycle-next-keys',
+;;    `icicle-prefix-cycle-next-action-keys',
+;;    `icicle-prefix-cycle-next-alt-action-keys',
+;;    `icicle-prefix-cycle-next-help-keys',
+;;    `icicle-prefix-cycle-previous-keys',
+;;    `icicle-prefix-cycle-previous-action-keys',
+;;    `icicle-prefix-cycle-previous-alt-action-keys',
+;;    `icicle-prefix-cycle-previous-help-keys',
+;;    `icicle-previous-candidate-keys',
+;;    `icicle-quote-shell-file-name-flag',
+;;    `icicle-read+insert-file-name-keys', `icicle-regexp-quote-flag',
+;;    `icicle-regexp-search-ring-max', `icicle-region-background',
+;;    `icicle-require-match-flag', `icicle-saved-completion-sets',
+;;    `icicle-search-cleanup-flag', `icicle-search-from-isearch-keys',
+;;    `icicle-search-highlight-all-current-flag',
+;;    `icicle-search-highlight-context-levels-flag',
+;;    `icicle-search-highlight-threshold', `icicle-search-hook',
+;;    `icicle-search-replace-common-match-flag',
+;;    `icicle-search-replace-literally-flag',
+;;    `icicle-search-replace-whole-candidate-flag',
+;;    `icicle-search-ring-max', `icicle-search-whole-word-flag',
+;;    `icicle-shell-command-candidates-cache',
+;;    `icicle-show-Completions-help-flag',
+;;    `icicle-show-Completions-initially-flag',
+;;    `icicle-show-multi-completion-flag', `icicle-sort-comparer',
+;;    `icicle-sort-orders-alist', `icicle-special-candidate-regexp',
+;;    `icicle-S-TAB-completion-methods-alist',
+;;    `icicle-S-TAB-completion-methods-per-command',
+;;    `icicle-swank-prefix-length', `icicle-swank-timeout',
+;;    `icicle-TAB-completion-methods',
+;;    `icicle-TAB-completion-methods-per-command',
+;;    `icicle-TAB-shows-candidates-flag', `icicle-recenter',
+;;    `icicle-test-for-remote-files-flag',
+;;    `icicle-thing-at-point-functions',
+;;    `icicle-top-level-key-bindings',
+;;    `icicle-top-level-when-sole-completion-delay',
+;;    `icicle-top-level-when-sole-completion-flag',
+;;    `icicle-touche-pas-aux-menus-flag', `icicle-transform-function',
+;;    `icicle-type-actions-alist',
+;;    `icicle-unpropertize-completion-result-flag',
+;;    `icicle-update-input-hook', `icicle-use-~-for-home-dir-flag',
+;;    `icicle-use-C-for-actions-flag',
+;;    `icicle-use-anything-candidates-flag',
+;;    `icicle-use-candidates-only-once-flag',
+;;    `icicle-word-completion-keys',
+;;    `icicle-WYSIWYG-Completions-flag', `icicle-yank-function'.
+;;
+;;  Functions defined here:
+;;
+;;    `icicle-bind-top-level-commands',
+;;    `icicle-buffer-sort-*...*-last',
+;;    `icicle-compute-shell-command-candidates', `icicle-remap'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+;;
+;;  Note: Occasionally I have renamed or removed an Icicles option.
+;;  If you have customized such an option, then your customization
+;;  will no longer have any effect.  With the exception of options
+;;  `icicle-mode' and `icicle-mode-hook', library `icicles-opt.el'
+;;  always contains the complete set of Icicles options.  If your
+;;  custom file or init file contains an Icicles option that is not
+;;  listed above, then you can remove it because it is obsolete.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Constants used to define user options")
+;;  (@> "User options, organized alphabetically, except for dependencies")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; Emacs 20 does not DTRT wrt `:type' and `:set' sexps at compile time,
+;; so there seems no way around this, short of coding without push and dolist.
+;; For Emacs < 21: dolist, push
+(eval-and-compile (when (< emacs-major-version 21) (require 'cl)))
+
+(require 'thingatpt)        ;; symbol-at-point, thing-at-point, thing-at-point-url-at-point
+(require 'thingatpt+ nil t) ;; (no error if not found): list-nearest-point-as-string,
+                            ;; region-or-word-nearest-point, symbol-name-nearest-point
+
+(require 'hexrgb nil t) ;; (no error if not found): hexrgb-approx-equal, hexrgb-saturation 
+(when (featurep 'hexrgb) (require 'icicles-face))
+  ;; icicle-increment-color-hue, icicle-increment-color-value
+
+;; Quiet the byte-compiler.
+(defvar shell-completion-execonly)      ; In `shell.el'.
+
+(defvar icicle-mode-map)
+(defvar icicle-dot-string-internal)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Constants used to define user options")
+
+;;; Constants used to define user options --
+
+;;;###autoload
+(defconst icicle-Completions-misc-submenu
+    '(misc-menu
+      menu-item
+      "Miscellaneous"
+      (keymap
+       (complete-for-past-completion menu-item "Complete for Past Completion Input"
+        icicle-retrieve-previous-input
+        :visible (or (and icicle-C-l-uses-completion-flag (not current-prefix-arg))
+                  (and (not icicle-C-l-uses-completion-flag) current-prefix-arg)))
+       (previous-completion-input menu-item "Previous Completion Input"
+        icicle-retrieve-previous-input
+        :visible (not (or (and icicle-C-l-uses-completion-flag (not current-prefix-arg))
+                       (and (not icicle-C-l-uses-completion-flag) current-prefix-arg))))
+       (next-completion-input menu-item "Next Completion Input"
+        icicle-retrieve-next-input)
+       (one-off-eval menu-item "One-Off Eval..."
+        icicle-pp-eval-expression-in-minibuffer)
+       (sep-misc "--")
+       (icicles-help menu-item "Icicles Help" icicle-minibuffer-help)))
+  "Submenu for miscellaneous operations on completions.")
+
+;;;###autoload
+(defconst icicle-Completions-save/retrieve-submenu
+    '(save-retrieve-menu
+      menu-item
+      "Save/Retrieve"
+      (keymap
+       (save-all menu-item "Save All" icicle-candidate-set-save)
+       (save-all-var menu-item "             to Variable..."
+        icicle-candidate-set-save-to-variable)
+       (save-all-cache menu-item "             to Cache File..."
+        icicle-candidate-set-save-persistently)
+       (add-all-to-saved menu-item "Add All to Saved" icicle-candidate-set-save-more)
+       (save-selected menu-item "Save Selected (Region) Candidates"
+        icicle-candidate-set-save-selected
+        :enable (and mark-active (> (region-end) (region-beginning))))
+       (clear-saved menu-item "Clear Saved Candidates"
+        icicle-candidate-set-save-selected
+        :enable (and (boundp 'icicle-saved-completion-candidates)
+                 icicle-saved-completion-candidates))
+       (add-selected-to-saved menu-item "Add Selected (Region) Candidates"
+        icicle-candidate-set-save-more-selected
+        :enable (and mark-active (> (region-end) (region-beginning))))
+       (sep-save/retrieve-2 "--")
+       (retrieve-saved menu-item "Retrieve Saved" icicle-candidate-set-retrieve
+        :enable (and (boundp 'icicle-saved-completion-candidates)
+                 icicle-saved-completion-candidates))
+       (retrieve-more-saved menu-item "Retrieve More Saved"
+        icicle-candidate-set-retrieve-more
+        :enable (and (boundp 'icicle-saved-completion-candidates)
+                 icicle-saved-completion-candidates))))
+  "Submenu for saving and retrieving completion candidates.")
+
+;;;###autoload
+(defconst icicle-Completions-sets-submenu
+    '(sets-menu
+      menu-item
+      "Sets"
+      (keymap
+       (complement menu-item "Complement" icicle-candidate-set-complement)
+       (widen menu-item "Or Match Alternative..." icicle-widen-candidates)
+       (narrow menu-item "Match Also Regexp..." icicle-narrow-candidates)
+       (save-pred-read-var menu-item "Save Predicate to Variable...  (`C-u')"
+        icicle-save-predicate-to-variable
+        :visible current-prefix-arg)
+       (save-pred-std-var menu-item "Save Predicate to `icicle-input-string'"
+        icicle-save-predicate-to-variable
+        :visible (not current-prefix-arg))
+       (intersect menu-item "Intersect Saved" icicle-candidate-set-intersection
+        :enable icicle-saved-completion-candidates)
+       (difference menu-item "Subtract Saved" icicle-candidate-set-difference
+        :enable icicle-saved-completion-candidates)
+       (union menu-item "Add (Union) Saved" icicle-candidate-set-union
+        :enable icicle-saved-completion-candidates)
+       (keep-past-chrono menu-item "Only Previously Entered, By Time  (`C-u')"
+        icicle-keep-only-past-inputs
+        :visible current-prefix-arg)
+       (keep-past-alpha menu-item "Only Previously Entered"
+        icicle-keep-only-past-inputs
+        :visible (not current-prefix-arg))))
+  "Submenu for set operations on completion candidates.")
+
+;;;###autoload
+(defconst icicle-Completions-sorting-submenu
+    '(sorting-menu
+      menu-item
+      "Sorting"
+      (keymap
+       (change-sort-order menu-item "Change Sort Order" icicle-change-sort-order
+        :visible (or (and icicle-change-sort-order-completion-flag (not current-prefix-arg))
+                  (and (not icicle-change-sort-order-completion-flag) current-prefix-arg)))
+       (next-sort-order menu-item "Next Sort Order" icicle-change-sort-order
+        :visible (not (or (and icicle-change-sort-order-completion-flag (not current-prefix-arg))
+                       (and (not icicle-change-sort-order-completion-flag) current-prefix-arg))))
+       (change-alt-sort menu-item "Change Alternative Sort Order  (`M-,')"
+        icicle-change-alternative-sort-order
+        :visible (or (and icicle-change-sort-order-completion-flag (not current-prefix-arg))
+                  (and (not icicle-change-sort-order-completion-flag) current-prefix-arg)))
+       (next-alt-sort menu-item "Next Alternative Sort Order  (`M-,')"
+        icicle-change-alternative-sort-order
+        :visible (not (or (and icicle-change-sort-order-completion-flag (not current-prefix-arg))
+                       (and (not icicle-change-sort-order-completion-flag) current-prefix-arg))))
+       (swap-sort menu-item "Swap Alternative/Normal Sort"
+        icicle-toggle-alternative-sorting)))
+  "Submenu for sorting completion candidates.")
+
+;;;###autoload
+(defconst icicle-Completions-this-candidate-submenu
+    '(this-candidate-menu
+      menu-item
+      "This Candidate"
+      (keymap
+       (help-on-cand menu-item "Help About" icicle-help-on-candidate)
+       (sep-this-1 "--")
+       (action menu-item "Act On  (`C-mouse-2')" icicle-candidate-action)
+       (read-fn-invoke menu-item "Apply a Function To...  (`M-mouse-2')"
+        icicle-candidate-read-fn-invoke)
+       (insert-in-minibuffer menu-item "Insert in Minibuffer  (`C-insert')"
+        (lambda ()
+          (interactive)
+          (select-window (active-minibuffer-window))
+          (goto-char (icicle-minibuffer-prompt-end))
+          (icicle-clear-minibuffer)
+          (insert icicle-last-completion-candidate))
+        :help "Insert candidate in minibuffer")
+       (sep-this-2 "--")
+       (all-cands menu-item "Act on Each Individually" icicle-all-candidates-action)
+       (all-list menu-item "Act on All as a List" icicle-all-candidates-list-action)))
+  "Submenu for acting on candidate under the mouse.")
+
+;;;###autoload
+(defconst icicle-Completions-toggle-submenu
+    '(toggle-menu
+      menu-item
+      "Toggle/Cycle/Change"
+      (keymap
+       (highlighting-past menu-item "Toggle Highlighting Saved Candidates"
+        icicle-toggle-highlight-saved-candidates)
+       (highlighting-past menu-item "Toggle Highlighting Past Inputs"
+        icicle-toggle-highlight-historical-candidates)
+       (removing-dups menu-item "Toggle Duplicate Removal" icicle-toggle-transforming)
+       (case-sensitivity menu-item "Toggle Case Sensitivity  (`C-A')"
+        icicle-toggle-case-sensitivity)
+       ;; This one is not a toggle or cycle.
+       (regexp-quote-input menu-item "Regexp-Quote Current Input"
+        icicle-regexp-quote-input
+        :visible (not (and mark-active (> (region-end) (region-beginning)))))
+       ;; This one is not a toggle or cycle.
+       (regexp-quote-region menu-item "Regexp-Quote Input Region"
+        icicle-regexp-quote-input
+        :visible (and mark-active (> (region-end) (region-beginning))))
+       (matching-of-newlines menu-item "Toggle `.' Matching of Newlines Too"
+        icicle-toggle-dot)
+       (literal-vs-regexp menu-item "Toggle Escaping Special Regexp Chars"
+        icicle-toggle-regexp-quote)
+       (incremental-completion menu-item "Toggle Incremental Completion"
+        icicle-toggle-incremental-completion)
+       (expanding-to-common menu-item "Toggle Common Match Expansion"
+        icicle-toggle-expand-to-common-match)
+       (hiding-non-matching-lines menu-item "Toggle Hiding Non-Matching Lines"
+        icicle-toggle-hiding-non-matching-lines)
+       (hiding-common-match menu-item "Toggle Hiding Common Match"
+        icicle-toggle-hiding-common-match)
+       (oneoff-next-S-TAB menu-item "ONE-OFF Next S-TAB Completion Method (`C-u')"
+        icicle-next-S-TAB-completion-method
+        :visible current-prefix-arg)
+       (next-S-TAB menu-item "Next S-TAB Completion Method"
+        icicle-next-S-TAB-completion-method
+        :visible (not current-prefix-arg))
+       (oneoff-next-TAB menu-item "ONE-OFF Next TAB Completion Method (`C-u')"
+        icicle-next-TAB-completion-method
+        :visible current-prefix-arg)
+       (next-TAB menu-item "Next TAB Completion Method"
+        icicle-next-TAB-completion-method
+        :visible (not current-prefix-arg))
+       (next-thumbnail-setting menu-item "Next Image-File Thumbnail Setting"
+        icicle-cycle-image-file-thumbnail)
+       (proxy-candidates menu-item "Toggle Including Proxy Candidates"
+        icicle-toggle-proxy-candidates)
+       (WYSIWYG menu-item "Toggle WYSIWYG for `*Completions*'" icicle-toggle-WYSIWYG-Completions)
+       (angle-brackets menu-item "Toggle Using Angle Brackets" icicle-toggle-angle-brackets)
+       (ignored-files menu-item "Toggle Ignored File Extensions  (`C-.')"
+        icicle-toggle-ignored-extensions)
+       (using-C-for-actions menu-item "Toggle Using `C-' for Actions"
+        icicle-toggle-C-for-actions)
+       (using-~-for-home menu-item "Toggle Using `~' for $HOME"
+        icicle-toggle-~-for-home-dir)
+       (sep-toggle-1 "--")
+       (search-highlight-all menu-item "Toggle All-Current Search Highlighting  (`C-^')"
+        icicle-toggle-highlight-all-current)
+       (search-whole-word menu-item "Toggle Whole-Word Searching  (`M-q')"
+        icicle-toggle-search-whole-word)
+       (search-cleanup menu-item "Toggle Removal of Search Highlighting  (`C-.')"
+        icicle-toggle-search-cleanup)
+       (search-replace-whole menu-item "Toggle Replacing Whole Search Hit  (`M-_')"
+        icicle-toggle-search-replace-whole)
+       (search-replace-common menu-item "Toggle Replacing Expanded Common Match"
+        icicle-toggle-search-replace-common-match)
+       (sep-toggle-2 "--")
+       (option menu-item "+ Toggle Option..." icicle-toggle-option
+        :visible (and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg))))
+       (any-var menu-item "+ Toggle Any Variable..." icicle-toggle-option
+        :visible (and current-prefix-arg
+                  (not (wholenump (prefix-numeric-value current-prefix-arg)))))
+       (boolean menu-item "+ Toggle Boolean Option..."
+        :visible (not current-prefix-arg))
+       ;; This one is not a toggle or cycle.
+       (reset-var menu-item "+ Set Any Variable to `nil'..." icicle-reset-option-to-nil
+        :visible current-prefix-arg)
+       ;; This one is not a toggle or cycle.
+       (reset-option menu-item "+ Set Option to `nil'..."icicle-reset-option-to-nil
+        :visible (not current-prefix-arg))
+       ;; This one is not a toggle or cycle.
+       (set-option-to-t menu-item "+ Set Option to `t'..." icicle-set-option-to-t
+        :visible (and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg))))
+       ;; This one is not a toggle or cycle.
+       (set-var-to-t menu-item "+ Set Any Variable to `t'..." icicle-set-option-to-t
+        :visible (and current-prefix-arg
+                  (not (wholenump (prefix-numeric-value current-prefix-arg)))))
+       ;; This one is not a toggle or cycle.
+       (set-boolean-to-t menu-item "+ Set Boolean Option to `t'..." icicle-set-option-to-t
+        :visible (not current-prefix-arg))))
+  "Submenu for toggling, cycling or changing a variable or a behavior.")
+ 
+;;(@* "User options, organized alphabetically, except for dependencies")
+
+;;; User options, organized alphabetically, except for dependencies --
+
+;;;###autoload
+(defcustom icicle-act-before-cycle-flag nil
+  "*Non-nil means act on current candidate, then cycle to next/previous.
+Otherwise (nil), cycle to the next or previous candidate, and then act
+on it.
+
+This affects keys such as the following:
+
+ `C-down',   `C-wheel-down',   `C-next',   `C-end',
+ `C-M-down', `C-M-wheel-down', `C-M-next', `C-M-end',
+ `C-S-down', `C-S-wheel-down', `C-S-next', `C-S-end'.
+
+Note: A few Icicles commands ignore this setting, in order to \"do the
+right thing\"."
+  :type 'boolean :group 'Icicles-Key-Bindings :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-add-proxy-candidates-flag nil ; Toggle with `C-M-_'.
+  "*Non-nil means to include proxy candidates whenever possible.
+A proxy candidate is a special candidate (shown in `*Completions*'
+using face `icicle-special-candidate') whose name is a placeholder for
+the real candidate.  The proxy candidate typically stands for some
+value obtained from the cursor position or by some action such as
+clicking the mouse.  Example candidates include a color or file name,
+named by proxy candidates such as `*copied foreground*' or `*file at
+point*'.
+
+You can toggle this option at any time from the minibuffer using
+`\\\\[icicle-toggle-proxy-candidates]'.  However, for \
+commands that provide many proxy candidates, if
+the flag is off initially when input is read, then you must re-invoke
+the completing command for the new value to take effect.  (This is for
+performance reasons.)"
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-alternative-actions-alist ()
+  "*Alist of Emacs commands and alternative action functions.
+This always overrides any alternative action defined by
+`icicle-candidate-alt-action-fn'.
+
+Each alist element has the form (COMMAND . FUNCTION), where COMMAND is
+a command (a symbol) that reads input and FUNCTION is the
+alternative-action function it uses.  To disable alternative action
+for a given command, use `ignore' as the FUNCTION.
+
+This option has no effect on `icicle-all-candidates-list-alt-action',
+that is, `M-|', but it does affect `C-|'."
+  :type '(alist
+          :key-type   (symbol   :tag "Command")
+          :value-type (function :tag "Alternative action (function)"))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-alternative-sort-comparer ; Toggle with `C-M-,'.
+  'icicle-historical-alphabetic-p
+  "*An alternative sort function, in place of `icicle-sort-comparer'.
+You can swap this with `icicle-sort-comparer' at any time by using
+`icicle-toggle-alternative-sorting' (\\\
+`\\[icicle-toggle-alternative-sorting]' in the minibuffer)."
+  :type '(choice (const :tag "None" nil) function) :group 'Icicles-Completions-Display)
+
+;; Must be before `icicle-dot-string'.
+;;;###autoload
+(defconst icicle-anychar-regexp (let ((strg  (copy-sequence "\\(.\\|[\n]\\)")))
+                                  (set-text-properties 0 (length strg)
+                                                       '(display "." face highlight)
+                                                       strg)
+                                  strg)
+  "Regexp that matches any single character, including newline.")
+
+;;;###autoload
+(defcustom icicle-anything-transform-candidates-flag nil
+  "*Non-nil means `icicle-anything' transforms completion candidates.
+Function `anything-transform-candidates' is used for the transforming.
+
+The advantage of a nil value is that `icicle-anything' then acts as a
+multi-command: you can act on multiple candidates, or apply multiple
+actions for the same candidate, within a single invocation of
+`icicle-anything' (or related commands).
+
+The advantage of a non-nil value is that some of the displayed
+Anything candidates might be more readable.
+
+This option has no effect if library `anything.el' cannot be loaded."
+  :type 'boolean :group 'Icicles-Completions-Display :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-apropos-complete-keys '([S-tab] [S-iso-lefttab]) ; `S-TAB'
+  ;; In Emacs 22 and later, `backtab' is the canonical key that represents both `S-tab' and
+  ;; `S-iso-lefttab', so in principle that could be used in the default value for Emacs 22+.
+  ;;
+  ;; In other words, the following should be sufficient:
+  ;;   (if (> emacs-major-version 21)
+  ;;       '([backtab])
+  ;;     '([S-tab] [S-iso-lefttab]))
+  ;;
+  ;; However, some Emacs 22+ libraries, such as `info.el', are brain-dead and explicitly
+  ;; bind both `backtab' and `S-tab'.  I filed Emacs bug #1281.
+  "*Key sequences to use for `icicle-apropos-complete'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards - for example, `S-tab' and `S-iso-lefttab'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-complete-no-display-keys '([C-M-S-tab] ; `C-M-S-TAB'
+                                                     [C-M-S-iso-lefttab])
+  "*Key sequences to use for `icicle-apropos-complete-no-display'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards - for example, `C-M-S-tab' and `C-M-S-iso-lefttab'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-next-keys '([next]) ; `next'
+  "*Key sequences for apropos completion to cycle to the next candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-apropos-cycle-next-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-next-action-keys '([C-next]) ; `C-next'
+  "*Keys for apropos completion to cycle next and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-apropos-cycle-next-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-next-alt-action-keys '([C-S-next]) ; `C-S-next'
+  "*Keys for apropos completion to cycle next and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-next-help-keys '([(control meta next)]) ; `C-M-next'
+  "*Keys for apropos completion to cycle next and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-previous-keys '([prior]) ; `prior'
+  "*Key sequences for apropos completion to cycle to the previous candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-apropos-cycle-previous-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-previous-action-keys '([C-prior]) ; `C-prior'
+  "*Keys for apropos completion to cycle previous and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-apropos-cycle-previous-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-previous-alt-action-keys '([C-S-prior]) ; `C-S-prior'
+  "*Keys for apropos completion to cycle previous and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-apropos-cycle-previous-help-keys '([(control meta prior)]) ; `C-M-prior'
+  "*Keys for apropos completion to cycle previous and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-bookmark-name-length-max 70
+  "*Maximum number of characters used to name a bookmark.
+When `icicle-bookmark-cmd' is used with a non-negative numeric prefix
+arg, the name of the bookmark that is set has at most this many chars."
+  :type 'integer :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-bookmark-refresh-cache-flag t
+  "*t means `icicle-bookmark' refreshes the bookmark-list cache.
+Use nil to speed up `icicle-bookmark(-other-window)' if you have a lot
+of bookmarks, at the cost of having the bookmark list possibly not be
+up to date.  Use t if you want to be sure the list is refreshed.
+
+If nil, the list of bookmarks is updated only if you use `C-u'.
+If t, the list is always updated unless you use `C-u'.
+
+This affects only commands such as `icicle-bookmark' that use the full
+bookmark list.  It does not affect more specific Icicles bookmark
+commands such as `\\[icicle-bookmark-dired-other-window]' or the use
+of a negative prefix arg with
+`\\[icicle-bookmark-cmd]'.
+
+Regardless of the option value, the cache is refreshed whenever you
+use `S-delete' to delete a candidate bookmark."
+  :type 'boolean :group 'Icicles-Completions-Display :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-extras nil
+  "*List of additional buffer-name candidates added to the normal list.
+List elements are strings."
+  :type '(repeat string) :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-ignore-space-prefix-flag t
+  "*Override `icicle-ignore-space-prefix-flag' for `icicle-buffer*'.
+Note: This option is provided mainly for use (binding) in
+`icicle-define-command' and `icicle-define-file-command'.
+You probably do not want to set this globally, but you can."
+  :type 'boolean :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-match-regexp nil
+  "*nil or a regexp that buffer-name completion candidates must match.
+If nil, then this does nothing.  If a regexp, then show only
+candidates that match it (and match the user input).
+See also `icicle-buffer-no-match-regexp'."
+  :type '(choice (const :tag "None" nil) regexp)
+  :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-no-match-regexp nil
+  "*nil or a regexp that buffer-name completion candidates must not match.
+If nil, then this does nothing.  If a regexp, then show only
+candidates that do not match it.
+See also `icicle-buffer-match-regexp'."
+  :type '(choice (const :tag "None" nil) regexp)
+  :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-predicate nil
+  "*nil or a predicate that buffer-name candidates must satisfy.
+If nil, then this does nothing.  Otherwise, this is a function of one
+argument, a candidate, and only candidates that satisfy the predicate
+are displayed.  For example, this value will show only buffers that
+are associated with files:
+
+  (lambda (bufname) (buffer-file-name (get-buffer bufname)))
+
+This predicate is applied after matching against user input.  It thus
+corresponds to `icicle-must-pass-after-match-predicate', not to
+`icicle-must-pass-predicate'."
+  :type '(choice (const :tag "None" nil) function)
+  :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-require-match-flag nil
+  "*Override `icicle-require-match-flag' for `icicle-buffer*' commands.
+Controls the REQUIRE-MATCH arg to `completing-read' and `read-file-name'.
+The possible values are as follows:
+- nil means this option imposes nothing on completion;
+  the REQUIRE-MATCH argument provided to the function governs behavior
+- `no-match-required' means the same as a nil value for REQUIRE-MATCH
+- `partial-match-ok' means the same as a t value for REQUIRE-MATCH
+- `full-match-required' means the same as a non-nil, non-t value for
+  REQUIRE-MATCH
+
+Note: This option is provided mainly for use (binding) in
+`icicle-define-command' and `icicle-define-file-command'.
+You probably do not want to set this globally, but you can."
+  :type '(choice
+          (const :tag "Do not impose any match behavior"   nil)
+          (const :tag "Do not require a match"             no-match-required)
+          (const :tag "Require a partial match, with RET"  partial-match-ok)
+          (const :tag "Require a full match"               full-match-required))
+  :group 'Icicles-Buffers :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-buffer-sort 'icicle-buffer-sort-*...*-last
+  "*A sort function for buffer names, or nil.
+Examples of sort functions are `icicle-buffer-sort-*...*-last' and
+`string<'.  If nil, then buffer names are not sorted."
+  :type '(choice (const :tag "None" nil) function)
+  :group 'Icicles-Buffers :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-buffers-ido-like-flag nil
+  "*t means `icicle-buffer' and similar commands act more Ido-like.
+Specifically, those commands then bind these options to t:
+ `icicle-show-Completions-initially-flag'
+ `icicle-top-level-when-sole-completion-flag'
+ `icicle-default-value'"
+  :type 'boolean
+  :group 'Icicles-Buffers :group 'Icicles-Completions-Display :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-candidate-width-factor 80
+  "*Percentage of widest candidate width to use for calculating columns.
+The number of columns of candidates displayed in `*Completions*' is no
+more than the window width divided by this percentage of the maximum
+candidate width.
+
+Increasing this toward 100 spreads columns out. Decreasing it
+compresses columns together.  The higher the value, the more
+candidates will form well-defined columns, but the likelier that
+horizontal space will be wasted between them.  The lower the value,
+the more candidates will not line up in columns, but the less
+horizontal space will be wasted between them.
+
+When most candidates are almost as wide as the widest candidate, a
+high value works well.  When most candidates are much shorter than the
+widest candidate, a low value works well.
+
+If you use Do Re Mi (library `doremi.el'), then you can modify this
+option incrementally during completion, seeing the effect as it
+changes.  Use `C-x w' from the minibuffer, then use the `right' and
+`left' arrow keys or the mouse wheel to increment and decrement the
+value.  WYSIWYG.
+
+See also option `icicle-inter-candidates-min-spaces' and (starting
+with Emacs 23) option `icicle-Completions-text-scale-decrease'."
+  :type 'integer :group 'Icicles-Completions-Display)
+
+;; Must be before `icicle-change-region-background-flag'.
+;;;###autoload
+(defcustom icicle-mark-position-in-candidate 'input-end
+  "*Position of mark when you cycle through completion candidates.
+This is the mark position in the minibuffer.
+Possible values are those for `icicle-point-position-in-candidate'."
+  :type '(choice
+          (const :tag "Leave mark at the beginning of the minibuffer input"  input-start)
+          (const :tag "Leave mark at the end of the minibuffer input"        input-end)
+          (const :tag "Leave mark at the beginning of the completion root"   root-start)
+          (const :tag "Leave mark at the end of the completion root"         root-end))
+  :group 'Icicles-Minibuffer-Display)
+
+;; Must be before `icicle-change-region-background-flag'.
+;;;###autoload
+(defcustom icicle-point-position-in-candidate 'root-end
+  "*Position of cursor when you cycle through completion candidates.
+This is the cursor position in the minibuffer.
+Possible values are:
+ `input-start': beginning of the minibuffer input
+ `input-end':   end of the minibuffer input
+ `root-start':  beginning of the completion root
+ `root-end':    end of the completion root
+When input is expected to be a file name, `input-start' is just after
+the directory, which is added automatically during completion cycling.
+See also `icicle-mark-position-in-candidate'."
+  :type '(choice
+          (const :tag "Leave cursor at the beginning of the minibuffer input"  input-start)
+          (const :tag "Leave cursor at the end of the minibuffer input"        input-end)
+          (const :tag "Leave cursor at the beginning of the completion root"   root-start)
+          (const :tag "Leave cursor at the end of the completion root"         root-end))
+  :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-change-region-background-flag
+  (not (eq icicle-point-position-in-candidate icicle-mark-position-in-candidate))
+  "*Non-nil means use color `icicle-region-background' during input.
+See `icicle-region-background'.  If you load library `hexrgb.el'
+before Icicles, then `icicle-region-background' will be a slightly
+different hue from your normal background color.  This makes
+minibuffer input easier to read than if your normal `region' face were
+used.  This has an effect only during minibuffer input.  A non-nil
+value for this option is particularly useful if you use
+delete-selection mode."
+  :type 'boolean :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-change-sort-order-completion-flag nil
+  "*Non-nil means `icicle-change-sort-order' uses completion, by default.
+Otherwise, it cycles among the possible sort orders.  You can override
+the behavior by using `C-u' with `icicle-change-sort-order'."
+  :type 'boolean :group 'Icicles-Completions-Display :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-C-l-uses-completion-flag nil
+  "*Non-nil means \\\
+`\\[icicle-retrieve-previous-input]' uses completion for choosing completion history
+entries, by default.  Otherwise, it cycles among the possible previous
+inputs.  You can override the behavior by using `C-u' with `\\[icicle-retrieve-previous-input]'."
+  :type 'boolean :group 'Icicles-Minibuffer-Display :group 'Icicles-Matching)
+
+;; Replace this list by your favorite color themes. Each must be the name of a defined function.
+;; By default, this includes all color themes defined globally (variable `color-themes').
+;;
+;; NOTE: We need the `condition-case' because of a BUG in `directory-files' for Emacs 20.
+;; Bug reported to `color-theme.el' maintainer 2009-11-22.  The problem is that the default value
+;; of `color-theme-libraries' concats `file-name-directory', which ends in `/', with `/themes',
+;; not with `themes'.  So the result is `...//themes'.  That is tolerated by Emacs 21+
+;; `directory-files', but not for Emacs 20.  Until this `color-theme.el' bug is fixed, Emacs 20
+;; users will need to manually load `color-theme-libraries.el'.
+;;;###autoload
+(defcustom icicle-color-themes ()
+  "*List of color themes to cycle through using `M-x icicle-color-theme'.
+Note: Starting with Color Theme version 6.6.0, you will need to put
+library `color-theme-library.el', as well as library `color-theme.el',
+in your `load-path'."
+  :type 'hook :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-comint-dynamic-complete-replacements
+  '((comint-dynamic-complete-filename    'icicle-comint-dynamic-complete-filename)
+    (shell-dynamic-complete-command      'icicle-shell-dynamic-complete-command)
+    (shell-dynamic-complete-environment-variable
+     'icicle-shell-dynamic-complete-environment-variable)
+    (shell-dynamic-complete-filename     'icicle-shell-dynamic-complete-filename)
+    (ess-complete-filename               'icicle-ess-complete-filename)
+    (ess-complete-object-name            'icicle-ess-complete-object-name)
+    )
+  "*List of function replacements for `comint-dynamic-complete-functions'.
+Instead of using `comint-dynamic-complete-functions' as is, command
+`icicle-comint-dynamic-complete' replaces functions in that list
+according to the value of this option.
+
+Each option list element is itself a list of two elements.  The first
+is a function to replace (a symbol), and the second is the replacement
+function (a sexp that evaluates to a function).  For example, this
+list element says to replace completion function `foo' by completion
+function `my-foo': (foo 'my-foo).
+
+You can use this option to provide Icicles completion for various
+modes that inherit from Comint mode or otherwise use
+`comint-dynamic-complete'."
+  :type '(repeat (list symbol sexp)) :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-command-abbrev-alist ()
+  "*Alist of command abbreviations and commands, with frequency of use.
+Each element has the form (COMMAND ABBREV N), where ABBREV is an
+abbreviation of COMMAND and N is the number of times COMMAND has been
+invoked via ABBREV.  Both COMMAND and ABBREV are symbols."
+  :type '(alist :key-type symbol :value-type (list symbol integer)) :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-command-abbrev-match-all-parts-flag nil
+  "*Non-nil means `icicle-command-abbrev' matches each command-name part.
+Otherwise, an abbrev need match only a prefix of the command name."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-command-abbrev-priority-flag nil
+  "*nil means commands take precedence over abbreviations for `\\\
+\\[icicle-command-abbrev]'."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-complete-key-anyway-flag nil
+  "*Non-nil means bind `S-TAB' for key completion even if already
+bound.  If nil, then each of the keys in `icicle-key-complete-keys' is
+bound to `icicle-complete-keys' in each keymap of
+`icicle-keymaps-for-key-completion' only if `S-TAB' is not already
+bound in the keymap.
+
+Note: the keys in `icicle-key-complete-keys' are always bound to
+`icicle-complete-keys' in `icicle-mode-map'.  This option affects only
+the binding of those keys in `icicle-keymaps-for-key-completion'."
+  :type 'boolean :group 'Icicles-Key-Completion :group 'Icicles-Key-Bindings)
+
+(when (fboundp 'map-keymap)             ; Emacs 22+.
+  (defcustom icicle-complete-keys-self-insert-ranges ()
+    "*Non-nil means `icicle-complete-keys' includes self-inserting keys.
+That means keys bound to `self-insert-command'.
+
+For Emacs 22, this is effectively Boolean: any non-nil value allows
+all self-inserting keys as candidates.
+
+In Emacs 23+, there are thousands of self-inserting keys, so it is not
+practical to allow all as candidates.  Instead, a non-nil value is a
+list of character ranges of the form (MIN . MAX).  Characters in the
+inclusive range MIN through MAX are possible key-completion
+candidates.
+
+For Emacs 23+, if you use a non-nil value then use only small ranges
+for better performance, e.g., `((0 . 687))' covers Latin characters.
+
+In general, leave the value as nil.  Use vanilla Emacs 23+ command
+`ucs-insert' to insert characters by completing against their Unicode
+names.  With Icicles key completion you do not complete against the
+Unicode names.  Instead, you can see the characters in
+`*Completions*'.
+
+For reference, below are the ranges supported by `ucs-insert' (Emacs
+23+).  But unless you have a very powerful computer, choose only only
+one or two small ranges of characters you actually might use.
+
+BMP ranges:
+ (0 . 13311)       = (#x0000 . #x33FF)
+ (19904 . 19967)   = (#x4DC0 . #x4DFF)
+ (40960 . 55295)   = (#xA000 . #x0D7FF)
+ (64256 . 65533)   = (#xFB00 . #xFFFD)
+
+Upper ranges:
+ (65536 . 79103)   = (#x10000 . #x134FF)
+ (118784 . 131071) = (#x1D000 . #x1FFFF)
+ (917504 . 918015) = (#xE0000 . #xE01FF)"
+    :type '(alist :key-type integer :value-type integer) :group 'Icicles-Key-Completion))
+
+;;;###autoload
+(defcustom icicle-completing-read+insert-keys '([(control meta shift ?c)]) ; `C-M-S-c'
+  "*Key sequences to invoke `icicle-completing-read+insert'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Such a key has no effect unless
+`icicle-completing-read+insert-candidates' is non-nil."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-completion-history-max-length (if icicle-C-l-uses-completion-flag 1000 100)
+  "*Maximum number of inputs to save in the completion history.
+This is the history that you access using \\\
+`\\[icicle-retrieve-previous-input]' and `\\[icicle-retrieve-next-input]'."
+  :type 'integer :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-Completions-display-min-input-chars 0
+  "*`*Completions*' window is removed if fewer chars than this are input.
+You might want to set this to, say 1 or 2, to avoid display of a large
+set of candidates during incremental completion.  The default value of
+0 causes this option to have no effect: `*Completions*' is never
+removed based only on the number of input characters."
+  :type 'integer :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-completions-format (if (boundp 'completions-format) ; Defined in Emacs 23+.
+                                         completions-format
+                                       'horizontal)  
+  "*Layout of completion candidates in buffer `*Completions*'.
+`vertical' means display down columns first, then to the right.
+`horizontal' or nil means display across rows first, then down.
+
+Note that multi-line candidates are always displayed in a single
+column, and in this case it makes no difference what the value of the
+option is - the effect is the same."
+  :type '(choice
+          (const :tag "Display vertically"    vertical)
+          (other :tag "Display horizontally"  horizontal))
+  :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-move-Completions-frame 'right
+  "*Non-nil means move `*Completions*' frame to the edge of the display.
+This is done by `icicle-candidate-action'.
+It only happens if `*Completions*' is alone in its frame.
+This can be useful to make `*Completions*' more visible.
+Possible values are `right', `left', and nil (do not move)."
+  :type '(choice
+          (const :tag "Move to right edge"  right)
+          (const :tag "Move to right edge"  left)
+          (const :tag "Do not move"         nil))
+  :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-Completions-mouse-3-menu-entries `(,icicle-Completions-this-candidate-submenu
+                                                     ,icicle-Completions-sorting-submenu
+                                                     ,icicle-Completions-save/retrieve-submenu
+                                                     ,icicle-Completions-sets-submenu
+                                                     ,icicle-Completions-toggle-submenu
+                                                     ,icicle-Completions-misc-submenu)
+  "*Entries for the `mouse-3' popup menu in `*Completions*'.
+The menu is created by `icicle-Completions-mouse-3-menu'.
+
+The option value is a list.  Each element defines a submenu or a menu
+item.  A null element (`nil') is ignored.
+
+Several alternative entry formats are available.  When customizing,
+choose an alternative in the Customize `Value Menu'.
+
+In this description:
+ SYMBOL      is a symbol identifying the menu entry.
+ `menu-item' is just that text, literally.
+ NAME        is a string naming the menu item or submenu.
+ COMMAND     is the command to be invoked by an item.
+ MENU-KEYMAP is a menu keymap or a var whose value is a menu keymap.
+ KEYWORDS    is a property list of menu keywords (`:enable',
+             `:visible', `:filter', `:keys', etc.).
+
+1. Single menu item.  For a selectable item, use
+   (SYMBOL menu-item NAME COMMAND . KEYWORDS).  For a non-selectable
+   item such as a separator, use (SYMBOL NAME) or
+   (SYMBOL menu-item NAME nil . KEYWORDS).
+
+2. Items taken from a menu-keymap variable, such as
+   `menu-bar-edit-menu'.  Just use the name of the variable (a
+   symbol).  The items appear at the top level of the popup menu, not
+   in a submenu.
+
+3. Submenu.  Use (SYMBOL menu-item NAME MENU-KEYMAP . KEYWORDS) or
+   (SYMBOL NAME . MENU-KEYMAP).  Remember that MENU-KEYMAP can also be
+   a variable (symbol) whose value is a menu keymap.
+
+All of these are standard menu elements, with the exception of the use
+of a keymap variable to represent its value.
+
+See also:
+ * (elisp) Format of Keymaps
+ * (elisp) Classifying Events
+ * (elisp) Extended Menu Items
+
+Example submenu element:
+ (toto menu-item \"Toto\" menu-bar-toto-menu)
+
+Example selectable menu-item element:
+ (foo menu-item \"Foo\"   foo-command
+       :visible (not buffer-read-only))"
+  :type  '(repeat
+           (choice
+            ;; These could be combined, but it's better for users to see separate choices.
+            (restricted-sexp
+             :tag "Submenu (SYMBOL menu-item NAME MENU-KEYMAP . KEYWORDS) or (SYMBOL NAME . MENU-KEYMAP)"
+             :match-alternatives
+             ((lambda (x)
+                (and (consp x) (symbolp (car x))
+                     (or (and (stringp (cadr x)) (cddr x)) ; (SYMBOL NAME . MENU-KEYMAP)
+                         ;; (SYMBOL menu-item NAME MENU-KEYMAP . KEYWORDS)
+                         (and (eq 'menu-item (cadr x))
+                              (stringp (car (cddr x)))
+                              (or (keymapp (car (cdr (cddr x)))) ; Can be a keymap var.
+                                  (and (symbolp (car (cdr (cddr x))))
+                                       (boundp (car (cdr (cddr x))))
+                                       (keymapp (symbol-value (car (cdr (cddr x)))))))))))
+              'nil))
+            (restricted-sexp
+             :tag "Items from a keymap variable's value."
+             :match-alternatives ((lambda (x) (and (symbolp x) (keymapp (symbol-value x))))
+                                  'nil))
+            (restricted-sexp
+             :tag "Selectable item (SYMBOL menu-item NAME COMMAND . KEYWORDS)"
+             :match-alternatives ((lambda (x) (and (consp x) (symbolp (car x))
+                                                   (eq 'menu-item (cadr x))
+                                                   (stringp (car (cddr x)))
+                                                   (commandp (car (cdr (cddr x))))))
+                                  'nil))
+            (restricted-sexp
+             :tag "Non-selectable item (SYMBOL NAME) or (SYMBOL menu-item NAME nil . KEYWORDS)"
+             :match-alternatives ((lambda (x) (and (consp x) (symbolp (car x))
+                                                   (or (and (stringp (cadr x)) (null (caddr x)))
+                                                       (and (eq 'menu-item (cadr x))
+                                                            (stringp (car (cddr x)))
+                                                            (null (car (cdr (cddr x))))))))
+                                  'nil))))
+  :group 'Icicles-Completions-Display)
+
+(when (fboundp 'text-scale-decrease)    ; Emacs 23+
+  (defcustom icicle-Completions-text-scale-decrease 0.75
+    "*Initial height decrease for text in buffer `*Completions*'.
+A value of 0.0 means the height is not decreased at all.
+This is used as the argument to function `text-scale-decrease'.
+If you use library `doremi-frm.el', you can use `C-x -' to
+incrementally resize the text during completion.
+
+See also options `icicle-candidate-width-factor' and
+`icicle-inter-candidates-min-spaces'."
+    :type 'number :group 'Icicles-Completions-Display))
+
+;;;###autoload
+(defcustom icicle-Completions-window-max-height 30
+  "*Maximum height of `*Completions*' window, in lines.
+The window is fit to the buffer size, with this as maximum height.
+Not used if `*Completions*' is a special buffer with its own frame.
+Not used in Emacs releases prior to 21."
+  :type 'integer :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-customize-save-flag t
+  "*Non-nil means save some updated Icicles options when you quit Emacs.
+That is, add some functions to `kill-emacs-hook' that call
+`customize-save-variable'.  Currently, this includes only function
+`icicle-command-abbrev-save', which saves updated option
+`icicle-command-abbrev-alist'."
+  :type 'boolean :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-customize-save-variable-function 'customize-save-variable
+  "*Function used to save user option changes.
+I RECOMMEND that you do NOT change this.
+
+The option value is a function that has the same signature as
+`customize-save-variable' (perhaps with additional arguments after VAR
+and VAL, the variable to save and its new value.
+
+If you do not want changes that Icicles commands make to certain user
+options to be saved automatically, you can set this to the function
+\(symbol) `ignore'.  If you want to use your own function to somehow
+save the current value, you can set this to your function."
+  :type 'function :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-cycle-into-subdirs-flag nil
+  "*Non-nil means minibuffer-input cycling explores subdirectories.
+If this is non-nil, then you might want to use a function such as
+`icicle-dirs-last-p' for option `icicle-sort-comparer', to prevent
+cycling into subdirectories depth first.  Command
+`icicle-sort-by-directories-last' does that."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-default-cycling-mode 'prefix
+  "*Default completion mode for per-mode cycling.
+When you hit a completion key (`TAB' or `S-TAB'), it sets the current
+completion mode (prefix or apropos, respectively).  That determines
+the kind of completion to be used by the per-mode cycling keys.
+
+This option controls which completion mode to use if you cycle using a
+per-mode key (e.g. `down') *before* hitting a completion key.
+
+ - `prefix'  means cycle prefix completions
+ - `apropos' means cycle apropos completions
+ - Any other non-nil value means cycle inputs from the input history
+ - nil means do not cycle - you must first hit a completion key
+
+The per-mode cycling keys are the values of
+`icicle-modal-cycle-up-keys' (backward) and
+`icicle-modal-cycle-down-keys' (forward).  By default, these are keys
+`up' and `down' as well as the mouse wheel.
+
+For example, if the value is `prefix' (the default) then you can
+immediately cycle prefix completions using `up', `down', or the mouse
+wheel, without first hitting `TAB'.
+
+Once you have used `TAB' or `S-TAB', the only way to traverse the
+history is using `M-p' and `M-n' (they always traverse the history).
+
+This option affects only cycling with the per-mode keys.  You can
+always use the mode-specific cycling keys instead to cycle according
+to a particular mode.  The mode-specific keys are (by default):
+
+ - `end'  and `home'  for prefix completion
+ - `next' and `prior' for apropos completion
+
+\(By default there is no conflict between the cycling keys that are
+mode-specific and those that are per-mode.  But if you customize them
+in such a way that you set a key to both, the mode-specific use takes
+priority.)
+
+After you change the value of this option, toggle Icicle mode off,
+then on again, for the change to take effect in the same session."
+  :type '(choice
+          (const :tag "Prefix cycling for per-mode keys, by default"                     prefix)
+          (const :tag "Apropos cycling for per-mode keys, by default"                    apropos)
+          (const :tag "No per-mode cycling - invoke completion first (`TAB', `S-TAB')"   nil)
+          (other :tag "History cycling for per-mode keys, by default"                    t))
+  :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-default-thing-insertion 'alternatives
+  "*Behavior of successive `\\\\[icicle-insert-string-at-point]'.
+If `alternatives', then the next function in the `car' of
+`icicle-thing-at-point-functions' is used to retrieve the text to be
+inserted.
+If `more-of-the-same', then the function that is the `cdr' of
+`icicle-thing-at-point-functions' is used to retrieve the text to be
+inserted."
+  :type `(choice
+          (const :tag ,(substitute-command-keys
+                        "Successive calls to `\\\
+\\[icicle-insert-string-at-point]' use different text-grabbing functions.")
+           alternatives)
+          (const :tag ,(substitute-command-keys
+                        "Successive calls to `\\\
+\\[icicle-insert-string-at-point]' grab more text at point.")
+           more-of-the-same))
+  :group 'Icicles-Key-Bindings)
+
+;; We don't use `define-obsolete-variable-alias' so that byte-compilation in older Emacs
+;; works for newer Emacs too.
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'icicle-init-value-flag 'icicle-default-value)
+  (make-obsolete-variable 'icicle-init-value-flag 'icicle-default-value "2008-04-18"))
+
+;;;###autoload
+(defcustom icicle-default-value t
+  "*How to treat the default value when reading minibuffer input.
+
+When the default value argument to functions such as
+`completing-read', `read-file-name', `read-from-minibuffer', and
+`read-string' is non-nil and the initial-input argument is nil or
+\"\", the default value can be added to the prompt as a hint or
+inserted into the minibuffer as the initial input.
+
+Adding it to the prompt is the default behavior and corresponds to the
+behavior of vanilla Emacs.
+
+Inserting the default value in the minibuffer as the initial input has
+the advantage of not requiring you to use `M-n' to retrieve it.  It
+has the disadvantage of making you use `M-p' (or do something else) to
+get rid of the default value in the minibuffer if you do not want to
+use or edit it.  If you often want to use or edit the default value,
+then set `icicle-default-value' to non-nil and non-t.  If you rarely
+do so, then set it to nil or t.
+
+If inserted in the minibuffer, the value of this option also
+determines whether or not the inserted text is preselected and where
+the cursor is left: at the beginning or end of the text.
+
+These are the possible option values:
+
+  nil               - Do not insert default value or add it to prompt.
+  t                 - Add default value to prompt.  Do not insert it.
+  `insert-start'    - Insert default value and leave cursor at start.
+  `insert-end'      - Insert default value and leave cursor at end.
+  `preselect-start' - Insert and preselect default value;
+                      leave cursor at beginning.
+  `preselect-end'   - Insert and preselect default value;
+                      leave cursor at end.
+
+My own preference is `insert-end'.
+
+Preselection can be useful in Delete Selection mode or PC Selection
+mode.  It makes it easy to replace the value by typing characters, or
+delete it by hitting `C-d' or `DEL' (backspace).  However, all of the
+initial input is lost if you type or hit `C-d' or `DEL'.  That is
+inconvenient if you want to keep most of it and edit it only slightly."
+  :type '(choice
+          (const :tag "Do not insert default value or add it to prompt"            nil)
+          (const :tag "Add default value to prompt (do not insert in minibuffer)"  t)
+          (const :tag "Insert default value.  Leave cursor at beginning"           insert-start)
+          (const :tag "Insert default value.  Leave cursor at end"                 insert-end)
+          (const :tag "Insert default value, select it, leave cursor at beginning"
+           preselect-start)
+          (const :tag "Insert default value, select it, leave cursor at end"
+           preselect-end))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-define-alias-commands-flag t
+  "*Non-nil means define some commands that do not begin with `icicle-'.
+For convenience, a few top-level commands are defined, typically as
+aliases for commands with longer names.  For example, command `toggle'
+is defined as an alias for command `icicle-toggle-option'.  In any
+case, no such command is ever defined by Icicles if a function with
+the same name is already defined."
+   :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-deletion-action-flag t
+  "*Non-nil means `S-delete' during completion deletes the current object.
+More precisely, it deletes the object named by the current completion
+candidate, if a deletion action is defined for the current command.
+If no deletion action is defined, then the value of this option has no
+effect.
+
+If you are worried about inadvertently deleting an object by
+accidentally hitting `S-delete', you can customize this to nil to
+inhibit `S-delete' object deletion during completion."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-dot-show-regexp-flag nil
+  "*Non-nil means show `icicle-anychar-regexp' explicitly for `.'.
+Otherwise, display it as a highlighted `.' only.
+This has no effect for Emacs versions prior to 21: acts as if non-nil."
+  :type 'boolean :group 'Icicles-Matching :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-dot-string "."
+  "*String inserted by `icicle-insert-dot-command'.
+It is either \".\" or the value of `icicle-anychar-regexp'.
+You can toggle this at any time using command `icicle-toggle-dot',
+bound to \\`\\[icicle-toggle-dot]' during completion."
+  :set #'(lambda (sym defs)
+           (custom-set-default sym defs)
+           (setq icicle-dot-string-internal  icicle-dot-string))
+  :type `(choice
+          (const :tag "Match any char EXCEPT newline"       ".")
+          (const :tag "Match any char, including NEWLINE"   ,icicle-anychar-regexp))
+  :group 'Icicles-Matching :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-expand-input-to-common-match-flag t ; Toggle with `C-;'.
+  "*Non-nil means `S-TAB' expands input, still matching all candidates.
+The expansion replaces your input in the minibuffer.
+
+Your expanded input is typically the longest substring common to all
+completion candidates and that matches your (complete) input pattern.
+
+If you want to edit your original input, use \\\
+`\\[icicle-retrieve-previous-input]'.
+
+For apropos completion, your input is, in general, a regexp.  Setting
+this option to nil will let you always work with a regexp in the
+minibuffer for apropos completion - your regexp is then never replaced
+by the expanded common match.
+
+You can toggle this option at any time from the minibuffer using
+`C-;'."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-extras nil
+  "*List of additional file-name candidates added to the normal list.
+List elements are strings."
+  :type '(repeat string) :group 'Icicles-Files :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-match-regexp nil
+  "*nil or a regexp that file-name completion candidates must match.
+If nil, then this does nothing.  If a regexp, then show only
+candidates that match it (and match the user input).
+See also `icicle-file-no-match-regexp'."
+  :type '(choice (const :tag "None" nil) regexp)
+  :group 'Icicles-Files :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-no-match-regexp nil
+  "*nil or a regexp that file-name completion candidates must not match.
+If nil, then this does nothing.  If a regexp, then show only
+candidates that do not match it.
+See also `icicle-file-match-regexp'."
+  :type '(choice (const :tag "None" nil) regexp)
+  :group 'Icicles-Files :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-predicate nil
+  "*nil or a predicate that file-name candidates must satisfy.
+If nil, then this does nothing.  Otherwise, this is a function of one
+argument, a candidate, and only candidates that satisfy the predicate
+are displayed.  For example, this value will show only names of files
+with more than 5000 bytes:
+
+  (lambda (fil) (> (nth 5 (file-attributes file)) 5000))
+
+This predicate is applied after matching against user input.  It thus
+corresponds to `icicle-must-pass-after-match-predicate', not to
+`icicle-must-pass-predicate'."
+  :type '(choice (const :tag "None" nil) function)
+  :group 'Icicles-Files :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-require-match-flag nil
+  "*Override `icicle-require-match-flag' for file-name completion.
+The possible values are as follows:
+- nil means this option imposes nothing on completion;
+  the REQUIRE-MATCH argument provided to the function governs behavior
+- `no-match-required' means the same as a nil value for REQUIRE-MATCH
+- `partial-match-ok' means the same as a t value for REQUIRE-MATCH
+- `full-match-required' means the same as a non-nil, non-t value for
+  REQUIRE-MATCH
+
+Note: This option is provided mainly for use (binding) in
+`icicle-define-command' and `icicle-define-file-command'.
+You probably do not want to set this globally, but you can."
+  :type '(choice
+          (const :tag "Do not impose any match behavior"   nil)
+          (const :tag "Do not require a match"             no-match-required)
+          (const :tag "Require a partial match, with RET"  partial-match-ok)
+          (const :tag "Require a full match"               full-match-required))
+  :group 'Icicles-Files :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-file-sort nil
+  "*A sort function for file names, or nil.
+Examples of sort functions are `icicle-dirs-last-p' and
+`icicle-last-modified-first-p'.  If nil, then file names are not
+sorted."
+  :type '(choice (const :tag "None" nil) function)
+  :group 'Icicles-Files :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-files-ido-like-flag nil
+  "*t means `icicle-file' and similar commands act more Ido-like.
+Specifically, those commands then bind these options to t:
+ `icicle-show-Completions-initially-flag'
+ `icicle-top-level-when-sole-completion-flag'
+ `icicle-default-value'"
+  :type 'boolean
+  :group 'Icicles-Files :group 'Icicles-Completions-Display :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-filesets-as-saved-completion-sets-flag t
+  "*Non-nil means you can use filesets to save candidates persistently.
+This means that you can save file-name candidates in a persistent
+Icicles saved completion set (cache file) or in in an Emacs fileset.
+It also means that an Icicles persistent completion set can contain
+filesets, in addition to file names: any number of filesets, and
+filesets of different type.  Available only for Emacs 22 and later,
+and you must load library `filesets.el'."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-functions-to-redefine
+  '(bbdb-complete-name                   comint-dynamic-complete
+    comint-dynamic-complete-filename     comint-replace-by-expanded-filename
+    customize-apropos                    customize-apropos-faces
+    customize-apropos-groups             customize-apropos-options
+    customize-apropos-options-of-type    customize-face
+    customize-face-other-window          dabbrev-completion
+    ;; Use these two if you want Icicles completion for shell commands.
+    ;; See http://www.emacswiki.org/emacs/Icicles_-_Shell-Command_Enhancements.
+    ;; 
+    ;; dired-read-shell-command
+    ;; read-shell-command
+    ess-complete-object-name
+    gud-gdb-complete-command
+    Info-goto-node                       Info-index
+    Info-menu
+    lisp-complete-symbol
+    lisp-completion-at-point             minibuffer-default-add-completions
+    read-color                           read-from-minibuffer
+    read-string
+    recentf-make-menu-items              repeat-complex-command)
+  "*List of symbols representing functions to be redefined in Icicle mode.
+In Icicle mode, each such FUNCTION is aliased to Icicles function
+`icicle-FUNCTION'.  The original functions are restored when you exit
+Icicle mode, by aliasing each FUNCTION to `old-FUNCTION'.
+
+Aliasing takes place only if `old-FUNCTION' is defined.  Icicles
+predefines each `old-FUNCTION' found in the default value, as well as
+each corresponding `icicle-FUNCTION' .  If you add additional
+functions of your own choosing, then you will also need to define
+`old-FUNCTION' and `icicle-FUNCTION' accordingly - see the Icicles
+code for examples.
+
+If you customize this option, then you must exit and re-enter Icicle
+mode to ensure that the change takes effect.
+
+For this option to have an effect upon startup, it must be set before
+you enter Icicle mode.  This means that you must ensure that the code
+that sets it is invoked before you enter Icicle mode.  If you use
+Customize to change this option, then ensure that the code inserted by
+Customize into your `user-init-file' or your `custom-file' is invoked
+before you enter Icicle mode."
+  :type '(repeat (restricted-sexp :tag "Command"
+                  ;; Use `symbolp' instead of `functionp' or `fboundp', in case the library
+                  ;; defining the function is not loaded.
+                  :match-alternatives (symbolp) :value ignore))
+  :set #'(lambda (sym defs)
+           (custom-set-default sym defs)
+           (when (boundp 'icicle-mode-map) ; Avoid error on initialization.
+             (icicle-redefine-standard-functions)))
+  :initialize #'custom-initialize-default
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-guess-commands-in-path nil
+  "*Non-nil means all shell commands are available for completion.
+This is used in Icicle mode whenever a shell-command is read.
+
+If non-nil, then all executable files (or all files, if option
+`shell-completion-execonly' is nil) in your search path are included
+among the completion candidates, in addition to any commands that are
+guessed as being appropriate for the target files (e.g. marked files
+in Dired).
+
+If non-nil and if option `icicle-shell-command-candidates-cache' is
+nil, then the list of commands is computed once and cached as the
+value of `icicle-shell-command-candidates-cache'.  The particular
+non-nil value of `icicle-guess-commands-in-path' determines when the
+cache is filled, as follows:
+
+- If the value is `load', then the cache is filled when Icicles is
+  first loaded, and it is saved persistently.
+
+- If the value is `first-use', then the cache is filled when you first
+  complete a shell command, and the computed list is not saved
+  persistently.
+
+If the value is not `load', then whenever you enter Icicle mode the
+cache is emptied.
+
+If your environment changes and you want to update the cached list,
+you can use command `icicle-recompute-shell-command-candidates'.  With
+a prefix argument, that command also saves the cache persistently."
+  :type '(choice
+          (const :tag "Do not add shell commands from search path"              nil)
+          (const :tag "Compute shell commands from path when Icicles is loaded" load)
+          (const :tag "Compute shell commands from path upon first use"         first-use))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-help-in-mode-line-delay 5
+  "*Seconds to show help in the mode-line for individual completions.
+If buffer `*Completions*' is displayed, then use its mode-line.
+Otherwise, use the mode-line of the current buffer.
+
+The help is shown when you cycle among completion candidates and when
+your input is completed (entirely) to a candidate.
+
+Face `icicle-mode-line-help' is used for the help.
+
+A value of zero means do not show such help at all.  In any case, a
+user event (e.g. a key press) always interrupts this display.
+
+Note that `post-command-hook' actions do not take place until this
+display is finished."
+  :type 'number :group 'Icicles-Completions-Display :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-hide-common-match-in-Completions-flag nil
+  "*Non-nil means hide the common match for your input, in `*Completions*'.
+You can toggle this option during completion using `C-x .' (no prefix
+arg).  See also option `icicle-hide-non-matching-lines-flag'.
+
+The common match used here is governed by option
+`icicle-expand-input-to-common-match-flag'.  It is elided using
+ellipsis (`...')."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-hide-non-matching-lines-flag nil
+  "*Non-nil means hide search candidate lines that do not match input.
+This applies only to multi-line candidates in buffer `*Completions*'.
+Lines that do not contain text matched by your current
+minibuffer input are elided using ellipsis (`...').
+You can toggle this option during completion using `C-u C-x .'.
+
+See also option `icicle-hide-common-match-in-Completions-flag'."
+  :type 'boolean :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-historical-candidates-flag t ; Toggle with `C-pause'.
+  "*Non-nil means highlight `*Completions*' candidates that have been used.
+This is done using face `icicle-historical-candidate'.
+Historical candidates are those that you have entered (using `RET' or
+`S-RET') previously.  You can toggle this option from the minibuffer
+at any time using `C-pause'."
+  :type 'boolean :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-input-completion-failure 'implicit-strict
+  "*Non-nil means highlight the part of your input that does not complete.
+This is done using face `icicle-input-completion-fail' or
+`icicle-input-completion-fail-lax'.
+
+You can use `\\\\[icicle-goto/kill-failed-input]' \
+to go to the start of the highlighted part.
+Repeat to kill it.
+
+This highlighting can have a negative impact on performance, because
+it can mean recomputing completion candidates multiple times, in order
+to determine the longest part that completes.  For this reason, you
+can fine tune when you want this highlighting to occur.  The values of
+this option and options
+`icicle-highlight-input-completion-failure-delay' and
+`icicle-highlight-input-completion-failure-threshold' determine when
+the highlighting can take place.
+
+In particular, highlighting the non-matching part of remote file names
+can be slow.  Two values of this option allow remote file name
+highlighting: `always' and `explicit-remote'.  The other values do not
+highlight remote file names.  You probably do not want to use a value
+of `always'.
+
+If the value is nil, then highlighting never occurs.  If the value is
+`explicit-strict', `explicit', or `explicit-remote', then highlighting
+occurs only upon demand: when you hit `TAB' or `S-TAB' to request
+completion.  If the value is `implicit-strict', `implicit', or
+`always', then highlighting occurs also when you update your input
+during incremental completion.
+
+If the value is `implicit-strict' or `implicit', then highlighting
+occurs not only upon demand but also during incremental completion if
+`icicle-incremental-completion-flag' is non-nil.  Remember that you
+can toggle incremental completion, using `C-#' in the minibuffer.
+
+I use a value of `implicit' myself, but the default value is
+`implicit-strict' because, depending on your setup and use cases,
+`implicit' can impact performance for file-name completion (which is
+lax, not strict).  I suggest you try `implicit' to see - this feature
+is especially useful for file names.
+
+Summary of choices for when to highlight:
+
+nil               Never
+`explicit-strict' When you hit `TAB'/`S-TAB' for strict completion
+`explicit'        When you hit `TAB'/`S-TAB'
+`explicit-remote' When you hit `TAB'/`S-TAB', including remote files
+`implicit-strict' During strict completion
+`implicit'        During lax or strict completion
+`always'          Always, even for names of remote files
+
+After highlighting, you can use `C-M-l' to move the cursor to the
+start of the mismatch, for editing there.  You can use a second
+`C-M-l' to kill (delete) the mismatch up to the next input line (if
+any).  You can repeat `C-M-l' to kill additional input lines.
+
+See also:
+* `icicle-highlight-input-completion-failure-delay'
+* `icicle-highlight-input-completion-failure-threshold'"
+  :type '(choice
+          (const :tag "Never"                                               nil)
+          (const :tag "Explicit (`TAB'/`S-TAB') strict completion"          explicit-strict)
+          (const :tag "Explicit (`TAB'/`S-TAB') lax and strict completion"  explicit)
+          (const :tag "Explicit completion, even of remote file names"      explicit-remote)
+          (const :tag "Strict completion"                                   implicit-strict)
+          (const :tag "Lax and strict completion"                           implicit)
+          (const :tag "Always (including for remote file names)"            always))
+  :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-input-completion-failure-delay 0.7
+  "*Seconds to wait before highlighting non-completing part of your input.
+Zero means there is no wait."
+  :type 'number :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-input-completion-failure-threshold 1000
+  "*More candidates means do not highlight non-completing part of input.
+See also `icicle-highlight-input-completion-failure'."
+  :type 'integer :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-input-initial-whitespace-flag t
+  "*Non-nil means highlight initial whitespace in your input.
+This is done using face `icicle-whitespace-highlight'.
+Purpose: Otherwise, you might not notice that you accidentally typed
+some whitespace at the beginning of your input, so you might not
+understand the set of matching candidates (or lack thereof).
+
+Note: Highlighting input completion failure (see option
+`icicle-highlight-input-completion-failure') subsumes
+initial-whitespace highlighting.  This means that if no completion
+candidate starts with whitespace, and if Icicles is highlighting input
+completion failure, then only that highlighting is shown."
+  :type 'boolean :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-highlight-lighter-flag t
+  "*Non-nil means highlight the `Icy' mode-line lighter during completion.
+See the Icicles doc, section `Nutshell View of Icicles', subsection
+`Completion Status Indicators' for more information."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-highlight-saved-candidates-flag t ; Toggle with `S-pause'.
+  "*Non-nil means highlight `*Completions*' candidates that have been saved.
+This is done using face `icicle-saved-candidate'.
+You save candidates using, for example, `C-M->'.  You can toggle this
+option from the minibuffer at any time using `S-pause'."
+  :type 'boolean :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-ignore-comments-flag t
+  "Non-nil means `icicle-with-comments-hidden' hides comments.
+You can toggle this option using `C-M-;' in the minibuffer, but to see
+the effect you might need to invoke the current command again."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-ignored-directories (and (boundp 'vc-directory-exclusion-list)
+                                           vc-directory-exclusion-list)
+  "*Directories ignored by `icicle-locate-file'."
+  :type '(repeat string) :group 'Icicles-Files)
+
+;;;###autoload
+(defcustom icicle-ignore-space-prefix-flag nil ; Toggle with `M-_'.
+  "*Non-nil means ignore completion candidates that start with a space.
+However, such candidates are not ignored for prefix completion when
+the input also starts with a space.  You can toggle this option from
+the minibuffer using `M-_'.
+Note: Some Icicles functionalities ignore the value of this option."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-image-files-in-Completions (and (fboundp 'image-file-name-regexp)
+                                                  (if (fboundp 'display-graphic-p)
+                                                      (display-graphic-p)
+                                                    window-system)
+                                                  t)
+  "*Non-nil means show thumbnail images for image files in `*Completions*'.
+This has no effect if your Emacs version does not have image support.
+
+ `nil'   means show only file names.
+ `image' means show only thumbnail images.
+ `t'     means show both file names and thumbnail images.
+
+You can cycle the value during completion using `C-x t'."
+  :type '(choice
+          (const :tag "Both name and thumbnail"  t)
+          (const :tag "Thumbnail image only"     'image-only)
+          (const :tag "File name only"           nil))
+  :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-incremental-completion-delay 0.7
+  "*Number of seconds to wait before updating `*Completions*' incrementally.
+There is no wait if the number of completion candidates is less than
+or equal to `icicle-incremental-completion-threshold'.
+See also `icicle-incremental-completion-flag'."
+  :type 'number :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-incremental-completion-flag t ; Toggle with `C-#'.
+  "*Non-nil means update `*Completions*' buffer incrementally, as you type.
+nil means do not update `*Completions*' incrementally, as you type.
+t means do nothing if `*Completions*' is not already displayed.
+Non-nil and non-t means display `*Completions*' and update it.
+You can toggle this between t and nil from the minibuffer at any time
+using `C-#'.
+
+Note: Incremental completion is effectively turned off when a remote
+file name is read, that is, whenever your file-name input matches a
+remote-file syntax.
+
+See also `icicle-incremental-completion-delay' and
+`icicle-incremental-completion-threshold'."
+  :type '(choice
+          (const :tag "Do not update `*Completions*' incrementally"                nil)
+          (const :tag "Update `*Completions*' incrementally if already displayed"  t)
+          (other :tag "Update `*Completions*' incrementally always"                always))
+  :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-incremental-completion-threshold 1000
+  "*More candidates means apply `icicle-incremental-completion-delay'.
+See also `icicle-incremental-completion-flag' and
+`icicle-incremental-completion-delay'.
+This threshold is also used to decide when to display the message
+ \"Displaying completion candidates...\"."
+  :type 'integer :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-inhibit-advice-functions
+  '(choose-completion choose-completion-string completing-read
+    completion-setup-function dired-smart-shell-command
+    display-completion-list exit-minibuffer face-valid-attribute-values
+    minibuffer-complete-and-exit mouse-choose-completion
+    next-history-element read-face-name read-file-name read-number
+    shell-command shell-command-on-region switch-to-completions
+    completing-read-multiple)
+  "*Functions that Icicles redefines, and for which advice is deactivated.
+Icicle mode deactivates all advice for such functions.  The advice is
+reactivated when you leave Icicle mode."
+  :type '(repeat (function :tag "Function for which Icicles deactivates advice"))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-inhibit-ding-flag nil
+  "*Non-nil means Icicles never uses an audible bell (ding).
+If nil, Icicles sometimes signals you with a sound."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-input-string ".*"
+  "*String to insert in minibuffer via `\\\
+\\[icicle-insert-string-from-variable]'.
+Typically, this is a regexp or a portion of a regexp."
+  :type 'string :group 'Icicles-Miscellaneous)
+
+(when (fboundp 'defvaralias)            ; Emacs 22+
+  (defvaralias 'icicle-key-descriptions-use-angle-brackets-flag
+      'icicle-key-descriptions-use-<>-flag))
+
+;;;###autoload
+(defcustom icicle-inter-candidates-min-spaces 1
+  "*Min number of spaces between candidates displayed in `*Completions*'.
+If you use Do Re Mi (library `doremi.el'), then you can modify this
+option incrementally during completion, seeing the effect as it
+changes.  Use `\\\
+\\[icicle-doremi-inter-candidates-min-spaces+]' from the minibuffer, then use the `up' and
+`down' arrow keys or the mouse wheel to increment and decrement the
+value.  WYSIWYG.
+
+See also option `icicle-candidate-width-factor' and (starting with
+Emacs 23) option `icicle-Completions-text-scale-decrease'."
+  :type 'integer :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-isearch-complete-keys '([C-M-tab] ; `M-TAB', `C-M-TAB'
+                                          [M-tab] "\M-\t" [escape tab] ; Replace vanilla. 
+                                          "\M-o") ; Like Icicles minibuffer `M-o'.
+  "*Key sequences to use for `icicle-isearch-complete'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.
+
+The default value includes `M-TAB', which replaces the vanilla binding
+of `isearch-complete'.
+
+It also includes `ESC TAB' and `C-M-TAB', because some operating
+systems intercept `M-TAB' for their own use.  (Note: For MS Windows,
+you can use (w32-register-hot-key [M-tab]) to allow Emacs to use
+`M-TAB'.)
+
+It also includes `M-o', in keeping with the Icicles use of `M-o'
+during minibuffer completion."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-key-complete-keys '([S-tab] [S-iso-lefttab]) ; `S-TAB'
+  ;; $$$$$ The following should be sufficient, but some Emacs 22+ libraries, such as `info.el',
+  ;; are brain-dead and explicitly bind both `backtab' and `S-tab'.  I filed Emacs bug #1281.
+  ;;   (if (> emacs-major-version 21)
+  ;;       '([backtab])
+  ;;     '([S-tab] [S-iso-lefttab]))
+  "*Key sequences to use for `icicle-complete-key'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards - for example, `S-tab' and `S-iso-lefttab'."
+;; In Emacs 22 and later, `backtab' is the canonical key that represents
+;; both `S-tab' and `S-iso-lefttab', so that is used in the default
+;; value.  If, for some reason, `backtab' is not being translated to
+;; `S-tab' and `S-iso-lefttab' on your platform, you might want to
+;; customize the value to ([S-tab] [S-iso-lefttab]).  And if your Emacs
+;; version is 22 or later, please file an Emacs bug about the lack of
+;; translation.
+  :type '(repeat sexp) :group 'Icicles-Key-Completion :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-key-descriptions-use-<>-flag nil
+  "*Non-nil means Icicles key descriptions should use angle brackets (<>).
+For example, non-nil gives `'; nil gives `mode-line'.
+
+This does not affect Emacs key descriptions outside of
+Icicles (e.g. `C-h k' or `C-h w').
+
+This has no effect for versions of Emacs prior to 21, because
+they never use angle brackets."
+  :type 'boolean :group 'Icicles-Key-Completion :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-keymaps-for-key-completion
+  '(bookmark-bmenu-mode-map bmkp-jump-map bmkp-jump-other-window-map
+    calendar-mode-map dired-mode-map facemenu-keymap jde-mode-map jde-jdb-mode-map
+    senator-mode-map srecode-mode-map synonyms-mode-map vc-dired-mode-map)
+  "*List of keymaps in which to bind `S-TAB' to `icicle-complete-keys'.
+List elements are symbols that are bound to keymaps.
+
+Each keymap should have at least one prefix key.  `S-TAB' is bound in
+each keymap, so that you can use it to complete the prefix keys.
+
+If one of the keymaps is not defined when Icicle mode is entered, then
+it is ignored.  If you later define it, then just exit and reenter
+Icicle mode, to bind `S-TAB' in the newly defined map.  For example,
+use `M-x icy-mode' twice after entering Calendar mode, to be able to
+complete `calendar-mode' prefix keys such as `A'.
+
+Do not add `global-map' or any keymaps, such as `ctl-x-map', that are
+accessible from the global keymap to the list - they are already
+treated, by default.
+
+Do not add any of the translation keymaps, `function-key-map',
+`key-translation-map', or `iso-transl-ctl-x-8-map' to the list - that
+will not work."
+  :type '(repeat symbol) :group 'Icicles-Key-Completion :group 'Icicles-Key-Bindings)
+
+(when (boundp 'kmacro-ring)             ; Emacs 22+
+  (defcustom icicle-kmacro-ring-max (if (boundp 'most-positive-fixnum)
+                                        most-positive-fixnum
+                                      67108863) ; 1/2 of `most-positive-fixnum' on Windows.
+    "*Icicles version of `kmacro-ring-max'."
+    :type 'integer :group 'Icicles-Miscellaneous))
+
+;;;###autoload
+(defcustom icicle-levenshtein-distance 1
+  "*Levenshtein distance allowed for strings to be considered as matching.
+Icicles matching function `icicle-levenshtein-match' considers a
+string to match another if the first string is within this distance of
+some substring of the second.
+This option is used only if you have library `levenshtein.el'."
+  :type 'integer :group 'Icicles-Matching)
+
+;;; $$$$$$
+;;; (defcustom icicle-list-end-string "
+
+;;; "
+;;;   "*String appended to a completion candidate that is a list of strings.
+;;; When a completion candidate is a list of strings, they are joined
+;;; pairwise using `icicle-list-join-string', and `icicle-list-end-string'
+;;; is appended to the joined strings.  The result is what is displayed as
+;;; a completion candidate in buffer `*Completions*', and that is what is
+;;; matched by your minibuffer input.
+
+;;; The purpose of `icicle-list-end-string' is to allow some separation
+;;; between the displayed completion candidates.  Candidates that are
+;;; provided to input-reading functions such as `completing-read' as lists
+;;; of strings are often displayed using multiple lines of text.  If
+;;; `icicle-list-end-string' is \"\", then the candidates appear run
+;;; together, with no visual separation.
+
+;;; It is important to remember that `icicle-list-end-string' is part of
+;;; each completion candidate in such circumstances.  This matters if you
+;;; use a regexp that ends in `$', matching the end of the candidate."
+;;;   :type 'string :group 'Icicles-Completions-Display)
+
+;; Note: If your copy of this file does not have the two-character string "^G^J"
+;; (Control-G, Control-J) or, equivalently, \007\012, as the default value, you will want
+;; to change the file to have that.  To insert these control characters in the file, use
+;; `C-q'.  Emacs Wiki loses the ^G from the file, so I use \007, which works OK.
+;;
+;;;###autoload
+(defcustom icicle-list-join-string (let ((strg  (copy-sequence "\007\012")))
+                                     ;; Emacs 20 ignores `display', so don't bother.
+                                     ;; Emacs 21 has a big bug, which interprets `display' badly.
+                                     (when (> emacs-major-version 21) ; Avoid Emacs 21 bug.
+                                       (set-text-properties 0 1 '(display "") strg))
+                                     strg)
+  "*String joining items in a completion that is a list of strings.
+When a completion candidate is a list of strings, this string is used
+to join the strings in the list, for display and matching purposes.
+When completing input, you type regexps that match the strings,
+separating them pairwise by the value of `icicle-list-join-string'.
+Actually, what you enter is interpreted as a single regexp to be
+matched against the joined strings.  Typically, the candidate list
+contains two strings: a name and its doc string.
+
+A good value for this option is a string that:
+ 1) does not normally occur in doc strings,
+ 2) visually separates the two strings it joins, and
+ 3) is not too difficult or too long to type.
+
+The default value is \"^G\^J\", that is, control-g followed by
+control-j (newline):
+ 1) ^G does not normally occur in doc strings
+ 2) a newline visually separates the multiple component strings, which
+    helps readability in buffer `*Completions*'
+ 3) you can type the value using `C-q C-g C-q C-j'.
+
+For readability (in Emacs 22 and later), the default value has a
+`display' property that makes it appear as simply a newline in
+`*Completions*' - the `^G' is hidden.  you can also make the default
+value appear this way in your minibuffer input also, by using \
+`\\\\[icicle-insert-list-join-string].'
+
+If you like the default value of `^G^J', but you prefer that the `^G'
+not be hidden, then just customize this option.  In Customize, use
+`Show initial Lisp expression' after clicking the `State' button, to
+be able to edit the default value.  Remove the `set-text-properties'
+expression, which sets text property `display' to \"\"."
+  :type 'string :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-list-nth-parts-join-string " "
+  "*String joining candidate parts split by `icicle-list-use-nth-parts'.
+This has an effect on multi-completion candidates only, and only if
+the current command uses `icicle-list-use-nth-parts'."
+  :type 'string :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-max-candidates nil
+  "*Non-nil means truncate completion candidates to at most this many.
+If you use library `doremi.el' then you can use `C-x #' during
+completion to increment or decrement the option value using the
+vertical arrow keys or the mouse wheel.  A numeric prefix argument for
+`C-x #' sets the increment size.  A plain prefix argument (`C-u')
+resets `icicle-max-candidates' to nil, meaning no truncation."
+  :type '(choice (const :tag "None" nil) integer)
+  :group 'Icicles-Completions-Display :group 'Icicles-Matching
+  :group 'Icicles-Buffers :group 'Icicles-Files)
+
+;;;###autoload
+(defcustom icicle-menu-items-to-history-flag t
+  "*Non-nil means to add menu-item commands to the command history.
+This history is `extended-command-history'.
+
+After you change the value of this option, toggle Icicle mode off,
+then on again, for the change to take effect in the same session."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;; Inspired from `icomplete-minibuffer-setup-hook'.
+;;;###autoload
+(defcustom icicle-minibuffer-setup-hook nil
+  "*Functions run at the end of minibuffer setup for Icicle mode."
+  :type 'hook :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-down-keys ; `down', `wheel-down'
+  (if (boundp 'mouse-wheel-down-event)  ; Emacs 22+
+      (list
+       [down]
+       (vector nil mouse-wheel-up-event)
+       (vector mouse-wheel-up-event))
+    '([down]))
+  "*Key sequences to use for modal cycling to the next candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-modal-cycle-down-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-down-action-keys ; `C-down', `C-wheel-down'
+  (if (boundp 'mouse-wheel-up-event)    ; Emacs 22+
+      (list
+       [C-down]
+       (vector nil (list 'control
+                         mouse-wheel-up-event))
+       (vector (list 'control
+                     mouse-wheel-up-event)))
+    '([C-down]))
+  "*Keys for modal completion to cycle next and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-modal-cycle-down-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-down-alt-action-keys ; `C-S-down', `C-S-wheel-down'
+  (if (boundp 'mouse-wheel-up-event)    ;Emacs22+
+      (list
+       [C-S-down]
+       (vector nil (list 'control 'shift
+                         mouse-wheel-up-event))
+       (vector (list 'control 'shift
+                     mouse-wheel-up-event)))
+    '([C-S-down]))
+  "*Keys for modal completion to cycle next and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-down-help-keys ; `C-M-down', `C-M-wheel-down'
+  (if (boundp 'mouse-wheel-up-event)    ; Emacs 22+
+      (list
+       [(control meta down)]
+       (vector nil (list 'control 'meta
+                         mouse-wheel-up-event))
+       (vector (list 'control 'meta
+                     mouse-wheel-up-event)))
+    '([(control meta down)]))
+  "*Keys for modal completion to cycle next and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-up-keys   ; `up', `wheel-up'
+  (if (boundp 'mouse-wheel-down-event)  ; Emacs 22+
+      (list
+       [up]
+       (vector nil mouse-wheel-down-event)
+       (vector mouse-wheel-down-event))
+    '([up]))
+  "*Key sequences to use for modal cycling to the previous candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-modal-cycle-up-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-up-action-keys ; `C-up', `C-wheel-up'
+  (if (boundp 'mouse-wheel-down-event)  ; Emacs 22+
+      (list
+       [C-up]
+       (vector nil (list 'control
+                         mouse-wheel-down-event))
+       (vector (list 'control
+                     mouse-wheel-down-event)))
+    '([C-up]))
+  "*Keys for modal completion to cycle previous and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-modal-cycle-up-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-up-alt-action-keys ; `C-S-up', `C-S-wheel-up'
+  (if (boundp 'mouse-wheel-down-event)  ; Emacs 22+
+      (list
+       [C-S-up]
+       (vector nil (list 'control 'shift
+                         mouse-wheel-down-event))
+       (vector (list 'control 'shift
+                     mouse-wheel-down-event)))
+    '([C-S-up]))
+  "*Keys for modal completion to cycle previous and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-modal-cycle-up-help-keys ; `C-M-up', `C-M-wheel-up'
+  (if (boundp 'mouse-wheel-down-event)  ; Emacs 22+
+      (list
+       [(control meta up)]
+       (vector nil (list 'control 'meta
+                         mouse-wheel-down-event))
+       (vector (list 'control 'meta
+                     mouse-wheel-down-event)))
+    '([(control meta up)]))
+  "*Keys for modal completion to cycle previous and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-no-match-hook nil
+  "*List of hook functions run during completion when there are no matches."
+  :type 'hook :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-option-type-prefix-arg-list '(direct inherit inherit-or-value direct-or-value
+                                                inherit-or-regexp direct-or-regexp)
+  "*Symbols controlling prefix args for `icicle-describe-option-of-type'.
+A list of six symbols taken from this list:
+
+  direct            inherit             inherit-or-value
+  direct-or-value   inherit-or-regexp   direct-or-regexp
+
+Choose the order you like.  The list members map, in order left to
+right, to these prefix argument keys:
+
+ `C-u C-u'           `C-0'            `C-u'
+ `C-9' (positive)    no prefix arg    `C--' (negative)
+
+For the meanings of the symbols, see the doc string of
+`icicle-describe-option-of-type', which describes the default
+prefix-argument bindings for the command."
+  :type '(list symbol symbol symbol symbol symbol symbol) :group 'Icicles-Key-Bindings)
+
+(when (> emacs-major-version 22)
+  (defcustom icicle-populate-interactive-history-flag nil
+    "*Non-nil means populate `icicle-interactive-history'.
+That means add commands invoked interactively to that history, for use
+during completion by `C-M-pause'.
+
+After you change the value of this option, toggle Icicle mode off,
+then on again, for the change to take effect in the same session.
+
+Be aware that this history can become quite long.
+
+Furthermore, there is an Emacs bug (#3984) that causes interactiveness
+tests (`interactive-p' and `called-interactively-p') to fail, whenever
+`call-interactively' is advised (which is how Icicles implements this
+feature)."
+    :type 'boolean :group 'Icicles-Miscellaneous))
+
+;;;###autoload
+(defcustom icicle-pp-eval-expression-print-length nil
+  "*Value for `print-length' while printing value in `pp-eval-expression'.
+A value of nil means no limit."
+  :type '(choice (const :tag "No Limit" nil) integer) :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-pp-eval-expression-print-level nil
+  "*Value for `print-level' while printing value in `pp-eval-expression'.
+A value of nil means no limit."
+  :type '(choice (const :tag "No Limit" nil) integer) :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-prefix-complete-keys '([tab] [(control ?i)]) ; `C-i' is `TAB'.
+  "*Key sequences to use for `icicle-prefix-complete'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-complete-no-display-keys '([(control meta tab)]) ; `C-M-TAB'
+  "*Key sequences to use for `icicle-prefix-complete-no-display'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-next-keys '([end]) ; `end'
+  "*Key sequences for prefix completion to cycle to the next candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-prefix-cycle-next-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-next-action-keys '([C-end]) ; `C-end'
+  "*Keys for prefix completion to cycle next and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-prefix-cycle-next-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-next-alt-action-keys '([C-S-end]) ; `C-S-end'
+  "*Keys for prefix completion to cycle next and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-next-help-keys '([(control meta end)]) ; `C-M-end'
+  "*Keys for prefix completion to cycle next and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-previous-keys '([home]) ; `home'
+  "*Key sequences for prefix completion to cycle to the previous candidate.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-prefix-cycle-previous-action-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-previous-action-keys '([C-home]) ; `C-home'
+  "*Keys for prefix completion to cycle previous and perform action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Option `icicle-use-C-for-actions-flag' swaps these keys with
+`icicle-prefix-cycle-previous-keys'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-previous-alt-action-keys '([C-S-home]) ; `C-S-home'
+  "*Keys for prefix completion to cycle previous and perform alt action.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-prefix-cycle-previous-help-keys '([(control meta home)]) ; `C-M-home'
+  "*Keys for prefix completion to cycle previous and show candidate help.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-previous-candidate-keys '([S-tab] [S-iso-lefttab]) ; `S-TAB'
+  ;; $$$$$ The following should be sufficient, but some Emacs 22+ libraries, such as `info.el',
+  ;; are brain-dead and explicitly bind both `backtab' and `S-tab'.  I filed Emacs bug #1281.
+  ;;   (if (> emacs-major-version 21)
+  ;;       '([backtab])
+  ;;     '([S-tab] [S-iso-lefttab]))
+  "*Key sequences to use for `icicle-move-to-previous-completion'.
+In buffer `*Completions*', this moves backward among candidates.
+
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards - for example, `S-tab' and `S-iso-lefttab'."
+;; In Emacs 22 and later, `backtab' is the canonical key that represents
+;; both `S-tab' and `S-iso-lefttab', so that is used in the default
+;; value.  If, for some reason, `backtab' is not being translated to
+;; `S-tab' and `S-iso-lefttab' on your platform, you might want to
+;; customize the value to ([S-tab] [S-iso-lefttab]).  And if your Emacs
+;; version is 22 or later, please file an Emacs bug about the lack of
+;; translation.
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-quote-shell-file-name-flag t
+  "*Non-nil means to double-quote the file name that starts a shell command.
+This is used by `icicle-read-shell-command-completing'.
+
+If this is nil, then Emacs commands such as `M-!' will not quote a
+shell-command file name such as `c:/Program Files/My Dir/mycmd.exe'.
+In that case, a shell such as `bash' fails for a shell command such as
+`c:/Program Files/My Dir/mycmd.exe arg1 arg2 &', because it interprets
+only `c:/Program' as the shell command.  That is, it interprets the
+space characters in the file name as separators.  If this is non-nil,
+then input such as `c:/Program Files/My Dir/mycmd.exe arg1 arg2 &' is
+passed to the shell as
+`\"c:/Program Files/My Dir/mycmd.exe\" arg1 arg2 &'.
+
+See the doc string of `icicle-quote-file-name-part-of-cmd' for
+information about the characters that, like SPC, lead to quoting."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-read+insert-file-name-keys '([(control meta shift ?f)]) ; `C-M-S-f'
+  "*Key sequences to invoke `icicle-read+insert-file-name'.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-regexp-quote-flag nil ; Toggle with `C-`'.
+  "*Non-nil means special characters in regexps are escaped.
+This means that no characters are recognized as special: they match
+themselves.  This turns apropos completion into simple substring
+completion.  It also turns Icicles searching into literal searching.
+You can toggle this option from the minibuffer at any
+time using `C-`'."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-regexp-search-ring-max (if (boundp 'most-positive-fixnum)
+                                             (/ most-positive-fixnum 10)
+                                           13421772) ; 1/10 of `most-positive-fixnum' on Windows.
+  "*Icicles version of `regexp-search-ring-max'."
+  :type 'integer :group 'Icicles-Searching)
+
+;; You can use `icicle-increment-color-value' in place of `icicle-increment-color-hue', if you
+;; prefer highlighting background to be slightly darker instead of a slightly different hue.
+;;
+;;;###autoload
+(defcustom icicle-region-background
+  (if (featurep 'hexrgb)
+      (let* ((bg   (or (and (boundp '1on1-active-minibuffer-frame-background)
+                            1on1-active-minibuffer-frame-background) ; In `oneonone.el'.
+                       (let ((frame-bg  (cdr (assq 'background-color (frame-parameters)))))
+                         (when (member frame-bg '(nil unspecified "unspecified-bg"))
+                           (setq frame-bg  (if (eq (frame-parameter nil 'background-mode) 'dark)
+                                               "Black"
+                                             "White")))
+                         (and frame-bg (x-color-defined-p frame-bg) frame-bg))
+                       (face-background 'region)))
+             (sat  (condition-case nil (hexrgb-saturation bg) (error nil))))
+        (if sat
+            (if (hexrgb-approx-equal sat 0.0)
+                (icicle-increment-color-value
+                 bg                     ; Grayscale - change bg value slightly.
+                 (if (eq (frame-parameter nil 'background-mode) 'dark) 20 -10))
+              (icicle-increment-color-hue bg 24)) ; Color - change bg hue slightly.
+          (face-background 'region)))
+    (face-background 'region))          ; Use normal region background.
+  "*Background color to use for the region during minibuffer cycling.
+This has no effect if `icicle-change-region-background-flag' is nil.
+If you do not define this explicitly, and if you have loaded library
+`hexrgb.el' (recommended), then this color will be slightly
+different from your frame background.  This still lets you notice the
+region, but it makes the region less conspicuous, so you can more
+easily read your minibuffer input."
+  :type (if (and (require 'wid-edit nil t) (get 'color 'widget-type)) 'color 'string)
+  :group 'Icicles-Minibuffer-Display)
+
+;;;###autoload
+(defcustom icicle-require-match-flag nil
+  "*Control REQUIRE-MATCH arg to `completing-read' and `read-file-name'.
+The possible values are as follows:
+- nil means this option imposes nothing on completion;
+  the REQUIRE-MATCH argument provided to the function governs behavior
+- `no-match-required' means the same as a nil value for REQUIRE-MATCH
+- `partial-match-ok' means the same as a t value for REQUIRE-MATCH
+- `full-match-required' means the same as a non-nil, non-t value for
+  REQUIRE-MATCH
+
+Note: This option is provided mainly for use (binding) in
+`icicle-define-command' and `icicle-define-file-command'.
+You probably do not want to set this globally, but you can."
+  :type '(choice
+          (const :tag "Do not impose any match behavior"   nil)
+          (const :tag "Do not require a match"             no-match-required)
+          (const :tag "Require a partial match, with RET"  partial-match-ok)
+          (const :tag "Require a full match"               full-match-required))
+  :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-saved-completion-sets nil
+  "*Completion sets available for `icicle-candidate-set-retrieve'.
+The form is ((SET-NAME . CACHE-FILE-NAME)...), where SET-NAME is the
+name of a set of completion candidates and CACHE-FILE-NAME is the
+absolute name of the cache file that contains those candidates.
+You normally do not customize this directly, statically.
+Instead, you add or remove sets using commands
+`icicle-add/update-saved-completion-set' and
+`icicle-remove-saved-completion-set'."
+  :type '(repeat (cons string file)) :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-search-cleanup-flag t
+  "*Controls whether to remove highlighting after a search.
+If this is nil, highlighting can be removed manually with
+`\\[icicle-search-highlight-cleanup]'.
+
+You can toggle this option from the minibuffer during Icicles
+search (e.g., `C-c`') using `C-.'."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-from-isearch-keys '([S-tab] [S-iso-lefttab]) ; `S-TAB'
+  ;; $$$$$ The following should be sufficient, but some Emacs 22+ libraries, such as `info.el',
+  ;; are brain-dead and explicitly bind both `backtab' and `S-tab'.  I filed Emacs bug #1281.
+  ;;   (if (> emacs-major-version 21)
+  ;;       '([backtab])
+  ;;     '([S-tab] [S-iso-lefttab]))
+  "*Key sequences to use to start `icicle-search' from Isearch.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards - for example, `S-tab' and `S-iso-lefttab'."
+;; In Emacs 22 and later, `backtab' is the canonical key that represents
+;; both `S-tab' and `S-iso-lefttab', so that is used in the default
+;; value.  If, for some reason, `backtab' is not being translated to
+;; `S-tab' and `S-iso-lefttab' on your platform, you might want to
+;; customize the value to ([S-tab] [S-iso-lefttab]).  And if your Emacs
+;; version is 22 or later, please file an Emacs bug about the lack of
+;; translation.
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-search-highlight-all-current-flag nil ; Toggle with `C-^'.
+  "*Non-nil means highlight input match in each context search hit.
+Setting this to non-nil can impact performance negatively, because the
+highlighting is updated with each input change.  You can toggle this
+option from the minibuffer during Icicles search (e.g., `C-c`') using
+`C-^'."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-highlight-context-levels-flag t
+  "*Non-nil means highlight 1-8 context levels, within the search context.
+Level highlighting is done only when this is non-nil and a subgroup is
+not used as the search context, that is, the context corresponds to
+the entire search regexp."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-highlight-threshold 100000
+  "*Max number of context search hits to highlight at once.
+This highlighting uses face `icicle-search-main-regexp-others'."
+  :type 'integer :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-hook nil
+  "*List of functions run by `icicle-search' after you visit a search hit.
+See `run-hooks'."
+  :type 'hook :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-replace-common-match-flag t ; Toggle with `M-;'.
+  "*Non-nil means to replace the expanded common match of your input.
+This has no effect if either
+`icicle-search-highlight-all-current-flag' or
+`icicle-expand-input-to-common-match-flag' is nil.
+You can toggle those options from the minibuffer using `C-^' and
+`C-|', respectively.  You can toggle
+`icicle-search-replace-common-match-flag' using `M-;'."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-replace-literally-flag nil ; Toggle with `M-`'.
+  "*Non-nil means to treat replacement text literally.
+Otherwise (nil), interpret `\\' specially in replacement text, as in
+the LITERAL argument to `replace-match'.
+
+You can use `M-`' to toggle this at any time during Icicles search."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-replace-whole-candidate-flag t ; Toggle with `C-,'.
+  "*Non-nil means replacement during search replaces the entire search hit.
+Otherwise (nil), replace only what matches your current input.
+
+You can use `C-,' to toggle this at any time during Icicles search."
+  :type 'boolean :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-ring-max (if (boundp 'most-positive-fixnum)
+                                             (/ most-positive-fixnum 10)
+                                           13421772) ; 1/10 of `most-positive-fixnum' on Windows.
+  "*Icicles version of `search-ring-max'."
+  :type 'integer :group 'Icicles-Searching)
+
+;;;###autoload
+(defcustom icicle-search-whole-word-flag nil ; Toggle with `M-q'.
+  "*Non-nil means that `icicle-search' looks for a whole word.
+You can use `M-q' to toggle this at any time during Icicles search;
+the new value takes effect for the next complete search.
+
+Whole-word searching here means that matches can contain embedded
+strings of non word-constituent chars (they are skipped over, when
+matching, included in the match), and any leading or trailing
+word-constituent chars in the search string are dropped (ignored for
+matching, not included in the match).  This means, for instance, that
+you can match `foo-bar' as a word, even in contexts (such as Emacs
+Lisp) where `-' is not a word-constituent character.  Similarly, you
+can include embedded whitespace in a \"word\", e.g., `foo bar'."
+  :type 'boolean :group 'Icicles-Searching)
+
+;; Based more or less on `shell-dynamic-complete-as-command'.
+;; Must be before `icicle-shell-command-candidates-cache'.
+(defun icicle-compute-shell-command-candidates ()
+  "Compute shell command candidates from search path, and return them.
+The candidates are the executable files in your search path or, if
+`shell-completion-execonly' is nil, all files in your search path."
+  (require 'shell)                      ; `shell-completion-execonly'
+  (message "Finding commands in search path...")
+  (let* ((filenondir         "")
+         (path-dirs          (cdr (reverse exec-path)))
+         (cwd                (file-name-as-directory (expand-file-name default-directory)))
+         (ignored-extensions (and comint-completion-fignore
+                                  (mapconcat #'(lambda (x) (concat (regexp-quote x) "$"))
+                                             comint-completion-fignore "\\|")))
+         (dir                "")
+         (comps-in-dir       ())
+         (file               "")
+         (abs-file-name      "")
+         (completions        ()))
+    ;; Go through each dir in the search path, finding completions.
+    (while path-dirs
+      (setq dir           (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
+            comps-in-dir  (and (file-accessible-directory-p dir)
+                               (file-name-all-completions filenondir dir)))
+      ;; Go  see whether it should be used.
+      (while comps-in-dir
+        (setq file           (car comps-in-dir)
+              abs-file-name  (concat dir file))
+        (when (and (not (member file completions))
+                   (not (and ignored-extensions (string-match ignored-extensions file)))
+                   (or (string-equal dir cwd) (not (file-directory-p abs-file-name)))
+                   (or (null shell-completion-execonly) (file-executable-p abs-file-name)))
+          (setq completions  (cons file completions)))
+        (setq comps-in-dir  (cdr comps-in-dir)))
+      (setq path-dirs  (cdr path-dirs)))
+    completions))
+
+;;;###autoload
+(defcustom icicle-shell-command-candidates-cache (and (eq icicle-guess-commands-in-path 'load)
+                                                      (icicle-compute-shell-command-candidates))
+  "*Cache for shell command candidates.
+You typically do not need to customize this option.
+It is an option mainly to persist its value.
+See `icicle-guess-commands-in-path'."
+  :type '(repeat sexp) :group 'Icicles-Miscellaneous)
+
+(if (and (fboundp 'defvaralias) (boundp 'completion-show-help))
+    (defvaralias 'icicle-show-Completions-help-flag 'completion-show-help)
+  (defcustom icicle-show-Completions-help-flag t
+    "*Non-nil means display help lines at the top of buffer `*Completions*'."
+    :type 'boolean :group 'Icicles-Completions-Display))
+
+;;;###autoload
+(defcustom icicle-show-Completions-initially-flag nil
+  "*Non-nil means to show buffer `*Completions*' even without user input.
+nil means that `*Completions*' is shown upon demand, via `TAB' or
+`S-TAB'.
+
+For an alternative but similar behavior to using non-nil for
+`icicle-show-Completions-initially-flag', you can set option
+`icicle-incremental-completion-flag' to a value that is neither nil
+nor t.  That displays buffer `*Completions*' as soon as you type or
+delete input, but not initially."
+  :type 'boolean :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-show-multi-completion-flag t
+  "*Non-nil means to show completion candidates as multi-completions.
+This has an effect only where multi-completion is available.
+Also, some commands, such as `icicle-locate-file', use a prefix arg to
+determine whether to show multi-completions.  Such commands generally
+ignore this option.
+
+A typical example of showing multi-completions is adding buffer names
+to candidates to show which buffer they are associated with.  Some
+commands, such as `icicle-search', append the name of the associated
+buffer, highlighted, to the normal completion candidate.  This lets
+you easily see which buffer the candidate applies to.  Also, the
+buffer name is part of the candidate, so you can match against it.
+
+Note: Even when the option value is nil, you can use `C-M-mouse-2' and
+so on to see information about a candidate.  This information
+typically includes whatever a non-nil value of the option would have
+shown.
+
+You can toggle this option from the minibuffer using `M-m'.  The new
+value takes effect after you exit the minibuffer (i.e., for the next
+command)."
+  :type 'boolean :group 'Icicles-Completions-Display)
+
+;; This is similar to `bmkp-sort-comparer'.
+;;;###autoload
+(defcustom icicle-sort-comparer 'icicle-case-string-less-p ; Cycle with `C-,'.
+  "*Predicate or predicates for sorting (comparing) two items.
+Used in particular to sort completion candidates.  In that case, this
+determines the order of candidates when cycling and their order in
+buffer `*Completions*'.
+
+When `icicle-cycle-into-subdirs-flag' is non-nil, you might want to
+use a function such as `icicle-dirs-last-p' for this option, to
+prevent cycling into subdirectories depth first.  Command
+`icicle-sort-by-directories-last' does that.
+
+You can cycle completion sort orders at any time using `C-,' in the
+minibuffer.
+
+Although this is a user option, it may be changed by program
+locally, for use in particular contexts.  In particular, you can bind
+this to nil in an Emacs-Lisp function, to inhibit sorting in that
+context.
+
+Various sorting commands change the value of this option dynamically
+\(but they do not save the changed value).
+
+The value must be one of the following:
+
+* nil, meaning do not sort
+
+* a predicate that takes two items as args
+
+* a list of the form ((PRED...) FINAL-PRED), where each PRED and
+  FINAL-PRED are binary predicates
+
+If the value is a non-empty list, then each PRED is tried in turn
+until one returns a non-nil value.  In that case, the result is the
+car of that value.  If no non-nil value is returned by any PRED, then
+FINAL-PRED is used and its value is the result.
+
+Each PRED should return `(t)' for true, `(nil)' for false, or nil for
+undecided.  A nil value means that the next PRED decides (or
+FINAL-PRED, if there is no next PRED).
+
+Thus, a PRED is a special kind of predicate that indicates either a
+boolean value (as a singleton list) or \"I cannot decide - let the
+next guy else decide\".  (Essentially, each PRED is a hook function
+that is run using `run-hook-with-args-until-success'.)
+
+Examples:
+
+ nil           - No sorting.
+
+ string-lessp  - Single predicate that returns nil or non-nil.
+
+ ((p1 p2))     - Two predicates `p1' and `p2', which each return
+                 (t) for true, (nil) for false, or nil for undecided.
+
+ ((p1 p2) string-lessp)
+               - Same as previous, except if both `p1' and `p2' return
+                 nil, then the return value of `string-lessp' is used.
+
+Note that these two values are generally equivalent, in terms of their
+effect (*):
+
+ ((p1 p2))
+ ((p1) p2-plain) where p2-plain is (icicle-make-plain-predicate p2)
+
+Likewise, these three values generally act equivalently:
+
+ ((p1))
+ (() p1-plain)
+ p1-plain        where p1-plain is (icicle-make-plain-predicate p1)
+
+The PRED form lets you easily combine predicates: use `p1' unless it
+cannot decide, in which case try `p2', and so on.  The value ((p2 p1))
+tries the predicates in the opposite order: first `p2', then `p1' if
+`p2' returns nil.
+
+Using a single predicate or FINAL-PRED makes it easy to reuse an
+existing predicate that returns nil or non-nil.
+
+You can also convert a PRED-type predicate (which returns (t), (nil),
+or nil) into an ordinary predicate, by using function
+`icicle-make-plain-predicate'.  That lets you reuse elsewhere, as
+ordinary predicates, any PRED-type predicates you define.
+
+Note: As a convention, predefined Icicles PRED-type predicate names
+have the suffix `-cp' (for \"component predicate\") instead of `-p'."
+  ;; We don't bother to define a `icicle-reverse-multi-sort-order'
+  ;; analogous to `bmkp-reverse-multi-sort-order'.  If we did, the doc
+  ;; string would need to be updated to say what the doc string of
+  ;; `bmkp-sort-comparer' says about `bmkp-reverse-multi-sort-order'.
+  :type '(choice
+          (const    :tag "None (do not sort)" nil)
+          (function :tag "Sorting Predicate")
+          (list     :tag "Sorting Multi-Predicate"
+           (repeat (function :tag "Component Predicate"))
+           (choice
+            (const    :tag "None" nil)
+            (function :tag "Final Predicate"))))
+  :group 'Icicles-Matching :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-buffer-configs
+  `(("All" nil nil nil nil ,icicle-sort-comparer)
+    ("Files" nil nil (lambda (bufname) (buffer-file-name (get-buffer bufname))) nil
+     ,icicle-sort-comparer)
+    ("Files and Scratch" nil nil (lambda (bufname) (buffer-file-name (get-buffer bufname)))
+     ("*scratch*") ,icicle-sort-comparer)
+    ("All, *...* Buffers Last" nil nil nil nil icicle-buffer-sort-*...*-last))
+  "*List of option configurations available for `icicle-buffer-config'.
+The form is (CONFIG...), where CONFIG is a list of these items:
+
+ - Configuration name                    (string)
+ - `icicle-buffer-match-regexp' value    (regexp string)
+ - `icicle-buffer-no-match-regexp' value (regexp string)
+ - `icicle-buffer-predicate' value       (function)
+ - `icicle-buffer-extras' value          (list of strings)
+ - `icicle-buffer-sort' value            (function)
+
+A configuration describes which buffer names are displayed during
+completion and their order."
+  :type '(repeat (list
+                  string                ; Configuration name
+                  (choice (const :tag "None" nil) (string :tag "Match regexp"))
+                  (choice (const :tag "None" nil) (string :tag "No-match regexp"))
+                  (choice (const :tag "None" nil) (function :tag "Predicate")) ; Predicate
+                  (choice (const :tag "None" nil) (repeat (string :tag "Extra buffer")))
+                  (choice (const :tag "None" nil) (function :tag "Sort function"))))
+  :group 'Icicles-Buffers)
+
+(defun icicle-buffer-sort-*...*-last (buf1 buf2)
+  "Return non-nil if BUF1 is `string<' BUF2 or only BUF2 starts with \"*\"."
+  (let ((b1  (if completion-ignore-case (downcase buf1) buf1))
+        (b2  (if completion-ignore-case (downcase buf2) buf2)))
+    (if (string-match "^\\*" b1)
+        (and (string-match "^\\*" b2) (string< b1 b2))
+      (or (string-match "^\\*" b2) (string< b1 b2)))))
+
+(when (> emacs-major-version 20)
+  (defcustom icicle-sort-orders-alist ()
+    "*Alist of available sort functions.
+This is a pseudo option - you probably do NOT want to customize this.
+Instead, use macro `icicle-define-sort-command' to define a new sort
+function and automatically add it to this list.
+
+Each alist element has the form (SORT-ORDER . COMPARER):
+
+ SORT-ORDER is a short string or symbol describing the sort order.
+ Examples: \"by date\", \"alphabetically\", \"directories first\".
+
+ COMPARER compares two items.  It must be acceptable as a value of
+ `icicle-sort-comparer'."
+    :type '(alist
+            :key-type (choice :tag "Sort order" string symbol)
+            :value-type (choice
+                         (const    :tag "None (do not sort)" nil)
+                         (function :tag "Sorting Predicate")
+                         (list     :tag "Sorting Multi-Predicate"
+                          (repeat (function :tag "Component Predicate"))
+                          (choice
+                           (const    :tag "None" nil)
+                           (function :tag "Final Predicate")))))
+    :group 'Icicles-Completions-Display :group 'Icicles-Matching))
+
+(unless (> emacs-major-version 20)      ; Emacs 20: custom type `alist' doesn't exist.
+  (defcustom icicle-sort-orders-alist ()
+    "*Alist of available sort functions.
+This is a pseudo option - you probably do NOT want to customize this.
+Instead, use macro `icicle-define-sort-command' to define a new sort
+function and automatically add it to this list.
+
+Each alist element has the form (SORT-ORDER . COMPARER):
+
+ SORT-ORDER is a short string or symbol describing the sort order.
+ Examples: \"by date\", \"alphabetically\", \"directories first\".
+
+ COMPARER compares two items.  It must be acceptable as a value of
+ `icicle-sort-comparer'."
+    :type '(repeat
+            (cons
+             (choice :tag "Sort order" string symbol)
+             (choice
+              (const    :tag "None (do not sort)" nil)
+              (function :tag "Sorting Predicate")
+              (list     :tag "Sorting Multi-Predicate"
+               (repeat (function :tag "Component Predicate"))
+               (choice
+                (const    :tag "None" nil)
+                (function :tag "Final Predicate"))))))
+    :group 'Icicles-Completions-Display :group 'Icicles-Matching))
+
+;;;###autoload
+(defcustom icicle-special-candidate-regexp nil
+  "*Regexp to match special completion candidates, or nil to do nothing.
+The candidates are highlighted in buffer `*Completions*' using face
+`icicle-special-candidate'."
+  :type '(choice (const :tag "None" nil) regexp) :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-S-TAB-completion-methods-alist ; Cycle with `M-('.
+  `(("apropos" . string-match)
+    ("scatter" . icicle-scatter-match)
+    ,@(and (require 'fuzzy nil t)       ; `fuzzy.el', part of library Autocomplete.
+           '(("Jaro-Winkler" . fuzzy-match)))
+    ,@(and (require 'levenshtein nil t)
+           '(("Levenshtein" . icicle-levenshtein-match)
+             ("Levenshtein strict" . icicle-levenshtein-strict-match))))
+  "*Alist of completion methods used by `S-TAB'.
+Each element has the form (NAME . FUNCTION), where NAME is a string
+name and FUNCTION is the completion match function.  NAME is used in
+messages to indicate the type of completion matching.
+
+By default, `S-TAB' is the key for this completion. The actual keys
+used are the value of option `icicle-apropos-complete-keys'.
+
+See also options `icicle-TAB-completion-methods' and
+`icicle-S-TAB-completion-methods-per-command'."
+  :type '(alist
+          :key-type   (string :tag "Name used in messages")
+          :value-type (symbol :tag "Completion matching function"))
+  :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-S-TAB-completion-methods-per-command ()
+  "*Alist of commands and their available S-TAB completion methods.
+Each command is advised so that when invoked only the specified S-TAB
+completion methods are available for it when you use `M-('.  (This
+makes sense only for commands that read input from the minibuffer.)
+
+This option gives you greater control over which completion methods
+are available.  See also option
+`icicle-TAB-completion-methods-per-command', which does the same thing
+for `TAB' completion.  The default behavior is provided by option
+`icicle-S-TAB-completion-methods-alist' (and
+`icicle-TAB-completion-methods' for `TAB').
+
+NOTE: If you remove an entry from this list, that does NOT remove the
+advice for that command.  To do that you will need to explicitly
+invoke command `icicle-set-S-TAB-methods-for-command' using a negative
+prefix argument (or else start a new Emacs session)."
+  :type (let ((methods  ()))
+          (when (require 'levenshtein nil t)
+            (push '(const :tag "Levenshtein strict"
+                    ("Levenshtein strict" . icicle-levenshtein-strict-match))
+                  methods)
+            (push '(const :tag "Levenshtein" ("Levenshtein" . icicle-levenshtein-match))
+                  methods))
+          (when (require 'fuzzy nil t) ; `fuzzy.el', part of library Autocomplete.
+            (push '(const :tag "Jaro-Winkler" ("Jaro-Winkler" . fuzzy-match)) methods))
+          (push '(const :tag "scatter" ("scatter" . icicle-scatter-match)) methods)
+          (push '(const :tag "apropos" ("apropos" . string-match)) methods)
+          `(alist
+            :key-type   (restricted-sexp
+                         :tag "Command"
+                         ;; Use `symbolp' instead of `commandp', in case the library
+                         ;; defining the command is not yet loaded.
+                         :match-alternatives (symbolp) :value ignore)
+            :value-type (repeat :tag "S-TAB completion methods" (choice ,@methods))))
+  :set #'(lambda (sym val)
+           (custom-set-default sym val)
+           (when (fboundp 'icicle-set-S-TAB-methods-for-command)
+             (dolist (entry  val)
+               (icicle-set-S-TAB-methods-for-command (car entry) (cdr entry)))))
+  :initialize #'custom-initialize-default
+  :group 'Icicles-matching)
+            
+;;;###autoload
+(defcustom icicle-swank-prefix-length 1
+  "*Length (chars) of symbol prefix that much match, for swank completion."
+  :type 'integer :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-swank-timeout 3000
+  "*Number of msec before swank (fuzzy symbol) completion gives up."
+  :type 'integer :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-TAB-completion-methods ; Cycle with `C-('.
+  (let ((methods  ()))
+    (when (require 'el-swank-fuzzy nil t) (push 'swank        methods))
+    (when (require 'fuzzy-match nil t)    (push 'fuzzy        methods))
+    (when (boundp 'completion-styles)     (push 'vanilla      methods))
+    (push 'basic methods)
+    methods)
+  "*List of completion methods to use for \
+`\\\\[icicle-prefix-complete]'.
+The first method in the list is the default method.
+
+The available methods can include these:
+
+1. `basic'
+2. `vanilla' (provided you have Emacs 23 or later)
+3. `fuzzy'   (provided you have library `fuzzy-match.el')
+4. `swank'   (provided you have library `el-swank-fuzzy.el')
+
+1. Basic completion means ordinary prefix completion. It is the
+`basic' completion style of Emacs 23 or later, and it is essentially
+the completion style prior to Emacs 23 (Emacs 22 completion was
+slightly different - see Emacs 23 option `custom-styles' for more
+info).
+
+2. Vanilla completion respects option `completion-styles' (new in
+Emacs 23), so that `TAB' behaves similarly in Icicles to what it does
+in vanilla Emacs.  The vanilla method also completes environment
+variables during file-name completion and in shell commands.  The
+non-vanilla methods do not complete environment variables, but the
+variables are expanded to their values when you hit `RET'.
+
+3. Fuzzy completion is a form of prefix completion in which matching
+finds the candidates that have the most characters in common with your
+input, in the same order, and with a minimum of non-matching
+characters.  It can skip over non-matching characters, as long as the
+number of characters skipped in the candidate is less that those
+following them that match.  After the matching candidates are found,
+they are sorted by skip length and then candidate length.
+
+Fuzzy completion is described in detail in the commentary of library
+`fuzzy-match.el'.  There is no fuzzy completion of file names - fuzzy
+completion is the same as basic for file names.  Fuzzy completion is
+always case-sensitive.
+
+4. Swank completion in Icicles is the same as fuzzy completion, except
+regarding symbols.  That is, swank completion per se applies only to
+symbols.  Symbols are completed using the algorithm of library
+`el-swank-fuzzy.el'.
+
+Icicles options `icicle-swank-timeout' and
+`icicle-swank-prefix-length' give you some control over the behavior.
+When the `TAB' completion method is `swank', you can use `C-x 1'
+\(`icicle-doremi-increment-swank-timeout+') and `C-x 2'
+\(`icicle-doremi-increment-swank-prefix-length+') in the minibuffer to
+increment these options on the fly using the arrow keys `up' and
+`down'.
+
+Swank symbol completion uses heuristics that relate to supposedly
+typical patterns found in symbol names.  It also uses a timeout that
+can limit the number of matches.  It is generally quite a bit slower
+than fuzzy completion, and it sometimes does not provide all
+candidates that you might think should match, even when all of your
+input is a prefix (or even when it is already complete!).  If swank
+completion produces no match when you think it should, remember that
+you can use `\\[icicle-next-TAB-completion-method]' on the fly to \
+change the completion method.
+
+
+If you do not customize `icicle-TAB-completion-methods', then the
+default value (that is, the available `TAB' completion methods) will
+reflect your current Emacs version and whether you have loaded
+libraries `fuzzy-match.el' and `el-swank-fuzzy.el'.
+
+By default, `TAB' is the key for this completion. The actual keys
+used are the value of option `icicle-prefix-complete-keys'.
+
+See also options `icicle-TAB-completion-methods-per-command'
+`icicle-S-TAB-completion-methods-alist'."
+  :type (let ((methods  ()))
+          (when (require 'el-swank-fuzzy nil t)
+            (push '(const :tag "Swank (Fuzzy Symbol)" swank) methods))
+          (when (require 'fuzzy-match nil t)
+            (push '(const :tag "Fuzzy" fuzzy) methods))
+          (when (boundp 'completion-styles)
+            (push '(const :tag "Vanilla `completion-styles'" vanilla) methods))
+          (push '(const :tag "Basic" basic) methods)
+          `(repeat (choice ,@methods)))
+  :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-TAB-completion-methods-per-command ()
+  "*Alist of commands and their available TAB completion methods.
+Each command is advised so that when invoked only the specified TAB
+completion methods are available for it when you use `C-('.  (This
+makes sense only for commands that read input from the minibuffer.)
+
+This option gives you greater control over which completion methods
+are available.  See also option
+`icicle-S-TAB-completion-methods-per-command', which does the same
+thing for `S-TAB' completion.  The default behavior is provided by
+option `icicle-TAB-completion-methods' (and
+`icicle-S-TAB-completion-methods-alist' for `S-TAB').
+
+NOTE: If you remove an entry from this list, that does NOT remove the
+advice for that command.  To do that you will need to explicitly
+invoke command `icicle-set-TAB-methods-for-command' using a negative
+prefix argument (or else start a new Emacs session)."
+  :type (let ((methods  ()))
+          (when (require 'el-swank-fuzzy nil t)
+            (push '(const :tag "Swank (Fuzzy Symbol)" swank) methods))
+          (when (require 'fuzzy-match nil t)
+            (push '(const :tag "Fuzzy" fuzzy) methods))
+          (when (boundp 'completion-styles)
+            (push '(const :tag "Vanilla `completion-styles'" vanilla) methods))
+          (push '(const :tag "Basic" basic) methods)
+          `(alist
+            :key-type   (restricted-sexp
+                         :tag "Command"
+                         ;; Use `symbolp' instead of `commandp', in case the library
+                         ;; defining the command is not yet loaded.
+                         :match-alternatives (symbolp) :value ignore)
+            :value-type (repeat :tag "TAB completion methods" (choice ,@methods))))
+  :set #'(lambda (sym val)
+           (custom-set-default sym val)
+           (when (fboundp 'icicle-set-TAB-methods-for-command)
+             (dolist (entry  val)
+               (icicle-set-TAB-methods-for-command (car entry) (cdr entry)))))
+  :initialize #'custom-initialize-default
+  :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-TAB-shows-candidates-flag t
+  "*Non-nil means that `TAB' always shows completion candidates.
+Otherwise (nil), follow the standard Emacs behavior of completing to
+the longest common prefix, and only displaying the candidates after a
+second `TAB'.
+
+Actually, the concerned keys are those defined by option
+`icicle-prefix-complete-keys', not necessarily `TAB'."
+  :type 'boolean :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-recenter -4
+  "Argument passed to `recenter' to recenter point in the target window.
+Used during functions such as `icicle-search' when the destination to
+visit would otherwise be off-screen."
+  :type '(choice
+	  (const   :tag "To mid-window" nil)
+	  (integer :tag "On this line number (negative: from bottom)" nil))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-test-for-remote-files-flag t ; Toggle with `C-^'.
+  "*Non-nil means Icicles tests for remote file names.
+A value of nil turns off all handling of remote file names by Tramp,
+including file-name completion.
+
+The testing due to a non-nil value takes a little time, but the test
+result saves time with Tramp handling, and it is used to avoid some
+other costly operations when a file is determined to be remote.  These
+operations are (a) incremental completion and (b) highlighting of the
+part of your current input that does not complete.
+
+Use a nil value only when you are sure that the file names you are
+completing are local.  The effect will be a slight speed increase for
+operations (a) and (b) for local files.
+
+In addition, a nil value has the effect of ignoring the restriction of
+input mismatch highlighting to strict completion.  That is, it treats
+an `icicle-highlight-input-completion-failure' value of
+`explicit-strict' or `implicit-strict' as if it were `implicit'.  The
+assumption here is that you use these highlighting values only to
+avoid the cost of remote file name completion.
+
+You can toggle this option from the minibuffer using `C-^' (except
+during Icicles search)."
+  :initialize (lambda (opt-name val) (set opt-name t))
+  :set #'(lambda (opt-name val)
+           (or (not (require 'tramp nil t))
+               (prog1 (set opt-name (not val))
+                 (icicle-toggle-remote-file-testing))))
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-thing-at-point-functions
+  (progn (or (require 'ffap- nil t) (require 'ffap nil t)) ; Try `ffap-.el' first.
+         (cons
+          `(,(if (fboundp 'non-nil-symbol-name-nearest-point)
+                 'non-nil-symbol-name-nearest-point
+                 (lambda () (symbol-name (symbol-at-point))))
+            ,(if (fboundp 'word-nearest-point)
+                 'word-nearest-point
+                 (lambda () (thing-at-point 'word)))
+            ,@(and (fboundp 'list-nearest-point-as-string) '(list-nearest-point-as-string))
+            ,@(and (fboundp 'list-nearest-point-as-string)
+                   '((lambda () (list-nearest-point-as-string 2))))
+            ,@(and (fboundp 'list-nearest-point-as-string)
+                   '((lambda () (list-nearest-point-as-string 3))))
+            ,@(and (fboundp 'ffap-guesser) '(ffap-guesser))
+            thing-at-point-url-at-point)
+          'forward-word))
+  "*Functions that return a string at or near the cursor when you use `M-.'.
+A cons cell whose car and cdr may each be empty.
+
+The car of the cons cell is a list of functions that grab different
+kinds of strings at or near point.  They are used in sequence by
+command `icicle-insert-string-at-point' (bound to `M-.').  I recommend
+that you also use library `thingatpt+.el', so that `M-.' can take
+advantage of the string-grabbing functions it defines.
+
+The cdr of the cons cell is nil or a function that advances point one
+text thing.  Each time command `icicle-insert-string-at-point' is
+called successively, this is called to grab more things of text (of
+the same kind).  By default, successive words are grabbed.
+
+If either the car or cdr is empty, then the other alone determines the
+behavior of `icicle-insert-string-at-point'.  Otherwise, option
+`icicle-default-thing-insertion' determines whether the car or cdr is
+used by `icicle-insert-string-at-point'.  `C-u' with no number
+reverses the meaning of `icicle-default-thing-insertion'."
+  :type
+  '(cons
+    (choice
+     (repeat (function :tag "Function to grab some text at point and insert it in minibuffer"))
+     (const :tag "No alternative text-grabbing functions" nil))
+    (choice
+     (const :tag "No function to successively grab more text" nil)
+     (function :tag "Function to advance point one text thing")))
+  :group 'Icicles-Miscellaneous)
+
+;; Must be before `icicle-top-level-key-bindings'.
+;;;###autoload
+(define-widget 'icicle-key-definition 'lazy
+  "Key definition type for Icicle mode keys.
+A list of three components: KEY, COMMAND, CONDITION, that represents
+an `icicle-mode-map' binding of COMMAND according to KEY, if CONDITION
+evaluates to non-nil.
+
+KEY is either a key sequence (string or vector) or a command.
+COMMAND is a command.
+CONDITION is a sexp.
+
+If KEY is a command, then the binding represented is its remapping to
+COMMAND."
+  :indent 1 :offset 0 :tag ""           ; $$$$$ "Icicle Mode Key Definition"
+  :type
+  '(list
+    (choice
+     (key-sequence :tag "Key" :value [ignore])
+     ;; Use `symbolp' instead of `commandp', in case the library defining the
+     ;; command is not loaded.
+     (restricted-sexp :tag "Command to remap" :match-alternatives (symbolp) :value ignore))
+     ;; Use `symbolp' instead of `commandp'...
+    (restricted-sexp :tag "Command" :match-alternatives (symbolp) :value ignore)
+    (sexp :tag "Condition")))
+
+;; Must be before `icicle-top-level-key-bindings'.
+(defun icicle-remap (old new map &optional oldmap)
+  "Bind command NEW in MAP to all keys currently bound to OLD.
+If command remapping is available, use that.  Otherwise, bind NEW to
+whatever OLD is bound to in MAP, or in OLDMAP, if provided."
+  (if (fboundp 'command-remapping)
+      (define-key map (vector 'remap old) new) ; Ignore OLDMAP for Emacs 22.
+    (substitute-key-definition old new map oldmap)))
+
+;; Must be before `icicle-top-level-key-bindings'.
+(defun icicle-bind-top-level-commands (&optional defs)
+  "Bind top-level commands for Icicle mode."
+  (unless defs (setq defs  icicle-top-level-key-bindings))
+  (let (key command condition)
+    (dolist (key-def defs)
+      (setq key        (car key-def)
+            command    (cadr key-def)
+            condition  (car (cddr key-def)))
+      (when (eval condition)
+        (if (symbolp key)
+            (icicle-remap key command icicle-mode-map (current-global-map))
+          (define-key icicle-mode-map key command))))))            
+
+;; Must be before `icicle-top-level-key-bindings'.
+;;;###autoload
+(defcustom icicle-yank-function 'yank
+  "*Yank function.  A function that takes a prefix argument.  This
+should be a command that is bound to whatever key you use to yank
+text, whether in Icicle mode or not.  In Icicle mode, command
+`icicle-yank-maybe-completing' calls this function, except when
+`icicle-yank-maybe-completing' is called from the minibuffer or called
+with a negative prefix argument.  `icicle-yank-maybe-completing'
+passes the raw prefix argument to `icicle-yank-function'.
+
+By default (see option `icicle-top-level-key-bindings'), the command
+that is the value of this option is remapped to
+`icicle-yank-maybe-completing' the first time you enter Icicle mode.
+If you customize `icicle-yank-function', then, to take advantage of
+this default remapping behavior, you will need to save your
+customization and then restart Emacs.
+
+Alternatively, you can customize both `icicle-yank-function' and the
+corresponding entry in `icicle-top-level-key-bindings', and then
+toggle Icicle mode off and then back on."
+  :type 'function :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-top-level-key-bindings
+  `((,(kbd "") icicle-switch-to/from-minibuffer    t) ; `pause'
+    (,(kbd "C-c `")   icicle-search-generic               t) ; `C-c `'
+    (,(kbd "C-c $")   icicle-search-word                  t) ; `C-c $'
+    (,(kbd "C-c ^")   icicle-search-keywords              t) ; `C-c ^'
+    (,(kbd "C-c '")   icicle-occur                        t) ; `C-c ''
+    (,(kbd "C-c =")   icicle-imenu                        t) ; `C-c ='
+    (,(kbd "C-c \"")  icicle-search-text-property         t) ; `C-c "'
+    (,(kbd "C-c /")   icicle-complete-thesaurus-entry     t) ; `C-c /'
+    (,(kbd "C-x M-e") icicle-execute-named-keyboard-macro t) ; `C-x M-e'
+    (,(kbd "C-x SPC") icicle-command-abbrev               t) ; `C-x SPC'
+    (,(kbd "C-x 5 o") icicle-select-frame                 t) ; `C-x 5 o'
+    (,(kbd "C-h C-o") icicle-describe-option-of-type      t) ; `C-h C-o'
+    ,@(and (require 'kmacro nil t)      ; (Emacs 22+)
+           `((,(kbd "S-")    icicle-kmacro            t))) ; `S-f4'
+    (abort-recursive-edit           icicle-abort-recursive-edit        t) ; `C-]'
+    (bookmark-jump                  icicle-bookmark                    t) ; `C-x r b'
+    (bookmark-jump-other-window     icicle-bookmark-other-window       t) ; `C-x 4 j j'
+    (bookmark-set                   icicle-bookmark-cmd                t) ; `C-x r m'
+    (minibuffer-keyboard-quit      icicle-abort-recursive-edit ; `C-g' (minibuffer - `delsel.el')
+     (fboundp 'minibuffer-keyboard-quit))
+    (delete-window                  icicle-delete-window               t) ; `C-x 0'
+    (delete-windows-for             icicle-delete-window               t) ; `C-x 0' (`frame-cmds.el')
+    (dired                          icicle-dired                       t) ; `C-x d'
+    (dired-other-window             icicle-dired-other-window          t) ; `C-x 4 d'
+    (exchange-point-and-mark        icicle-exchange-point-and-mark     t) ; `C-x C-x'
+    (execute-extended-command       icicle-execute-extended-command    t) ; `M-x'
+    (find-file                      icicle-file                        t) ; `C-x C-f'
+    (find-file-other-window         icicle-file-other-window           t) ; `C-x 4 f'
+    (find-file-read-only            icicle-find-file-read-only         t) ; `C-x C-r'
+    (find-file-read-only-other-window
+     icicle-find-file-read-only-other-window                           t) ; `C-x 4 r'
+    ;; There are no key bindings in vanilla Emacs for `insert-buffer'.
+    ;; If you use `setup-keys.el', then these are its bindings: `C-S-insert', `M-S-f1'.
+    (insert-buffer                  icicle-insert-buffer               t)
+    (kill-buffer                    icicle-kill-buffer                 t) ; `C-x k'
+    (kill-buffer-and-its-windows    icicle-kill-buffer                 t) ; `C-x k' (`misc-cmds.el')
+    (other-window                 icicle-other-window-or-frame         t) ; `C-x o'
+    (other-window-or-frame        icicle-other-window-or-frame         t) ; `C-x o' (`frame-cmds.el')
+    (pop-global-mark
+     icicle-goto-global-marker-or-pop-global-mark                      t) ; `C-x C-@', `C-x C-SPC'
+    (set-mark-command
+     icicle-goto-marker-or-set-mark-command                            t) ; `C-@', `C-SPC'
+    (switch-to-buffer               icicle-buffer                      t) ; `C-x b'
+    (switch-to-buffer-other-window  icicle-buffer-other-window         t) ; `C-x 4 b'
+    (where-is                       icicle-where-is                    t) ; `C-h w'
+    (,icicle-yank-function          icicle-yank-maybe-completing       t) ; `C-y'
+
+    ;; These are available only if you use library `bookmark+.el'.
+    ;;
+    (,(kbd "C-x j t a a")   icicle-find-file-tagged              (featurep 'bookmark+)) ; `C-x j t a a'
+    (,(kbd "C-x 4 j t a a") icicle-find-file-tagged-other-window (featurep 'bookmark+)) ; `C-x 4 j t a a'
+    (bmkp-autofile-set icicle-bookmark-a-file  (fboundp 'bmkp-bookmark-a-file)) ; `C-x p c a'
+    (bmkp-tag-a-file icicle-tag-a-file         (fboundp 'bmkp-tag-a-file)) ; `C-x p t + a'
+    (bmkp-untag-a-file icicle-untag-a-file     (fboundp 'bmkp-untag-a-file)) ; `C-x p t - a'
+    (bmkp-find-file-all-tags
+     icicle-find-file-all-tags (fboundp 'bmkp-find-file-all-tags)) ; `C-x j t a *'
+    (bmkp-find-file-all-tags-other-window
+     icicle-find-file-all-tags-other-window (fboundp 'bmkp-find-file-all-tags)) ; `C-x 4 j t a *'
+    (bmkp-find-file-all-tags-regexp
+     icicle-find-file-all-tags-regexp       (fboundp 'bmkp-find-file-all-tags-regexp)) ; `C-x j t a % *'
+    (bmkp-find-file-all-tags-regexp-other-window
+     icicle-find-file-all-tags-regexp-other-window
+     (fboundp 'bmkp-find-file-all-tags-regexp-other-window)) ; `C-x 4 j t a % *'
+    (bmkp-find-file-some-tags
+     icicle-find-file-some-tags (fboundp 'bmkp-find-file-some-tags)) ; `C-x j t a +'
+    (bmkp-find-file-some-tags-other-window
+     icicle-find-file-some-tags-other-window
+     (fboundp 'bmkp-find-file-some-tags-other-window)) ; `C-x 4 j t a +'
+    (bmkp-find-file-some-tags-regexp
+     icicle-find-file-some-tags-regexp (fboundp 'bmkp-find-file-some-tags-regexp)) ; `C-x j t a % +'
+    (bmkp-find-file-some-tags-regexp-other-window
+     icicle-find-file-some-tags-regexp-other-window
+     (fboundp 'bmkp-find-file-some-tags-regexp-other-window)) ; `C-x 4 j t a % +'
+    ;;   (Other-window means nothing for a bookmark list or a desktop.)
+    (bmkp-bookmark-list-jump
+     icicle-bookmark-bookmark-list (fboundp 'bmkp-bookmark-list-jump)) ; `C-x j B'
+    (bmkp-desktop-jump icicle-bookmark-desktop (fboundp 'bmkp-desktop-jump)) ; `C-x j K'
+    (bmkp-dired-jump icicle-bookmark-dired (fboundp 'bmkp-dired-jump)) ; `C-x j d'
+    (bmkp-dired-jump-other-window
+     icicle-bookmark-dired-other-window (fboundp 'bmkp-dired-jump)) ; `C-x 4 j d'
+    (bmkp-file-jump icicle-bookmark-file (fboundp 'bmkp-file-jump)) ; `C-x j f'
+    (bmkp-file-jump-other-window
+     icicle-bookmark-file-other-window (fboundp 'bmkp-file-jump)) ; `C-x 4 j f'
+    (bmkp-file-this-dir-jump
+     icicle-bookmark-file-this-dir (fboundp 'bmkp-file-this-dir-jump)) ; `C-x j C-f'
+    (bmkp-file-this-dir-jump-other-window
+     icicle-bookmark-file-this-dir-other-window (fboundp 'bmkp-file-this-dir-jump)) ; `C-x 4 j C-f'
+    (bmkp-gnus-jump icicle-bookmark-gnus (fboundp 'bmkp-gnus-jump)) ; `C-x j g'
+    (bmkp-gnus-jump-other-window
+     icicle-bookmark-gnus-other-window (fboundp 'bmkp-gnus-jump)) ; `C-x 4 j g'
+    (bmkp-info-jump icicle-bookmark-info (fboundp 'bmkp-info-jump)) ; `C-x j i'
+    (bmkp-info-jump-other-window
+     icicle-bookmark-info-other-window (fboundp 'bmkp-info-jump)) ; `C-x 4 j i'
+    (bmkp-local-file-jump icicle-bookmark-local-file (fboundp 'bmkp-local-file-jump)) ; `C-x j l'
+    (bmkp-local-file-jump-other-window
+     icicle-bookmark-local-file-other-window (fboundp 'bmkp-local-file-jump)) ; `C-x 4 j l'
+    (bmkp-man-jump icicle-bookmark-man  (fboundp 'bmkp-man-jump)) ; `C-x j m'
+    (bmkp-man-jump-other-window icicle-bookmark-man-other-window  (fboundp 'bmkp-man-jump)) ; `C-x 4 j m'
+    (bmkp-non-file-jump icicle-bookmark-non-file (fboundp 'bmkp-non-file-jump)) ; `C-x j b'
+    (bmkp-non-file-jump-other-window
+     icicle-bookmark-non-file-other-window (fboundp 'bmkp-non-file-jump)) ; `C-x 4 j b'
+    (bmkp-region-jump icicle-bookmark-region (fboundp 'bmkp-region-jump)) ; `C-x j r'
+    (bmkp-region-jump-other-window
+     icicle-bookmark-region-other-window (fboundp 'bmkp-region-jump)) ; `C-x 4 j r'
+    (bmkp-remote-file-jump icicle-bookmark-remote-file (fboundp 'bmkp-remote-file-jump)) ; `C-x j n'
+    (bmkp-remote-file-jump-other-window
+     icicle-bookmark-remote-file-other-window (fboundp 'bmkp-remote-file-jump)) ; `C-x 4 j n'
+    (bmkp-specific-buffers-jump
+     icicle-bookmark-specific-buffers (fboundp 'bmkp-specific-buffers-jump)) ; `C-x j = b'
+    (bmkp-specific-buffers-jump-other-window
+     icicle-bookmark-specific-buffers-other-window (fboundp 'bmkp-specific-buffers-jump)) ; `C-x 4 j = b'
+    (bmkp-specific-files-jump
+     icicle-bookmark-specific-files (fboundp 'bmkp-specific-files-jump)) ; `C-x j = f'
+    (bmkp-specific-files-jump-other-window
+     icicle-bookmark-specific-files-other-window (fboundp 'bmkp-specific-files-jump)) ; `C-x 4 j = f'
+    (bmkp-this-buffer-jump icicle-bookmark-this-buffer (fboundp 'bmkp-this-buffer-jump)) ; `C-x j .'
+    (bmkp-this-buffer-jump-other-window
+     icicle-bookmark-this-buffer-other-window (fboundp 'bmkp-this-buffer-jump)) ; `C-x 4 j .'
+    (bmkp-all-tags-jump icicle-bookmark-all-tags (fboundp 'bmkp-all-tags-jump)) ; `C-x j t *'
+    (bmkp-all-tags-jump-other-window
+     icicle-bookmark-all-tags-other-window (fboundp 'bmkp-all-tags-jump)) ; `C-x 4 j t *'
+    (bmkp-all-tags-regexp-jump
+     icicle-bookmark-all-tags-regexp (fboundp 'bmkp-all-tags-regexp-jump)) ; `C-x j t % *'
+    (bmkp-all-tags-regexp-jump-other-window
+     icicle-bookmark-all-tags-regexp-other-window (fboundp 'bmkp-all-tags-regexp-jump)) ; `C-x 4 j t % *'
+    (bmkp-some-tags-jump icicle-bookmark-some-tags (fboundp 'bmkp-some-tags-jump)) ; `C-x j t +'
+    (bmkp-some-tags-jump-other-window
+     icicle-bookmark-some-tags-other-window (fboundp 'bmkp-some-tags-jump)) ; `C-x 4 j t +'
+    (bmkp-some-tags-regexp-jump
+     icicle-bookmark-some-tags-regexp (fboundp 'bmkp-some-tags-regexp-jump)) ; `C-x j t % +'
+    (bmkp-some-tags-regexp-jump-other-window
+     icicle-bookmark-some-tags-regexp-other-window
+     (fboundp 'bmkp-some-tags-regexp-jump)) ; `C-x 4 j t % +'
+    (bmkp-file-all-tags-jump
+     icicle-bookmark-file-all-tags (fboundp 'bmkp-file-all-tags-jump)) ; `C-x j t f *'
+    (bmkp-file-all-tags-jump-other-window
+     icicle-bookmark-file-all-tags-other-window (fboundp 'bmkp-file-all-tags-jump)) ; `C-x 4 j t f *'
+    (bmkp-file-all-tags-regexp-jump
+     icicle-bookmark-file-all-tags-regexp (fboundp 'bmkp-file-all-tags-regexp-jump)) ; `C-x j t f % *'
+    (bmkp-file-all-tags-regexp-jump-other-window
+     icicle-bookmark-file-all-tags-regexp-other-window
+     (fboundp 'bmkp-file-all-tags-regexp-jump)) ; `C-x 4 j t f % *'
+    (bmkp-file-some-tags-jump
+     icicle-bookmark-file-some-tags (fboundp 'bmkp-file-some-tags-jump)) ; `C-x j t f +'
+    (bmkp-file-some-tags-jump-other-window
+     icicle-bookmark-file-some-tags-other-window (fboundp 'bmkp-file-some-tags-jump)) ; `C-x 4 j t f +'
+    (bmkp-file-some-tags-regexp-jump
+     icicle-bookmark-file-some-tags-regexp (fboundp 'bmkp-file-some-tags-regexp-jump)) ; `C-x j t f % +'
+    (bmkp-file-some-tags-regexp-jump-other-window
+     icicle-bookmark-file-some-tags-regexp-other-window
+     (fboundp 'bmkp-file-some-tags-regexp-jump)) ; `C-x 4 j t f % +'
+    (bmkp-file-this-dir-all-tags-jump
+     icicle-bookmark-file-this-dir-all-tags
+     (fboundp 'bmkp-file-this-dir-all-tags-jump)) ; `C-x j t C-f *'
+    (bmkp-file-this-dir-all-tags-jump-other-window
+     icicle-bookmark-file-this-dir-all-tags-other-window
+     (fboundp 'bmkp-file-this-dir-all-tags-jump)) ; `C-x 4 j t C-f *'
+    (bmkp-file-this-dir-all-tags-regexp-jump
+     icicle-bookmark-file-this-dir-all-tags-regexp ; `C-x j t % C-f *'
+     (fboundp 'bmkp-file-this-dir-all-tags-regexp-jump))
+    (bmkp-file-this-dir-all-tags-regexp-jump-other-window
+     icicle-bookmark-file-this-dir-all-tags-regexp-other-window
+     (fboundp 'bmkp-file-this-dir-all-tags-regexp-jump)) ; `C-x 4 j t % C-f *'
+    (bmkp-file-this-dir-some-tags-jump
+     icicle-bookmark-file-this-dir-some-tags
+     (fboundp 'bmkp-file-this-dir-some-tags-jump)) ; `C-x j t C-f +'
+    (bmkp-file-this-dir-some-tags-jump-other-window
+     icicle-bookmark-file-this-dir-some-tags-other-window
+     (fboundp 'bmkp-file-this-dir-some-tags-jump)) ; `C-x 4 j t C-f +'
+    (bmkp-file-this-dir-some-tags-regexp-jump
+     icicle-bookmark-file-this-dir-some-tags-regexp
+     (fboundp 'bmkp-file-this-dir-some-tags-regexp-jump)) ; `C-x j t % C-f +'
+    (bmkp-file-this-dir-some-tags-regexp-jump-other-window
+     icicle-bookmark-file-this-dir-some-tags-regexp-other-window
+     (fboundp 'bmkp-file-this-dir-some-tags-regexp-jump)) ; `C-x 4 j t % C-f +'
+    (bmkp-url-jump icicle-bookmark-url (fboundp 'bmkp-url-jump)) ; `C-x j u'
+    (bmkp-url-jump-other-window icicle-bookmark-url-other-window (fboundp 'bmkp-url-jump)) ; `C-x 4 j u'
+    (bmkp-w3m-jump icicle-bookmark-w3m (fboundp 'bmkp-w3m-jump)) ; `C-x j w'
+    (bmkp-w3m-jump-other-window icicle-bookmark-w3m-other-window (fboundp 'bmkp-w3m-jump)) ; `C-x 4 j w'
+
+    ;; Don't let Emacs 20 or 21 use `substitute-key-definition' on `M-.' or `M-*', since we need
+    ;; these keys for the minibuffer.  Leave them unbound in `icicle-mode-map' until Emacs 22+.
+    (find-tag            icicle-find-tag              (fboundp 'command-remapping)) ; `M-.'
+    (find-tag-other-window        icicle-find-first-tag-other-window t) ; `C-x 4 .'
+    (pop-tag-mark        icicle-pop-tag-mark          (fboundp 'command-remapping)) ; `M-*'
+    (eval-expression     icicle-pp-eval-expression    (fboundp 'command-remapping)) ; `M-:'
+    (pp-eval-expression icicle-pp-eval-expression (fboundp 'command-remapping)) ;`M-:' (`pp+.el')
+    ;; For La Carte (`lacarte.el'), not Icicles, but it's convenient to do this here.
+    (,(kbd "ESC M-x")      lacarte-execute-command ; `ESC M-x'
+     (fboundp 'lacarte-execute-command))
+    (,(kbd "M-`")          lacarte-execute-menu-command ; `M-`' - replaces `tmm-menubar'.
+     (fboundp 'lacarte-execute-menu-command))
+    (,(kbd "")        lacarte-execute-menu-command ; `f10' - replaces `menu-bar-open'.
+     (fboundp 'lacarte-execute-menu-command)))
+  "*List of top-level commands to bind in Icicle mode.
+Each list element is of custom type `icicle-key-definition' and has
+the form (KEY COMMAND CONDITION).
+
+KEY is either a key sequence (string or vector) to bind COMMAND to or
+a command to remap to COMMAND.
+COMMAND is bound according to the value of KEY, unless the result of
+evaluating CONDITION is nil.
+
+In Customize, to specify a key sequence, choose `Key' in the `Value
+Menu', then enter a key description such as that returned by `C-h k'.
+For convenience, you can use insert each key in the key description by
+hitting `C-q' then the key.  For example, to enter the key description
+`C-c M-k' you can use `C-q C-c C-q M-k'.
+
+If you customize this option, then you must exit and re-enter Icicle
+mode to ensure that the change takes effect.  This is really necessary
+only if your changes would undefine a key.
+
+For this option to have an effect upon startup, it must be set before
+you enter Icicle mode.  This means that you must ensure that the code
+that sets it is invoked before you enter Icicle mode.  If you use
+Customize to change this option, then ensure that the code inserted by
+Customize into your `user-init-file' or your `custom-file' is invoked
+before you enter Icicle mode."
+  :type (if (> emacs-major-version 20)
+            '(repeat icicle-key-definition)
+          '(repeat
+            (list
+             (choice
+              (restricted-sexp :tag "Key"
+               :match-alternatives ((lambda (x) (or (stringp x) (vectorp x))))
+               :value [ignore])
+              (restricted-sexp :tag "Command to remap"
+               ;; Use `symbolp' instead of `commandp', in case the library defining the
+               ;; command is not loaded.
+               :match-alternatives (symbolp) :value ignore))
+             ;; Use `symbolp' instead of `commandp'...
+             (restricted-sexp :tag "Command"
+              :match-alternatives (symbolp) :value ignore)
+             (sexp :tag "Condition"))))
+  :set #'(lambda (sym defs)
+           (custom-set-default sym defs)
+           (when (boundp 'icicle-mode-map) ; Avoid error on initialization.
+             (icicle-bind-top-level-commands defs)))
+  :initialize #'custom-initialize-default
+  :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-top-level-when-sole-completion-delay 0.7
+  "*Number of secs to wait to return to top level if only one completion.
+This has no effect if `icicle-top-level-when-sole-completion-flag' is
+nil.  Editing the completion (typing or deleting a character) before
+the delay expires prevents its automatic acceptance.
+
+Do not set this to 0.0.  Set it to slightly more than zero if you want
+instant action."
+  :type 'number :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-top-level-when-sole-completion-flag nil
+  "*Non-nil means to return to top level if only one matching completion.
+The sole completion is accepted."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-touche-pas-aux-menus-flag nil
+  "*Non-nil means do not add items to menus except Minibuf and Icicles.
+This value is used only when Icicles mode is initially established, so
+changing this has no effect after Icicles has been loaded.  However,
+you can change it and save the new value so it will be used next time.
+
+For this option to have an effect upon startup, it must be set before
+you enter Icicle mode.  This means that you must ensure that the code
+that sets it is invoked before you enter Icicle mode.  If you use
+Customize to change this option, then ensure that the code inserted by
+Customize into your `user-init-file' or your `custom-file' is invoked
+before you enter Icicle mode."
+  :type 'boolean :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-transform-function nil ; Toggle with `C-$,'.
+  "*Function used to transform the list of completion candidates.
+This is applied to the list of initial candidates.
+If this is nil, then no transformation takes place.
+
+You can toggle this option at any time from the minibuffer using
+`C-$,'.
+
+NOTE: Although this is a user option, you probably do *NOT* want to
+customize it.  Icicles commands already \"do the right thing\" when it
+comes to candidate transformation.  The value of this option may be
+changed by program locally, for use in particular contexts.  For
+example, when you use `C-c C-`' (\ `icicle-search-generic') in a
+*shell* buffer, Icicles uses this variable with a value of
+`icicle-remove-duplicates', to remove duplicate shell commands from
+your input history list.
+
+Emacs-Lisp programmers can use this variable to transform the list of
+candidates in any way they like.  A typical use is to remove
+duplicates, by binding it to `icicle-remove-duplicates' or
+`icicle-remove-dups-if-extras'."
+  :type '(choice (const :tag "None" nil) function) :group 'Icicles-Completions-Display)
+
+;;;###autoload
+(defcustom icicle-type-actions-alist
+  '(("buffer"
+     (lambda (b) (with-current-buffer b (ps-print-buffer))) ; E.g. showing you can use lambda.
+     1-window-frames-on  another-buffer  browse-url-of-buffer  buffer-disable-undo
+     buffer-enable-undo  buffer-file-name  buffer-local-variables  buffer-modified-p
+     buffer-name  buffer-size  bury-buffer  choose-grep-buffer  current-line-string
+     delete-1-window-frames-on  delete-windows-for  delete-windows-on
+     delete/iconify-windows-on  describe-buffer-bindings  diff-buffer-with-file
+     display-buffer  display-buffer-other-frame  echo-in-buffer  eval-buffer  fontify-buffer
+     generate-new-buffer  get-buffer  get-buffer-process  get-buffer-window
+     get-buffer-window-list  grepp-choose-grep-buffer  ibuffer-jump-to-buffer
+     icicle-char-properties-in-buffer  icicle-delete-window  icicle-delete-windows-on
+     icicle-help-line-buffer  icicle-kill-a-buffer  insert-buffer  insert-buffer-substring
+     insert-buffer-substring-as-yank  insert-buffer-substring-no-properties  kill-buffer
+     kill-buffer-and-its-windows  kill-buffer-if-not-modified  last-buffer
+     multi-window-frames-on  other-buffer  pop-to-buffer  pr-interface  remove-windows-on
+     replace-buffer-in-windows  smiley-buffer  switch-to-buffer  switch-to-buffer-other-frame
+     switch-to-buffer-other-window  view-buffer  view-buffer-other-frame
+     view-buffer-other-window)
+    ("color"
+     color-defined-p  color-gray-p  color-supported-p  color-values  colors
+     doremi-set-background-color  doremi-set-foreground-color  eyedrop-color-message
+     facemenu-set-background  facemenu-set-foreground  hexrgb-blue  hexrgb-color-name-to-hex
+     hexrgb-complement  hexrgb-green  hexrgb-hex-to-color-values  hexrgb-hue  hexrgb-red
+     hexrgb-saturation  hexrgb-value  icicle-color-help icicle-color-name-w-bg
+     palette-brightness-scale  palette-color-message  palette-complement-or-alternative
+     palette-hex-info  palette-hsv-info  palette-rgb-info  palette-swatch  ps-e-color-values
+     ps-e-x-color-values  set-background-color  set-border-color  set-cursor-color
+     set-foreground-color  set-mouse-color  tty-color-canonicalize  tty-color-desc
+     tty-color-standard-values  tty-color-translate  tty-color-values  x-color-defined-p
+     x-color-values)
+    ("command"
+     command-remapping  define-prefix-command  describe-command  disable-command
+     doremi-push-frame-config-for-command  enable-command  Info-find-emacs-command-nodes
+     Info-goto-emacs-command-node)
+    ("face"
+     color-theme-spec  custom-facep  customize-face  customize-face-other-window
+     custom-theme-recalc-face  describe-face  face-all-attributes  face-attr-construct
+     face-background  face-background-20+  face-background-pixmap  face-bold-p
+     face-default-spec  face-differs-from-default-p  face-doc-string  face-documentation
+     face-font  face-foreground  face-foreground-20+  face-id  face-inverse-video-p
+     face-italic-p  face-nontrivial-p  face-spec-reset-face  face-stipple  face-underline-p
+     face-user-default-spec  facemenu-add-face facemenu-add-new-face  facemenu-set-face
+     find-face-definition  hlt-choose-default-face  hlt-show-default-face
+     hlt-unhighlight-region-for-face  icicle-customize-face
+     icicle-customize-face-other-window  invert-face  make-face  make-face-bold
+     make-face-bold-italic  make-face-italic  make-face-unbold  make-face-unitalic
+     moccur-face-check  modify-face  ps-face-attributes  read-all-face-attributes
+     read-face-font)
+    ("file"
+     abbreviate-file-name  ange-ftp-chase-symlinks  ange-ftp-file-modtime  apropos-library  
+     auto-coding-alist-lookup  bookmark-file-or-variation-thereof  bookmark-load
+     browse-url-of-file  byte-compile-file  check-declare-file  comint-append-output-to-file
+     comint-quote-filename  comint-substitute-in-file-name  comint-unquote-filename
+     comint-write-output  compilation-get-file-structure  cookie-insert  create-file-buffer
+     delete-file  describe-file  dired-delete-file  diredp-mouse-diff  dired-show-file-type
+     dir-locals-find-file  dir-locals-read-from-file  do-after-load-evaluation  ebnf-eps-file
+     ebnf-print-file  ebnf-spool-file  ebnf-syntax-file  ediff-backup  epa-decrypt-file
+     epa-import-keys  epa-verify-file  eval-next-after-load  ffap-file-remote-p
+     ffap-locate-file  file-attributes  file-cache-add-file  file-chase-links
+     file-dependents  file-directory-p  file-executable-p  file-exists-p
+     file-loadhist-lookup  file-local-copy  file-modes  file-name-nondirectory
+     file-newest-backup  file-nlinks  file-ownership-preserved-p  file-provides
+     file-readable-p  file-regular-p  file-relative-name  file-remote-p  file-requires
+     file-symlink-p  file-system-info  file-truename  file-writable-p  find-alternate-file
+     find-alternate-file-other-window  find-buffer-visiting  finder-commentary  find-file
+     find-file-at-point  find-file-binary  find-file-literally  find-file-noselect
+     find-file-other-frame  find-file-other-window find-file-read-only
+     find-file-read-only-other-frame  find-file-read-only-other-window  find-file-text
+     get-file-buffer  gnus-audio-play  gnus-convert-png-to-face  hexl-find-file
+     highlight-compare-with-file   icicle-add-file-to-fileset
+     icicle-delete-file-or-directory  icicle-describe-file  icicle-file-remote-p
+     icicle-help-line-file  icicle-search-file  icicle-shell-command-on-file
+     image-type-from-file-header  image-type-from-file-name  Info-find-file  Info-index-nodes
+     info-lookup-file  Info-toc-nodes  info-xref-check  insert-file  insert-file-literally
+     insert-image-file  list-tags  lm-commentary  lm-creation-date  lm-keywords  lm-keywords-list
+     lm-last-modified-date  lm-summary  lm-synopsis  lm-verify  lm-version  load  load-file
+     load-history-regexp  make-backup-file-name  move-file-to-trash  open-dribble-file
+     open-termscript  play-sound-file  pr-ps-file-preview  pr-ps-file-print
+     pr-ps-file-ps-print  pr-ps-file-using-ghostscript  recentf-add-file  recentf-push
+     recentf-remove-if-non-kept  recover-file  rmail-input  rmail-output  set-file-times
+     set-visited-file-name  substitute-in-file-name  system-move-file-to-trash
+     untranslated-canonical-name  untranslated-file-p  url-basepath  vc-backend  
+     vc-delete-automatic-version-backups  vc-file-clearprops  vc-insert-file
+     vc-make-version-backup  vc-name  vc-state  vc-working-revision  view-file
+     view-file-other-frame  view-file-other-window  visit-tags-table  w32-browser
+     w32-long-file-name  w32-short-file-name  w32explore  woman-find-file  write-file
+     xml-parse-file)
+    ("frame"
+     current-window-configuration  delete-frame  delete-other-frames  thumfr-dethumbify-frame
+     doremi-undo-last-frame-color-change  thumfr-fisheye  fit-frame  fit-frame-maximize-frame
+     fit-frame-minimize-frame  fit-frame-restore-frame  frame-char-height  frame-char-width
+     frame-current-scroll-bars  frame-extra-pixels-height  frame-extra-pixels-width
+     frame-face-alist  frame-first-window  frame-focus  frame-height  frame-iconified-p
+     frame-parameters  frame-pixel-height  frame-pixel-width frame-root-window
+     frame-selected-window  frame-set-background-mode  frame-terminal
+     frame-visible-p  frame-width  get-a-frame  get-frame-name
+     hide-frame  icicle-select-frame-by-name  iconify-frame  lower-frame
+     make-frame-invisible  make-frame-visible  maximize-frame  maximize-frame-horizontally
+     maximize-frame-vertically  menu-bar-open  minimize-frame  next-frame
+     thumfr-only-raise-frame  previous-frame  raise-frame  really-iconify-frame
+     redirect-frame-focus  redraw-frame  restore-frame  restore-frame-horizontally
+     restore-frame-vertically  select-frame   select-frame-set-input-focus  set-frame-name
+     show-frame  thumfr-thumbify-frame  thumfr-thumbify-other-frames  thumfr-thumbnail-frame-p
+     thumfr-toggle-thumbnail-frame  toggle-max-frame  toggle-max-frame-horizontally
+     toggle-max-frame-vertically  toggle-zoom-frame  tty-color-alist  tty-color-clear
+     w32-focus-frame  window-list  window-system  window-tree  x-focus-frame  zoom-frm-in
+     zoom-frm-out  zoom-frm-unzoom)
+    ("function"
+     cancel-function-timers  describe-function  elp-instrument-function  find-function
+     find-function-other-frame  find-function-other-window  symbol-function  trace-function
+     trace-function-background)
+    ("option" custom-note-var-changed  customize-option  customize-option-other-window
+     describe-option  icicle-binary-option-p  tell-customize-var-has-changed)
+    ("process"
+     accept-process-output  anything-kill-async-process  clone-process  continue-process
+     delete-process  get-process  interrupt-process  kill-process  process-buffer
+     process-coding-system  process-command  process-contact  process-exit-status
+     process-filter  process-filter-multibyte-p  process-id
+     process-inherit-coding-system-flag  process-kill-without-query  process-mark
+     process-name  process-plist  process-query-on-exit-flag  process-running-child-p
+     process-send-eof  process-sentinel  process-status  process-tty-name  process-type
+     quit-process  set-process-coding-system  stop-process  tooltip-process-prompt-regexp
+     tq-create)
+    ("symbol"
+     apropos-describe-plist  apropos-macrop  apropos-score-symbol  byte-compile-const-symbol-p
+     custom-guess-type  custom-unlispify-tag-name  custom-variable-type  default-boundp
+     default-value  describe-minor-mode-from-symbol  fmakunbound
+     icicle-help-on-candidate-symbol  info-lookup-symbol  makunbound  symbol-file
+     symbol-function  symbol-plist  symbol-value)
+    ("variable"
+     custom-type  custom-variable-documentation  custom-variable-p  custom-variable-type
+     describe-variable  find-variable  find-variable-noselect  find-variable-other-frame
+     find-variable-other-window  help-custom-type  icicle-custom-type  kill-local-variable
+     local-variable-if-set-p  local-variable-p  make-local-variable  make-variable-buffer-local
+     make-variable-frame-local  symbol-value  user-variable-p  variable-binding-locus)
+    ("window"
+     balance-windows  browse-kill-ring-fit-window  compilation-set-window-height
+     delete-other-windows  delete-other-windows-vertically  delete-window
+     delete/iconify-window  fit-frame-max-window-size  fit-window-to-buffer
+     mouse-drag-vertical-line-rightward-window  mouse-drag-window-above  next-window
+     previous-window  remove-window  select-window  shrink-window-if-larger-than-buffer
+     split-window  truncated-partial-width-window-p  window--display-buffer-1
+     window--even-window-heights  window--try-to-split-window  window-body-height
+     window-buffer  window-buffer-height  window-current-scroll-bars  window-dedicated-p
+     window-display-table  window-edges  window-end  window-fixed-size-p  window-frame
+     window-fringes  window-full-width-p  window-height  window-hscroll  window-inside-edges
+     window-inside-pixel-edges  window-margins  window-minibuffer-p  window-parameters
+     window-pixel-edges  window-point  window-safely-shrinkable-p  window-scroll-bars
+     window-start  window-text-height  window-vscroll  window-width))
+  "*Alist of Emacs object types and associated actions.
+Each element has the form (TYPE FUNCTION...), where TYPE names an
+object type, and each FUNCTION accepts an object of type TYPE as its
+only required argument
+
+A FUNCTION here can be a symbol or a lambda form.  You can use a
+symbol that is not yet `fboundp', that is, one that does not yet have
+a function definition.  Any symbols that do not have function
+definitions when this option is used are simply filtered out.
+
+However, just because a function is defined at runtime does not mean
+that it will work.  For example, function `buffer-size' is included in
+the default value for type `buffer', but in Emacs 20 `buffer-size'
+accepts no arguments, so applying it to a buffer name raises an error.
+
+\[Note: If you have suggestions or corrections for the default value,
+send them in, using `\\[icicle-send-bug-report]'.  The initial list
+was drawn up quickly by looking at functions with the type in their
+name and that accept a value of that type as only required argument.
+There is no doubt that the default value could be improved.]"
+  :type '(alist
+          :key-type   (string :tag "Object type")
+          ;; We cannot use type `function' because some symbols might not yet be `fboundp'.
+          :value-type (repeat (restricted-sexp :tag "Action (function)"
+                               :match-alternatives (functionp symbolp))))
+  :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-unpropertize-completion-result-flag nil
+  "*Non-nil means strip text properties from the completion result.
+Set this option to non-nil only if you need to ensure, for some other
+library, that the string returned by `completing-read' and (starting
+with Emacs 23) `read-file-name' has no text properties.
+
+Typically, you will not use a non-nil value.  Internal text properties
+added by Icicles are always removed anyway.  A non-nil value lets you
+also remove properties such as `face'."
+  :type 'boolean :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-update-input-hook nil
+  "*Functions run when minibuffer input is updated (typing or deleting)."
+  :type 'hook :group 'Icicles-Miscellaneous)
+
+;;;###autoload
+(defcustom icicle-use-~-for-home-dir-flag t ; Toggle with `M-~'.
+  "*Non-nil means abbreviate your home directory using `~'.
+You can toggle this option from the minibuffer at any time using
+`M-~'."
+  :type 'boolean :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-use-C-for-actions-flag t ; Toggle with `M-g'.
+  "*Non-nil means use modifier `C-' (Control) for multi-command actions.
+If nil, then you need no `C-' modifier for actions, and, instead, you
+need a `C-' modifier for ordinary candidate cycling.
+
+It is not strictly correct to speak in terms of the `C-' modifier -
+that is only the default behavior.  The actual keys concerned are
+those defined by these options:
+
+ `icicle-modal-cycle-down-action-keys'
+ `icicle-modal-cycle-up-action-keys'
+ `icicle-apropos-cycle-next-action-keys'
+ `icicle-apropos-cycle-previous-action-keys'
+ `icicle-prefix-cycle-next-action-keys'
+ `icicle-prefix-cycle-previous-action-keys'
+
+You can toggle this option from the minibuffer at any time using
+`M-g'."
+  :type 'boolean :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-use-anything-candidates-flag t
+  "*Non-nil means Icicles can include Anything candidates for completion.
+When non-nil, Anything actions are used for candidate alternate
+actions in some Icicles commands, and Anything types and actions are
+used by command `icicle-object-action' (aka `a' and `what-which-how').
+
+This option has no effect if library `anything.el' cannot be loaded."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-use-candidates-only-once-flag nil
+  "*Non-nil means remove each candidate from the set after using it.
+When you use a multi-command and act on a candidate (for example, with
+`C-RET'), the candidate is removed from those available if this is
+non-nil.  If this is nil, then the candidate is not removed, so you
+can act on it again.
+
+You can customize this option if you prefer the non-nil behavior all
+of the time.  However, most users will not want to do that.
+
+If you write Emacs-Lisp code, you can bind this to non-nil during
+completion in contexts where it makes little sense for users to act on
+the same candidate more than once.  That way, users cannot choose it
+again, and they are not distracted seeing it as a candidate.
+
+See also non-option variable `icicle-use-candidates-only-once-alt-p'."
+  :type 'boolean :group 'Icicles-Matching)
+
+;;;###autoload
+(defcustom icicle-word-completion-keys '([(meta ?\ )]) ; `M-SPC'
+  "*Key sequences to use for minibuffer prefix word completion.
+A list of values that each has the same form as a key-sequence
+argument to `define-key'.  It is a list mainly in order to accommodate
+different keyboards.
+
+Because file names, in particular, can contain spaces, some people
+prefer such a key sequence to be non-printable, such as `M-SPC'.  This
+is the default value in Icicles.
+
+But because the spacebar is such a convenient key to hit, other people
+prefer to use `SPC' for word completion, and to insert a space some
+other way.  The usual way to do that is via `C-q SPC', but command
+`icicle-insert-a-space' is provided for convenience.  You can bind
+this to `M-SPC', for instance, in `minibuffer-local-completion-map',
+`minibuffer-local-completion-map', and
+`minibuffer-local-must-match-map'."
+  :type '(repeat sexp) :group 'Icicles-Key-Bindings)
+
+;;;###autoload
+(defcustom icicle-WYSIWYG-Completions-flag "MMMM"
+  "*Non-nil means show candidates in `*Completions*' using WYSIWYG.
+This has an effect only for completion of faces and colors.
+
+The particular non-nil value determines the appearance:
+* If t, the candidate is shown with its text properties.
+* If a string, the string is propertized and then appended to the
+  candidate,  to serve as a color swatch.
+
+Some commands might override a string value with different text.  This
+is the case for `icicle-read-color', for instance: the color swatch
+text is always the color's RGB code.
+
+Note that, starting with Emacs 22, if this option is non-nil, then
+command `describe-face' does not use `completing-read-multiple', since
+that (non-Icicles) function does not support WYSIWYG candidates."
+  :type '(choice
+          (string :tag "Show candidate plus a WYSIWYG swatch with text..."  :value "MMMM")
+          (const  :tag "Show candidate itself using WYSIWYG"                t)
+          (const  :tag "Show candidate as is, with no text properties"      nil))
+  :group 'Icicles-Completions-Display)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-opt)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-opt.el ends here
diff --git a/auto-install/icicles-var.el b/auto-install/icicles-var.el
new file mode 100644
index 0000000..95df059
--- /dev/null
+++ b/auto-install/icicles-var.el
@@ -0,0 +1,1454 @@
+;;; icicles-var.el --- Internal variables for Icicles
+;;
+;; Filename: icicles-var.el
+;; Description: Internal variables for Icicles
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Feb 27 09:23:26 2006
+;; Version: 22.0
+;; Last-Updated: Mon Sep  5 12:49:41 2011 (-0700)
+;;           By: dradams
+;;     Update #: 1538
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-var.el
+;; Keywords: internal, extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `apropos', `apropos-fn+var', `backquote', `bytecomp', `cl',
+;;   `el-swank-fuzzy', `ffap', `ffap-', `fuzzy', `fuzzy-match',
+;;   `hexrgb', `icicles-face', `icicles-mac', `icicles-opt',
+;;   `kmacro', `levenshtein', `regexp-opt', `thingatpt',
+;;   `thingatpt+', `wid-edit', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  This is a helper library for library `icicles.el'.  It defines
+;;  internal variables (not to be modified by users.  For Icicles
+;;  documentation, see `icicles-doc1.el' and `icicles-doc2.el'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `icicle-abs-file-candidates', `icicle-acting-on-next/prev',
+;;    `icicle-advice-info-list', `icicle-all-candidates-action',
+;;    `icicle-all-candidates-list-action-fn',
+;;    `icicle-all-candidates-list-alt-action-fn',
+;;    `icicle-apply-nomsg', `icicle-apropos-complete-match-fn',
+;;    `icicle-bookmark-history', `icicle-bookmark-types',
+;;    `icicle-buffer-config-history',
+;;    `icicle-buffer-sort-first-time-p', `icicle-bufflist',
+;;    `icicle-candidate-action-fn', `icicle-candidate-alt-action-fn',
+;;    `icicle-candidate-entry-fn', `icicle-candidate-help-fn',
+;;    `icicle-candidate-nb', `icicle-candidate-properties-alist',
+;;    `icicle-candidates-alist', `icicle-char-property-value-history',
+;;    `icicle-cmd-calling-for-completion', `icicle-cmd-reading-input',
+;;    `icicle-color-history', `icicle-color-theme-history',
+;;    `icicle-command-abbrev-history', `icicle-commands-for-abbrev',
+;;    `icicle-common-match-string',
+;;    `icicle-comp-base-is-default-dir-p',
+;;    `icicle-complete-input-overlay', `icicle-complete-keys-alist',
+;;    `icicle-completing-keys-p', `icicle-completing-p',
+;;    `icicle-completing-read+insert-candidates',
+;;    `icicle-completion-candidates',
+;;    `icicle-completion-prompt-overlay',
+;;    `icicle-completion-set-history', `icicle-confirm-exit-commands',
+;;    `icicle-current-completion-candidate-overlay',
+;;    `icicle-current-completion-mode', `icicle-current-input',
+;;    `icicle-current-raw-input', `icicle-current-TAB-method',
+;;    `icicle-cycling-p', `icicle-default-directory',
+;;    `icicle-default-thing-insertion-flipped-p',
+;;    `icicle-delete-candidate-object', `icicle-dictionary-history',
+;;    `icicle-dir-candidate-can-exit-p',
+;;    `icicle-doc-last-initial-cand-set',
+;;    `icicle-dot-string-internal', `icicle-edit-update-p',
+;;    `icicle-explore-final-choice',
+;;    `icicle-explore-final-choice-full', `icicle-extra-candidates',
+;;    `icicle-extra-candidates-dir-insert-p',
+;;    `icicle-face-name-history', `icicle-fancy-candidates-p',
+;;    `icicle-fancy-cands-internal-p',
+;;    `icicle-file-sort-first-time-p',
+;;    `icicle-filtered-default-value', `icicle-font-name-history',
+;;    `icicle-frame-alist', `icicle-frame-name-history',
+;;    `icicle-full-cand-fn', `icicle-function-name-history',
+;;    `icicle-fundoc-last-initial-cand-set',
+;;    `icicle-general-help-string',
+;;    `icicle-get-alist-candidate-function',
+;;    `icicle-hist-cands-no-highlight', `icicle-ignored-extensions',
+;;    `icicle-ignored-extensions-regexp',
+;;    `icicle-incremental-completion-p',
+;;    `icicle-Info-only-rest-of-book-p', `icicle-inhibit-sort-p',
+;;    `icicle-inhibit-try-switch-buffer', `icicle-initial-value',
+;;    `icicle-input-completion-fail-overlay', `icicle-input-fail-pos',
+;;    `icicle-insert-string-at-pt-end',
+;;    `icicle-insert-string-at-pt-start',
+;;    `icicle-interactive-history', `icicle-key-prefix-description',
+;;    `icicle-kill-history', `icicle-kmacro-alist',
+;;    `icicle-kmacro-history',
+;;    `icicle-last-apropos-complete-match-fn',
+;;    `icicle-last-completion-candidate',
+;;    `icicle-last-completion-command', `icicle-last-input',
+;;    `icicle-last-sort-comparer', `icicle-last-top-level-command',
+;;    `icicle-last-transform-function', `icicle-lighter-truncation',
+;;    `icicle-list-use-nth-parts', `icicle-menu-map',
+;;    `icicle-minibuffer-message-ok-p', `icicle-minor-mode-map-entry',
+;;    `icicle-ms-windows-drive-hash', `icicle-must-match-regexp',
+;;    `icicle-must-not-match-regexp',
+;;    `icicle-must-pass-after-match-predicate',
+;;    `icicle-must-pass-predicate',
+;;    `icicle-nb-candidates-before-truncation',
+;;    `icicle-nb-of-other-cycle-candidates', `icicle-new-last-cmd',
+;;    `icicle-next-apropos-complete-cycles-p',
+;;    `icicle-next-prefix-complete-cycles-p',
+;;    `icicle-old-read-file-name-fn', `icicle-orig-buff',
+;;    `icicle-orig-must-pass-after-match-pred',
+;;    `icicle-orig-pt-explore', `icicle-orig-window',
+;;    `icicle-orig-win-explore', `icicle-other-window',
+;;    `icicle-plist-last-initial-cand-set',
+;;    `icicle-predicate-types-alist', `icicle-pref-arg',
+;;    `icicle-pre-minibuffer-buffer', `icicle-post-command-hook',
+;;    `icicle-pre-command-hook',
+;;    `icicle-previous-raw-file-name-inputs',
+;;    `icicle-previous-raw-non-file-name-inputs',
+;;    `icicle-progressive-completing-p', `icicle-prompt',
+;;    `icicle-proxy-candidate-regexp', `icicle-proxy-candidates',
+;;    `icicle-read-expression-map', `icicle-remove-icicles-props-p',
+;;    `icicle-re-no-dot', `icicle-require-match-p',
+;;    `icicle-reverse-multi-sort-p', `icicle-reverse-sort-p',
+;;    `icicle-saved-candidate-overlays',
+;;    `icicle-saved-candidates-variables-obarray',
+;;    `icicle-saved-completion-candidate',
+;;    `icicle-saved-completion-candidates',
+;;    `icicle-saved-completion-candidates-internal',
+;;    `icicle-saved-ignored-extensions',
+;;    `icicle-saved-kmacro-ring-max', `icicle-saved-proxy-candidates',
+;;    `icicle-saved-regexp-search-ring-max',
+;;    `icicle-saved-region-background',
+;;    `icicle-saved-search-ring-max', `icicle-scan-fn-or-regexp',
+;;    `icicle-scroll-Completions-reverse-p', `icicle-search-command',
+;;    `icicle-search-complement-domain-p',
+;;    `icicle-search-context-level', `icicle-search-context-regexp',
+;;    `icicle-search-current-overlay', `icicle-search-final-choice',
+;;    `icicle-search-history', `icicle-search-in-context-fn',
+;;    `icicle-searching-p', `icicle-search-level-overlays',
+;;    `icicle-search-overlays', `icicle-search-refined-overlays',
+;;    `icicle-search-replacement',
+;;    `icicle-search-replacement-history',
+;;    `icicle-successive-grab-count',
+;;    `icicle-text-property-value-history',
+;;    `icicle-thing-at-pt-fns-pointer',
+;;    `icicle-transform-before-sort-p',
+;;    `icicle-universal-argument-map',
+;;    `icicle-use-candidates-only-once-alt-p',
+;;    `icicle-vardoc-last-initial-cand-set',
+;;    `icicle-vardoc-last-initial-option-cand-set',
+;;    `icicle-variable-name-history',
+;;    `icicle-whole-candidate-as-text-prop-p',
+;;    `lacarte-menu-items-alist'.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Internal variables (alphabetical)")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(require 'apropos-fn+var nil t) ;; (no error if not found): apropos-command,
+                                ;; apropos-function, apropos-option, apropos-variable
+(require 'icicles-opt) ;; icicle-sort-comparer
+
+;;; Defvars to quiet byte-compiler:
+(defvar kmacro-ring-max)                ; Defined in `kmacro.el' in Emacs 22+.
+(defvar minibuffer-confirm-exit-commands) ; Defined in `minibuffer.el' in Emacs 23+.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "Internal variables (alphabetical)")
+
+;;; Internal variables (alphabetical) --------------------------------
+
+(defvar lacarte-menu-items-alist nil)    ; Defined in `lacarte.el'.
+
+;; These two are defined here so they won't raise an error in `font-lock-add-keywords'.
+(defvar font-lock-function-name-face 'font-lock-function-name-face ; In `font-lock.el'.
+  "Face name to use for function names.")
+
+(defvar font-lock-keyword-face 'font-lock-keyword-face ; Defined in `font-lock.el'.
+  "Face name to use for keywords.")
+
+(defvar icicle-abs-file-candidates ()
+  "Current alist of absolute file-name candidates.
+An alist appropriate as the COLLECTION argument for `completing-read'.
+Each item is a cons whose car is an absolute file name (a string).")
+
+(defvar icicle-acting-on-next/prev nil
+  "Non-nil means this command acts on the previous or next candidate.
+The particular non-nil value indicates the navigation direction:
+`forward' or `backward'.")
+
+(defvar icicle-advice-info-list ()
+  "List of advice information for functions that Icicles redefines.
+If such redefined functions are advised, then Icicles deactivates the
+advice when you turn on Icicle mode.  It restores the recorded advice
+activation state when you turn off Icicle mode.")
+
+(defvar icicle-all-candidates-action nil
+  "Non-nil means that we are acting on all candidates.
+That is, `icicle-all-candidates-action-1' is in progress.
+If neither nil nor t, then the value is the action function to use.")
+
+(defvar icicle-all-candidates-list-alt-action-fn nil
+  "Alternative action function to apply to a list of matching completions.")
+
+(defvar icicle-all-candidates-list-action-fn nil
+  "Action function to apply to a list of all matching completions.")
+
+(defvar icicle-apply-nomsg nil
+  "Non-nil means `icicle-apply' does not show status of applying function.")
+
+(defvar icicle-apropos-complete-match-fn 'string-match
+  "Function to filter apropos completion candidates.
+Takes as arguments an input string and a completion candidate, and
+returns non-nil if the string is considered to match the candidate.
+
+A value of nil instead of a function means completion candidates are
+not filtered by the input, except possibly by a function-valued
+`minibuffer-completion-table'.")
+
+(defvar icicle-bookmark-history nil "History for bookmark names.")
+
+(defvar icicle-bookmark-types ()
+  "List of strings naming bookmark types.
+The list represents the set of all bookmarks of the given types.
+An empty list and the singleton list `(all)', where `all' is a symbol,
+are equivalent and stand for the set of all bookmarks (of any type).")
+
+(defvar icicle-buffer-config-history nil "History for buffer configuration names.")
+
+(defvar icicle-buffer-sort-first-time-p t
+  "Non-nil means buffer-name completion has not yet been used.")
+
+(defvar icicle-bufflist nil
+  "List of buffers defined by macro `icicle-buffer-bindings'.")
+
+(defvar icicle-candidate-action-fn nil
+  "Action function to apply to current completion candidate.
+For `icicle-all-candidates-action' to be able to report successes,
+this should return nil for \"success\" and non-nil for \"failure\".")
+
+(defvar icicle-candidate-alt-action-fn nil
+  "Alternative action function to apply to current completion candidate.
+For `icicle-all-candidates-alt-action' to be able to report successes,
+this should return nil for \"success\" and non-nil for \"failure\".")
+
+(defvar icicle-candidate-entry-fn nil
+  "Function to apply to selected entries in `icicle-candidates-alist'.")
+
+(defvar icicle-candidate-help-fn nil
+  "Help function to be applied to current completion candidate.
+If non-nil, it must be a function that accepts a completion candidate
+  (a string or a symbol) as argument.
+If nil, default help function `icicle-help-on-candidate' is used.")
+
+(defvar icicle-candidate-nb nil
+  "Current completion candidate number, or nil if not cycling candidates.
+Numbering starts at zero.")
+
+(defvar icicle-candidate-properties-alist nil
+  "Alist of multi-completion indexes and associated text properties.
+The text properties apply to candidates in `*Completions*'.
+Each alist entry has the form (NTH PROPERTIES) or (NTH PROPERTIES
+JOIN-TOO).
+
+NTH is a whole-number index identifying the multi-completion part.
+
+PROPERTIES is a list of text properties to apply to the part.
+
+JOIN-TOO non-nil means to also apply PROPERTIES to the join string
+that follows the part.
+
+Example alist:
+
+ ((3 (face 'underline))
+  (2 (invisible t) t))
+
+The first entry underlines the third multi-completion part.
+The second entry makes both the second part and the join string that
+follows it invisible.")
+
+(defvar icicle-candidates-alist nil
+  "Alist of candidate entries.
+The car (key) of each entry is treated as a completion candidate.
+The cdr is some other data to be used when the candidate is chosen.
+This is reset to nil at the beginning of each top-level command.
+
+This is used typically by commands that allow different cdrs for the
+same car.  Icicles search is one such example.")
+
+(defvar icicle-char-property-value-history nil "History for character property values.")
+
+(defvar icicle-cmd-calling-for-completion 'ignore
+  "Last command causing display of list of possible completions.")
+
+(defvar icicle-cmd-reading-input 'ignore
+  "Last command reading input in the minibuffer.")
+
+(defvar icicle-color-history nil "History for color names.")
+
+(defvar icicle-color-theme-history nil "History for color-theme names.")
+
+(defvar icicle-command-abbrev-history nil "History of command and abbrev entries.")
+
+(defvar icicle-commands-for-abbrev nil
+  "List of commands that match the current abbreviation.")
+
+(defvar icicle-common-match-string nil
+  "Expanded common match among all completion candidates.
+nil means no such common match is available.")
+
+(defvar icicle-comp-base-is-default-dir-p nil
+  "Non-nil means to use `default-directory' as the completion base.
+This means use its length as `completion-base-size'.")
+
+(defvar icicle-complete-input-overlay nil
+  "Overlay used to highlight minibuffer input when it is complete.")
+
+(defvar icicle-complete-keys-alist () "Alist of keys and their bindings.
+Each alist element is of the form (NAME KEY . BINDING), where:
+ NAME is a symbol naming the key and its binding, whose name has form:
+   KEYNAME  =  BINDING-NAME
+ KEY is the actual key sequence
+ BINDING is the actual binding of KEY.
+
+Used only for Emacs 22 and later.")
+
+(defvar icicle-completing-keys-p nil
+  "Non-nil means completion is currently for a key sequence.
+Used only for Emacs 22 and later.")
+
+(defvar icicle-completing-p nil "Cached value of function `icicle-completing-p'.")
+
+(defvar icicle-completion-candidates nil "Current list of completion candidates.")
+
+(defvar icicle-completion-prompt-overlay nil
+  "Overlay used to highlight saved completion candidates.")
+
+(defvar icicle-completing-read+insert-candidates ()
+  "`completing-read' COLLECTION arg to use for `icicle-completing-read+insert'.")
+
+(defvar icicle-completion-set-history nil "History for completion-set names.")
+
+(defvar icicle-confirm-exit-commands
+  (and (boundp 'minibuffer-confirm-exit-commands)
+       (append '(icicle-prefix-complete icicle-prefix-complete-no-display
+                 icicle-prefix-word-complete
+                 icicle-apropos-complete icicle-apropos-complete-no-display
+                 icicle-apropos-complete-and-narrow ; ????
+                 ;; icicle-apropos-complete-and-exit ; ????
+                 )
+               minibuffer-confirm-exit-commands))
+  "Version of `minibuffer-confirm-exit-commands' for Icicle mode.
+Effective starting with Emacs 23.")
+
+(defvar icicle-current-completion-candidate-overlay nil
+  "Overlay used to highlight current completion candidate.")
+
+(defvar icicle-current-completion-mode nil
+  "Symbol `prefix' or `apropos', specifying the current completion mode.")
+
+(defvar icicle-current-input "" "Current minibuffer input.")
+
+(defvar icicle-current-TAB-method nil
+  "*Current completion method for \
+`\\\\[icicle-prefix-complete]'.")
+
+(defvar icicle-current-raw-input "" "Current minibuffer raw (unexpanded) input.
+This can be different from `icicle-current-input' only when
+`icicle-expand-input-to-common-match-flag' is non-nil.")
+
+(defvar icicle-cycling-p nil
+  "Non-nil means the user is currently cycling completion candidates.")
+
+(defvar icicle-default-directory default-directory
+  "Local copy of `default-directory'.
+Set whenever minibuffer is entered or input is completed.")
+
+(defvar icicle-default-thing-insertion-flipped-p nil
+  "Non-nil means a previous `M-.' in this succession was used with `C-u'.
+This means that the meaning of `icicle-default-thing-insertion' has
+been reversed.")
+
+(defvar icicle-delete-candidate-object nil
+  "Defines deletion action for command `icicle-delete-candidate-object'.
+The value can be a function or a symbol bound to an alist.
+
+If the value is a function, then the function is called on the current
+completion candidate (a string) to delete some corresponding object.
+
+If the value is a symbol (variable) bound to an alist, then
+`icicle-delete-current-candidate-object' is called to delete the
+corresponding object from that alist.  If the variable is also a user
+option, then the option is saved after the candidate is deleted.
+
+Note that if the value is a variable and you use multi-completion
+candidates during completion, then the alist value of the variable
+must itself contain multi-completions.  Otherwise, no candidate will
+be deleted, because `icicle-delete-current-candidate-object' deletes
+the full candidate object.")
+
+(defvar icicle-dictionary-history nil "History for dictionary entries.")
+
+(defvar icicle-dir-candidate-can-exit-p nil
+  "Non-nil means you can exit the minibuffer when you choose a directory.")
+
+(defvar icicle-doc-history () "History for documentation entries.")
+
+(defvar icicle-doc-last-initial-cand-set ()
+  "Cache for initial set of completion candidates for `icicle-doc'.")
+
+(defvar icicle-dot-string-internal icicle-dot-string
+  "Internal version of `icicle-dot-string' (same values).
+This is changed automatically by Icicles when you switch completion
+mode, whereas `icicle-dot-string' is changed only via user commands.")
+
+(defvar icicle-edit-update-p nil
+  "Internal flag: non-nil when editing text in minibuffer.
+More precisely, non-nil when updating the completions list inside
+simple character-editing commands such as `icicle-self-insert' and
+`icicle-delete-backward-char'.")
+
+(defvar icicle-explore-final-choice ""
+  "Final `icicle-explore' completion choice (a string).")
+
+(defvar icicle-explore-final-choice-full nil
+  "Full alist element that corresponds to `icicle-explore-final-choice'.
+This is an element of `icicle-candidates-alist'.
+The element's car is a completion-candidate string.")
+
+(defvar icicle-extra-candidates nil "A list of extra completion candidates (strings).")
+
+(defvar icicle-extra-candidates-dir-insert-p t
+  "Non-nil means, for an extra candidate, insert a directory component.
+Can be bound to nil to prevent adding a directory to non file-name
+extra candidates during file-name completion.  An extra candidate is
+one that is a member of `icicle-extra-candidates'.")
+
+(defvar icicle-face-name-history nil "History for font names.")
+
+(defvar icicle-fancy-candidates-p nil
+  "Non-nil means we are completing using possibly fancy candidates.
+That is, some candidates might have attached properties.
+
+You can bind this in your code if you need to treat fancy candidates
+and your code has no direct access to the `completing-read' PROMPT
+string.  See section `Candidates with Text Properties' of the Icicles
+doc.
+
+If you set this to non-nil, instead of binding it, then Icicles will
+always check whether each completion candidate might be fancy.  That
+can be costly.")
+
+(defvar icicle-fancy-cands-internal-p nil
+  "Same as `icicle-fancy-candidates-p', but for internal use only.
+Do not set or bind this.  This is bound only by `completing-read'.")
+
+(defvar icicle-file-sort-first-time-p t
+  "Non-nil means file-name completion has not yet been used.")
+
+(defvar icicle-filtered-default-value nil
+  "Minibuffer default value, after filtering with `icicle-filter-wo-input'.")
+
+(defvar icicle-font-name-history nil "History for font names.")
+
+(defvar icicle-frame-alist nil "Alist of frames, returned by `icicle-make-frame-alist'.")
+
+(defvar icicle-frame-name-history nil "History for frame names.")
+
+(defvar icicle-full-cand-fn nil
+  "nil or a function to create a full candidate from a display candidate.
+If candidates are currently multi-completions then the display
+candidate is assumed to have been transformed first (using
+`icicle-transform-multi-completion').")
+
+(defvar icicle-function-name-history nil "History for function names.
+Each name is a symbol name or a lambda form, as a string.")
+
+(defvar icicle-fundoc-last-initial-cand-set ()
+  "Cache for initial set of completion candidates for `icicle-fundoc'.")
+
+(defvar icicle-general-help-string "
+ 
+
+Customize Icicles: `M-x icicle-customize-icicles-group'.
+Summary of customizable options and faces (alphabetical order).
+
+Some of the options can be toggled or cycled - the keys for this are
+noted in parentheses.
+
+* `case-fold-search', `completion-ignore-case',
+  (`C-u') `read-file-name-completion-ignore-case'
+                                         - Case sensitivity? (`C-A')
+* `completion-ignored-extensions'        - Ignored filenames (`C-.')
+* `icicle-act-before-cycle-flag'         - Act then cycle or reverse?
+* `icicle-add-proxy-candidates-flag'     - Include proxies? (`C-M-_')
+* `icicle-alternative-actions-alist'     - Overriding alt actions
+* `icicle-alternative-sort-comparer'     - Other sort (`M-,', `C-M-,')
+* `icicle-apropos-complete-keys*'        - Keys to apropos-complete
+* `icicle-apropos-cycle-*-keys'          - Keys to apropos-cycle
+* `icicle-bookmark-name-length-max'      - Max length of bookmark name
+* `icicle-bookmark-refresh-cache-flag'   - Refresh bookmarks cache?
+* `icicle-top-level-key-bindings'        - Bind top-level commands
+* `icicle-buffer-*'                      - `icicle-buffer' options
+* `icicle-candidate-width-factor'        - Width %%, candidate columns
+* `icicle-change-region-background-flag' - Change region color?
+* `icicle-change-sort-order-completion-flag' - Control `C-,' behavior
+* `icicle-C-l-uses-completion-flag'      - `C-l' uses completion?
+* `icicle-color-themes'                  - For `icicle-color-theme'
+* `icicle-comint-dynamic-complete-replacements' - Comint complete fns
+* `icicle-command-abbrev*'               - Command abbrev behavior
+* `icicle-complete-key-anyway-flag'      - `S-TAB' must complete keys
+* `icicle-complete-keys-self-insert-ranges'- `S-TAB' for self-insert?
+* `icicle-completing-read+insert-keys'   - Keys for complete-on-demand
+* `icicle-completion-history-max-length' - Completion history length
+* `icicle-Completions-display-min-input-chars'- Remove `*Completions*'
+                                           if fewer chars input
+* `icicle-completions-format'            - `*Completions*' layout
+* `icicle-move-Completions-frame'        - `*Completions*' at edge?
+* `icicle-Completions-text-scale-decrease'- `*Completions*' shrink
+* `icicle-Completions-window-max-height' - Max lines, `*Completions*'
+* `icicle-customize-save-flag'           - Save some options on quit?
+* `icicle-cycle-into-subdirs-flag'       - Explore subdirectories?
+* `icicle-default-cycling-mode'          - Default completion mode for
+                                           per-mode cycling
+* `icicle-default-thing-insertion'       - Control behavior of \
+\\\\[icicle-insert-string-at-point]
+* `icicle-default-value'                 - How to treat default value
+* `icicle-define-alias-commands-flag'    - Define top-level aliases?
+* `icicle-deletion-action-flag'          - `S-delete' deletes?
+* `icicle-dot-show-regexp-flag'          - Show regexp for `.'?
+* `icicle-dot-string'                    - String that `.' inserts
+* `icicle-expand-input-to-common-match-flag'- Expand input? (`C-;')
+* `icicle-file-*'                        - `icicle-file' options
+* `icicle-filesets-as-saved-completion-sets-flag'- Use filesets?
+* `icicle-guess-commands-in-path'        - Shell commands to complete
+* `icicle-help-in-mode-line-delay'       - Secs to show candidate help
+* `icicle-hide-common-match-in-Completions-flag'- Show common match?
+* `icicle-hide-non-matching-lines-flag'  - Hide non-match lines?
+* `icicle-highlight-historical-candidates-flag'
+                                         - Highlight past input?
+* `icicle-highlight-input-completion-failure*'- Input non-match sign
+* `icicle-highlight-input-initial-whitespace-flag'
+                                         - Highlight input whitespace?
+* `icicle-highlight-lighter-flag'        - Highlight mode-line `Icy'
+* `icicle-ignore-space-prefix-flag'      - See initial space? (`M-_')
+* `icicle-incremental-completion-delay'  - Delay before update cands
+* `icicle-incremental-completion-flag'   - Icompletion? (`C-#')
+* `icicle-incremental-completion-threshold'- # of candidates for delay
+* `icicle-inhibit-advice-functions'      - Advice-inhibited functions
+* `icicle-inhibit-ding-flag'             - Suppress audible bell
+* `icicle-input-string'                  - String inserted by `C-='
+* `icicle-inter-candidates-min-spaces'   - Min spaces among candidates
+* `icicle-isearch-complete-keys'         - Keys to complete search
+* `icicle-key-complete-keys'             - Keys to complete keys
+* `icicle-key-descriptions-use-<>-flag'  - Show key names with \"<>\"?
+* `icicle-keymaps-for-key-completion'    - `S-TAB' = key-complete maps
+* `icicle-kmacro-ring-max'               - Icicles `kmacro-ring-max'
+* `icicle-levenshtein-distance'          - Levenshtein match distance
+* `icicle-list-join-string'              - Multi-completion join
+* `icicle-list-nth-parts-join-string'    - Join split-candidate parts
+* `icicle-mark-position-in-candidate'    - Mark position in cycling
+* `icicle-menu-items-to-history-flag'    - Add menus to history?
+* `icicle-minibuffer-setup-hook'         - Functions run after setup
+* `icicle-modal-cycle-*-keys'            - Keys for modal cycling
+* `icicle-option-type-prefix-arg-list'   - Prefix-args for `C-h C-o'
+* `icicle-point-position-in-candidate'   - Cursor position in cycling
+* `icicle-populate-interactive-history-flag'- Track interactive use?
+* `icicle-pp-eval-expression-print-*'    - Print control for `pp-*'
+* `icicle-prefix-complete-keys*'         - Keys to prefix-complete
+* `icicle-prefix-cycle-*-keys'           - Keys to prefix-cycle
+* `icicle-previous-candidate-keys'       - Back keys, `*Completions*'
+* `icicle-quote-shell-file-name-flag'    - Quote file name in shell?
+* `icicle-read+insert-file-name-keys'    - Keys for on-demand file
+* `icicle-regexp-quote-flag'             - Escape chars? (`C-`')
+* `icicle-regexp-search-ring-max'        - `regexp-search-ring-max'
+* `icicle-region-background'             - Background for region
+* `icicle-require-match-flag'            - Override REQUIRE-MATCH?
+* `icicle-saved-completion-sets'         - Completion sets for \
+`\\[icicle-candidate-set-retrieve]'
+* `icicle-search-cleanup-flag'           - Remove search highlighting?
+                                           (`C-.')
+* `icicle-search-from-isearch-keys'      - Isearch-to-Icicles keys
+* `icicle-search-highlight-all-current-flag'- In each hit (`C-^')
+* `icicle-search-highlight-context-levels-flag' -
+                                           Highlight match subgroups?
+* `icicle-search-highlight-threshold'    - # hits to highlight at once
+* `icicle-search-hook'                   - Functions run by `C-c `'
+* `icicle-search-replace-common-match-flag' - Replace ECM? (`M-;')
+* `icicle-search-replace-literally-flag' - Replace text literally?
+* `icicle-search-replace-whole-candidate-flag' - Replace input match
+                                           or whole search hit?(`M-_')
+* `icicle-search-ring-max'               - Icicles `search-ring-max'
+* `icicle-search-whole-word-flag'        - Find whole words? (`M-q')
+* `icicle-show-Completions-help-flag'    - Show `*Completions*' help?
+* `icicle-show-Completions-initially-flag'- Show `*Completions*' 1st?
+* `icicle-show-multi-completion-flag'    - Show extra candidate info?
+* `icicle-sort-comparer'                 - Sort candidates (`C-,')
+* `icicle-sort-orders-alist'             - Predicates for sorting
+* `icicle-special-candidate-regexp'      - To highlight special cands
+* `icicle-S-TAB-completion-methods-alist'- `S-TAB' methods (`M-(')
+* `icicle-swank-*'                       - Swank completion control
+* `icicle-TAB-completion-methods'        - `TAB' methods (`C-(')
+* `icicle-TAB-shows-candidates-flag'     - 1st `TAB' shows candidates?
+* `icicle-test-for-remote-files-flag'    - Check remote files? (`C-^')
+* `icicle-thing-at-point-functions'      - Functions to yank things
+* `icicle-top-level-key-bindings'        - Top-level key bindings
+* `icicle-top-level-when-sole-completion-*'- Exiting if one completion
+* `icicle-touche-pas-aux-menus-flag'     - Add to standard menus?
+* `icicle-transform-function'            - Remove duplicates (`C-$')
+* `icicle-type-actions-alist'            - Objects and their types
+* `icicle-unpropertize-completion-result-flag'- Properties in result?
+* `icicle-update-input-hook'             - Fns run when input changes
+* `icicle-use-~-for-home-dir-flag'       - Use `~' for $HOME? (`M-~')
+* `icicle-use-C-for-actions-flag'        - `C-' for actions? (`M-g')
+* `icicle-use-candidates-only-once-flag' - Remove used candidate?
+* `icicle-word-completion-keys'          - Keys for word completion
+* `icicle-WYSIWYG-Completions-flag'      - WYSIWYG `*Completions*'?
+* `icicle-yank-function'                 - Yank function to use
+
+Faces that highlight input in minibuffer.
+
+* `icicle-complete-input'               - Input when it is complete
+* `icicle-completion'                   - Completing?
+* `icicle-input-completion-fail*'       - Non-match part of input
+* `icicle-match-highlight-minibuffer'   - Matched part of input
+* `icicle-multi-command-completion'     - Multi-command completion?
+* `icicle-mustmatch-completion'         - Strict completion?
+* `icicle-whitespace-highlight'         - Initial whitespace in input
+
+Faces that highlight candidates in buffer `*Completions*'.
+
+* `icicle-candidate-part'               - Part of candidate
+* `icicle-common-match-highlight-Completions' - Max common substring
+* `icicle-current-candidate-highlight'  - Current candidate (cycling)
+* `icicle-extra-candidate'              - Extra candidate
+* `icicle-historical-candidate'         - Highlight candidates used
+* `icicle-match-highlight-Completions'  - Matched part of input
+* `icicle-proxy-candidate'              - Proxy candidate
+* `icicle-saved-candidate'              - Saved candidate
+* `icicle-special-candidate'            - Special candidate
+
+Faces that highlight information in the mode line.
+
+* `icicle-completion'                   - Completing?
+* `icicle-mode-line-help'               - Candidate help
+* `icicle-multi-command-completion'     - Multi-command completion?
+* `icicle-mustmatch-completion'         - Strict completion?
+
+Faces that highlight for command `icicle-search'.
+
+* `icicle-search-context-level-*'       - Regexp subgroup highlighting
+* `icicle-search-current-input'         - What input matches
+* `icicle-search-main-regexp-current'   - Current match of 1st regexp
+* `icicle-search-main-regexp-others'    - Other matches of 1st regexp
+ 
+
+Some top-level Icicles commands (alphabetical order, with exceptions).
+
+Some are bound in Icicle mode.  Bind the others to keys you like.
+See recommended bindings in `icicles.el'.
+Multi-commands are indicated by `+': They act any number of times.
+You can tell a multi-command when you execute it by the fact that the
+input prompt is prefixed by `+'.
+
++ `clear-option' (alias)               - Set binary option to nil
++ `icicle-add-buffer-candidate'        - To always-candidate buffer
++ `icicle-remove-buffer-candidate'     -   From same
+  `icicle-add-buffer-config'           - To `icicle-buffer-configs'
++ `icicle-remove-buffer-config'        -   From same
+  `icicle-add/update-saved-completion-set' - To
+                                        `icicle-saved-completion-sets'
++ `icicle-remove-saved-completion-set' -   From same
+  `icicle-add-entry-to-saved-completion-set' - Add completion to a set
+  `icicle-remove-entry-from-saved-completion-set' - Remove from set
++ `icicle-apply'                       - Apply function to alist items
+  `icicle-apropos'                     - `apropos', but shows matches
+  `icicle-apropos-command'             - Enhanced `apropos-command'
+  `icicle-apropos-variable'            - Enhanced `apropos-variable'
+  `icicle-apropos-zippy'               - Show matching Zippy quotes
++ `icicle-bookmark'(`-other-window')   - Jump to a bookmark
++ `icicle-bookmark-bookmark-list'      - Jump to bookmark list
++ `icicle-bookmark-desktop'            - Jump to desktop bookmark
++ `icicle-bookmark-dired-other-window' - Jump to a Dired bookmark
++ `icicle-bookmark-file-other-window'  - Jump to a file bookmark
++ `icicle-bookmark-gnus-other-window'  - Jump to a Gnus bookmark
++ `icicle-bookmark-info-other-window'  - Jump to an Info bookmark
++ `icicle-bookmark-local-file-other-window' - Jump to a local file
++ `icicle-bookmark-man-other-window'   - Jump to a `man'-page bookmark
++ `icicle-bookmark-non-file-other-window' - Jump to buffer bookmark
++ `icicle-bookmark-region-other-window' - Jump to a region bookmark
++ `icicle-bookmark-remote-file-other-window' - Jump to a remote file
++ `icicle-bookmark-url-other-window'   - Jump to a URL bookmark
++ `icicle-buffer'(`-other-window')     - Switch to buffer (`C-x b')
++ `icicle-buffer-config'               - Pick `icicle-buffer' options
++ `icicle-buffer-list'                 - Choose a list of buffer names
+  `icicle-change-alternative-sort-order' - Choose an alternative sort
+  `icicle-change-sort-order'           - Choose a sort order
++ `icicle-choose-faces'                - Choose a list of face names
++ `icicle-choose-invisible-faces'      - Choose invisible face names
++ `icicle-choose-visible-faces'        - Choose visible face names
++ `icicle-clear-current-history'       - Clear current history entries
++ `icicle-clear-history'               - Clear entries from a history
++ `icicle-color-theme'                 - Change color theme
++ `icicle-comint-command'              - Reuse command (`C-c TAB')
+  `icicle-comint-dynamic-complete'     - Text completion in shell
++ `icicle-comint-search'               - Reuse command (`C-c `')
++ `icicle-command-abbrev'              - `M-x' + abbrevs (`C-x SPC')
++ `icicle-compilation-search'          - Search, show hits (`C-c `')
++ `icicle-complete-keys'               - Complete keys (`S-TAB')
+  `icicle-complete-thesaurus-entry'    - Complete word (`C-c /')
++ `icicle-completing-yank'             - `yank' using completion
++ `icicle-customize-face'              - Multi-`customize-face'
+  `icicle-customize-icicles-group'     - Customize options and faces
++ `icicle-delete-file'                 - Delete file/directory
+  `icicle-delete-window'               - Delete window (`C-u': buffer)
++ `icicle-delete-windows'              - Delete windows (`C-u C-x 0')
++ `icicle-dired'                       - Multi-command Dired
++ `icicle-doc'                         - Show doc for fn, var, or face
+  `icicle-doremi-candidate-width-factor+' - +/- candidate column width
+  `icicle-doremi-increment-max-candidates+' - +/ max candidates shown
+  `icicle-doremi-increment-swank-prefix-length+' - +/- swank prefix
+  `icicle-doremi-increment-swank-timeout+' - +/- swank match timeout
+  `icicle-doremi-increment-variable+'  - Increment var using Do Re Mi
+  `icicle-doremi-inter-candidates-min-spaces+' - +/- candidate spacing
+  `icicle-doremi-zoom-Completions+'    - +/- `*Completions*' text size
++ `icicle-execute-extended-command'    - Multi-command `M-x'
++ `icicle-execute-named-keyboard-macro' - Execute named keyboard macro
+  `icicle-face-list'                   - Choose a list of face names
+  `icicle-file-list'                   - Choose a list of file names
++ `icicle-file'(`-other-window')       - Visit file/dir (`C-x C-f')
++ `icicle-find-file'(`-other-window')  -         same: relative only
++ `icicle-find-file-absolute'(`-other-window') - same: absolute only
++ `icicle-find-file-in-tags-table'(`-other-window') - Tags-table file
++ `icicle-find-first-tag'(`-other-window') - Find source def (tag)
++ `icicle-find-tag'                    - Find definition (tag) (`M-.')
++ `icicle-font'                        - Change font of frame
++ `icicle-frame-bg'                    - Change background of frame
++ `icicle-frame-fg'                    - Change foreground of frame
++ `icicle-fundoc'                      - Show function description
++ `icicle-goto-global-marker'          - Go to a global marker
++ `icicle-goto-marker'                 - Go to a marker in this buffer
++ `icicle-hide-faces'                  - Hide faces you choose
++ `icicle-hide-only-faces'             - Hide some faces; show others
++ `icicle-imenu*'                      - Navigate among Imenu entries
+  `icicle-increment-option'            - Increment a numeric option
+  `icicle-increment-variable'          - Increment a numeric variable
++ `icicle-Info-goto-node'              - Multi-cmd `Info-goto-node'
++ `icicle-Info-index'                  - Multi-command `Info-index'
++ `icicle-Info-menu'                   - Multi-command `Info-menu'
+  `icicle-Info-virtual-book'           - Open a virtual Info book
+  `icicle-insert-buffer'               - Multi-command `insert-buffer'
++ `icicle-insert-thesaurus-entry'      - Insert thesaurus entry
++ `icicle-keyword-list'                - Choose a list of keywords
++ `icicle-kill-buffer'                 - Kill buffer (`C-x k')
++ `icicle-kmacro'                      - Call keyboard macro (`S-f4')
++ `icicle-locate-file'(`-other-window') - Visit file in a directory
+  `icicle-minibuffer-help'             - Show Icicles minibuffer help
+  `icy-mode' or `icicle-mode'          - Toggle Icicle mode
+  `icicle-next-S-TAB-completion-method' - Next `S-TAB' method (`M-(')
+  `icicle-next-TAB-completion-method'  - Next `TAB' method (`C-(')
++ `icicle-occur'                       - Incremental `occur' (`C-c '')
++ `icicle-other-window-or-frame'       - Other window/frame (`C-x o')
++ `icicle-pick-color-by-name'          - Pick a color name in palette
++ `icicle-plist'                       - Show symbols, property lists
++ `icicle-recent-file'(`-other-window') - Open recently used file
+  `icicle-recompute-shell-command-candidates' - Update from $PATH
++ `icicle-remove-file-from-recentf-list' - Remove from recent files
++ `icicle-reset-option-to-nil'         - Set binary option to nil
+  `icicle-save-string-to-variable'     - Save text for use with \
+`\\[icicle-insert-string-from-variable]'
++ `icicle-search'                      - Search (`C-c `')
++ `icicle-search-bookmark'             - Search bookmarks separately
++ `icicle-search-bookmark-list-bookmark' - Search bookmark lists
++ `icicle-search-bookmarks-together'   - Search bookmarks together
++ `icicle-search-char-property'        - Search for overlay/text props
++ `icicle-search-dired-bookmark'       - Search Dired bookmarks
++ `icicle-search-dired-marked'         - Search marked files in Dired
++ `icicle-search-file'                 - Search multiple files
++ `icicle-search-file-bookmark'        - Search bookmarked files
++ `icicle-search-gnus-bookmark'        - Search bookmarked Gnus msgs
++ `icicle-search-ibuffer-marked'       - Search marked bufs in Ibuffer
++ `icicle-search-info-bookmark'        - Search bookmarked Info nodes
++ `icicle-search-keywords'             - Search for keywords (`C-c ^')
++ `icicle-search-local-file-bookmark'  - Search bookmarked local files
++ `icicle-search-man-bookmark'         - Search bookmarked `man' pages
++ `icicle-search-non-file-bookmark'    - Search bookmarked buffers
++ `icicle-search-overlay-property'     - Search for overlay properties
++ `icicle-search-pages'                - Search Emacs pages
++ `icicle-search-paragraphs'           - Search Emacs paragraphs
++ `icicle-search-region-bookmark'      - Search bookmarked regions
++ `icicle-search-remote-file-bookmark' - Search remote bookmarks
++ `icicle-search-sentences'            - Search sentences as contexts
++ `icicle-search-text-property'        - Search for face... (`C-c \"')
++ `icicle-search-url-bookmark'         - Search bookmarked URLs
++ `icicle-search-word'                 - Whole-word search
++ `icicle-select-bookmarked-region'    - Select bookmarked regions
++ `icicle-select-frame'                - Select a frame by name
++ `icicle-select-window'               - Select window by buffer name
+  `icicle-send-bug-report'             - Send Icicles bug report
++ `icicle-set-option-to-t'             - Set binary option to t
++ `icicle-show-faces'                  - Show chosen invisible faces
++ `icicle-show-only-faces'             - Show some faces; hide others
+  `icicle-toggle-~-for-home-dir'       - Toggle using `~' for $HOME
+  `icicle-toggle-alternative-sorting'  - Swap alternative sort
+  `icicle-toggle-angle-brackets'       - Toggle using angle brackets
+  `icicle-toggle-C-for-actions'        - Toggle using `C-' for actions
+  `icicle-toggle-case-sensitivity'     - Toggle case sensitivity
+  `icicle-toggle-dot'                  - Toggle `.' matching newlines
+  `icicle-toggle-expand-to-common-match' - Toggle input ECM expansion
+  `icicle-toggle-hiding-common-match'  - Toggle match, `*Completions*'
+  `icicle-toggle-highlight-all-current' - Toggle max search highlight
+  `icicle-toggle-highlight-historical-candidates'
+                                       - Toggle past-input highlight
+  `icicle-toggle-highlight-saved-candidates'
+                                       - Toggle highlighting saved
+  `icicle-toggle-ignored-extensions'   - Toggle ignored files
+  `icicle-toggle-ignored-space-prefix' - Toggle ignoring space prefix
+  `icicle-toggle-incremental-completion' - Toggle apropos icompletion
++ `icicle-toggle-option'               - Toggle binary user option
+  `icicle-toggle-proxy-candidates'     - Toggle proxy candidates
+  `icicle-toggle-regexp-quote'         - Toggle regexp escaping
+  `icicle-toggle-search-cleanup'       - Toggle search highlighting
+  `icicle-toggle-search-replace-common-match' - Toggle ECM replacement
+  `icicle-toggle-search-whole-word'    - Toggle whole-word searching
+  `icicle-toggle-show-multi-completion' - Toggle multi-completions
+  `icicle-toggle-sorting'              - Toggle sorting of completions
+  `icicle-toggle-transforming'         - Toggle duplicate removal
+  `icicle-toggle-WYSIWYG-Completions' - Toggle WYSIWYG `*Completions*'
++ `icicle-vardoc'                      - Show variable description
++ `icicle-where-is'                    - `where-is' multi-command
+  `icicle-yank-maybe-completing'       - `yank' + completion (`C-y')
++ `toggle' (alias)                     - Toggle binary user option
+ 
+
+These are all of the top-level bindings in Icicle mode:
+
+\\{icicle-mode-map}"
+  "General help string included in `icicle-minibuffer-help'.")
+
+(defvar icicle-get-alist-candidate-function 'icicle-get-alist-candidate
+  "Function used to retrieve a full completion candidate.
+The signature must match that of the default value,
+`icicle-get-alist-candidate'.")
+
+(defvar icicle-hist-cands-no-highlight ()
+  "List of candidates not highlighted using `icicle-historical-candidate'.
+Bind, don't assign this, since the same string can have different
+meanings in different contexts.")
+
+(defvar icicle-ignored-extensions completion-ignored-extensions
+  "Copy of `completion-ignored-extensions', serving as a control flag.
+When `completion-ignored-extensions' changes, we remake
+`icicle-ignored-extensions-regexp'.")
+
+(defvar icicle-ignored-extensions-regexp
+  (concat "\\(" (mapconcat #'regexp-quote completion-ignored-extensions "$\\|")
+          "$\\)\\'")
+  "Regular expression matching ignored file extensions.
+If this is nil, then no file extensions are ignored.
+The ignored file extensions come from `completion-ignored-extensions'.")
+
+(defvar icicle-incremental-completion-p nil
+  "Takes the place of `icicle-incremental-completion-flag' during input.
+The program updates this to `always' from `t' after `*Completions*' has
+been displayed.")
+
+(defvar icicle-Info-only-rest-of-book-p nil
+  "Non-nil means complete only Info nodes from the rest of the book.")
+
+(defvar icicle-inhibit-sort-p nil
+  "Non-nil means that users cannot sort completion candidates.
+They also cannot remove duplicates.")
+
+(defvar icicle-inhibit-try-switch-buffer nil
+  "Non-nil means do not switch back to `icicle-orig-buff'.
+\(The potential switching is in `icicle-try-switch-buffer'.)")
+
+(defvar icicle-initial-value ""
+  "Initial value used in minibuffer completion.
+Any function that reads from the minibuffer and accepts a default
+value or initial value should, before reading, put that value in
+`icicle-initial-value'.  For example, `completing-read' does that.
+
+In addition, `completing-read' and `read-file-name' will respect this
+value, using it as the initial value if none is provided explicitly.
+This means that you can bind `icicle-initial-value' around an
+expression that calls `completing-read' or `read-file-name', and the
+bound value will be used as the initial value.")
+
+(defvar icicle-input-completion-fail-overlay nil
+  "Overlay used to highlight the input portion that does not complete.")
+
+(defvar icicle-input-fail-pos nil
+  "Position in minibuffer of start of completion match failure.
+Nil means no match failure is known.")
+
+(defvar icicle-insert-string-at-pt-end nil
+  "Position of end of text `icicle-insert-string-at-point' inserted.")
+
+(defvar icicle-insert-string-at-pt-start nil
+  "Position of start of text `icicle-insert-string-at-point' inserted.")
+
+(defvar icicle-interactive-history ()
+  "History of commands called using `call-interactively'.")
+
+(defvar icicle-key-prefix-description ""
+  "Description of a prefix key at some point during key completion.") 
+
+(defvar icicle-kill-history nil "History of kill-ring entries.")
+
+(when (boundp 'kmacro-ring)             ; Emacs 22+
+  (defvar icicle-kmacro-alist nil
+    "Alist with elements (CANDIDATE-NAME . RING-ITEM).
+CANDIDATE-NAME is 1, 2, 3....
+
+RING-ITEM is an item in `kmacro-ring' or `(kmacro-ring-head)'.")
+  (defvar icicle-kmacro-history nil "History for keyboard-macro names."))
+
+(defvar icicle-last-apropos-complete-match-fn 'string-match
+  "Last value of `icicle-apropos-complete-match-fn'.")
+
+(defvar icicle-last-completion-candidate ""
+  "Last completion candidate used in minibuffer completion.")
+
+(defvar icicle-last-completion-command nil "Last completion command used.")
+
+(defvar icicle-last-input "" "Last minibuffer input typed (not from cycling).")
+
+(defvar icicle-last-sort-comparer (or icicle-sort-comparer 'icicle-case-string-less-p)
+  "Local copy of `icicle-sort-comparer', so we can restore it.")
+
+(defvar icicle-last-top-level-command nil "Last top-level command used.")
+
+(defvar icicle-last-transform-function (or icicle-transform-function
+                                           'icicle-remove-duplicates)
+  "Local copy of `icicle-transform-function', so we can restore it.")
+
+(defvar icicle-lighter-truncation "..."
+  "String appended to Icy lighter to show candidates-list truncation.")
+
+(defvar icicle-list-use-nth-parts nil
+  "List of indexes of multi-completion pieces to use.
+This is not an internal variable.  You can bind this in your own Lisp
+code to affect completion behavior.
+
+An empty list means use the entire multi-completion.  Otherwise,
+concatenate, in order, the Nth parts of the multi-completion, where N
+is each of the (one-based) indexes, in turn.  Any index larger than
+the actual number of parts in the multi-completion means use the last
+part.
+
+For example: If the value is (1), then use only the first part of the
+multi-completion as the completion candidate. If the value is (2 1),
+then use as candidate the second part followed by the first part, the
+two parts being joined by option `icicle-list-nth-parts-join-string'.
+If the value is (1 99) and the multi-completion has fewer than 99
+parts, then use the first and last parts, joined by
+`icicle-list-nth-parts-join-string'.  If the value is (2 1 2), then
+use the second part, first part, and second part again - you can use a
+given part any number of times.")
+
+(defvar icicle-menu-map nil "Icicles menu-bar menu keymap.")
+
+(defvar icicle-minibuffer-message-ok-p t
+  "Non-nil means we can show messages in minibuffer.
+This affects only `icicle-msg-maybe-in-minibuffer'.")
+
+(defvar icicle-minor-mode-map-entry nil "Icicles mode entry in `minor-mode-map-alist'.")
+
+(defvar icicle-ms-windows-drive-hash (and (fboundp 'make-hash-table)
+                                          (make-hash-table :test 'equal))
+  "Hash table for caching result of MS Windows `NET USE' system calls.
+For Emacs 20 and 21, this is not used unless you load library `cl.el'
+at runtime.")
+
+(defvar icicle-must-match-regexp nil
+  "A regexp that completion candidates must match, or nil.
+If nil, then this does nothing.  If a regexp (string), then show only
+candidates whose display form matches it (and matches the user input).
+The display form is the string shown in `*Completions*'.
+
+Note: This is similar to the standard variable
+`completion-regexp-list', except:
+* `completion-regexp-list' is a list of regexps, not just one.
+* `icicle-must-match-regexp' is used after filtering using option
+  `icicle-transform-function'.
+
+See also `icicle-must-not-match-regexp'.")
+
+(defvar icicle-must-not-match-regexp nil
+  "A regexp that completion candidates must not match, or nil.
+If nil, then this does nothing.  If a regexp (string), then show only
+candidates whose display form does not match it.
+The display form is the string shown in `*Completions*'.
+See also `icicle-must-match-regexp'.")
+
+(defvar icicle-must-pass-after-match-predicate nil
+  "Predicate that completions must satisfy after matching input, or nil.
+This is just like `icicle-must-pass-predicate', except that it is
+applied only to display candidates that match your current input.")
+
+(defvar icicle-must-pass-predicate nil
+  "Predicate that completion display candidates must satisfy, or nil.
+If nil, then this does nothing.  Otherwise, this is a function of one
+argument, a display candidate (a string), and only the display
+candidates that satisfy the predicate are displayed.  A display
+candidate is a string of text such as you see in buffer
+`*Completions*'.
+
+Note that this predicate is different from the PREDICATE argument for
+function `completing-read' or `read-file-name'.  The latter applies to
+the elements of the COLLECTION argument, which are typically alist
+entries or obarray symbols.  `icicle-must-pass-predicate' applies
+instead to a string, the display form of a completion candidate.
+
+See also `icicle-must-pass-after-match-predicate'.")
+
+(defvar icicle-nb-candidates-before-truncation 0
+  "Number of candidates, before truncation per `icicle-max-candidates'.")
+
+(defvar icicle-nb-of-other-cycle-candidates 0
+  "Number of other candidates available for cycling.
+This is for use by other libraries, in particular, `icomplete+.el'.")
+
+(defvar icicle-new-last-cmd nil
+  "Copy of current command being executed.
+Used by, e.g., `icicle-execute-extended-command'.")
+
+(defvar icicle-next-apropos-complete-cycles-p nil
+  "Whether the next apropos-completion command should cycle.")
+
+(defvar icicle-next-prefix-complete-cycles-p nil
+  "Whether the next prefix-completion command should cycle.")
+
+(defvar icicle-old-read-file-name-fn (and (not (boundp 'read-file-name-function)) ; Em 22+
+                                          'orig-read-file-name) ; Emacs 20, 21
+  "Value of `read-file-name-function' outside of Icicle mode.
+For versions of Emacs < 22, this is the original `read-file-name'.")
+
+(defvar icicle-orig-buff nil
+  "Current buffer when you invoked an Icicles multi-command.")
+
+(defvar icicle-orig-must-pass-after-match-pred nil
+  "Saved value of `icicle-must-pass-after-match-predicate'.")
+
+(defvar icicle-orig-pt-explore nil
+  "Point when you invoked `icicle-explore'.")
+
+(defvar icicle-orig-window nil
+  "Selected window when you invoked an Icicles multi-command.")
+
+(defvar icicle-orig-win-explore nil
+  "Selected window when you invoked `icicle-explore'.")
+
+(defvar icicle-other-window nil
+  "Window scrolled by `icicle-scroll-forward'/`icicle-scroll-backward'")
+
+(defvar icicle-plist-last-initial-cand-set ()
+  "Cache for initial set of completion candidates for `icicle-plist'.")
+
+(defvar icicle-post-command-hook nil
+  "Functions added to `post-command-hook' when in Icicle mode.
+Use command `icy-mode' (aka `icicle-mode') to set this up properly.")
+
+(defvar icicle-pre-command-hook nil
+  "Functions added to `pre-command-hook' when in Icicle mode.
+Use command `icy-mode' (aka `icicle-mode') to set this up properly.")
+
+(defvar icicle-predicate-types-alist
+  '(("arrayp") ("atom") ("auto-save-file-name-p" . "file") ("backup-file-name-p" . "file")
+    ("booleanp") ("bool-vector-p") ("bufferp" . "buffer")
+    ("byte-code-function-p" . "function") ("byte-compile-const-symbol-p" . "symbol")
+    ("case-table-p") ("char-or-string-p") ("char-table-p") ("color-defined-p" . "color")
+    ("commandp" . "command") ("consp") ("custom-variable-p" . "option")
+    ("display-table-p") ("facep" . "face") ("fboundp" . "function")
+    ("ffap-file-remote-p" . "file") ("file-accessible-directory-p" . "file")
+    ("file-directory-p" . "file") ("file-executable-p" . "file")
+    ("file-exists-p" . "file") ("file-name-absolute-p" . "file")
+    ("file-readable-p" . "file") ("file-regular-p" . "file") ("file-remote-p" . "file")
+    ("file-symlink-p" . "file") ("file-writable-p" . "file") ("floatp")
+    ("frame-configuration-p") ("frame-iconified-p" . "frame") ("frame-live-p" . "frame")
+    ("frame-visible-p" . "frame") ("framep" . "frame") ("functionp" . "function")
+    ("hash-table-p") ("icicle-binary-option-p" . "option") ("info-file-exists-p" . "file")
+    ("integer-or-marker-p") ("integerp") ("keymapp") ("keywordp") ("listp")
+    ("local-variable-p" . "variable") ("markerp") ("wholenump") ("nlistp") ("numberp")
+    ("number-or-marker-p") ("overlayp") ("processp" . "process")
+    ("process-running-child-p" . "process") ("risky-local-variable-p" . "variable")
+    ("safe-local-variable-p" . "variable") ("sequencep") ("string-or-null-p") ("stringp")
+    ("subrp") ("symbolp" . "symbol") ("syntax-table-p")
+    ("thumfr-thumbnail-frame-p" . "frame") ("truncated-partial-width-window-p" . "window")
+    ("user-variable-p" . "option") ("vectorp") ("window-configuration-p")
+    ("window-fixed-size-p" . "window") ("window-full-width-p" . "window")
+    ("window-live-p" . "window") ("window-minibuffer-p" . "window") ("windowp" . "window")
+    ("window-safely-shrinkable-p" . "window") ("x-color-defined-p" . "color"))
+  "Alist of type names that are predicate names.
+Each element is cons of a predicate name and the associated type from
+`icicle-type-actions-alist' (or nil if there is no associated type).")
+
+(defvar icicle-pref-arg nil
+  "Prefix arg value when you invoked an Icicles multi-command.")
+
+(defvar icicle-pre-minibuffer-buffer nil
+  "Buffer that was current before the minibuffer became active.")
+
+(defvar icicle-previous-raw-file-name-inputs nil
+  "Previous inputs user has typed during file-name completion.
+These are inputs typed but not necessarily entered with `RET'.")
+
+(defvar icicle-previous-raw-non-file-name-inputs nil
+  "Previous inputs user has typed during non-file-name completion.
+These are inputs typed but not necessarily entered with `RET'.")
+
+(defvar icicle-progressive-completing-p nil
+  "Non-nil means this completion is a narrowing completion.")
+
+(defvar icicle-prompt ""
+  "A minibuffer prompt.")
+
+(defvar icicle-proxy-candidate-regexp nil
+  "Regexp to match proxy candidates, or nil to do nothing.
+The candidates are highlighted in buffer `*Completions*' using face
+`icicle-proxy-candidate'.")
+
+(defvar icicle-proxy-candidates nil "List of proxy completion candidates (strings).")
+
+(defvar icicle-read-expression-map nil
+  "Icicle mode version of `read-expression-map'.
+Several Emacs-Lisp mode key bindings are used.")
+(unless icicle-read-expression-map
+  (let ((map  (make-sparse-keymap)))
+    (define-key map "\M-\t" 'lisp-complete-symbol)
+    (define-key map "\t" 'lisp-indent-line)
+    (define-key map "\e\C-q" 'indent-sexp)
+    (define-key map "\e\t" 'lisp-complete-symbol)
+    (define-key map "\e\C-x" 'eval-defun)
+    (define-key map "\e\C-q" 'indent-pp-sexp)
+    ;;(define-key map "\177" 'backward-delete-char-untabify)
+    (set-keymap-parent map minibuffer-local-map)
+    (setq icicle-read-expression-map  map)))
+
+(defvar icicle-remove-icicles-props-p t
+  "Non-nil means to remove Icicles text properties from completion result.
+Icicles binds this internal variable to nil in contexts where it needs
+the completion result string to retain its Icicles text properties.
+
+Otherwise, function `icicle-unpropertize' removes at least the Icicles
+internal text properties from the final completion result.  Depending
+on the value of option `icicle-unpropertize-completion-result-flag',
+it may also remove all text properties.")
+
+(defvar icicle-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"
+  "Regexp that matches anything except `.' and `..'.")
+
+(defvar icicle-require-match-p nil
+  "Current REQUIRE-MATCH arg to `completing-read' or `read-file-name'.
+Starting with Emacs 23, this is no longer enough to tell whether a
+match is required - use function `icicle-require-match-p' instead.")
+
+(defvar icicle-reverse-multi-sort-p nil
+  "Non-nil means the truth values returned by predicates are complemented.
+This changes the order of the sorting groups, but it does not in
+general reverse that order.  The order within each group is unchanged
+\(not reversed).")
+
+(defvar icicle-reverse-sort-p nil
+  "Non-nil means that candidates are being sorted in the reverse order.")
+
+(defvar icicle-saved-candidate-overlays nil
+  "Overlays used to highlight saved completion candidates.")
+
+(defvar icicle-saved-candidates-variables-obarray (make-vector 100 0)
+  "Obarray of variables you have saved sets of completion candidates in.
+Used for completion in `icicle-candidate-set-retrieve-from-variable'.")
+
+(defvar icicle-saved-completion-candidate nil
+  "Completion candidate to be restored after recursive `completing-read'.")
+
+(defvar icicle-saved-completion-candidates nil
+  "Completion candidates saved using `icicle-candidate-set-save'.")
+
+(defvar icicle-saved-completion-candidates-internal nil
+  "Completion candidates saved temporarily by program.")
+
+(defvar icicle-saved-ignored-extensions nil
+  "Local copy of `icicle-ignored-extensions', so we can restore it.")
+
+(when (boundp 'kmacro-ring)             ; Emacs 22+
+  (defvar icicle-saved-kmacro-ring-max kmacro-ring-max
+    "Saved value of `kmacro-ring-max', so it can be restored."))
+
+(defvar icicle-saved-regexp-search-ring-max regexp-search-ring-max
+  "Saved value of `search-ring-max', so it can be restored.")
+
+(defvar icicle-saved-proxy-candidates nil "Saved value of `icicle-proxy-candidates'.")
+
+(defvar icicle-saved-region-background nil
+  "Background of `region' face.  Saved so it can be restored.")
+
+(defvar icicle-saved-search-ring-max search-ring-max
+  "Saved value of `search-ring-max', so it can be restored.")
+
+(defvar icicle-scan-fn-or-regexp nil
+  "`icicle-search' parameter SCAN-FN-OR-REGEXP.  Used by `M-,'.")
+
+(defvar icicle-scroll-Completions-reverse-p nil
+  "Non-nil means `icicle-scroll-Completions-*' scrolls in opposite direction.")
+
+(defvar icicle-search-command 'icicle-search
+  "Command to use for Icicles searches.
+You can set a buffer-local value of this variable, to use a specific
+search command in a particular mode.")
+
+(defvar icicle-search-complement-domain-p nil
+  "Non-nil means complement the initial search candidates wrt the buffer.
+This has an effect only on (some) Icicles search commands.
+The scan function or regexp for the search command defines a set of
+matches in the buffer.  If this option is non-nil then the actual
+candidates used are the sections of buffer text that are separated by
+the initial candidates, that is, the non-candidates as defined by the
+scan or regexp.")
+
+(defvar icicle-search-context-level 0
+  "Match level for `icicle-search' context regexp.
+0 means use whatever matches the whole context regexp as the search
+context.  1 means use whatever matches the first subgroup of the
+regexp as the search context, and so on.")
+
+(defvar icicle-search-context-regexp ""
+  "Current search-context regexp used in `icicle-search'.")
+
+(defvar icicle-search-current-overlay nil
+  "Overlay used to highlight current match of `icicle-search' regexp arg.")
+
+(defvar icicle-search-final-choice nil
+  "Final user input from `icicle-search'.
+This might or might not be one of the possible search candidates.")
+
+(defvar icicle-search-history nil "History for `icicle-search' final choices.")
+
+(defvar icicle-search-in-context-fn 'icicle-search-in-context-default-fn
+  "Function used by `icicle-search-action' to act on search context.
+The default value is `icicle-search-in-context-default-fn'.
+The function must take two arguments:
+ - A full search candidate object, which is a cons of the candidate
+   name and its source-file marker.
+ - A replacement string, or nil, if no replacement is to be made.
+
+When the function is called, the region has been narrowed to the
+current search context.")
+
+(defvar icicle-searching-p nil "Non-nil means an Icicles search command is in progress.")
+
+(defvar icicle-search-level-overlays nil
+  "Overlays used to highlight context levels other than the top level.")
+
+(defvar icicle-search-overlays nil
+  "Overlays used to highlight match of `icicle-search' regexp argument.")
+
+(defvar icicle-search-refined-overlays nil
+  "Overlay(s) used to highlight match of current input for `icicle-search'.
+If `icicle-search-highlight-threshold' is less than one, then this is
+a single overlay (or nil).  Otherwise, this is a list of overlays.")
+
+(defvar icicle-search-replacement nil
+  "Replacement string for use during `icicle-search'.")
+
+(defvar icicle-search-replacement-history nil
+  "History variable for reading replacement string for `icicle-search'.")
+
+(defvar icicle-successive-grab-count 0
+  "Number of text things to be grabbed by next `\\\
+\\[icicle-insert-string-at-point]'.")
+
+(defvar icicle-text-property-value-history nil
+  "History variable for reading text properties.")
+
+;; (defvar icicle-text-properties-alist
+;;   '(;; Properties listed in Elisp manual node `Special Properties':
+;;     ("category") ("face") ("font-lock-face") ("mouse-face") ("fontified") ("display")
+;;     ("help-echo") ("keymap") ("local-map") ("syntax-table") ("read-only") ("invisible")
+;;     ("intangible") ("field") ("cursor") ("pointer") ("line-spacing") ("line-height")
+;;     ("modification-hooks") ("insert-in-front-hooks") ("insert-behind-hooks")
+;;     ("point-entered") ("point-left")
+;;     ;; Properties listed in Elisp manual node `Format Properties':
+;;     ("hard") ("right-margin") ("left-margin") ("justification")
+;;     ;; Properties listed in Elisp manual node `Links and Mouse-1':
+;;     ("follow-link")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp':
+;;     ("allout-was-hidden") ("ansi-color") ("buffer") ("buffer-name") ("column")
+;;     ("button") ("skip") ("literal") ("front-sticky") ("rear-nonsticky") ("composition")
+;;     ("untranslated-utf-8") ("yank-handler") ("dired-filename") ("read-face-name")
+;;     ("directory") ("message") ("debug") ("font-lock-multiline") ("unknown")
+;;     ("insert-in-front-hooks") ("kbd-help") ("hilit-chg") ("ibuffer-filter-group-name")
+;;     ("ibuffer-properties") ("ibuffer-title") ("ibuffer-summary")
+;;     ("ibuffer-title-header") ("inhibit-line-move-field-capture") ("image-counter")
+;;     ("header-line") ("cvs-goal-column") ("occur-target") ("occur-match")
+;;     ("foreign-selection") ("before-string") ("after-string") ("ses")
+;;     ("smerge-force-highlighting") ("speedbar-function") ("speedbar-token")
+;;     ("speedbar-text") ("type") ("stroke-glyph") ("data") ("thumb-image-file")
+;;     ("original-file-name") ("associated-dired-buffer") ("tags") ("comment")
+;;     ("tumme-thumbnail") ("tutorial-remark") ("vc-cvs-annotate-time") ("end-name")
+;;     ("old-name") ("end-link") ("old-link") ("end-perm") ("old-perm") ("perm-changed")
+;;     ("widget-doc") ("secret") ("real-field")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/emacs-lisp':
+;;     ("elp-symname") ("printed-value") ("duplicable")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/emulation':
+;;     ("cursor")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/erc':
+;;     ("erc-callback") ("erc-data") ("erc-identified") ("erc-parsed") ("erc-parsed")
+;;     ("timestamp") ("erc-prompt")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/eshell':
+;;     ("comment") ("arg-begin") ("arg-end") ("escaped") ("history") ("number")
+;;     ("test-func")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/gnus':
+;;     ("earcon-data") ("earcon-callback") ("gnus-category") ("gnus-part")
+;;     ("article-type") ("gnus-decoration") ("dummy-invisible") ("original-date")
+;;     ("gnus-data") ("gnus-callback") ("gnus-prev") ("gnus-next") ("gnus-mime-details")
+;;     ("gnus-line-format") ("gnus-backlog") ("gnus-image-category")
+;;     ("gnus-image-text-deletable") ("gnus-group") ("gnus-level") ("gnus-indentation")
+;;     ("gnus-unread") ("gnus-number") ("articles") ("gnus-server") ("gnus-named-server")
+;;     ("gnus-intangible") ("gnus-topic") ("gnus-topic-level") ("gnus-topic-unread")
+;;     ("gnus-topic-visible") ("gnus-active") ("gnus-position") ("gnus-time")
+;;     ("gnus-face") ("gnus-undeletable") ("message-rank") ("egg-end") ("egg-lang")
+;;     ("egg-start") ("message-hidden") ("message-deletable") ("buffer") ("from") ("mm")
+;;     ("script-name")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/international':
+;;     ("kkc-conversion-index") ("advice") ("untranslated-utf-8") ("composition")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/mail':
+;;     ("footnote-number") ("rmail-fontified")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/mh-e':
+;;     ("mh-data") ("mh-mime-inserted") ("mh-part") ("mh-region") ("mh-callback")
+;;     ("mh-button-pressed") ("mh-line-format") ("mh-folder") ("mh-children-p")
+;;     ("mh-expanded") ("mh-level") ("mh-count")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/net':
+;;     ("feed") ("w3m-image") ("nt-age") ("nt-title") ("nt-guid") ("nt-desc")
+;;     ("org-invisible") ("nt-link") ("nt-type") ("nt-face")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/progmodes':
+;;     ("c-type") ("c-awk-NL-prop") ("c-is-sws") ("c-decl-arg-start") ("c-decl-end")
+;;     ("c-decl-id-start") ("c-decl-type-start") ("message") ("REx-interpolated")
+;;     ("in-pod") ("here-doc-group") ("syntax-type") ("indentable") ("REx-part2")
+;;     ("first-format-line") ("attrib-group") ("cperl-postpone") ("cpp-data")
+;;     ("cpp-callback") ("token") ("ebrowse-tree") ("ebrowse-member") ("ebrowse-what")
+;;     ("gdb-enabled") ("gdb-bptno") ("gdb-max-frames") ("link") ("fetch") ("begin-glyph")
+;;     ("begin-glyph-layout") ("idlwave-class") ("data") ("source") ("keyword")
+;;     ("find-args")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/term':
+;;     ("mac-ts-active-input-string")
+;;     ;; Others in Emacs-Lisp libraries in directory `lisp/textmodes':
+;;     ("fill-space") ("priority") ("test") ("end-glyph") ("begin-glyph") ("org-cwidth")
+;;     ("org-dwidth") ("org-dwidth-n") ("org-linked-text") (":org-clock-minutes")
+;;     ("org-protected") ("org-date-line") ("org-today") ("day") ("org-agenda-type")
+;;     ("time-of-day") ("org-not-done-regexp") ("prefix-length") ("tags") ("org-marker")
+;;     ("org-agenda-diary-link") ("org-hd-marker") ("dotime") ("org-category")
+;;     ("undone-face") ("done-face") ("xr-alist") ("table-cell") ("text-clones")
+;;     ;; Others in my own libraries:
+;;     ("font-lock-ignore") ("highlight") ("back-link") ("forward-link"))
+;;   "Alist of text properties known to Emacs.
+;; Each element is of form (PROP), where PROP is the name of a text
+;; property (a string).")
+
+(defvar icicle-thing-at-pt-fns-pointer 0
+  "Current index into the car of `icicle-thing-at-point-functions'.
+This points to the current function in the list.")
+
+(defvar icicle-transform-before-sort-p nil
+  "Non-nil means transform each multi-completion candidate before sorting.
+Bind this to non-nil if you do not want sorting to use the whole
+multi-completion.")
+
+(defvar icicle-universal-argument-map
+  (let ((map  (make-sparse-keymap)))
+    (define-key map [t] 'icicle-universal-argument-other-key)
+    (define-key map (vector meta-prefix-char t) 'icicle-universal-argument-other-key)
+    (define-key map [switch-frame] nil)
+    (define-key map [?\C-u] 'icicle-universal-argument-more)
+    (define-key map [?-] 'icicle-universal-argument-minus)
+    (define-key map [?0] 'icicle-digit-argument)
+    (define-key map [?1] 'icicle-digit-argument)
+    (define-key map [?2] 'icicle-digit-argument)
+    (define-key map [?3] 'icicle-digit-argument)
+    (define-key map [?4] 'icicle-digit-argument)
+    (define-key map [?5] 'icicle-digit-argument)
+    (define-key map [?6] 'icicle-digit-argument)
+    (define-key map [?7] 'icicle-digit-argument)
+    (define-key map [?8] 'icicle-digit-argument)
+    (define-key map [?9] 'icicle-digit-argument)
+    (define-key map [kp-0] 'icicle-digit-argument)
+    (define-key map [kp-1] 'icicle-digit-argument)
+    (define-key map [kp-2] 'icicle-digit-argument)
+    (define-key map [kp-3] 'icicle-digit-argument)
+    (define-key map [kp-4] 'icicle-digit-argument)
+    (define-key map [kp-5] 'icicle-digit-argument)
+    (define-key map [kp-6] 'icicle-digit-argument)
+    (define-key map [kp-7] 'icicle-digit-argument)
+    (define-key map [kp-8] 'icicle-digit-argument)
+    (define-key map [kp-9] 'icicle-digit-argument)
+    (define-key map [kp-subtract] 'icicle-universal-argument-minus)
+    map)
+  "Keymap used while processing `C-u' during Icicles completion.")
+
+(defvar icicle-use-candidates-only-once-alt-p nil
+  "*Non-nil means remove each candidate from the set after using it.
+This is similar to `icicle-use-candidates-only-once-flag', but it is
+used only for alternative actions (e.g. `C-S-RET').")
+
+(defvar icicle-vardoc-last-initial-cand-set ()
+  "Cache for initial set of completion candidates for `icicle-vardoc'.")
+
+(defvar icicle-vardoc-last-initial-option-cand-set ()
+  "Cache for initial option completion candidates for `icicle-vardoc'.")
+
+(defvar icicle-whole-candidate-as-text-prop-p nil
+  "Non-nil means string candidate has candidate data as text property.
+If non-nil, then the value of text property `icicle-whole-candidate'
+for a string completion candidate (e.g. what is displayed) is the cdr
+of the full completion-candidate alist element.  The car of that
+element is the string.")
+
+(defvar icicle-variable-name-history nil "History for variable names.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles-var)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles-var.el ends here
diff --git a/auto-install/icicles.el b/auto-install/icicles.el
new file mode 100644
index 0000000..75439df
--- /dev/null
+++ b/auto-install/icicles.el
@@ -0,0 +1,1352 @@
+;;; icicles.el --- Minibuffer input completion and cycling.
+;;
+;; Filename: icicles.el
+;; Description: Minibuffer completion and cycling.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Tue Aug  1 14:21:16 1995
+;; Version: 22.0
+;; Last-Updated: Thu Sep  8 14:34:00 2011 (-0700)
+;;           By: dradams
+;;     Update #: 22978
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles.el
+;; Keywords: extensions, help, abbrev, local, minibuffer,
+;;           keys, apropos, completion, matching, regexp, command
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `advice', `advice-preload', `apropos', `apropos+',
+;;   `apropos-fn+var', `avoid', `backquote', `bookmark', `bookmark+',
+;;   `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
+;;   `bookmark+-lit', `bookmark+-mac', `bytecomp', `cl', `cus-edit',
+;;   `cus-face', `cus-load', `cus-start', `custom', `dired',
+;;   `dired+', `dired-aux', `dired-x', `doremi', `easymenu',
+;;   `ediff-diff', `ediff-help', `ediff-init', `ediff-merg',
+;;   `ediff-mult', `ediff-util', `ediff-wind', `el-swank-fuzzy',
+;;   `ffap', `ffap-', `fit-frame', `frame-cmds', `frame-fns',
+;;   `fuzzy', `fuzzy-match', `help+20', `hexrgb', `icicles-cmd1',
+;;   `icicles-cmd2', `icicles-face', `icicles-fn', `icicles-mac',
+;;   `icicles-mcmd', `icicles-mode', `icicles-opt', `icicles-var',
+;;   `image-dired', `info', `info+', `kmacro', `levenshtein',
+;;   `menu-bar', `menu-bar+', `misc-cmds', `misc-fns', `mkhtml',
+;;   `mkhtml-htmlize', `mouse3', `mwheel', `pp', `pp+', `regexp-opt',
+;;   `ring', `ring+', `second-sel', `strings', `thingatpt',
+;;   `thingatpt+', `unaccent', `w32-browser', `w32browser-dlgopen',
+;;   `wid-edit', `wid-edit+', `widget'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Minibuffer input completion and cycling of completion candidates.
+;;
+;;  Input completion takes as input a string and returns a name that
+;;  contains the input string.  This library enables minibuffer
+;;  cycling of completion candidates, and provides additional support
+;;  for input completion.
+;;
+;;  Two kinds of completion are offered here, which are distinguished
+;;  by how the input string is matched against the completed name:
+;;
+;;   - Prefix completion - The input string is a prefix of the
+;;                         completed name.  This is the usual Emacs
+;;                         completion.
+;;
+;;   - Apropos completion - The input string is a regular expression
+;;                          that matches somewhere (anywhere) within
+;;                          the completed name.  You can think of the
+;;                          name as having been returned by `apropos'
+;;                          (except it also works for file and buffer
+;;                          names).
+;;
+;;  Files `icicles-doc1.el' and `icicles-doc2.el' contain the doc for
+;;  Icicles, including how to install and use Icicles.  You can also
+;;  read the Icicles doc, in formatted form, on the Emacs-Wiki Web
+;;  site: http://www.emacswiki.org/cgi-bin/wiki/Icicles.  Emacs Wiki
+;;  also has a few addtional pages about Icicles.  In particular, if
+;;  you are new to Emacs, as well as Icicles, see this page:
+;;  http://www.emacswiki.org/cgi-bin/wiki/EmacsNewbieWithIcicles.
+;;
+;;  See also: Library `lacarte.el', which lets you execute menu
+;;  commands, cycling and completing them.  It is not part of Icicles,
+;;  but it is greatly enhanced by Icicles.
+ 
+;;(@> "Index")
+;;
+;;  Index
+;;  -----
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Things Defined in Icicles")
+ 
+;;(@* "Things Defined in Icicles")
+;;
+;;  Things Defined in Icicles
+;;  -------------------------
+;;
+;;  Key bindings defined in Icicles: see (@> "Key Bindings"), below.
+;;
+;;  Macros defined in Icicles:
+;;
+;;    `icicle-buffer-bindings', `icicle-condition-case-no-debug',
+;;    `icicle-define-add-to-alist-command',
+;;    `icicle-define-bookmark-command',
+;;    `icicle-define-bookmark-command-1',
+;;    `icicle-define-bookmark-other-window-command',
+;;    `icicle-define-command', `icicle-define-file-command',
+;;    `icicle-define-search-bookmark-command',
+;;    `icicle-define-sort-command', `icicle-file-bindings',
+;;    `icicle-maybe-byte-compile-after-load'
+;;    `icicle-maybe-cached-action', `icicle-with-comments-hidden',
+;;    `icicle-with-selected-window'.
+;;
+;;  Commands defined in Icicles -
+;;
+;;   Commands to be used mainly at top level:
+;;
+;;    `a', `any', `buffer', `clear-option',
+;;    `cycle-icicle-image-file-thumbnail', `file',
+;;    `icicle-add-buffer-candidate', `icicle-add-buffer-config',
+;;    `icicle-add-entry-to-saved-completion-set',
+;;    `icicle-add-file-to-fileset',
+;;    `icicle-add/update-saved-completion-set', `icicle-anything',
+;;    `icicle-apply' `icicle-apropos', `icicle-apropos-command',
+;;    `icicle-apropos-function', `icicle-apropos-option',
+;;    `icicle-apropos-variable', `icicle-apropos-zippy',
+;;    `icicle-bbdb-complete-name', `icicle-bookmark',
+;;    `icicle-bookmark-a-file', `icicle-bookmark-all-tags',
+;;    `icicle-bookmark-all-tags-other-window',
+;;    `icicle-bookmark-all-tags-regexp',
+;;    `icicle-bookmark-all-tags-regexp-other-window',
+;;    `icicle-bookmark-bookmark-list', `icicle-bookmark-cmd',
+;;    `icicle-bookmark-desktop', `icicle-bookmark-dired',
+;;    `icicle-bookmark-dired-other-window',
+;;    `icicle-bookmarked-buffer-list', `icicle-bookmarked-file-list',
+;;    `icicle-bookmark-file', `icicle-bookmark-file-all-tags',
+;;    `icicle-bookmark-file-all-tags-other-window',
+;;    `icicle-bookmark-file-all-tags-regexp',
+;;    `icicle-bookmark-file-all-tags-regexp-other-window',
+;;    `icicle-bookmark-file-other-window',
+;;    `icicle-bookmark-file-some-tags',
+;;    `icicle-bookmark-file-some-tags-other-window',
+;;    `icicle-bookmark-file-some-tags-regexp',
+;;    `icicle-bookmark-file-some-tags-regexp-other-window',
+;;    `icicle-bookmark-file-this-dir',
+;;    `icicle-bookmark-file-this-dir-other-window',
+;;    `icicle-bookmark-file-this-dir-all-tags',
+;;    `icicle-bookmark-file-this-dir-all-tags-other-window',
+;;    `icicle-bookmark-file-this-dir-all-tags-regexp',
+;;    `icicle-bookmark-file-this-dir-all-tags-regexp-other-window',
+;;    `icicle-bookmark-file-this-dir-some-tags',
+;;    `icicle-bookmark-file-this-dir-some-tags-other-window',
+;;    `icicle-bookmark-file-this-dir-some-tags-regexp',
+;;    `icicle-bookmark-file-this-dir-some-tags-regexp-other-window',
+;;    `icicle-bookmark-gnus', `icicle-bookmark-gnus-other-window',
+;;    `icicle-bookmark-info', `icicle-bookmark-info-other-window',
+;;    `icicle-bookmark-jump', `icicle-bookmark-jump-other-window',
+;;    `icicle-bookmark-list', `icicle-bookmark-local-file',
+;;    `icicle-bookmark-local-file-other-window',
+;;    `icicle-bookmark-man', `icicle-bookmark-man-other-window',
+;;    `icicle-bookmark-non-file',
+;;    `icicle-bookmark-non-file-other-window',
+;;    `icicle-bookmark-other-window', `icicle-bookmark-region',
+;;    `icicle-bookmark-region-other-window',
+;;    `icicle-bookmark-remote-file',
+;;    `icicle-bookmark-remote-file-other-window',
+;;    `icicle-bookmark-save-marked-files',
+;;    `icicle-bookmark-save-marked-files-as-project',
+;;    `icicle-bookmark-save-marked-files-more',
+;;    `icicle-bookmark-save-marked-files-persistently',
+;;    `icicle-bookmark-save-marked-files-to-variable',
+;;    `icicle-bookmark-set', `icicle-bookmark-some-tags',
+;;    `icicle-bookmark-some-tags-other-window',
+;;    `icicle-bookmark-some-tags-regexp',
+;;    `icicle-bookmark-some-tags-regexp-other-window',
+;;    `icicle-bookmark-specific-buffers',
+;;    `icicle-bookmark-specific-buffers-other-window',
+;;    `icicle-bookmark-specific-files',
+;;    `icicle-bookmark-specific-files-other-window',
+;;    `icicle-bookmark-this-buffer',
+;;    `icicle-bookmark-this-buffer-other-window',
+;;    `icicle-bookmark-url', `icicle-bookmark-url-other-window'
+;;    `icicle-bookmark-w3m-other-window', `icicle-buffer',
+;;    `icicle-buffer-config', `icicle-buffer-list',
+;;    `icicle-buffer-other-window',
+;;    `icicle-change-alternative-sort-order',
+;;    `icicle-change-history-variable', `icicle-choose-faces',
+;;    `icicle-choose-invisible-faces', `icicle-choose-visible-faces',
+;;    `icicle-clear-history', `icicle-clear-current-history',
+;;    `icicle-color-theme', `icicle-comint-command',
+;;    `icicle-comint-dynamic-complete',
+;;    `icicle-comint-dynamic-complete-filename',
+;;    `icicle-comint-replace-by-expanded-filename',
+;;    `icicle-comint-search', `icicle-command-abbrev',
+;;    `icicle-compilation-search', `icicle-complete-keys',
+;;    `icicle-complete-thesaurus-entry', `icicle-completing-yank',
+;;    `icicle-customize-apropos', `icicle-customize-apropos-faces',
+;;    `icicle-customize-apropos-groups',
+;;    `icicle-customize-apropos-options',
+;;    `icicle-customize-apropos-options-of-type',
+;;    `icicle-customize-face', `icicle-customize-icicles-group',
+;;    `icicle-cycle-image-file-thumbnail',
+;;    `icicle-dabbrev-completion', `icicle-delete-file',
+;;    `icicle-delete-window', `icicle-delete-windows',
+;;    `icicle-delete-windows-on', `icicle-describe-file',
+;;    `icicle-describe-option-of-type', `icicle-directory-list',
+;;    `icicle-dired', `icicle-dired-chosen-files',
+;;    `icicle-dired-chosen-files-other-window',
+;;    `icicle-dired-other-window', `icicle-dired-project',
+;;    `icicle-dired-project-other-window',
+;;    `icicle-dired-saved-file-candidates',
+;;    `icicle-dired-saved-file-candidates-other-window',
+;;    `icicle-dired-save-marked',
+;;    `icicle-dired-save-marked-as-project',
+;;    `icicle-dired-save-marked-more',
+;;    `icicle-dired-save-marked-persistently',
+;;    `icicle-dired-save-marked-to-variable', `icicle-doc',
+;;    `icicle-doremi-candidate-width-factor+',
+;;    `icicle-doremi-increment-max-candidates+',
+;;    `icicle-doremi-increment-swank-prefix-length+',
+;;    `icicle-doremi-increment-swank-timeout+',
+;;    `icicle-doremi-increment-variable+',
+;;    `icicle-doremi-inter-candidates-min-spaces+',
+;;    `icicle-ess-complete-filename',
+;;    `icicle-ess-complete-object-name',
+;;    `icicle-ess-internal-complete-object-name',
+;;    `icicle-ess-R-complete-object-name',
+;;    `icicle-exchange-point-and-mark',
+;;    `icicle-execute-extended-command',
+;;    `icicle-execute-named-keyboard-macro', `icicle-face-list',
+;;    `icicle-file', `icicle-file-list', `icicle-file-other-window',
+;;    `icicle-find-file', `icicle-find-file-absolute',
+;;    `icicle-find-file-absolute-other-window',
+;;    `icicle-find-file-all-tags',
+;;    `icicle-find-file-all-tags-other-window',
+;;    `icicle-find-file-all-tags-regexp',
+;;    `icicle-find-file-all-tags-regexp-other-window',
+;;    `icicle-find-file-in-tags-table',
+;;    `icicle-find-file-in-tags-table-other-window',
+;;    `icicle-find-file-other-window', `icicle-find-file-read-only',
+;;    `icicle-find-file-read-only-other-window',
+;;    `icicle-find-file-some-tags',
+;;    `icicle-find-file-some-tags-other-window',
+;;    `icicle-find-file-some-tags-regexp',
+;;    `icicle-find-file-some-tags-regexp-other-window',
+;;    `icicle-find-file-tagged',
+;;    `icicle-find-file-tagged-other-window', `icicle-find-first-tag',
+;;    `icicle-find-first-tag-other-window', `icicle-find-tag',
+;;    `icicle-font', `icicle-frame-bg', `icicle-frame-fg',
+;;    `icicle-fundoc', `icicle-goto-global-marker',
+;;    `icicle-goto-global-marker-or-pop-global-mark',
+;;    `icicle-goto-marker', `icicle-goto-marker-or-set-mark-command',
+;;    `icicle-grep-saved-file-candidates',
+;;    `icicle-gud-gdb-complete-command', `icicle-handle-switch-frame',
+;;    `icicle-hide-faces', `icicle-hide-only-faces',
+;;    `icicle-hide/show-comments', `icicle-ido-like-mode',
+;;    `icicle-imenu', `icicle-imenu-command',
+;;    `icicle-imenu-command-full', `icicle-imenu-face-full',
+;;    `icicle-imenu-face-full', `icicle-imenu-full',
+;;    `icicle-imenu-key-explicit-map',
+;;    `icicle-imenu-key-explicit-map-full',
+;;    `icicle-imenu-key-implicit-map',
+;;    `icicle-imenu-key-implicit-map-full', `icicle-imenu-macro',
+;;    `icicle-imenu-macro-full',
+;;    `icicle-imenu-non-interactive-function',
+;;    `icicle-imenu-non-interactive-function-full',
+;;    `icicle-imenu-user-option', `icicle-imenu-user-option-full',
+;;    `icicle-imenu-variable', `icicle-imenu-variable-full',
+;;    `icicle-increment-option', `icicle-increment-variable',
+;;    `icicle-Info-goto-node', `icicle-Info-index',
+;;    `icicle-Info-index-20', `icicle-Info-menu',
+;;    `icicle-Info-virtual-book', `icicle-insert-buffer',
+;;    `icicle-insert-thesaurus-entry', `icicle-keyword-list',
+;;    `icicle-kill-buffer', `icicle-kmacro',
+;;    `icicle-lisp-complete-symbol', `icicle-locate-file',
+;;    `icicle-locate-file-no-symlinks',
+;;    `icicle-locate-file-no-symlinks-other-window',
+;;    `icicle-locate-file-other-window', `icicle-mode', `icy-mode',
+;;    `icicle-next-visible-thing', `icicle-object-action',
+;;    `icicle-occur', `icicle-other-window-or-frame',
+;;    `icicle-pick-color-by-name', `icicle-plist',
+;;    `icicle-pop-tag-mark', `icicle-pp-eval-expression',
+;;    `icicle-previous-visible-thing', `icicle-read-color',
+;;    `icicle-read-kbd-macro', `icicle-recent-file',
+;;    `icicle-recent-file-other-window',
+;;    `icicle-recompute-shell-command-candidates',
+;;    `icicle-regexp-list', `icicle-remove-buffer-candidate',
+;;    `icicle-remove-buffer-config',
+;;    `icicle-remove-entry-from-saved-completion-set',
+;;    `icicle-remove-file-from-recentf-list',
+;;    `icicle-remove-saved-completion-set',
+;;    `icicle-repeat-complex-command', `icicle-reset-option-to-nil',
+;;    `icicle-resolve-file-name', `icicle-save-string-to-variable',
+;;    `icicle-search', `icicle-search-all-tags-bookmark',
+;;    `icicle-search-all-tags-regexp-bookmark',
+;;    `icicle-search-autofile-bookmark', `icicle-search-bookmark',
+;;    `icicle-search-bookmark-list-bookmark',
+;;    `icicle-search-bookmark-list-marked',
+;;    `icicle-search-bookmarks-together', `icicle-search-buffer',
+;;    `icicle-search-buff-menu-marked', `icicle-search-char-property',
+;;    `icicle-search-defs', `icicle-search-defs-full',
+;;    `icicle-search-desktop-bookmark',
+;;    `icicle-search-dired-bookmark', `icicle-search-dired-marked',
+;;    `icicle-search-file', `icicle-search-file-bookmark',
+;;    `icicle-search-generic', `icicle-search-gnus-bookmark',
+;;    `icicle-search-highlight-cleanup',
+;;    `icicle-search-ibuffer-marked', `icicle-search-info-bookmark',
+;;    `icicle-search-keywords', `icicle-search-lines',
+;;    `icicle-search-local-file-bookmark',
+;;    `icicle-search-man-bookmark', `icicle-search-non-file-bookmark',
+;;    `icicle-search-overlay-property', `icicle-search-pages',
+;;    `icicle-search-paragraphs', `icicle-search-region-bookmark',
+;;    `icicle-search-remote-file-bookmark', `icicle-search-sentences',
+;;    `icicle-search-some-tags-bookmark',
+;;    `icicle-search-some-tags-regexp-bookmark',
+;;    `icicle-search-specific-buffers-bookmark',
+;;    `icicle-search-specific-files-bookmark',
+;;    `icicle-search-text-property', `icicle-search-thing',
+;;    `icicle-search-this-buffer-bookmark',
+;;    `icicle-search-url-bookmark', `icicle-search-w3m-bookmark',
+;;    `icicle-search-w-isearch-string', `icicle-search-word',
+;;    `icicle-search-xml-element',
+;;    `icicle-search-xml-element-text-node',
+;;    `icicle-select-bookmarked-region', `icicle-select-frame',
+;;    `icicle-select-frame-by-name', `icicle-select-window',
+;;    `icicle-select-window-by-name', `icicle-send-bug-report',
+;;    `icicle-set-option-to-t',
+;;    `icicle-set-S-TAB-methods-for-command',
+;;    `icicle-set-TAB-methods-for-command',
+;;    `icicle-shell-dynamic-complete-command',
+;;    `icicle-shell-dynamic-complete-environment-variable',
+;;    `icicle-shell-dynamic-complete-filename', `icicle-show-faces',
+;;    `icicle-show-only-faces', `icicle-sit-for',
+;;    `icicle-skip-this-command', `icicle-sort-alphabetical',
+;;    `icicle-sort-by-abbrev-frequency',
+;;    `icicle-sort-by-directories-first',
+;;    `icicle-sort-by-directories-last', `icicle-sort-by-file-type.',
+;;    `icicle-sort-by-last-file-modification-time',
+;;    `icicle-sort-by-last-use-as-input',
+;;    `icicle-sort-by-previous-use-alphabetically',
+;;    `icicle-sort-by-2nd-parts-alphabetically',
+;;    `icicle-sort-case-insensitive',
+;;    `icicle-sort-extra-candidates-first',
+;;    `icicle-sort-proxy-candidates-first',
+;;    `icicle-sort-special-candidates-first',
+;;    `icicle-sort-special-candidates-first',
+;;    `icicle-sort-turned-OFF', `icicle-synonyms',
+;;    `icicle-tag-a-file', `icicle-tags-search',
+;;    `icicle-toggle-~-for-home-dir',
+;;    `icicle-toggle-alternative-sorting',
+;;    `icicle-toggle-angle-brackets',
+;;    `icicle-toggle-case-sensitivity', `icicle-toggle-C-for-actions',
+;;    `icicle-toggle-hiding-common-match',
+;;    `icicle-toggle-hiding-non-matching-lines',
+;;    `icicle-toggle-highlight-all-current',
+;;    `icicle-toggle-highlight-historical-candidates',
+;;    `icicle-toggle-highlight-saved-candidates',
+;;    `icicle-toggle-ignored-extensions',
+;;    `icicle-toggle-ignored-space-prefix',
+;;    `icicle-toggle-ignoring-comments',
+;;    `icicle-toggle-incremental-completion',
+;;    `icicle-toggle-literal-replacement', `icicle-toggle-option',
+;;    `icicle-toggle-proxy-candidates', `icicle-toggle-regexp-quote',
+;;    `icicle-toggle-remote-file-testing',
+;;    `icicle-toggle-search-cleanup',
+;;    `icicle-toggle-search-complementing-domain',
+;;    `icicle-toggle-search-replace-whole',
+;;    `icicle-toggle-search-whole-word', `icicle-toggle-sorting',
+;;    `icicle-toggle-transforming',
+;;    `icicle-toggle-WYSIWYG-Completions', `icicle-untag-a-file',
+;;    `icicle-vardoc', `icicle-where-is',
+;;    `icicle-yank-maybe-completing', `old-bbdb-complete-name',
+;;    `old-comint-dynamic-complete',
+;;    `old-comint-dynamic-complete-filename',
+;;    `old-comint-replace-by-expanded-filename',
+;;    `old-dired-read-shell-command', `old-ess-complete-object-name',
+;;    `old-gud-gdb-complete-command', `old-read-shell-command',
+;;    `orig-read-file-name', `toggle', `synonyms',
+;;    `toggle-icicle-~-for-home-dir',
+;;    `toggle-icicle-alternative-sorting',
+;;    `toggle-icicle-angle-brackets',
+;;    `toggle-icicle-case-sensitivity', `toggle-icicle-C-for-actions',
+;;    `toggle-icicle-fuzzy-completion',
+;;    `toggle-icicle-hiding-common-match',
+;;    `toggle-icicle-hiding-non-matching-lines',
+;;    `toggle-icicle-highlight-all-current',
+;;    `toggle-icicle-highlight-historical-candidates',
+;;    `toggle-icicle-highlight-saved-candidates',
+;;    `toggle-icicle-ignored-extensions',
+;;    `toggle-icicle-ignored-space-prefix',
+;;    `toggle-icicle-incremental-completion',
+;;    `toggle-icicle-literal-replacement',
+;;    `toggle-icicle-proxy-candidates', `toggle-icicle-regexp-quote',
+;;    `toggle-icicle-remote-file-testing',
+;;    `toggle-icicle-search-cleanup',
+;;    `toggle-icicle-search-complementing-domain',
+;;    `toggle-icicle-search-replace-whole',
+;;    `toggle-icicle-search-whole-word',
+;;    `toggle-icicle-show-multi-completion', `toggle-icicle-sorting',
+;;    `toggle-icicle-transforming',
+;;    `toggle-icicle-WYSIWYG-Completions', `what-which-how'.
+;;
+;;   Commands to be used mainly in the minibuffer or `*Completions*':
+;;
+;;    `cycle-icicle-image-file-thumbnail',
+;;    `icicle-abort-recursive-edit', `icicle-all-candidates-action',
+;;    `icicle-all-candidates-alt-action',
+;;    `icicle-all-candidates-list-action',
+;;    `icicle-all-candidates-list-alt-action',
+;;    `icicle-apropos-complete', `icicle-apropos-complete-and-exit',
+;;    `icicle-apropos-complete-and-narrow',
+;;    `icicle-apropos-complete-and-widen',
+;;    `icicle-apropos-complete-no-display',
+;;    `icicle-backward-char-dots',
+;;    `icicle-backward-delete-char-untabify',
+;;    `icicle-backward-kill-paragraph',
+;;    `icicle-backward-kill-sentence', `icicle-backward-kill-sexp',
+;;    `icicle-backward-kill-word', `icicle-beginning-of-line+',
+;;    `icicle-bookmark-bookmark-list-narrow',
+;;    `icicle-bookmark-desktop-narrow',
+;;    `icicle-bookmark-dired-narrow',`icicle-bookmark-file-narrow',
+;;    `icicle-bookmark-gnus-narrow', `icicle-bookmark-info-narrow',
+;;    `icicle-bookmark-local-file-narrow',
+;;    `icicle-bookmark-man-narrow', `icicle-bookmark-non-file-narrow',
+;;    `icicle-bookmark-region-narrow',
+;;    `icicle-bookmark-remote-file-narrow',
+;;    `icicle-bookmark-specific-buffers-narrow',
+;;    `icicle-bookmark-specific-files-narrow',
+;;    `icicle-bookmark-this-buffer-narrow',
+;;    `icicle-bookmark-url-narrow', `icicle-bookmark-w3m-narrow',
+;;    `icicle-candidate-action', `icicle-candidate-alt-action',
+;;    `icicle-candidate-read-fn-invoke',
+;;    `icicle-candidate-set-complement',
+;;    `icicle-candidate-set-define',
+;;    `icicle-candidate-set-difference',
+;;    `icicle-candidate-set-intersection',
+;;    `icicle-candidate-set-retrieve',
+;;    `icicle-candidate-set-retrieve-from-variable',
+;;    `icicle-candidate-set-retrieve-more',
+;;    `icicle-candidate-set-retrieve-persistent',
+;;    `icicle-candidate-set-save', `icicle-candidate-set-save-more',
+;;    `icicle-candidate-set-save-more-selected',
+;;    `icicle-candidate-set-save-persistently',
+;;    `icicle-candidate-set-save-selected',
+;;    `icicle-candidate-set-save-to-variable',
+;;    `icicle-candidate-set-swap', `icicle-candidate-set-truncate',
+;;    `icicle-candidate-set-union', `icicle-cd-for-abs-files',
+;;    `icicle-cd-for-loc-files',
+;;    `icicle-change-alternative-sort-order',
+;;    `icicle-change-sort-order', `icicle-change-sort-order',
+;;    `icicle-choose-completion', `icicle-clear-current-history',
+;;    `icicle-completing-read+insert',
+;;    `icicle-Completions-mouse-3-menu',
+;;    `icicle-cycle-image-file-thumbnail',
+;;    `icicle-search-define-replacement',
+;;    `icicle-delete-backward-char', `icicle-delete-candidate-object',
+;;    `icicle-delete-char', `icicle-digit-argument',
+;;    `icicle-dispatch-C-^', `icicle-dispatch-C-.',
+;;    `icicle-dispatch-C-x.', `icicle-dispatch-M-_',
+;;    `icicle-dispatch-M-comma', `icicle-dispatch-M-q',
+;;    `icicle-doremi-candidate-width-factor+',
+;;    `icicle-doremi-increment-max-candidates+',
+;;    `icicle-doremi-increment-swank-prefix-length+',
+;;    `icicle-doremi-increment-swank-timeout+',
+;;    `icicle-doremi-inter-candidates-min-spaces',
+;;    `icicle-doremi-zoom-Completions+', `icicle-end-of-line+',
+;;    `icicle-erase-minibuffer',
+;;    `icicle-erase-minibuffer-or-history-element',
+;;    `icicle-exit-minibuffer', `icicle-forward-char-dots',
+;;    `icicle-goto/kill-failed-input', `icicle-help-on-candidate',
+;;    `icicle-help-on-next-apropos-candidate',
+;;    `icicle-help-on-next-prefix-candidate',
+;;    `icicle-help-on-previous-apropos-candidate',
+;;    `icicle-help-on-previous-prefix-candidate',
+;;    `icicle-help-string-non-completion', `icicle-history',
+;;    `icicle-insert-completion', `icicle-insert-dot-command',
+;;    `icicle-insert-history-element',
+;;    `icicle-insert-key-description',
+;;    `icicle-insert-list-join-string',
+;;    `icicle-insert-newline-in-minibuffer',
+;;    `icicle-insert-string-at-point',
+;;    `icicle-insert-string-from-variable', `icicle-isearch-complete',
+;;    `icicle-keep-only-past-inputs', `icicle-kill-line',
+;;    `icicle-kill-paragraph', `icicle-kill-region',
+;;    `icicle-kill-region-wimpy', `icicle-kill-sentence',
+;;    `icicle-kill-sexp', `icicle-kill-word', `icicle-make-directory',
+;;    `icicle-minibuffer-complete-and-exit', `icicle-minibuffer-help',
+;;    `icicle-mouse-candidate-action',
+;;    `icicle-mouse-candidate-alt-action',
+;;    `icicle-mouse-candidate-read-fn-invoke',
+;;    `icicle-mouse-candidate-set-save',
+;;    `icicle-mouse-candidate-set-save-more',
+;;    `icicle-mouse-choose-completion',
+;;    `icicle-mouse-help-on-candidate',
+;;    `icicle-mouse-remove-candidate',
+;;    `icicle-mouse-save/unsave-candidate',
+;;    `icicle-mouse-save-then-kill', `icicle-mouse-yank-secondary',
+;;    `icicle-move-to-next-completion',
+;;    `icicle-move-to-previous-completion',
+;;    `icicle-narrow-candidates',
+;;    `icicle-narrow-candidates-with-predicate',
+;;    `icicle-negative-argument', `icicle-next-apropos-candidate',
+;;    `icicle-next-apropos-candidate-action',
+;;    `icicle-next-apropos-candidate-alt-action',
+;;    `icicle-next-candidate-per-mode',
+;;    `icicle-next-candidate-per-mode-action',
+;;    `icicle-next-candidate-per-mode-alt-action',
+;;    `icicle-next-candidate-per-mode-help', `icicle-next-line',
+;;    `icicle-next-prefix-candidate',
+;;    `icicle-next-prefix-candidate-action',
+;;    `icicle-next-prefix-candidate-alt-action',
+;;    `icicle-next-S-TAB-completion-method', `icicle-other-history',
+;;    `icicle-plus-saved-sort',
+;;    `icicle-pp-eval-expression-in-minibuffer',
+;;    `icicle-prefix-complete', `icicle-prefix-complete-no-display',
+;;    `icicle-prefix-word-complete',
+;;    `icicle-previous-apropos-candidate',
+;;    `icicle-previous-apropos-candidate-action',
+;;    `icicle-previous-apropos-candidate-alt-action',
+;;    `icicle-previous-candidate-per-mode',
+;;    `icicle-previous-candidate-per-mode-action',
+;;    `icicle-previous-candidate-per-mode-alt-action',
+;;    `icicle-previous-candidate-per-mode-help',
+;;    `icicle-previous-line', `icicle-previous-prefix-candidate',
+;;    `icicle-previous-prefix-candidate-action',
+;;    `icicle-previous-prefix-candidate-alt-action',
+;;    `icicle-read+insert-file-name', `icicle-regexp-quote-input',
+;;    `icicle-remove-candidate', `icicle-remove-Completions-window',
+;;    `icicle-resolve-file-name', `icicle-retrieve-last-input',
+;;    `icicle-retrieve-next-input', `icicle-retrieve-previous-input',
+;;    `icicle-reverse-sort-order',
+;;    `icicle-save-predicate-to-variable',
+;;    `icicle-save/unsave-candidate',
+;;    `icicle-scroll-Completions-backward',
+;;    `icicle-scroll-Completions-forward', `icicle-scroll-backward',
+;;    `icicle-scroll-forward', `icicle-search-define-replacement',
+;;    `icicle-self-insert', `icicle-sort-alphabetical',
+;;    `icicle-sort-by-abbrev-frequency',
+;;    `icicle-sort-by-directories-first',
+;;    `icicle-sort-by-directories-last',
+;;    `icicle-sort-by-last-file-modification-time',
+;;    `icicle-sort-by-last-use-as-input',
+;;    `icicle-sort-by-previous-use-alphabetically',
+;;    `icicle-sort-case-insensitive',
+;;    `icicle-sort-proxy-candidates-first', `icicle-sort-turned-OFF',
+;;    `icicle-switch-to-Completions-buf',
+;;    `icicle-switch-to-completions',
+;;    `icicle-switch-to/from-minibuffer', `icicle-toggle-.',
+;;    `icicle-toggle-~-for-home-dir', `icicle-toggle-C-for-actions',
+;;    `icicle-toggle-alternative-sorting',
+;;    `icicle-toggle-angle-brackets',
+;;    `icicle-toggle-case-sensitivity', `icicle-toggle-dot',
+;;    `icicle-toggle-expand-to-common-match',
+;;    `icicle-toggle-hiding-common-match',
+;;    `icicle-toggle-hiding-non-matching-lines',
+;;    `icicle-toggle-highlight-all-current',
+;;    `icicle-toggle-highlight-historical-candidates',
+;;    `icicle-toggle-highlight-saved-candidates',
+;;    `icicle-toggle-ignored-extensions',
+;;    `icicle-toggle-ignored-space-prefix',
+;;    `icicle-toggle-ignoring-comments',
+;;    `icicle-toggle-incremental-completion',
+;;    `icicle-toggle-literal-replacement',
+;;    `icicle-toggle-proxy-candidates', `icicle-toggle-regexp-quote',
+;;    `icicle-toggle-search-cleanup',
+;;    `icicle-toggle-search-complementing-domain',
+;;    `icicle-toggle-search-replace-common-match',
+;;    `icicle-toggle-search-replace-whole',
+;;    `icicle-toggle-search-whole-word',
+;;    `icicle-toggle-show-multi-completion', `icicle-toggle-sorting',
+;;    `icicle-toggle-transforming', `icicle-transpose-chars',
+;;    `icicle-transpose-sexps', `icicle-transpose-words',
+;;    `icicle-universal-argument', `icicle-universal-argument-minus',
+;;    `icicle-universal-argument-more',
+;;    `icicle-universal-argument-other-key', `icicle-up-directory',
+;;    `icicle-use-interactive-command-history',
+;;    `icicle-widen-candidates', `icicle-yank', `icicle-yank-pop',
+;;    `icicle-yank-secondary', `old-choose-completion',
+;;    `old-exit-minibuffer', `old-minibuffer-complete-and-exit',
+;;    `old-sit-for', `old-switch-to-completions', `toggle-icicle-.',
+;;    `toggle-icicle-~-for-home-dir', `toggle-icicle-C-for-actions',
+;;    `toggle-icicle-alternative-sorting',
+;;    `toggle-icicle-angle-brackets',
+;;    `toggle-icicle-case-sensitivity', `toggle-icicle-dot',
+;;    `toggle-icicle-expand-to-common-match',
+;;    `toggle-icicle-fuzzy-completion',
+;;    `toggle-icicle-hiding-common-match',
+;;    `toggle-icicle-hiding-non-matching-lines',
+;;    `toggle-icicle-highlight-all-current',
+;;    `toggle-icicle-highlight-historical-candidates',
+;;    `toggle-icicle-ignored-extensions',
+;;    `toggle-icicle-ignored-space-prefix',
+;;    `toggle-icicle-incremental-completion',
+;;    `toggle-icicle-literal-replacement',
+;;    `toggle-icicle-proxy-candidates', `toggle-icicle-regexp-quote',
+;;    `toggle-icicle-search-cleanup',
+;;    `toggle-icicle-search-complementing-domain',
+;;    `toggle-icicle-search-replace-common-match',
+;;    `toggle-icicle-search-replace-whole',
+;;    `toggle-icicle-search-whole-word', `toggle-icicle-sorting',
+;;    `toggle-icicle-transforming'.
+;;
+;;  Faces defined in Icicles (in Custom group `icicles'):
+;;
+;;    `icicle-candidate-part',
+;;    `icicle-common-match-highlight-Completions',
+;;    `icicle-complete-input', `icicle-completion',
+;;    `icicle-Completions-instruction-1',
+;;    `icicle-Completions-instruction-2',
+;;    `icicle-current-candidate-highlight', `icicle-extra-candidate',
+;;    `icicle-historical-candidate', `icicle-input-completion-fail',
+;;    `icicle-input-completion-fail-lax',
+;;    `icicle-match-highlight-Completions',
+;;    `icicle-match-highlight-minibuffer', `icicle-mode-line-help',
+;;    `icicle-mustmatch-completion', `icicle-proxy-candidate',
+;;    `icicle-saved-candidate', `icicle-search-context-level-1',
+;;    `icicle-search-context-level-2',
+;;    `icicle-search-context-level-3',
+;;    `icicle-search-context-level-4',
+;;    `icicle-search-context-level-5',
+;;    `icicle-search-context-level-6',
+;;    `icicle-search-context-level-7',
+;;    `icicle-search-context-level-8', `icicle-search-current-input',
+;;    `icicle-search-main-regexp-current',
+;;    `icicle-search-main-regexp-others', `icicle-special-candidate',
+;;    `icicle-whitespace-highlight', `minibuffer-prompt'.
+;;
+;;  User options defined in Icicles:
+;;
+;;    `icicle-act-before-cycle-flag',
+;;    `icicle-add-proxy-candidates-flag',
+;;    `icicle-alternative-actions-alist',
+;;    `icicle-alternative-sort-comparer',
+;;    `icicle-anything-transform-candidates-flag',
+;;    `icicle-apropos-complete-keys',
+;;    `icicle-apropos-complete-no-display-keys',
+;;    `icicle-apropos-cycle-next-keys',
+;;    `icicle-apropos-cycle-next-action-keys',
+;;    `icicle-apropos-cycle-next-alt-action-keys',
+;;    `icicle-apropos-cycle-next-help-keys',
+;;    `icicle-apropos-cycle-previous-keys',
+;;    `icicle-apropos-cycle-previous-action-keys',
+;;    `icicle-apropos-cycle-previous-alt-action-keys',
+;;    `icicle-apropos-cycle-previous-help-keys',
+;;    `icicle-bookmark-name-length-max',
+;;    `icicle-bookmark-refresh-cache-flag', `icicle-buffer-configs',
+;;    `icicle-buffer-extras',
+;;    `icicle-buffer-ignore-space-prefix-flag',
+;;    `icicle-buffer-match-regexp', `icicle-buffer-no-match-regexp',
+;;    `icicle-buffer-predicate', `icicle-buffer-require-match-flag'
+;;    `icicle-buffer-sort', `icicle-buffers-ido-like-flag',
+;;    `icicle-byte-compile-eval-after-load-flag',
+;;    `icicle-candidate-width-factor',
+;;    `icicle-change-region-background-flag',
+;;    `icicle-change-sort-order-completion-flag',
+;;    `icicle-C-l-uses-completion-flag', `icicle-color-themes',
+;;    `icicle-comint-dynamic-complete-replacements',
+;;    `icicle-command-abbrev-alist',
+;;    `icicle-command-abbrev-match-all-parts-flag',
+;;    `icicle-command-abbrev-priority-flag',
+;;    `icicle-complete-key-anyway-flag',
+;;    `icicle-complete-keys-self-insert-ranges',
+;;    `icicle-completing-read+insert-keys',
+;;    `icicle-completion-history-max-length',
+;;    `icicle-Completions-display-min-input-chars',
+;;    `icicle-completions-format',
+;;    `icicle-Completions-mouse-3-menu-entries',
+;;    `icicle-Completions-text-scale-decrease',
+;;    `icicle-Completions-window-max-height',
+;;    `icicle-customize-save-flag',
+;;    `icicle-customize-save-variable-function',
+;;    `icicle-cycle-into-subdirs-flag', `icicle-default-cycling-mode',
+;;    `icicle-default-thing-insertion', `icicle-default-value',
+;;    `icicle-define-alias-commands-flag',
+;;    `icicle-deletion-action-flag', `icicle-dot-show-regexp-flag',
+;;    `icicle-dot-string', `icicle-expand-input-to-common-match-flag',
+;;    `icicle-file-extras', `icicle-file-match-regexp',
+;;    `icicle-file-no-match-regexp', `icicle-file-predicate',
+;;    `icicle-file-require-match-flag', `icicle-file-sort',
+;;    `icicle-files-ido-like-flag',
+;;    `icicle-filesets-as-saved-completion-sets-flag',
+;;    `icicle-functions-to-redefine', `icicle-guess-commands-in-path',
+;;    `icicle-help-in-mode-line-delay',
+;;    `icicle-hide-common-match-in-Completions-flag',
+;;    `icicle-hide-non-matching-lines-flag',
+;;    `icicle-highlight-historical-candidates-flag',
+;;    `icicle-highlight-input-completion-failure',
+;;    `icicle-highlight-input-completion-failure-delay',
+;;    `icicle-highlight-input-completion-failure-threshold',
+;;    `icicle-highlight-input-initial-whitespace-flag',
+;;    `icicle-highlight-lighter-flag',
+;;    `icicle-highlight-saved-candidates-flag',
+;;    `icicle-ignore-comments-flag', `icicle-ignored-directories',
+;;    `icicle-ignore-space-prefix-flag',
+;;    `icicle-image-files-in-Completions',
+;;    `icicle-incremental-completion-delay',
+;;    `icicle-incremental-completion-flag',
+;;    `icicle-incremental-completion-threshold',
+;;    `icicle-inhibit-advice-functions', `icicle-inhibit-ding-flag',
+;;    `icicle-input-string', `icicle-inter-candidates-min-spaces',
+;;    `icicle-isearch-complete-keys', `icicle-key-complete-keys',
+;;    `icicle-key-descriptions-use-<>-flag',
+;;    `icicle-key-descriptions-use-angle-brackets-flag',
+;;    `icicle-keymaps-for-key-completion', `icicle-kmacro-ring-max',
+;;    `icicle-levenshtein-distance', `icicle-list-join-string',
+;;    `icicle-list-nth-parts-join-string',
+;;    `icicle-mark-position-in-candidate', `icicle-max-candidates',
+;;    `icicle-menu-items-to-history-flag',
+;;    `icicle-minibuffer-setup-hook', `icicle-modal-cycle-down-keys',
+;;    `icicle-modal-cycle-down-action-keys',
+;;    `icicle-modal-cycle-down-alt-action-keys',
+;;    `icicle-modal-cycle-down-help-keys',
+;;    `icicle-modal-cycle-up-keys',
+;;    `icicle-modal-cycle-up-action-keys',
+;;    `icicle-modal-cycle-up-alt-action-keys',
+;;    `icicle-modal-cycle-up-help-keys', `icicle-mode',
+;;    `icicle-mode-hook', `icicle-move-Completions-frame',
+;;    `icicle-no-match-hook', `icicle-option-type-prefix-arg-list',
+;;    `icicle-point-position-in-candidate',
+;;    `icicle-populate-interactive-history-flag',
+;;    `icicle-pp-eval-expression-print-length',
+;;    `icicle-pp-eval-expression-print-level',
+;;    `icicle-prefix-complete-keys',
+;;    `icicle-prefix-complete-no-display-keys',
+;;    `icicle-prefix-cycle-next-keys',
+;;    `icicle-prefix-cycle-next-action-keys',
+;;    `icicle-prefix-cycle-next-alt-action-keys',
+;;    `icicle-prefix-cycle-next-help-keys',
+;;    `icicle-prefix-cycle-previous-keys',
+;;    `icicle-prefix-cycle-previous-action-keys',
+;;    `icicle-prefix-cycle-previous-alt-action-keys',
+;;    `icicle-prefix-cycle-previous-help-keys',
+;;    `icicle-previous-candidate-keys',
+;;    `icicle-quote-shell-file-name-flag',
+;;    `icicle-read+insert-file-name-keys', `icicle-recenter',
+;;    `icicle-regexp-quote-flag', `icicle-regexp-search-ring-max',
+;;    `icicle-region-background', `icicle-require-match-flag',
+;;    `icicle-saved-completion-sets', `icicle-search-cleanup-flag',
+;;    `icicle-search-from-isearch-keys',
+;;    `icicle-search-highlight-all-current-flag',
+;;    `icicle-search-highlight-context-levels-flag',
+;;    `icicle-search-highlight-threshold', `icicle-search-hook',
+;;    `icicle-search-replace-common-match-flag',
+;;    `icicle-search-replace-literally-flag',
+;;    `icicle-search-replace-whole-candidate-flag',
+;;    `icicle-search-ring-max', `icicle-search-whole-word-flag',
+;;    `icicle-shell-command-candidates-cache',
+;;    `icicle-show-Completions-help-flag',
+;;    `icicle-show-Completions-initially-flag',
+;;    `icicle-show-multi-completion-flag', `icicle-sort-comparer',
+;;    `icicle-sort-orders-alist', `icicle-special-candidate-regexp',
+;;    `icicle-S-TAB-completion-methods-alist',
+;;    `icicle-S-TAB-completion-methods-per-command',
+;;    `icicle-swank-prefix-length', `icicle-swank-timeout',
+;;    `icicle-TAB-completion-methods',
+;;    `icicle-TAB-completion-methods-per-command',
+;;    `icicle-TAB-shows-candidates-flag',
+;;    `icicle-test-for-remote-files-flag',
+;;    `icicle-thing-at-point-functions',
+;;    `icicle-top-level-key-bindings',
+;;    `icicle-top-level-when-sole-completion-delay',
+;;    `icicle-top-level-when-sole-completion-flag',
+;;    `icicle-touche-pas-aux-menus-flag', `icicle-transform-function',
+;;    `icicle-type-actions-alist',
+;;    `icicle-unpropertize-completion-result-flag',
+;;    `icicle-update-input-hook', `icicle-use-~-for-home-dir-flag',
+;;    `icicle-use-C-for-actions-flag',
+;;    `icicle-use-anything-candidates-flag',
+;;    `icicle-use-candidates-only-once-flag',
+;;    `icicle-word-completion-keys',
+;;    `icicle-WYSIWYG-Completions-flag', `icicle-yank-function'.
+;;
+;;  Non-interactive functions in Icicles:
+;;
+;;    `custom-variable-p', `icicle-2nd-part-string-less-p',
+;;    `icicle-abbreviate-or-expand-file-name', `icicle-activate-mark',
+;;    `icicle-add-key+cmd', `icicle-add-menu-item-to-cmd-history',
+;;    `icicle-add/remove-tags-and-refresh',
+;;    `icicle-all-candidates-action-1', `icicle-all-completions',
+;;    `icicle-all-exif-data', `icicle-alpha-p',
+;;    `icicle-alt-act-fn-for-type', `icicle-any-candidates-p',
+;;    `icicle-anychar-regexp', `icicle-anything-candidate-value',
+;;    `icicle-apply-action', `icicle-apply-list-action',
+;;    `icicle-apply-to-saved-candidate',
+;;    `icicle-apropos-any-candidates-p',
+;;    `icicle-apropos-any-file-name-candidates-p',
+;;    `icicle-apropos-candidates', `icicle-apropos-complete-1',
+;;    `icicle-backward-delete-char-untabify-dots',
+;;    `icicle-barf-if-outside-Completions',
+;;    `icicle-barf-if-outside-Completions-and-minibuffer',
+;;    `icicle-barf-if-outside-minibuffer', `icicle-binary-option-p',
+;;    `icicle-bind-completion-keys',
+;;    `icicle-bind-file-candidate-keys', `icicle-bind-isearch-keys',
+;;    `icicle-bind-key-completion-keys-for-map-var',
+;;    `icicle-bind-key-completion-keys-in-keymaps-from',
+;;    `icicle-bind-other-keymap-keys',
+;;    `icicle-bind-top-level-commands', `icicle-bookmark-cleanup',
+;;    `icicle-bookmark-cleanup-on-quit',
+;;    `icicle-bookmark-delete-action', `icicle-bookmark-help-string',
+;;    `icicle-bookmark-jump-1',
+;;    `icicle-buffer-file/process-name-less-p',
+;;    `icicle-buffer-smaller-p', `icicle-buffer-sort-*...*-last',
+;;    `icicle-call-then-update-Completions',
+;;    `icicle-cancel-Help-redirection', `icicle-candidate-action-1',
+;;    `icicle-candidate-set-1', `icicle-candidate-set-retrieve-1',
+;;    `icicle-candidate-set-save-1',
+;;    `icicle-candidate-set-save-selected-1',
+;;    `icicle-candidate-short-help',
+;;    `icicle-case-insensitive-string-less-p',
+;;    `icicle-case-string-less-p', `icicle-cdr-lessp',
+;;    `icicle-char-properties-in-buffer',
+;;    `icicle-char-properties-in-buffers',
+;;    `icicle-choose-anything-candidate',
+;;    `icicle-choose-candidate-of-type',
+;;    `icicle-choose-completion-string', `icicle-clear-history-1',
+;;    `icicle-clear-history-entry', `icicle-clear-lighter',
+;;    `icicle-clear-minibuffer', `icicle-color-blue-lessp',
+;;    `icicle-color-completion-setup',
+;;    `icicle-color-distance-hsv-lessp',
+;;    `icicle-color-distance-rgb-lessp', `icicle-color-green-lessp',
+;;    `icicle-color-help', `icicle-color-hsv-lessp',
+;;    `icicle-color-hue-lessp', `icicle-color-name-w-bg',
+;;    `icicle-color-red-lessp', `icicle-color-saturation-lessp',
+;;    `icicle-color-value-lessp', `icicle-column-wise-cand-nb',
+;;    `icicle-Completions-popup-choice',
+;;    `icicle-Completions-popup-choice-1',
+;;    `icicle-comint-dynamic-complete-as-filename',
+;;    `icicle-comint-dynamic-simple-complete',
+;;    `icicle-comint-hook-fn',
+;;    `icicle-comint-replace-orig-completion-fns',
+;;    `icicle-comint-search-get-final-choice',
+;;    `icicle-comint-search-get-minibuffer-input',
+;;    `icicle-comint-search-send-input',
+;;    `icicle-command-abbrev-action', `icicle-command-abbrev-command',
+;;    `icicle-command-abbrev-matching-commands',
+;;    `icicle-command-abbrev-record', `icicle-command-abbrev-regexp',
+;;    `icicle-command-abbrev-save',
+;;    `icicle-command-abbrev-used-more-p',
+;;    `icicle-command-names-alphabetic-p',
+;;    `icicle-compilation-hook-fn',
+;;    `icicle-compilation-search-in-context-fn',
+;;    `icicle-complete-again-update', `icicle-complete-keys-1',
+;;    `icicle-complete-keys-action', `icicle-completing-p',
+;;    `icicle-completing-read', , `icicle-completing-read-multiple',
+;;    `icicle-completing-read-history',
+;;    `icicle-completion-all-completions',
+;;    `icicle-completion-setup-function',
+;;    `icicle-completion-try-completion',
+;;    `icicle-compute-shell-command-candidates',
+;;    `icicle-convert-dots',
+;;    `icicle-current-completion-in-Completions',
+;;    `icicle-current-sort-functions', `icicle-current-sort-order',
+;;    `icicle-current-TAB-method', `icicle-customize-faces',
+;;    `icicle-custom-type', `icicle-dabbrev--abbrev-at-point',
+;;    `icicle-default-buffer-names',
+;;    `icicle-define-crm-completion-map', ,
+;;    `icicle-define-cycling-keys', `icicle-defined-thing-p',
+;;    `icicle-define-icicle-maps', `icicle-define-minibuffer-maps',
+;;    `icicle-delete-backward-char-dots',
+;;    `icicle-delete-candidate-object-1', `icicle-delete-char-dots',
+;;    `icicle-delete-count', `icicle-delete-current-candidate-object',
+;;    `icicle-delete-dups', `icicle-delete-file-or-directory',
+;;    `icicle-delete-whitespace-from-string',
+;;    `icicle-describe-opt-action',
+;;    `icicle-describe-opt-of-type-complete', `icicle-ding',
+;;    `icicle-dired-read-shell-command',
+;;    `icicle-dired-smart-shell-command',
+;;    `icicle-dir-prefix-wo-wildcards', `icicle-dirs-first-p',
+;;    `icicle-dirs-last-p', `icicle-displayable-cand-from-saved-set',
+;;    `icicle-display-cand-from-full-cand',
+;;    `icicle-display-completion-list', `icicle-display-Completions',
+;;    `icicle-display-candidates-in-Completions', `icicle-doc-action',
+;;    `icicle-edmacro-parse-keys',
+;;    `icicle-ensure-overriding-map-is-bound',
+;;    `icicle-execute-extended-command-1',
+;;    `icicle-expanded-common-match',
+;;    `icicle-expanded-common-match-1', `icicle-expand-file-name-20',
+;;    `icicle-expand-file-or-dir-name',
+;;    `icicle-explicit-saved-completion-candidates', `icicle-explore',
+;;    `icicle-extra-candidates-first-p',
+;;    `icicle-face-valid-attribute-values', `icicle-file-directory-p',
+;;    `icicle-file-name-apropos-candidates',
+;;    `icicle-file-name-directory',
+;;    `icicle-file-name-directory-w-default',
+;;    `icicle-file-name-input-p', `icicle-file-name-nondirectory',
+;;    `icicle-file-name-prefix-candidates', `icicle-file-readable-p',
+;;    `icicle-file-remote-p', `icicle-file-type-less-p',
+;;    `icicle-file-writable-p', `icicle-filesets-files-under',
+;;    `icicle-files-within', `icicle-files-within-1',
+;;    `icicle-filter-alist', `icicle-filter-wo-input',
+;;    `icicle-find-first-tag-action',
+;;    `icicle-find-first-tag-other-window-action',
+;;    `icicle-find-tag-action', `icicle-find-tag-define-candidates',
+;;    `icicle-find-tag-define-candidates-1',
+;;    `icicle-find-tag-final-act', `icicle-find-tag-help',
+;;    `icicle-find-tag-quit-or-error',
+;;    `icicle-first-matching-candidate', `icicle-first-N',
+;;    `icicle-fit-completions-window', `icicle-fix-default-directory',
+;;    `icicle-flat-list', `icicle-fn-doc-minus-sig',
+;;    `icicle-font-w-orig-size', `icicle-frame-name-history',
+;;    `icicle-frames-on', `icicle-function-name-history',
+;;    `icicle-fuzzy-candidates', `icicle-get-alist-candidate',
+;;    `icicle-get-anything-actions-for-type',
+;;    `icicle-get-anything-cached-candidates',
+;;    `icicle-get-anything-candidates',
+;;    `icicle-get-anything-candidates-of-type',
+;;    `icicle-get-anything-default-actions-for-type',
+;;    `icicle-get-anything-input-delay',
+;;    `icicle-get-anything-req-pat-chars',
+;;    `icicle-get-anything-types',
+;;    `icicle-get-candidates-from-saved-set', `icicle-goto-marker-1',
+;;    `icicle-goto-marker-1-action', `icicle-group-regexp',
+;;    `icicle-dired-guess-shell-command',
+;;    `icicle-help-on-candidate-symbol', `icicle-help-line-buffer',
+;;    `icicle-help-line-file', `icicle-help-string-completion',
+;;    `icicle-highlight-candidate-in-Completions',
+;;    `icicle-highlight-complete-input',
+;;    `icicle-highlight-initial-whitespace',
+;;    `icicle-highlight-input-noncompletion',
+;;    `icicle-highlight-input-noncompletion-rest',
+;;    `icicle-highlight-lighter', `icicle-historical-alphabetic-p',
+;;    `icicle-imenu-command-p', `icicle-imenu-in-buffer-p',
+;;    `icicle-imenu-non-interactive-function-p',
+;;    `icicle-increment-cand-nb+signal-end',
+;;    `icicle-increment-color-hue', `icicle-increment-color-value',
+;;    `icicle-Info-book-order-p',
+;;    `icicle-Info-build-node-completions',
+;;    `icicle-Info-build-node-completions-1',
+;;    `icicle-Info-goto-node-1', `icicle-Info-goto-node-action',
+;;    `icicle-Info-index-action', `icicle-Info-read-node-name',
+;;    `icicle-input-from-minibuffer',
+;;    `icicle-input-is-a-completion-p', `icicle-insert-candidates',
+;;    `icicle-insert-cand-in-minibuffer',
+;;    `icicle-insert-Completions-help-string', `icicle-insert-dot',
+;;    `icicle-insert-for-yank', `icicle-insert-input',
+;;    `icicle-insert-thesaurus-entry-cand-fn', `icicle-insert-thing',
+;;    `icicle-invisible-face-p', `icicle-invisible-p',
+;;    `icicle-isearch-complete-past-string', `icicle-join-nth-parts',
+;;    `icicle-key-description', `icicle-keys+cmds-w-prefix',
+;;    `icicle-kill-a-buffer',
+;;    `icicle-kill-a-buffer-and-update-completions',
+;;    `icicle-kmacro-action', `icicle-last-modified-first-p',
+;;    `icicle-levenshtein-match', `icicle-levenshtein-one-match',
+;;    `icicle-levenshtein-one-regexp',
+;;    `icicle-levenshtein-strict-match',
+;;    `icicle-lisp-completion-at-point',
+;;    `icicle-lisp-vanilla-completing-read',
+;;    `icicle-local-keys-first-p', `icicle-locate-file-1',
+;;    `icicle-locate-file-action',
+;;    `icicle-locate-file-other-window-action',
+;;    `icicle-looking-at-anychar-regexp-p',
+;;    `icicle-looking-back-at-anychar-regexp-p',
+;;    `icicle-major-mode-name-less-p', `icicle-make-color-candidate',
+;;    `icicle-make-face-candidate', `icicle-make-frame-alist',
+;;    `icicle-make-plain-predicate', `icicle-make-window-alist',
+;;    `icicle-markers', `icicle-markers-to-readable',
+;;    `icicle-marker+text',
+;;    `icicle-maybe-multi-completion-completing-p',
+;;    `icicle-maybe-sort-and-strip-candidates',
+;;    `icicle-maybe-sort-maybe-truncate', `icicle-mctize-all',
+;;    `icicle-mctized-display-candidate',
+;;    `icicle-mctized-full-candidate',
+;;    `icicle-merge-saved-order-less-p',
+;;    `icicle-minibuffer-default-add-completions',
+;;    `icicle-minibuf-input', `icicle-minibuf-input-sans-dir',
+;;    `icicle-minibuffer-default-add-dired-shell-commands',
+;;    `icicle-minibuffer-prompt-end', `icicle-minibuffer-setup',
+;;    `icicle-mode-line-name-less-p', `icicle-most-recent-first-p',
+;;    `icicle-mouse-candidate-action-1',
+;;    `icicle-msg-maybe-in-minibuffer', `icicle-ms-windows-NET-USE',
+;;    `icicle-multi-sort', `icicle-nb-Completions-cols',
+;;    `icicle-nb-of-cand-at-Completions-pos',
+;;    `icicle-nb-of-cand-in-Completions-horiz',
+;;    `icicle-next-candidate',
+;;    `icicle-next-single-char-property-change',
+;;    `icicle-next-visible-thing-1', `icicle-next-visible-thing-2',
+;;    `icicle-next-visible-thing-and-bounds',
+;;    `icicle-non-whitespace-string-p',
+;;    `icicle-not-basic-prefix-completion-p',
+;;    `icicle-part-1-cdr-lessp', `icicle-part-1-lessp',
+;;    `icicle-part-2-lessp', `icicle-part-3-lessp',
+;;    `icicle-part-4-lessp', `icicle-part-N-lessp',
+;;    `icicle-pick-color-by-name-action', `icicle-place-cursor',
+;;    `icicle-place-overlay', `icicle-position',
+;;    `icicle-prefix-any-candidates-p',
+;;    `icicle-prefix-any-file-name-candidates-p',
+;;    `icicle-prefix-candidates', `icicle-prefix-complete-1',
+;;    `icicle-prefix-keys-first-p',
+;;    `icicle-previous-single-char-property-change',
+;;    `icicle-proxy-candidate-first-p', `icicle-put-at-head',
+;;    `icicle-put-whole-cand-prop',
+;;    `icicle-quote-file-name-part-of-cmd',
+;;    `icicle-raise-Completions-frame', `icicle-readable-to-markers',
+;;    `icicle-read-args-for-set-completion-methods',
+;;    `icicle-read-char-exclusive', `icicle-read-face-name',
+;;    `icicle-read-file-name', `icicle-read-from-minibuffer',
+;;    `icicle-read-from-minibuf-nil-default',
+;;    `icicle-read-single-key-description', `icicle-read-number',
+;;    `icicle-read-shell-command',
+;;    `icicle-read-shell-command-completing', `icicle-read-string',
+;;    `icicle-read-string-completing',
+;;    `icicle-read-var-value-satisfying', `icicle-rebind-global',
+;;    `icicle-recentf-make-menu-items', `icicle-recompute-candidates',
+;;    `icicle-redefine-standard-functions',
+;;    `icicle-redefine-standard-options',
+;;    `icicle-redefine-std-completion-fns',
+;;    `icicle-region-or-buffer-limits', `icicle-remap',
+;;    `icicle-remove-buffer-candidate-action',
+;;    `icicle-remove-buffer-config-action',
+;;    `icicle-remove-cand-from-lists',
+;;    `icicle-remove-candidate-display-others',
+;;    `icicle-remove-color-duplicates', `icicle-remove-dots',
+;;    `icicle-remove-duplicates', `icicle-remove-dups-if-extras',
+;;    `icicle-remove-from-recentf-candidate-action',
+;;    `icicle-remove-if', `icicle-remove-if-not',
+;;    `icicle-remove-property', `icicle-replace-mct-cand-in-mct',
+;;    `icicle-remove-saved-set-action',
+;;    `icicle-replace-input-w-parent-dir', `icicle-require-match-p',
+;;    `icicle-restore-completion-keys',
+;;    `icicle-restore-other-keymap-keys',
+;;    `icicle-restore-region-face',
+;;    `icicle-restore-standard-commands',
+;;    `icicle-restore-standard-options',
+;;    `icicle-restore-std-completion-fns',
+;;    `icicle-retrieve-candidates-from-set', `icicle-reversible-sort',
+;;    `icicle-row-wise-cand-nb',
+;;    `icicle-run-icicle-post-command-hook',
+;;    `icicle-run-icicle-pre-command-hook', `icicle-saved-fileset-p',
+;;    `icicle-save-or-restore-input', `icicle-save-raw-input',
+;;    `icicle-scatter', `icicle-scatter-match',
+;;    `icicle-scroll-or-update-Completions', `icicle-search-action',
+;;    `icicle-search-action-1', `icicle-search-bookmark-action',
+;;    `icicle-search-char-property-scan',
+;;    `icicle-search-choose-buffers', `icicle-search-cleanup',
+;;    `icicle-search-define-candidates',
+;;    `icicle-search-define-candidates-1', `icicle-search-final-act',
+;;    `icicle-search-help',
+;;    `icicle-search-highlight-all-input-matches',
+;;    `icicle-search-highlight-and-maybe-replace',
+;;    `icicle-search-highlight-input-matches-here',
+;;    `icicle-search-in-context-default-fn',
+;;    `icicle-search-property-args', `icicle-search-quit-or-error',
+;;    `icicle-search-read-context-regexp', `icicle-search-read-word',
+;;    `icicle-search-regexp-scan',
+;;    `icicle-search-replace-all-search-hits',
+;;    `icicle-search-replace-cand-in-alist',
+;;    `icicle-search-replace-cand-in-mct',
+;;    `icicle-search-replace-fixed-case-p',
+;;    `icicle-search-replace-match', `icicle-search-thing-args',
+;;    `icicle-search-thing-scan', `icicle-search-where-arg',
+;;    `icicle-select-minibuffer-contents' `icicle-set-calling-cmd',
+;;    `icicle-set-completion-methods-for-command',
+;;    `icicle-set-difference', `icicle-set-intersection',
+;;    `icicle-set-union', `icicle-shell-command',
+;;    `icicle-shell-command-on-file',
+;;    `icicle-shell-command-on-region',
+;;    `icicle-shell-dynamic-complete-as-command',
+;;    `icicle-shell-dynamic-complete-as-environment-variable',
+;;    `icicle-show-help-in-mode-line', `icicle-show-in-mode-line',
+;;    `icicle-signum', `icicle-S-iso-lefttab-to-S-TAB',
+;;    `icicle-special-candidates-first-p',
+;;    `icicle-start-of-candidates-in-Completions',
+;;    `icicle-strip-ignored-files-and-sort',
+;;    `icicle-subst-envvar-in-file-name',
+;;    `icicle-substring-no-properties', `icicle-substrings-of-length',
+;;    `icicle-substitute-keymap-vars', `icicle-successive-action',
+;;    `icicle-take', `icicle-things-alist',
+;;    `icicle-this-command-keys-prefix',
+;;    `icicle-toggle-icicle-mode-twice', `icicle-top-level-prep',
+;;    `icicle-transform-candidates',
+;;    `icicle-transform-multi-completion',
+;;    `icicle-transform-sole-candidate',
+;;    `icicle-transpose-chars-dots', `icicle-try-switch-buffer',
+;;    `icicle-unbind-file-candidate-keys',
+;;    `icicle-unbind-isearch-keys',
+;;    `icicle-unbind-key-completion-keys-for-map-var',
+;;    `icicle-unbind-key-completion-keys-in-keymaps-from',
+;;    `icicle-undo-std-completion-faces',
+;;    `icicle-unhighlight-lighter', `icicle-unmap',
+;;    `icicle-unpropertize', `icicle-unsorted-apropos-candidates',
+;;    `icicle-unsorted-file-name-apropos-candidates',
+;;    `icicle-unsorted-file-name-prefix-candidates',
+;;    `icicle-unsorted-prefix-candidates', `icicle-upcase',
+;;    `icicle-upcase-if-ignore-case', `icicle-update-and-next',
+;;    `icicle-update-ignored-extensions-regexp',
+;;    `icicle-value-satisfies-type-p', `icicle-var-inherits-type-p',
+;;    `icicle-var-is-of-type-p', `icicle-var-matches-type-p',
+;;    `icicle-var-val-satisfies-type-p',
+;;    `old-choose-completion-string', `old-completing-read',
+;;    `old-completing-read-multiple', `old-completion-setup-function',
+;;    `old-dired-smart-shell-command', `old-display-completion-list',
+;;    `old-face-valid-attribute-values',
+;;    `old-minibuffer-default-add-completions', `old-read-face-name',
+;;    `old-read-from-minibuffer', `old-read-number',
+;;    `old-read-string', `old-shell-command',
+;;    `old-shell-command-on-region'.
+;;
+;;  Internal variables and constants defined in Icicles:
+;;
+;;    `icicle-abs-file-candidates', `icicle-acting-on-next/prev',
+;;    `icicle-active-map', `icicle-advice-info-list',
+;;    `icicle-all-candidates-action',
+;;    `icicle-all-candidates-list-action-fn',
+;;    `icicle-all-candidates-list-alt-action-fn',
+;;    `icicle-anychar-regexp', `icicle-apply-nomsg',
+;;    `icicle-apropos-complete-match-fn', `icicle-bookmark-history',
+;;    `icicle-bookmark-menu-map', `icicle-bookmark-types',
+;;    `icicle-buffer-config-history',
+;;    `icicle-buffer-sort-first-time-p', `icicle-bufflist',
+;;    `icicle-candidate-action-fn', `icicle-candidate-alt-action-fn',
+;;    `icicle-candidate-entry-fn', `icicle-candidate-help-fn',
+;;    `icicle-candidate-nb', `icicle-candidate-properties-alist',
+;;    `icicle-candidates-alist', `icicle-char-property-value-history',
+;;    `icicle-cmd-calling-for-completion', `icicle-cmd-reading-input',
+;;    `icicle-color-history', `icicle-color-theme-history',
+;;    `icicle-command-abbrev-history', `icicle-commands-for-abbrev',
+;;    `icicle-common-match-string',
+;;    `icicle-comp-base-is-default-dir-p',
+;;    `icicle-complete-input-overlay', `icicle-complete-keys-alist',
+;;    `icicle-completing-p',
+;;    `icicle-completing-read+insert-candidates',
+;;    `icicle-completion-candidates',
+;;    `icicle-completion-prompt-overlay',
+;;    `icicle-completion-set-history',
+;;    `icicle-Completions-misc-submenu',
+;;    `icicle-Completions-save/retrieve-submenu',
+;;    `icicle-Completions-sets-submenu',
+;;    `icicle-Completions-sorting-submenu',
+;;    `icicle-Completions-this-candidate-submenu',
+;;    `icicle-Completions-toggle-submenu'
+;;    `icicle-confirm-exit-commands',
+;;    `icicle-crm-local-completion-map',
+;;    `icicle-crm-local-must-match-map',
+;;    `icicle-current-completion-candidate-overlay',
+;;    `icicle-current-completion-mode', `icicle-current-input',
+;;    `icicle-current-raw-input', `icicle-current-TAB-method',
+;;    `icicle-custom-menu-map', `icicle-cycling-p',
+;;    `icicle-default-directory',
+;;    `icicle-default-thing-insertion-flipped-p',
+;;    `icicle-delete-candidate-object', `icicle-describe-menu-map',
+;;    `icicle-dictionary-history', `icicle-dir-candidate-can-exit-p',
+;;    `icicle-dirs-done', `icicle-doc-last-initial-cand-set',
+;;    `icicle-dot-string-internal', `icicle-edit-menu-map',
+;;    `icicle-edit-update-p', `icicle-explore-final-choice',
+;;    `icicle-explore-final-choice-full', `icicle-extra-candidates',
+;;    `icicle-extra-candidates-dir-insert-p',
+;;    `icicle-face-name-history', `icicle-fancy-candidates-p',
+;;    `icicle-fancy-cands-internal-p', `icicle-file-menu-map',
+;;    `icicle-files', `icicle-file-sort-first-time-p',
+;;    `icicle-filtered-default-value', `icicle-font-name-history',
+;;    `icicle-frame-alist', `icicle-frame-name-history',
+;;    `icicle-frames-menu-map', `icicle-full-cand-fn',
+;;    `icicle-function-name-history',
+;;    `icicle-fundoc-last-initial-cand-set',
+;;    `icicle-general-help-string',
+;;    `icicle-get-alist-candidate-function',
+;;    `icicle-hist-cands-no-highlight', `icicle-ignored-extensions',
+;;    `icicle-ignored-extensions-regexp',
+;;    `icicle-incremental-completion-p', `icicle-info-buff',
+;;    `icicle-info-menu-map', `icicle-Info-only-rest-of-book-p',
+;;    `icicle-info-window', `icicle-inhibit-sort-p',
+;;    `icicle-inhibit-try-switch-buffer', `icicle-initial-value',
+;;    `icicle-input-completion-fail-overlay', `icicle-input-fail-pos',
+;;    `icicle-insert-string-at-pt-end',
+;;    `icicle-insert-string-at-pt-start',
+;;    `icicle-interactive-history', `icicle-key-prefix',
+;;    `icicle-key-prefix-2', `icicle-key-prefix-description',
+;;    `icicle-kill-history', `icicle-kmacro-alist',
+;;    `icicle-kmacro-history',
+;;    `icicle-last-apropos-complete-match-fn',
+;;    `icicle-last-completion-candidate',
+;;    `icicle-last-completion-command', `icicle-last-input',
+;;    `icicle-last-sort-comparer', `icicle-last-top-level-command',
+;;    `icicle-last-transform-function', `icicle-last-thing-type',
+;;    `icicle-locate-file-action-fn',
+;;    `icicle-locate-file-no-symlinks-p', `icicle-lighter-truncation',
+;;    `icicle-list-use-nth-parts', `icicle-menu-map',
+;;    `icicle-minibuffer-message-ok-p', `icicle-minor-mode-map-entry',
+;;    `icicle-mode-map', `icicle-ms-windows-drive-hash',
+;;    `icicle-must-match-regexp', `icicle-must-not-match-regexp',
+;;    `icicle-must-pass-after-match-predicate',
+;;    `icicle-must-pass-predicate', `icicle-named-colors',
+;;    `icicle-nb-candidates-before-truncation',
+;;    `icicle-nb-of-other-cycle-candidates', `icicle-new-last-cmd',
+;;    `icicle-next-apropos-complete-cycles-p',
+;;    `icicle-next-prefix-complete-cycles-p',
+;;    `icicle-old-read-file-name-fn', `icicle-options-menu-map',
+;;    `icicle-orig-buff', `icicle-orig-buff-key-complete',
+;;    `icicle-orig-extra-cands', `icicle-orig-font',
+;;    `icicle-orig-frame', `icicle-orig-menu-bar',
+;;    `icicle-orig-must-pass-after-match-pred',
+;;    `icicle-orig-pixelsize', `icicle-orig-pointsize',
+;;    `icicle-orig-pt-explore', `icicle-orig-show-initially-flag',
+;;    `icicle-orig-sort-orders-alist', `icicle-orig-window',
+;;    `icicle-orig-win-key-complete', `icicle-other-window',
+;;    `icicle-plist-last-initial-cand-set',
+;;    `icicle-pre-minibuffer-buffer', `icicle-post-command-hook',
+;;    `icicle-pre-command-hook', `icicle-predicate-types-alist',
+;;    `icicle-previous-raw-file-name-inputs',
+;;    `icicle-previous-raw-non-file-name-inputs',
+;;    `icicle-progressive-completing-p', `icicle-prompt',
+;;    `icicle-proxy-candidate-regexp', `icicle-proxy-candidates',
+;;    `icicle-read-expression-map', `icicle-remove-icicles-props-p',
+;;    `icicle-re-no-dot', `icicle-require-match-p',
+;;    `icicle-reverse-multi-sort-p', `icicle-reverse-sort-p',
+;;    `icicle-saved-candidate-overlays',
+;;    `icicle-saved-candidates-variables-obarray',
+;;    `icicle-saved-completion-candidate',
+;;    `icicle-saved-completion-candidates',
+;;    `icicle-saved-completion-candidates-internal',
+;;    `icicle-saved-ignored-extensions',
+;;    `icicle-saved-kmacro-ring-max', `icicle-saved-proxy-candidates',
+;;    `icicle-saved-regexp-search-ring-max',
+;;    `icicle-saved-region-background',
+;;    `icicle-saved-search-ring-max',
+;;    `icicle-scroll-Completions-reverse-p', `icicle-search-command',
+;;    `icicle-search-complement-domain-p',
+;;    `icicle-search-context-level', `icicle-search-context-regexp',
+;;    `icicle-search-current-overlay', `icicle-search-final-choice',
+;;    `icicle-search-history', `icicle-search-in-context-fn',
+;;    `icicle-searching-p', `icicle-search-level-overlays',
+;;    `icicle-search-menu-map', `icicle-search-tags-menu-map',
+;;    `icicle-search-overlays', `icicle-search-refined-overlays',
+;;    `icicle-search-replacement',
+;;    `icicle-search-replacement-history',
+;;    `icicle-successive-grab-count',
+;;    `icicle-text-property-value-history',
+;;    `icicle-thing-at-pt-fns-pointer', `icicle-this-cmd-keys',
+;;    `icicle-transform-before-sort-p',
+;;    `icicle-universal-argument-map',
+;;    `icicle-vardoc-last-initial-cand-set',
+;;    `icicle-vardoc-last-initial-option-cand-set',
+;;    `icicle-variable-name-history',
+;;    `icicle-whole-candidate-as-text-prop-p',
+;;    `lacarte-menu-items-alist', `old-crm-local-completion-map',
+;;    `old-crm-local-must-match-map'.
+;;
+;;  Emacs functions defined in Icicles for older Emacs versions:
+;;
+;;    `select-frame-set-input-focus'.
+;;
+;;  Widgets (customization types) defined in Icicles:
+;;
+;;    `icicle-key-definition'.
+;;
+;;
+;;  ***** NOTE: These EMACS PRIMITIVES have been REDEFINED in Icicles:
+;;
+;;  `completing-read'              - (See below and doc string.)
+;;  `display-completion-list'      - (See below and doc string.)
+;;  `exit-minibuffer'              - Remove *Completion* window.
+;;  `minibuffer-complete-and-exit' - Remove *Completion* window.
+;;  `read-file-name'               - (See below and doc string.)
+;;  `read-from-minibuffer'         - (See below and doc string.)
+;;  `read-string'                  - (See below and doc string.)
+;;
+;;
+;;  ***** NOTE: The following functions defined in `dabbrev.el' have
+;;              been REDEFINED in Icicles:
+;;
+;;  `dabbrev-completion' - Use Icicles completion when you repeat
+;;                         (`C-M-/').
+;;
+;;
+;;  ***** NOTE: The following functions defined in `lisp.el' have
+;;              been REDEFINED in Icicles:
+;;
+;;  `lisp-complete-symbol' - Selects `*Completions*' window even if on
+;;                           another frame.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `mouse.el' have
+;;              been REDEFINED in Icicles:
+;;
+;;  `mouse-choose-completion' - Return the number of the completion.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `simple.el' have
+;;              been REDEFINED in Icicles:
+;;
+;;  `choose-completion-string' -
+;;     Don't exit minibuffer after `lisp-complete-symbol' completion.
+;;  `completion-setup-function' - 1. Put faces on inserted string(s).
+;;                                2. Help on help.
+;;  `switch-to-completions' - Always selects `*Completions*' window.
+;;
+;;  `next-history-element' (advised only) -
+;;     Depending on `icicle-default-value', select minibuffer
+;;     contents.
+;;
+;;  `repeat-complex-command' - Use `completing-read' to read command.
+;;
+;;  For descriptions of changes to this file, see `icicles-chg.el'.
+;;
+;;  ******************
+;;  NOTE: Whenever you update Icicles (i.e., download new versions of
+;;  Icicles source files), I recommend that you do the following:
+;;
+;;      1. Delete all existing byte-compiled Icicles files
+;;         (icicles*.elc).
+;;      2. Load Icicles (`load-library' or `require').
+;;      3. Byte-compile the source files.
+;;
+;;  In particular, always load `icicles-mac.el' (not
+;;  `icicles-mac.elc') before you byte-compile new versions of the
+;;  files, in case there have been any changes to Lisp macros (in
+;;  `icicles-mac.el').
+;;  ******************
+
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile
+ (when (< emacs-major-version 20) (require 'cl))) ;; when, unless
+
+;;;;;;;;;;;;;
+
+
+;;; Load other Icicles files (except documentation) ------------------
+
+(require 'icicles-mac)
+(require 'icicles-face) ;; Requires mac
+(require 'icicles-opt)  ;; Requires face
+(require 'icicles-var)  ;; Requires opt
+(require 'icicles-fn)   ;; Requires mac, opt, var
+(require 'icicles-mcmd) ;; Requires opt, var, fn, mac
+(require 'icicles-cmd1) ;; Requires mac, opt, var, fn, mcmd
+(require 'icicles-cmd2) ;; Requires mac, opt, var, fn, mcmd, cmd1
+(require 'icicles-mode) ;; Requires face, opt, cmd
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icicles)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icicles.el ends here
diff --git a/auto-install/icomplete+.el b/auto-install/icomplete+.el
new file mode 100644
index 0000000..f17a6d2
--- /dev/null
+++ b/auto-install/icomplete+.el
@@ -0,0 +1,769 @@
+;;; icomplete+.el --- Extensions to `icomplete.el'.
+;;
+;; Filename: icomplete+.el
+;; Description: Extensions to `icomplete.el'.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Mon Oct 16 13:33:18 1995
+;; Version: 21.0
+;; Last-Updated: Wed Aug 24 09:52:00 2011 (-0700)
+;;           By: dradams
+;;     Update #: 931
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/icomplete+.el
+;; Keywords: help, abbrev, internal, extensions, local
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `icomplete'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Extensions to `icomplete.el'.
+;;
+;;  Faces defined here:
+;;
+;;    `icompletep-choices', `icompletep-determined',
+;;    `icompletep-keys', `icompletep-nb-candidates'.
+;;
+;;  User option defined here:
+;;
+;;    `icompletep-prospects-length'.
+;;
+;;  Macros defined here (but identical to those in Emacs 23):
+;;
+;;    `with-local-quit', `with-no-input'.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `icomplete.el'
+;;              have been REDEFINED HERE:
+;;
+;;    `icomplete-completions' -
+;;       Prepends total number of candidates.
+;;       Sorts alternatives alphabetically, uses different face.
+;;       Highlights key-binding text.
+;;       Appends number of remaining cycle candidates (for Icicles).
+;;
+;;    `icomplete-exhibit' -
+;;       Saves match-data.
+;;       Doesn't insert if input begins with `('
+;;         (e.g. `repeat-complex-command').
+;;       Ensures that the insertion doesn't deactivate mark.
+;;
+;;
+;;  This file should be loaded after loading the standard GNU file
+;;  `icomplete.el'.  So, in your `~/.emacs' file, do this:
+;;  (eval-after-load "icomplete" '(progn (require 'icomplete+)))
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;; 2011/08/24 dadams
+;;     Added top-level puts for common-lisp-indent-function.
+;;     with-local-quit, while-no-input:
+;;       Define only if not defined.  Use put for indentation.  Remove declare declaration.
+;; 2011/06/05 dadams
+;;     icomplete-completions: Handle Emacs 24's new METADATA arg for completion-try-completion.
+;; 2011/01/04 dadams
+;;     Removed autoload cookies from non def* sexps.  Added them for defgroup, defface.
+;; 2010/07/29 dadams
+;;     with-local-quit, with-no-input: Protect declare with fboundp.
+;; 2009/08/06 dadams
+;;     icomplete-completions (Emacs < 23): Bind, don't set, to initialize nb-candidates.
+;; 2008/06/01 dadams
+;;     icomplete-completions (Emacs 23): Set candidates to nil if ((nil)).
+;;     Commented out vanilla Emacs code that's not used (last, base-size).
+;; 2008/05/30 dadams
+;;     Updated for Emacs 23 - complete rewrite.
+;;       Added: macros with-local-quit and with-no-input.
+;;       Added and adapted icomplete-exhibit and icomplete-completions for Emacs 23.
+;;     icompletep-prospects-length: Use only for Emacs < 23.
+;;     icomplete-exhibit: Removed vestigial test of icicle-apropos-completing-p.
+;; 2006/07/30 dadams
+;;     icomplete-exhibit: Save match-data.
+;; 2006/07/16 dadams
+;;     Added dark-background face suggestions from Le Wang - thx.
+;; 2006/06/18 dadams
+;;      icomplete-exhibit: Don't insert if Icicles apropos-completing.
+;; 2006/01/07 dadams
+;;      Added :link for sending bug report.
+;; 2006/01/06 dadams
+;;      Added defgroup.  Added :link.
+;;      Renamed: prefix icomplete- to icompletep-.
+;; 2005/12/18 dadams
+;;     Renamed faces without "-face".
+;;     Use defface.  Removed require of def-face-const.el.
+;;     icomplete-prospects-length: defvar -> defcustom.
+;; 2005/09/30 dadams
+;;     Commented out redefinitions of primitives, so no longer reset
+;;       minibuffer-completion-table to nil. Leaving the commented code in for now.
+;; 2005/08/16 dadams
+;;     icomplete-completions: If icicles.el is loaded, change no-match message slightly.
+;; 2005/07/24 dadams
+;;     icomplete-exhibit: Set deactivate-mark to nil at end.
+;;     Remove commented Emacs 19 code at end.
+;; 2005/07/19 dadams
+;;     Added: icomplete-nb-candidates-face.
+;;     icomplete-completions: Add number of icomplete candidates.
+;;                            Append number of other cycle candidates (icicle).
+;; 2005/05/29 dadams
+;;     read-from-minibuffer: Updated to deal with new arg in Emacs 22.
+;; 2004/12/02 dadams
+;;     Highlight keys (icomplete-completions).
+;; 2004/09/21 dadams
+;;     Removed (icomplete-mode 99) at end.
+;; 2004/04/13 dadams
+;;     I'm not sure that some of the "enhancements" here are still
+;;     needed.  This code was written long ago.  In particular, I'm not
+;;     sure that the changes to `icomplete-exhibit' and the
+;;     redefinitions of the Emacs primitives are needed.  Even if they
+;;     are not needed, I'm leaving them in, as they are benign :).
+;; 1995/12/15 dadams
+;;     Defined replacements that reset minibuffer-completion-table to avoid
+;;     icompletion: read-string, read-from-minibuffer, read-no-blanks-input.
+;; 1995/11/30 dadams
+;;     Added redefinition of yes-or-no-p.
+;; 1995/10/17 dadams
+;;     1) Added icomplete-choices-face and icomplete-determined-face.
+;;     2) Redefined icomplete-exhibit: Doesn't insert if input
+;;        begins with `('  (e.g. repeat-complex-command).
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(require 'icomplete)
+
+;; Quiet the byte-compiler.
+(defvar icomplete-eoinput)
+(defvar icompletep-prospects-length)
+(defvar icicle-nb-of-other-cycle-candidates)
+
+;;;;;;;;;;;;;;;;;;;
+
+;;;###autoload
+(defgroup Icomplete-Plus nil
+  "Icomplete Enhancements."
+  :prefix "icompletep-"
+  :group 'completion :group 'convenience :group 'matching :group 'minibuffer
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+icomplete+.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download"
+          "http://www.emacswiki.org/cgi-bin/wiki/icomplete+.el")
+  :link '(url-link :tag "Description"
+          "http://www.emacswiki.org/cgi-bin/wiki/IcompleteMode#IcompleteModePlus")
+  :link '(emacs-commentary-link :tag "Commentary" "icomplete+")
+  )
+
+;;;###autoload
+(defface icompletep-choices
+    '((((background dark)) (:foreground "Snow4"))
+      (t (:foreground "DarkBlue")))
+  "*Face for minibuffer reminder of possible completion suffixes."
+  :group 'Icomplete-Plus)
+
+;;;###autoload
+(defface icompletep-determined
+    '((t (:foreground "SeaGreen")))
+  "*Face for minibuffer reminder of possible completion prefix."
+  :group 'Icomplete-Plus)
+
+;;;###autoload
+(defface icompletep-nb-candidates
+  '((((background dark)) (:foreground "SpringGreen"))
+    (t (:foreground "DarkMagenta")))
+  "*Face for minibuffer reminder of number of completion candidates.
+This has no effect unless library `icicles.el' is being used."
+  :group 'Icomplete-Plus)
+
+;;;###autoload
+(defface icompletep-keys
+    '((t (:foreground "Red")))
+  "*Face for minibuffer reminder of possible completion key bindings."
+  :group 'Icomplete-Plus)
+
+(when (< emacs-major-version 23)
+  (defcustom icompletep-prospects-length 100 ; Default was 80
+    "*Length of string displaying icompletion candidates."
+    :type 'integer :group 'Icomplete-Plus))
+
+;;; Quiet the byte-compiler.
+(defvar icomplete-overlay)
+(defvar icomplete-prospects-height)
+
+
+
+;; REPLACES ORIGINAL defined in `icomplete.el':
+;;
+;; Save match-data.
+;; Don't insert if input begins with `(' (e.g. `repeat-complex-command').
+;;
+(when (< emacs-major-version 23)        ; Emacs 20, 21, 22.
+  (defun icomplete-exhibit ()
+    "Insert icomplete completions display.
+Should be run via minibuffer `post-command-hook'.
+See `icomplete-mode' and `minibuffer-setup-hook'."
+    (when (icomplete-simple-completing-p)
+      (save-match-data
+        (let* ((minibuf-begin (if (< emacs-major-version 21)
+                                  (point-min)
+                                (minibuffer-prompt-end)))
+               (contents (buffer-substring minibuf-begin (point-max)))
+               (buffer-undo-list t))
+          (save-excursion
+            (goto-char (point-max))
+            ;; Register the end of input, so we know where the extra stuff
+            ;; (match-status info) begins:
+            (unless (boundp 'icomplete-eoinput)
+              ;; In case it got wiped out by major mode business:
+              (make-local-variable 'icomplete-eoinput))
+            (setq icomplete-eoinput (point))
+            ;; Insert the match-status information:
+            (when (and (> (point-max) minibuf-begin)
+                       (save-excursion  ; Do nothing if looking at a list, string, etc.
+                         (goto-char minibuf-begin)
+                         (not (looking-at ; No (, ", ', 9 etc. at start.
+                               "\\(\\s-+$\\|\\s-*\\(\\s(\\|\\s\"\\|\\s'\\|\\s<\\|[0-9]\\)\\)")))
+                       (or
+                        ;; Don't bother with delay after certain number of chars:
+                        (> (point-max) icomplete-max-delay-chars)
+                        ;; Don't delay if alternatives number is small enough:
+                        (if minibuffer-completion-table
+                            (cond ((numberp minibuffer-completion-table)
+                                   (< minibuffer-completion-table
+                                      icomplete-delay-completions-threshold))
+                                  ((sequencep minibuffer-completion-table)
+                                   (< (length minibuffer-completion-table)
+                                      icomplete-delay-completions-threshold))
+                                  ))
+                        ;; Delay - give some grace time for next keystroke, before
+                        ;; embarking on computing completions:
+                        (sit-for icomplete-compute-delay)))
+              (insert
+               (icomplete-completions contents minibuffer-completion-table
+                                      minibuffer-completion-predicate
+                                      (not minibuffer-completion-confirm)))))
+          (setq deactivate-mark nil)))))) ; Don't let the insert deactivate the mark.
+
+
+;;; These two macros are defined in `subr.el' for Emacs 23+.
+;;; They are included here only so you can, if needed, byte-compile this file using Emacs < 23
+;;; and still use the byte-compiled file in Emacs 23+.
+(unless (fboundp 'with-local-quit)
+  (defmacro with-local-quit (&rest body)
+    "Execute BODY, allowing quits to terminate BODY but not escape further.
+When a quit terminates BODY, `with-local-quit' returns nil but
+requests another quit.  That quit will be processed as soon as quitting
+is allowed once again.  (Immediately, if `inhibit-quit' is nil.)"
+    `(condition-case nil
+      (let ((inhibit-quit nil))
+        ,@body)
+      (quit (setq quit-flag t)
+       ;; This call is to give a chance to handle quit-flag
+       ;; in case inhibit-quit is nil.
+       ;; Without this, it will not be handled until the next function
+       ;; call, and that might allow it to exit thru a condition-case
+       ;; that intends to handle the quit signal next time.
+       (eval '(ignore nil)))))
+  (put 'with-local-quit 'common-lisp-indent-function '(&body)))
+
+(unless (fboundp 'while-no-input)
+  (defmacro while-no-input (&rest body) ; Defined in `subr.el'.
+    "Execute BODY only as long as there's no pending input.
+If input arrives, that ends the execution of BODY,
+and `while-no-input' returns t.  Quitting makes it return nil.
+If BODY finishes, `while-no-input' returns whatever value BODY produced."
+    (let ((catch-sym (make-symbol "input")))
+      `(with-local-quit
+        (catch ',catch-sym
+          (let ((throw-on-input ',catch-sym))
+            (or (input-pending-p)
+                (progn ,@body)))))))
+  (put 'while-no-input 'common-lisp-indent-function '(&body)))
+
+
+
+;; REPLACES ORIGINAL defined in `icomplete.el':
+;;
+;; Save match-data.
+;; Don't insert if input begins with `(' (e.g. `repeat-complex-command').
+;;
+(when (> emacs-major-version 22)        ; Emacs 23+
+  (defun icomplete-exhibit ()
+    "Insert icomplete completions display.
+Should be run via minibuffer `post-command-hook'.  See `icomplete-mode'
+and `minibuffer-setup-hook'."
+    (when (and icomplete-mode (icomplete-simple-completing-p))
+      (save-excursion
+        (goto-char (point-max))
+        ;; Insert the match-status information.
+        (when (and (> (point-max) (minibuffer-prompt-end))
+                   buffer-undo-list     ; Wait for some user input.
+                   (save-excursion      ; Do nothing if looking at a list, string, etc.
+                     (goto-char (minibuffer-prompt-end))
+                     (save-match-data
+                       (not (looking-at ; No (, ", ', 9 etc. at start.
+                             "\\(\\s-+$\\|\\s-*\\(\\s(\\|\\s\"\\|\\s'\\|\\s<\\|[0-9]\\)\\)"))))
+                   (or
+                    ;; Don't bother with delay after certain number of chars:
+                    (> (- (point) (field-beginning)) icomplete-max-delay-chars)
+                    ;; Don't delay if alternatives number is small enough:
+                    (and (sequencep minibuffer-completion-table)
+                         (< (length minibuffer-completion-table)
+                            icomplete-delay-completions-threshold))
+                    ;; Delay - give some grace time for next keystroke, before
+                    ;; embarking on computing completions:
+                    (sit-for icomplete-compute-delay)))
+          (let ((text             (while-no-input
+                                   (icomplete-completions
+                                    (field-string)
+                                    minibuffer-completion-table
+                                    minibuffer-completion-predicate
+                                    (not minibuffer-completion-confirm))))
+                (buffer-undo-list t)
+                deactivate-mark)
+            ;; Do nothing if `while-no-input' was aborted.
+            (when (stringp text)
+              (move-overlay icomplete-overlay (point) (point) (current-buffer))
+              ;; The current C cursor code doesn't know to use the overlay's
+              ;; marker's stickiness to figure out whether to place the cursor
+              ;; before or after the string, so let's spoon-feed it the pos.
+              (put-text-property 0 1 'cursor t text)
+              (overlay-put icomplete-overlay 'after-string text))))))))
+
+
+
+;; REPLACES ORIGINAL defined in `icomplete.el':
+;;
+;; 1. Prepends total number of candidates.
+;; 2. Sorts alternatives, puts them in a different face, and separates them more.
+;; 3. Highlights key-binding text.
+;; 4. Appends number of remaining cycle candidates (for Icicles).
+;;
+(when (< emacs-major-version 23)        ; Emacs 20, 21, 22.
+  (defun icomplete-completions (name candidates predicate require-match)
+    "Identify prospective candidates for minibuffer completion.
+NAME is the name to complete.
+CANDIDATES are the candidates to match.
+PREDICATE filters matches: they succeed only if this returns non-nil.
+REQUIRE-MATCH non-nil means the input must match a candidate.
+
+The display is updated with each minibuffer keystroke during
+minibuffer completion.
+
+Prospective completion suffixes (if any) are displayed, bracketed by
+\"()\", \"[]\", or \"{}\".  The choice of brackets is as follows:
+
+  \(...) - A single prospect is identified and matching is enforced.
+  \[...] - A single prospect is identified and matching is optional.
+  \{...} - Multiple prospects are indicated, and further input is
+          needed to distinguish a single one.
+
+The displays for unambiguous matches have \" [ Matched ]\" appended
+\(whether complete or not), or \" \[ No match ]\", if no eligible
+matches exist.
+Keybindings for uniquely matched commands are displayed within the [].
+
+When more than one completion is available, the total number precedes
+the suffixes display, like this:
+  M-x forw    14 (ard-) { char line list...}
+
+If library `icicles.el' is also loaded, then you can cycle
+completions.  When you change cycling direction, the number of
+additional cycle candidates, besides the current one, is displayed
+following the rest of the icomplete info:
+  M-x forward-line   [Matched]  (13 more)."
+    ;; `all-completions' doesn't like empty `minibuffer-completion-table's (ie: (nil))
+    (when (and (listp candidates) (null (car candidates))) (setq candidates nil))
+    (let* ((comps (all-completions name candidates predicate))
+           (open-bracket-determined (if require-match "(" " ["))
+           (close-bracket-determined (if require-match ") " "] "))
+           (keys nil)
+           (nb-candidates (length comps))
+           nb-candidates-string)
+      ;; `concat'/`mapconcat' is the slow part.  With the introduction of
+      ;; `icompletep-prospects-length', there is no need for `catch'/`throw'.
+      (if (null comps) (format (if (fboundp 'icicle-apropos-complete)
+                                   "\t%sNo prefix matches%s"
+                                 "\t%sNo matches%s")
+                               open-bracket-determined
+                               close-bracket-determined)
+        (let* ((most-try (try-completion name (mapcar #'list comps)))
+               (most (if (stringp most-try) most-try (car comps)))
+               (most-len (length most))
+               (determ (and (> most-len (length name))
+                            (concat open-bracket-determined
+                                    (substring most (length name))
+                                    close-bracket-determined)))
+               (open-bracket-prospects "{ ")
+               (close-bracket-prospects " }")
+               (prospects-len 0)
+               prompt prompt-rest prospects most-is-exact comp)
+          (when determ
+            (put-text-property 0 (length determ) 'face 'icompletep-determined determ))
+          (if (eq most-try t)
+              (setq prospects nil)
+            (while (and comps (< prospects-len icompletep-prospects-length))
+              (setq comp (substring (car comps) most-len)
+                    comps (cdr comps))
+              (cond ((string-equal comp "") (setq most-is-exact t))
+                    ((member comp prospects))
+                    (t (setq prospects (cons comp prospects)
+                             prospects-len (+ (length comp) 1 prospects-len))))))
+          (setq prompt-rest
+                (if prospects
+                    (concat open-bracket-prospects
+                            (and most-is-exact ", ")
+                            (mapconcat 'identity
+                                       (sort prospects (function string-lessp))
+                                       "  ")
+                            (and comps "...")
+                            close-bracket-prospects)
+                  (concat "\t[ Matched"
+                          (if (setq keys (and icomplete-show-key-bindings
+                                              (commandp (intern-soft most))
+                                              (icomplete-get-keys most)))
+                              (concat "; " keys)
+                            (setq keys nil))
+                          " ]")))
+          (put-text-property 0 (length prompt-rest)
+                             'face 'icompletep-choices prompt-rest)
+          (cond ((< nb-candidates 2)
+                 (setq prompt (concat "      " determ prompt-rest))
+                 (when (eq last-command this-command)
+                   (setq icicle-nb-of-other-cycle-candidates 0))) ; We know now, so reset it.
+                (t
+                 (setq nb-candidates-string (format "%7d " nb-candidates))
+                 (put-text-property (string-match "\\S-" nb-candidates-string)
+                                    (1- (length nb-candidates-string))
+                                    'face 'icompletep-nb-candidates nb-candidates-string)
+                 (setq prompt (concat nb-candidates-string determ prompt-rest))))
+          ;; Highlight keys, after "Matched; " (18 chars).
+          (when keys (put-text-property (+ 18 (length determ)) (1- (length prompt))
+                                        'face 'icompletep-keys prompt))
+          ;; Append mention of number of other cycle candidates (from `icicles.el').
+          (when (and (boundp 'icicle-last-completion-candidate)
+                     (> icicle-nb-of-other-cycle-candidates 0)
+                     (= 1 nb-candidates)
+                     icicle-last-completion-candidate
+                     (not (eq last-command this-command)))
+            (setq nb-candidates-string  ; Reuse the string.
+                  (format "  (%d more)" icicle-nb-of-other-cycle-candidates))
+            (put-text-property (string-match "\\S-" nb-candidates-string)
+                               (length nb-candidates-string)
+                               'face 'icompletep-nb-candidates nb-candidates-string)
+            (setq prompt (concat prompt nb-candidates-string)))
+          prompt)))))
+
+
+
+;; REPLACES ORIGINAL defined in `icomplete.el':
+;;
+;; 1. Prepends total number of candidates.
+;; 2. Sorts alternatives alphabetically, puts them in a different face, and separates them more.
+;; 3. Highlights key-binding text.
+;; 4. Appends number of remaining cycle candidates (for Icicles).
+;;
+(when (> emacs-major-version 22)        ; Emacs 23.
+  (defun icomplete-completions (name candidates predicate require-match)
+    "Identify prospective candidates for minibuffer completion.
+NAME is the name to complete.
+CANDIDATES are the candidates to match.
+PREDICATE filters matches: they succeed only if it returns non-nil.
+REQUIRE-MATCH non-nil means the input must match a candidate.
+
+The display is updated with each minibuffer keystroke during
+minibuffer completion.
+
+Prospective completion suffixes (if any) are displayed, bracketed by
+\"()\", \"[]\", or \"{}\".  The choice of brackets is as follows:
+
+  \(...) - A single prospect is identified, and matching is enforced.
+  \[...] - A single prospect is identified, and matching is optional.
+  \{...} - Multiple prospects are indicated, and further input is
+          needed to distinguish a single one.
+
+The displays for unambiguous matches have ` [ Matched ]' appended
+\(whether complete or not), or ` \[ No matches ]', if no eligible
+matches exist.  \(Keybindings for uniquely matched commands are
+exhibited within brackets, [].)
+
+When more than one completion is available, the total number precedes
+the suffixes display, like this:
+  M-x forw    14 (ard-) { char line list...}
+
+If library `icicles.el' is also loaded, then you can cycle
+completions.  When you change cycling direction, the number of
+additional cycle candidates, besides the current one, is displayed
+following the rest of the icomplete info:
+  M-x forward-line   [Matched]  (13 more)."
+    ;; `all-completions' doesn't like empty `minibuffer-completion-table's (ie: (nil))
+    (when (and (listp candidates) (null (car candidates))) (setq candidates nil))
+    (let* (;; Don't use `completion-all-sorted-completions' as in vanilla Emacs.
+           ;; We need the number of comps, and we don't need that sort order.
+           ;; (comps (completion-all-sorted-completions))
+           (comps (all-completions name candidates predicate))
+           (nb-candidates (length comps))
+;;; We don't use `completion-all-sorted-completions', so we don't need `last' or `base-size'.
+;;; $$$$$      (last (if (consp comps) (last comps)))
+;;;            (base-size (cdr last))
+           (open-bracket (if require-match "(" " ["))
+           (close-bracket (if require-match ") " "] ")))
+      ;; `concat'/`mapconcat' is the slow part.
+      (if (not (consp comps))
+          (format (if (fboundp 'icicle-apropos-complete)
+                      "\t%sNo prefix matches%s"
+                    "\t%sNo matches%s")
+                  open-bracket close-bracket)
+;;; $$$$$   (if last (setcdr last nil))
+        (let* ((mdata  (and (fboundp 'completion--field-metadata)
+                            (completion--field-metadata (field-beginning))))
+               (most-try
+;;; $$$$$           (if (and base-size (> base-size 0))
+;;;                     (completion-try-completion name candidates predicate (length name))
+;;;                   ;; If `comps' are 0-based, result should be the same with `comps'.
+
+                ;; $$$$$$$$ UNLESS BUG #8795 is fixed, need METADATA even if nil.
+                (if (fboundp 'completion--field-metadata) ; Emacs 24 added a 5th arg, METADATA.
+                    (completion-try-completion name comps nil (length name) mdata)
+                  (completion-try-completion name comps nil (length name))))
+               (most (if (consp most-try) (car most-try) (if most-try (car comps) "")))
+               ;; Compare name and most, so we can determine if name is
+               ;; a prefix of most, or something else.
+               (compare (compare-strings name nil nil most nil nil completion-ignore-case))
+               (determ (and (not (or (eq t compare) (eq t most-try)
+                                     (= (setq compare (1- (abs compare))) (length most))))
+                            (concat open-bracket
+                                    (cond ((= compare (length name)) ; Typical: name is a prefix
+                                           (substring most compare))
+                                          ((< compare 5) most)
+                                          (t (concat "..." (substring most compare))))
+                                    close-bracket)))
+               (prospects-len (+ (string-width (buffer-string)) ; for prompt
+                                 8      ; for `nb-candidates-string': "%7d "
+                                 (length determ) ; for determined part
+                                 2      ; for "{ "
+                                 -2     ; for missing last "  " after last candidate
+                                 5))    ; for "... }"
+               (prospects-max
+                ;; Max total length to use, including the minibuffer content.
+                (* (+ icomplete-prospects-height
+                      ;; If the minibuffer content already uses up more than
+                      ;; one line, increase the allowable space accordingly.
+                      (/ prospects-len (window-width)))
+                   (window-width)))
+               (prefix-len
+                ;; Find the common prefix among `comps'.
+                (if (eq t (compare-strings (car comps) nil (length most) most nil nil
+                                           completion-ignore-case))
+                    (length most)       ; Common case.
+                  (let ((comps-prefix (try-completion "" comps)))
+                    (and (stringp comps-prefix) (length comps-prefix)))))
+               (keys nil)
+               prompt nb-candidates-string prompt-rest
+               prospects most-is-exact comp limit)
+          (when determ
+            (put-text-property 0 (length determ) 'face 'icompletep-determined determ))
+          (if (eq most-try t)           ; (or (null (cdr comps))
+              (setq prospects nil)
+            (while (and comps (not limit))
+              (setq comp   (if prefix-len (substring (car comps) prefix-len) (car comps))
+                    comps  (cdr comps))
+              (cond ((string-equal comp "") (setq most-is-exact t))
+                    ((member comp prospects))
+                    (t (setq prospects-len (+ (string-width comp)
+                                              2 ; for "  "
+                                              prospects-len))
+                       (if (< prospects-len prospects-max)
+                           (push comp prospects)
+                         (setq limit t))))))
+;;; $$$$$    ;; Restore the base-size info, since `completion-all-sorted-completions' is cached.
+;;;          (when last (setcdr last base-size))
+          (setq prompt-rest
+                (if prospects
+                    (concat "{ " (and most-is-exact ", ")
+                            (mapconcat 'identity (sort prospects (function string-lessp)) "  ")
+                            (and limit "...") " }")
+                  (concat "\t[ Matched"
+                          (if (setq keys (and icomplete-show-key-bindings
+                                              (commandp (intern-soft most))
+                                              (icomplete-get-keys most)))
+                              (concat "; " keys)
+                            (setq keys nil))
+                          " ]")))
+          (put-text-property 0 (length prompt-rest) 'face 'icompletep-choices prompt-rest)
+          (cond ((< nb-candidates 2)
+                 (setq prompt (concat "      " determ prompt-rest))
+                 (when (eq last-command this-command)
+                   (setq icicle-nb-of-other-cycle-candidates 0))) ; We know now, so reset it.
+                (t
+                 (setq nb-candidates-string (format "%7d " nb-candidates))
+                 (put-text-property (string-match "\\S-" nb-candidates-string)
+                                    (1- (length nb-candidates-string))
+                                    'face 'icompletep-nb-candidates nb-candidates-string)
+                 (setq prompt (concat nb-candidates-string determ prompt-rest))))
+          ;; Highlight keys, after "Matched; " (18 chars).
+          (when keys (put-text-property (+ 18 (length determ)) (1- (length prompt))
+                                        'face 'icompletep-keys prompt))
+          ;; Append mention of number of other cycle candidates (from `icicles.el').
+          (when (and (boundp 'icicle-last-completion-candidate)
+                     (> icicle-nb-of-other-cycle-candidates 0)
+                     (= 1 nb-candidates)
+                     icicle-last-completion-candidate
+                     (not (eq last-command this-command)))
+            (setq nb-candidates-string  ; Reuse the string.
+                  (format "  (%d more)" icicle-nb-of-other-cycle-candidates))
+            (put-text-property (string-match "\\S-" nb-candidates-string)
+                               (length nb-candidates-string)
+                               'face 'icompletep-nb-candidates nb-candidates-string)
+            (setq prompt (concat prompt nb-candidates-string)))          
+          prompt)))))
+
+
+
+;;; The following functions have been REDEFINED to reset the
+;;; `minibuffer-completion-table' in order to avoid icompletion.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; Note:  The function `read-input' is an alias for `read-string'.
+
+;; (or (fboundp 'old-read-string)
+;; (fset 'old-read-string (symbol-function 'read-string)))
+
+;; ;; REPLACES ORIGINAL:
+;; ;; Resets `minibuffer-completion-table' to avoid icompletion.
+;; (defsubst read-string
+;;   (prompt &optional initial-input history default-value inherit-input-method)
+;;   "Read a string from the minibuffer, prompting with string PROMPT.
+;; If non-nil, second arg INITIAL-INPUT is a string to insert before
+;;     reading.  This argument has been superseded by DEFAULT-VALUE and
+;;     should normally be `nil' in new code.  It behaves as in
+;;     `read-from-minibuffer'.  See the documentation for that function.
+;; The third arg HISTORY, if non-nil, specifies a history list and
+;;     optionally the initial position in that list.
+;;     See `read-from-minibuffer' for details of argument HISTORY.
+;; Fourth arg DEFAULT-VALUE is the default value.  If non-nil, it is used
+;;     for history commands and as the value to return if the user enters
+;;     an empty string.
+;; Fifth arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer
+;;     inherits the current input method and setting of
+;;     `enable-multibyte-characters'."
+;;   (setq minibuffer-completion-table nil) ; So won't icomplete by default.
+;;   (old-read-string prompt initial-input history default-value inherit-input-method))
+
+
+;; (or (fboundp 'old-read-from-minibuffer)
+;; (fset 'old-read-from-minibuffer (symbol-function 'read-from-minibuffer)))
+
+;; ;; REPLACES ORIGINAL:
+;; ;; Resets `minibuffer-completion-table' to avoid icompletion.
+;; (defsubst read-from-minibuffer
+;;   (prompt &optional initial-contents keymap read hist default-value
+;;           inherit-input-method keep-all)
+;;   "Read a string from the minibuffer, prompting with string PROMPT.
+;; The optional second arg INITIAL-CONTENTS is an obsolete alternative to
+;;   DEFAULT-VALUE.  It normally should be nil in new code, except when
+;;   HIST is a cons.  It is discussed in more detail below.
+;; Third arg KEYMAP is a keymap to use while reading;
+;;   if omitted or nil, the default is `minibuffer-local-map'.
+;; If fourth arg READ is non-nil, then interpret the result as a Lisp
+;;   object and return that object.  In other words, do this:
+;;       `(car (read-from-string INPUT-STRING))'
+;; Fifth arg HIST, if non-nil, specifies a history list and optionally
+;;   the initial position in the list.
+;;   It can be a symbol, which is the history list variable to use,
+;;   or it can be a cons cell (HISTVAR . HISTPOS).
+;;   In that case, HISTVAR is the history-list variable to use,
+;;   and HISTPOS is the initial position for use by the minibuffer
+;;   history commands.  For consistency, you should also specify that
+;;   element of the history as the value of INITIAL-CONTENTS.
+;;   Positions are counted starting from 1 at the beginning of the list.
+;; Sixth arg DEFAULT-VALUE is the default value.  If non-nil, it is
+;;   available for history commands; but, unless READ is non-nil,
+;;   `read-from-minibuffer' does NOT return DEFAULT-VALUE if the user
+;;   enters empty input!  It returns the empty string.
+;; Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer
+;;   inherits the current input method and the setting of
+;;   `enable-multibyte-characters'.
+;; Eighth arg KEEP-ALL, if non-nil, says to put all inputs in the history
+;;  list, even empty or duplicate inputs. (This argument is not available
+;;  in Emacs versions prior to Emacs 22.)
+;; If variable `minibuffer-allow-text-properties' is non-nil, then the
+;;   string returned includes whatever text properties were present in
+;;   the minibuffer.  Otherwise the value has no text properties.
+
+;; The remainder of this documentation describes INITIAL-CONTENTS in more
+;; detail.  It is relevant only when studying existing code, or when HIST
+;; is a cons.  If non-nil, INITIAL-CONTENTS is a string to be inserted
+;; into the minibuffer before reading input.  Normally, point is put at
+;; the end of that string.  However, if INITIAL-CONTENTS is (STRING .
+;; POSITION), the initial input is STRING, but point is placed at
+;; _one-indexed_ position POSITION in the minibuffer.  Any integer value
+;; less than or equal to one puts point at the beginning of the string.
+;; *Note* that this behavior differs from the way such arguments are used
+;; in `completing-read' and some related functions, which use
+;; zero-indexing for POSITION."
+;;   (setq minibuffer-completion-table nil) ; So won't icomplete by default.
+;;   (if (or (string-match "22." emacs-version) (string-match "21.3.50" emacs-version))
+;;       (old-read-from-minibuffer prompt initial-contents keymap read hist
+;;                                 default-value inherit-input-method keep-all)
+;;     (old-read-from-minibuffer prompt initial-contents keymap read hist
+;;                               default-value inherit-input-method))) ; No KEEP-ALL
+
+
+;; (or (fboundp 'old-read-no-blanks-input)
+;; (fset 'old-read-no-blanks-input (symbol-function 'read-no-blanks-input)))
+
+;; ;; REPLACES ORIGINAL:
+;; ;; Resets `minibuffer-completion-table' to avoid icompletion.
+;; (defsubst read-no-blanks-input (prompt &optional initial-contents inherit-input-method)
+;;   "Read a string from the minibuffer, not allowing blanks.
+;; Arg PROMPT is a prompt string.  Whitespace terminates the input.
+
+;; If optional second arg INITIAL-CONTENTS is non-nil, it should be a
+;; string, which is used as initial input, with point positioned at the
+;; end, so that a SPACE will accept the input.  INITIAL-CONTENTS can
+;; alternatively be a cons of a string and an integer.  Such values are
+;; treated as in `read-from-minibuffer', but are normally not useful in
+;; this function.
+
+;; Third arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer
+;; inherits the current input method and the setting of
+;; `enable-multibyte-characters'."
+;;   (setq minibuffer-completion-table nil) ; So won't icomplete by default.
+;;   (old-read-no-blanks-input prompt initial-contents inherit-input-method))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'icomplete+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; icomplete+.el ends here
+
diff --git a/auto-install/lacarte.el b/auto-install/lacarte.el
new file mode 100644
index 0000000..9c85e99
--- /dev/null
+++ b/auto-install/lacarte.el
@@ -0,0 +1,611 @@
+;;; lacarte.el --- Execute menu items as commands, with completion.
+;;
+;; Filename: lacarte.el
+;; Description: Execute menu items as commands, with completion.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 2005-2011, Drew Adams, all rights reserved.
+;; Created: Fri Aug 12 17:18:02 2005
+;; Version: 22.0
+;; Last-Updated: Tue Jan  4 10:59:52 2011 (-0800)
+;;           By: dradams
+;;     Update #: 638
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/lacarte.el
+;; Keywords: menu-bar, menu, command, help, abbrev, minibuffer, keys,
+;;           completion, matching, local, internal, extensions,
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Q. When is a menu not a menu?  A. When it's a la carte.
+;;
+;;  Library La Carte lets you execute menu items as commands, with
+;;  completion.  You can use it as an alternative to standard library
+;;  `tmm.el'.
+;;
+;;  Type a menu item.  Completion is available.  Completion candidates
+;;  are of the form menu > submenu > subsubmenu > ... > menu item.
+;;  For example:
+;;
+;;    File > Open Recent > Cleanup list
+;;    File > Open Recent > Edit list...
+;;
+;;  When you choose a menu-item candidate, the corresponding command
+;;  is executed.
+;;
+;;  Put this in your init file (~/.emacs):
+;;
+;;    (require 'lacarte)
+;;
+;;  Suggested key bindings:
+;;
+;;    (global-set-key [?\e ?\M-x] 'lacarte-execute-command)
+;;    (global-set-key [?\M-`]     'lacarte-execute-menu-command)
+;;    (global-set-key [f10]       'lacarte-execute-menu-command)
+;;
+;;  (The latter two replace standard bindings for `tmm-menubar'.  On
+;;  MS Windows, `f10' is normally bound to `menu-bar-open', which uses
+;;  the Windows native keyboard access to menus.)
+;;
+;;  To really take advantage of La Carte, use it together with
+;;  Icicles.  Icicles is not required to be able to use La Carte, but
+;;  it enhances the functionality of `lacarte.el' considerably.
+;;  (Note: `lacarte.el' was originally called `icicles-menu.el'.)
+;;
+;;  If you use MS Windows keyboard accelerators, consider using
+;;  `lacarte-remove-w32-keybd-accelerators' as the value of
+;;  `lacarte-convert-menu-item-function'.  It removes any unescaped
+;;  `&' characters (indicating an accelerator) from the menu items.
+;;  One library that adds keyboard accelerators to your menu items is
+;;  `menuacc.el', by Lennart Borgman (< l e n n a r t . b o r g m a n
+;;  @ g m a i l . c o m >).
+;;
+;;
+;;  Commands defined here:
+;;
+;;    `lacarte-execute-command', `lacarte-execute-menu-command'.
+;;
+;;  Options defined here: `lacarte-convert-menu-item-function'.
+;;
+;;  Non-interactive functions defined here:
+;;
+;;    `lacarte-escape-w32-accel', `lacarte-get-a-menu-item-alist',
+;;    `lacarte-get-a-menu-item-alist-1',
+;;    `lacarte-get-overall-menu-item-alist', `lacarte-menu-first-p',
+;;    `lacarte-remove-w32-keybd-accelerators'.
+;;
+;;  Internal variables defined here:
+;;
+;;    `lacarte-history', `lacarte-menu-items-alist'.
+;;
+;;
+;;  Getting Started
+;;  ---------------
+;;
+;;  In your init file (`~/.emacs'), bind `ESC M-x' as suggested above:
+;;
+;;    (global-set-key [?\e ?\M-x] 'lacarte-execute-command)
+;;
+;;  Type `ESC M-x' (or `ESC ESC x', which is the same thing).  You are
+;;  prompted for a command or menu command to execute.  Just start
+;;  typing its name.  Each menu item's full name, for completion, has
+;;  its parent menu names as prefixes.
+;;
+;;  ESC M-x
+;;  Command:
+;;  Command: t [TAB]
+;;  Command: Tools >
+;;  Command: Tools > Compa [TAB]
+;;  Command: Tools > Compare (Ediff) > Two F [TAB]
+;;  Command: Tools > Compare (Ediff) > Two Files... [RET]
+;;
+;;
+;;  Not Just for Wimps and Noobs Anymore
+;;  ------------------------------------
+;;
+;;  *You* don't use menus.  Nah, they're too slow!  Only newbies and
+;;  wimps use menus.  Well not any more.  Use the keyboard to access
+;;  any menu item, without knowing where it is or what its full name
+;;  is.  Type just part of its name and use completion to get the
+;;  rest: the complete path and item name.
+;;
+;;
+;;  Commands and Menu Commands
+;;  --------------------------
+;;
+;;  You can bind either `lacarte-execute-menu-command' or
+;;  `lacarte-execute-command' to a key such as `ESC M-x'.
+;;
+;;  `lacarte-execute-menu-command' uses only menu commands.
+;;  `lacarte-execute-command' lets you choose among ordinary Emacs
+;;  commands, in addition to menu commands.  You can use a prefix arg
+;;  with `lacarte-execute-command' to get the same effect as
+;;  `lacarte-execute-menu-command'.
+;;
+;;  Use `lacarte-execute-command' if you don't care whether a command
+;;  is on a menu.  Then, if you want a command that affects a buffer,
+;;  just type `buf'.  This is especially useful if you use Icicles -
+;;  see below.
+;;
+;;  By default, in Icicle mode, `ESC M-x' is bound to
+;;  `lacarte-execute-command', and `M-`' is bound to
+;;  `lacarte-execute-menu-command'.
+;;
+;;
+;;  Icicles Enhances Dining A La Carte
+;;  ----------------------------------
+;;
+;;  Use Icicles with La Carte to get more power and convenience.
+;;
+;;  It is Icicles that lets you choose menu items a la carte, in fact.
+;;  That is, you can access them directly, wherever they might be in
+;;  the menu hierachy.  Without Icicles, you are limited to choosing
+;;  items by their menu-hierarchy prefixes, and you must complete the
+;;  entire menu prefix to the item, from the top of the menu on down.
+;;  With Icicles, you can directly match any parts of a menu item and
+;;  its hierarchy path.  Icicles is here:
+;;  http://www.emacswiki.org/cgi-bin/wiki/Icicles.
+;;
+;;  Type any part of a menu-item, then use the Page Up and Page Down
+;;  keys (`prior' and `next') to cycle through all menu commands that
+;;  contain the text you typed somewhere in their name.  You can match
+;;  within any menu or within all menus; that is, you can match any
+;;  part(s) of the menu-hierachy prefix.
+;;
+;;  You can use `S-TAB' to show and choose from all such "apropos
+;;  completions", just as you normally use `TAB' to show all prefix
+;;  completions (that is, ordinary completions).  Vanilla, prefix
+;;  completion is still available using `TAB', and you can cycle
+;;  through the prefix completions using the arrow keys.
+;;
+;;  You can use Icicles "progressive completion" to match multiple
+;;  parts of a menu item separately, in any order.  For example, if
+;;  you want a menu command that has to do with buffers and
+;;  highlighting, type `buf M-SPC hig S-TAB'.
+;;
+;;  Icicles apropos completion also lets you type a regular expression
+;;  (regexp) - it is matched against all of the possible menu items.
+;;  So, for instance, you could type `^e.+buff [next] [next]...' to
+;;  quickly cycle to menu command `Edit > Go To > Goto End of Buffer'.
+;;  Or type `.*print.*buf S-TAB' to choose from the list of all menu
+;;  commands that match `print' followed somewhere by `buf'.
+;;
+;;  If you know how to use regexps, you can easily and quickly get to
+;;  a menu command you want, or at least narrow the list of candidates
+;;  for completion and cycling.
+;;
+;;  Additional benefits of using Icicles with La Carte:
+;;
+;;  * When you cycle to a candidate menu item, or you complete to one
+;;    (entirely), the Emacs command associated with the menu item is
+;;    shown in the mode line of buffer `*Completions*'.
+;;
+;;  * You can use `M-h' to complete your minibuffer input against
+;;    commands, including menu-item commands, that you have entered
+;;    previously.  You can also use the standard history keys
+;;    (e.g. `M-p', `M-r') to access these commands.
+;;
+;;
+;;  Menu Organization Helps You Find a Command
+;;  ------------------------------------------
+;;
+;;  Unlike commands listed in a flat `*Apropos*' page, menu items are
+;;  organized, grouped logically by common area of application
+;;  (`File', `Edit',...).  This grouping is also available when
+;;  cycling completion candidates using Icicles, and you can take
+;;  advantage of it to hasten your search for the right command.
+;;
+;;  You want to execute a command that puts the cursor at the end of a
+;;  buffer, but you don't remember its name, what menu it might be a
+;;  part of, or where it might appear in that (possibly complex) menu.
+;;  With Icicles and La Carte, you type `ESC M-x' and then type
+;;  `buffer' at the prompt.  You use the Page Up and Page Down keys to
+;;  cycle through all menu items that contain the word `buffer'.
+;;
+;;  There are lots of such menu items.  But all items from the same
+;;  menu (e.g. `File') are grouped together.  You cycle quickly (not
+;;  reading) to the `Edit' menu, because you guess that moving the
+;;  cursor has more to do with editing than with file operations, tool
+;;  use, buffer choice, help, etc.  Then you cycle more slowly among
+;;  the `buffer' menu items in the `Edit' menu.  You quickly find
+;;  `Edit > Go To > Goto End of Buffer'.  QED.
+;;
+;;
+;;  Learn About Menu Items By Exploring Them
+;;  ----------------------------------------
+;;
+;;  With Icicles, you can display the complete documentation (doc
+;;  string) for the command corresponding to each menu item, as the
+;;  item appears in the minibuffer.  To do this, just cycle menu-item
+;;  candidates using `C-down' or `C-next', instead of `[down]' or
+;;  `[next]'.  The documentation appears in buffer `*Help*'.
+;;
+;;  In sum, if you use La Carte, you will want to use it with Icicles
+;;  - enjoy!
+;;
+;;
+;;  To Do?
+;;  ------
+;;
+;;  1. Provide sorting by menu-bar order, instead of alphabetically.
+;;  2. Echo key bindings for each completed menu item.
+;;
+;;  3. Maybe use tmm-get-bind?
+ 
+;;(@> "Index")
+;;
+;;  If you have library `linkd.el' and Emacs 22 or later, load
+;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
+;;  navigate around the sections of this doc.  Linkd mode will
+;;  highlight this Index, as well as the cross-references and section
+;;  headings throughout this file.  You can get `linkd.el' here:
+;;  http://dto.freeshell.org/notebook/Linkd.html.
+;;
+;;  (@> "Change log")
+;;  (@> "User Options")
+;;  (@> "Internal Variables")
+;;  (@> "Functions")
+ 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;(@* "Change log")
+;;
+;; 2011/01/04 dadams
+;;     Added autoload cookies for defgroup, defcustom, and commands.
+;; 2010/06/26 dadams
+;;    lacarte-execute-command: Protected Icicles vars with boundp.  Thx to Alexey Romanov.
+;; 2010/05/11 dadams
+;;     lacarte-get-a-menu-item-alist-1: Add keyboard shortcuts to item names.
+;;     Applied Icicles renamings (belatedly):
+;;       icicle-sort-functions-alist to icicle-sort-orders-alist,
+;;       icicle-sort-function to icicle-sort-comparer.
+;; 2009/12/25 dadams
+;;     Added: lacarte-execute-command, lacarte-menu-first-p.
+;;     lacarte-get-a-menu-item-alist-1: Handle :filter (e.g. File > Open Recent submenus).
+;;     lacarte-execute-menu-command:
+;;       Just let-bind lacarte-menu-items-alist - don't use unwind-protect.
+;;     lacarte-get-overall-menu-item-alist: Reset lacarte-menu-items-alist to nil.
+;;     lacarte-get-a-menu-item-alist: Set to the return value.
+;; 2009/07/29 dadams
+;;     Added: lacarte-history.
+;;     lacarte-execute-menu-command:
+;;       Use lacarte-history as the history list.  Use strict completion.
+;; 2009/07/26 dadams
+;;     lacarte-execute-menu-command: Use icicle-interactive-history as the history list.
+;; 2008/08/28 dadams
+;;     Renamed from alacarte to lacarte.  Confusion with alacarte Ubuntu source package.
+;; 2008/05/21 dadams
+;;     Renamed library icicles-menu.el to alacarte.el.
+;;     alacarte-execute-menu-command: Case-insensitive completion, by default.
+;; 2008/05/20 dadams
+;;     icicle-get-a-menu-item-alist-1: Don't add non-selectable item to alist.
+;; 2006/12/22 dadams
+;;     icicle-convert-menu-item-function: Use choice as :type, allowing nil.
+;;     :group 'icicles -> :group 'Icicles.
+;; 2006/10/16 dadams
+;;     icicle-get-overall-menu-item-alist: Include minor-mode keymaps.
+;; 2006/03/16 dadams
+;;     Added to Commentary.
+;; 2006/02/18 dadams
+;;     icicle-execute-menu-command: \s -> \\s.  (Thx to dslcustomer-211-74.vivodi.gr.)
+;; 2006/01/07 dadams
+;;     Added :link for sending bug reports.
+;; 2006/01/06 dadams
+;;     Changed defgroup to icicles-menu from icicles.
+;;     Added :link.
+;; 2005/11/08 dadams
+;;     icicle-execute-menu-command:
+;;       Reset icicle-menu-items-alist in unwind-protect.
+;;       Fix for dynamic menus Select and Paste, Buffers, and Frames:
+;;         Treat special cases of last-command-event.
+;;     icicle-get-overall-menu-item-alist: setq result of sort.
+;; 2005/11/05 dadams
+;;     Replaced icicle-menu-items with icicle-menu-items-alist (no need for both).
+;;     icicle-execute-menu-command: Set, don't bind icicle-menu-items-alist.
+;; 2005/08/23 dadams
+;;     icicle-execute-menu-command: renamed alist to icicle-menu-items-alist, so can
+;;       refer to it unambiguously in icicle-help-on-candidate (in icicles.el).
+;; 2005/08/19 dadams
+;;     Added: icicle-convert-menu-item-function, icicle-remove-w32-keybd-accelerators,
+;;            icicle-escape-w32-accel.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(unless (fboundp 'replace-regexp-in-string) (require 'subr-21 nil t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+;;(@* "User Options")
+
+;;; User Options -------------------------------------------
+
+;;;###autoload
+(defgroup lacarte nil
+  "Execute menu items as commands, with completion."
+  :prefix "lacarte-" :group 'menu
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=
+lacarte.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download" "http://www.emacswiki.org/cgi-bin/wiki/lacarte.el")
+  :link '(url-link :tag "Description" "http://www.emacswiki.org/cgi-bin/wiki/LaCarte")
+  :link '(emacs-commentary-link :tag "Commentary" "lacarte.el")
+  )
+
+;;;###autoload
+(defcustom lacarte-convert-menu-item-function nil
+  "*Function to call to convert a menu item.
+Used by `lacarte-execute-menu-command'.  A typical use would be to
+remove the `&' characters used in MS Windows menus to define keyboard
+accelerators.  See `lacarte-remove-w32-keybd-accelerators'."
+  :type '(choice (const :tag "None" nil) function) :group 'lacarte)
+
+;; $$$ NOT YET IMPLEMENTED
+;; (defcustom lacarte-sort-menu-bar-order-flag nil
+;;   "*Non-nil means that `lacarte-execute-menu-command' uses menu-bar order.
+;; Nil means use alphabetic order.
+;; The order is what is used for completion.
+;; Note: Using a non-nil value imposes an extra sorting operation, which
+;;       slows down the creation of the completion-candidates list."
+;;   :type 'boolean :group 'lacarte)
+ 
+;;; Internal Variables -------------------------------------
+
+(defvar lacarte-history nil "History for menu items read using La Carte completion.")
+
+;; This is used also in `icicle-help-on-candidate', which is defined in Icicles
+;; (library `icicles-mcmd.el').
+(defvar lacarte-menu-items-alist nil
+  "Alist of pairs (MENU-ITEM . COMMAND).
+The pairs are defined by the current local and global keymaps.
+MENU-ITEM is a menu item, with ancestor-menu prefixes.
+  Example: `(\"Files > Insert File...\" . insert-file)'.
+COMMAND is the command  bound to the menu item.")
+ 
+;;; Functions -------------------------------
+
+;;;###autoload
+(defun lacarte-execute-command (&optional no-commands-p)
+  "Execute a menu-bar menu command or an ordinary command.
+Type a menu item or a command name.  Completion is available.
+With a prefix arg, only menu items are available.
+Completion is not case-sensitive.  However, if you use Icicles, then
+you can use `C-A' in the minibuffer to toggle case-sensitivity.
+
+If you use Icicles, then you can also sort the completion candidates
+in different ways, using `C-,'.  With Icicles, by default menu items
+are sorted before non-menu commands, and menu items are highlighted
+using face `icicle-special-candidate'."
+  (interactive "P")
+  (let ((lacarte-menu-items-alist         (lacarte-get-overall-menu-item-alist))
+        (completion-ignore-case           t) ; Not case-sensitive, by default.
+        (icicle-special-candidate-regexp  (and (not no-commands-p) ".* > \\(.\\|\n\\)*"))
+        (icicle-sort-orders-alist         (and (boundp 'icicle-sort-orders-alist)
+                                               (if no-commands-p
+                                                   icicle-sort-orders-alist
+                                                 (cons '("menu items first"
+                                                         .  lacarte-menu-first-p)
+                                                       icicle-sort-orders-alist))))
+        (icicle-sort-comparer             (and (boundp 'icicle-sort-comparer)
+                                               (if no-commands-p
+                                                   icicle-sort-comparer
+                                                 'lacarte-menu-first-p)))
+        choice cmd)
+    (unless no-commands-p
+      (mapatoms (lambda (symb)
+                  (when (commandp symb)
+                    (push (cons (symbol-name symb) symb) lacarte-menu-items-alist)))))
+    (setq choice  (completing-read (if no-commands-p "Menu command: " "Command: ")
+                                   lacarte-menu-items-alist nil t nil 'lacarte-history)
+          cmd     (cdr (assoc choice lacarte-menu-items-alist)))
+    (unless cmd (error "No such menu command"))
+    ;; Treat special cases of `last-command-event', reconstructing it for
+    ;; menu items that get their meaning from the click itself.
+    (cond ((eq cmd 'menu-bar-select-buffer)
+           (string-match " >\\s-+\\(.+\\)\\s-+\\*?%?\\s-+\\S-*\\s-*$" choice)
+           (setq choice (substring choice (match-beginning 1) (match-end 1)))
+           (when (string-match "  \\*?%?" choice)
+             (setq choice (substring choice 0 (match-beginning 0))))
+           (setq last-command-event choice))
+          ((eq cmd 'menu-bar-select-yank)
+           (string-match "Edit > Select and Paste > \\(.*\\)$" choice)
+           (setq last-command-event
+                 (substring choice (match-beginning 1) (match-end 1))))
+          ((eq cmd 'menu-bar-select-frame)
+           (string-match " >\\s-[^>]+>\\s-+\\(.+\\)$" choice)
+           (setq choice (substring choice (match-beginning 1) (match-end 1)))
+           (setq last-command-event choice)))
+    (call-interactively cmd)))
+
+(defun lacarte-menu-first-p (s1 s2)
+  "Return non-nil if S1 is a menu item and S2 is not."
+  (save-match-data
+    (and (string-match " > " s1) (not (string-match " > " s2)))))    
+
+;;;###autoload
+(defun lacarte-execute-menu-command ()
+  "Execute a menu-bar menu command.
+Type a menu item.  Completion is available.
+Completion is not case-sensitive.  However, if you use Icicles, then
+you can use `C-A' in the minibuffer to toggle case-sensitivity.
+If you use Icicles, then you can also sort the completion candidates
+in different ways, using `C-,'."
+  (interactive)
+  (let* ((lacarte-menu-items-alist  (lacarte-get-overall-menu-item-alist))
+         (completion-ignore-case    t) ; Not case-sensitive, by default.
+         (menu-item                 (completing-read "Menu command: "
+                                                     lacarte-menu-items-alist
+                                                     nil t nil 'lacarte-history))
+         (cmd                       (cdr (assoc menu-item lacarte-menu-items-alist))))
+    (unless cmd (error "No such menu command"))
+    ;; Treat special cases of `last-command-event', reconstructing it for
+    ;; menu items that get their meaning from the click itself.
+    (cond ((eq cmd 'menu-bar-select-buffer)
+           (string-match " >\\s-+\\(.+\\)\\s-+\\*?%?\\s-+\\S-*\\s-*$"
+                         menu-item)
+           (setq menu-item (substring menu-item (match-beginning 1) (match-end 1)))
+           (when (string-match "  \\*?%?" menu-item)
+             (setq menu-item (substring menu-item 0 (match-beginning 0))))
+           (setq last-command-event menu-item))
+          ((eq cmd 'menu-bar-select-yank)
+           (string-match "Edit > Select and Paste > \\(.*\\)$" menu-item)
+           (setq last-command-event
+                 (substring menu-item (match-beginning 1) (match-end 1))))
+          ((eq cmd 'menu-bar-select-frame)
+           (string-match " >\\s-[^>]+>\\s-+\\(.+\\)$" menu-item)
+           (setq menu-item (substring menu-item (match-beginning 1) (match-end 1)))
+           (setq last-command-event menu-item)))
+    (call-interactively cmd)))
+
+(defun lacarte-get-overall-menu-item-alist ()
+  "Alist formed from menu items in current active keymaps.
+See `lacarte-get-a-menu-item-alist' for the structure.
+As a side effect, this modifies `lacarte-get-a-menu-item-alist' and
+then resets it to ()"
+  (let ((alist
+         (apply #'nconc
+                (lacarte-get-a-menu-item-alist (assq 'menu-bar (current-local-map)))
+                (lacarte-get-a-menu-item-alist (assq 'menu-bar (current-global-map)))
+                (mapcar (lambda (map) (lacarte-get-a-menu-item-alist (assq 'menu-bar map)))
+                        (current-minor-mode-maps)))))
+    (setq lacarte-menu-items-alist ())
+    (if nil;; `lacarte-sort-menu-bar-order-flag' ; Not yet implemented.
+        (setq alist (sort alist SOME-PREDICATE))
+      alist)))
+
+(defun lacarte-get-a-menu-item-alist (keymap)
+  "Alist of pairs (MENU-ITEM . COMMAND) defined by KEYMAP.
+KEYMAP is any keymap that has menu items.
+MENU-ITEM is a menu item, with ancestor-menu prefixes.
+  Example: `(\"Files > Insert File...\" . insert-file)'.
+COMMAND is the command  bound to the menu item.
+Returns `lacarte-menu-items-alist' which it modifies."
+  (setq lacarte-menu-items-alist ())
+  (lacarte-get-a-menu-item-alist-1 keymap)
+  (setq lacarte-menu-items-alist (nreverse lacarte-menu-items-alist)))
+
+(defun lacarte-get-a-menu-item-alist-1 (keymap &optional root)
+  "Helper function for `lacarte-get-a-menu-item-alist'.
+This calls itself recursively, to process submenus.
+Returns `lacarte-menu-items-alist', which it modifies."
+  (let ((scan keymap))
+    (setq root (or root))               ; nil, for top level.
+    (while (consp scan)
+      (if (atom (car scan))
+          (setq scan (cdr scan))
+        (let ((defn (cdr (car scan)))
+              composite-name)
+          ;; Get REAL-BINDING for the menu item.
+          (cond
+            ;; (menu-item ITEM-STRING): non-selectable item - skip it.
+            ((and (eq 'menu-item (car-safe defn))
+                  (null (cdr-safe (cdr-safe defn))))
+             (setq defn nil))           ; So `keymapp' test, below, fails.
+
+            ;; (ITEM-STRING): non-selectable item - skip it.
+            ((and (stringp (car-safe defn)) (null (cdr-safe defn)))
+             (setq defn nil))           ; So `keymapp' test, below, fails.
+
+            ;; (menu-item ITEM-STRING REAL-BINDING . PROPERTIES), with `:filter'
+            ((and (eq 'menu-item (car-safe defn))
+                  (member :filter (cdr (cddr defn))))
+             (let ((filt  (cadr (member :filter (cdr (cddr defn))))))
+               (setq composite-name
+                     (concat root (and root " > ") (eval (cadr defn))
+                             (let ((keys  (car-safe (cdr-safe (cdr-safe (cdr-safe defn))))))
+                             (and (consp keys) (stringp (cdr keys)) (cdr keys)))))
+               (setq defn (if (functionp filt) ; Apply the filter to REAL-BINDING.
+                              (funcall filt (car (cddr defn)))
+                            (car (cddr defn))))))
+
+            ;; (menu-item ITEM-STRING REAL-BINDING . PROPERTIES)
+            ((eq 'menu-item (car-safe defn))
+             (setq composite-name
+                   (concat root (and root " > ") (eval (cadr defn))
+                           (let ((keys  (car-safe (cdr-safe (cdr-safe (cdr-safe defn))))))
+                             (and (consp keys) (stringp (cdr keys)) (cdr keys)))))
+             (setq defn (car (cddr defn))))
+
+            ;; (ITEM-STRING . REAL-BINDING) or
+            ;; (ITEM-STRING [HELP-STRING] (KEYBD-SHORTCUTS) . REAL-BINDING)
+            ((stringp (car-safe defn))
+             (setq composite-name (concat root (and root " > ") (eval (car defn))))
+             (setq defn (cdr defn))
+             ;; Skip HELP-STRING
+             (when (stringp (car-safe defn)) (setq defn (cdr defn)))
+             ;; Skip (KEYBD-SHORTCUTS): cached key-equivalence data for menu items.
+             ;; But first add shortcuts to composite name.
+             (when (and (consp defn) (consp (car defn)))
+               (when (stringp (cdar defn)) ; Add shortcuts to name.
+                 (setq composite-name (concat composite-name (cdar defn))))
+               (setq defn (cdr defn)))))
+
+          ;; If REAL-BINDING is a keymap, then recurse on it.
+          (when (keymapp defn)
+            ;; Follow indirections to ultimate symbol naming a command.
+            (while (and (symbolp defn) (fboundp defn) (keymapp (symbol-function defn)))
+              (setq defn (symbol-function defn)))
+            (if (eq 'keymap (car-safe defn))
+                (lacarte-get-a-menu-item-alist-1 (cdr defn) composite-name)
+              (lacarte-get-a-menu-item-alist-1 (symbol-function defn) composite-name)))
+
+          ;; Add menu item + command pair to `lacarte-menu-items-alist' alist.
+          ;; Don't add it if `composite-name' is nil - that's a non-selectable item.
+          (when (and root composite-name (not (keymapp defn)))
+            (setq lacarte-menu-items-alist
+                  (cons
+                   (cons (if (and (functionp lacarte-convert-menu-item-function)
+                                  (stringp composite-name)) ; Could be nil
+                             (funcall lacarte-convert-menu-item-function composite-name)
+                           composite-name)
+                         defn)
+                   lacarte-menu-items-alist))))
+        (when (consp scan) (setq scan (cdr scan)))))
+    lacarte-menu-items-alist))
+
+(defun lacarte-remove-w32-keybd-accelerators (menu-item)
+  "Remove `&' characters that define keyboard accelerators in MS Windows.
+\"&&\" is an escaped `&' - it is replaced by a single `&'.
+This is a candidate value for `lacarte-convert-menu-item-function'."
+  (replace-regexp-in-string "&&?" 'lacarte-escape-w32-accel menu-item))
+
+(defun lacarte-escape-w32-accel (match-string)
+  "If STRING is \"&&\", then return \"&\".  Else return \"\"."
+  (if (> (length match-string) 1) "&" ""))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'lacarte)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; lacarte.el ends here
diff --git a/auto-install/ring+.el b/auto-install/ring+.el
new file mode 100644
index 0000000..4c6de85
--- /dev/null
+++ b/auto-install/ring+.el
@@ -0,0 +1,155 @@
+;;; ring+.el --- Extensions to `ring.el'.
+;;
+;; Filename: ring+.el
+;; Description: Extensions to `ring.el'.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
+;; Created: Thu Apr 11 16:46:04 1996
+;; Version: 21.0
+;; Last-Updated: Tue Jan  4 13:43:06 2011 (-0800)
+;;           By: dradams
+;;     Update #: 211
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/ring+.el
+;; Keywords: extensions, lisp, emacs-lisp
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `ring'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;    Extensions to `ring.el'.
+;;
+;;  Main new functions here:
+;;
+;;    `ring-convert-sequence-to-ring', `ring-insert+extend',
+;;    `ring-remove+insert+extend', `ring-member', `ring-next',
+;;    `ring-previous'.
+;;
+;;
+;;  This file should be loaded after loading the standard GNU file
+;;  `ring.el'.  So, in your `~/.emacs' file, do this:
+;;  (eval-after-load "ring" '(progn (require 'ring+))
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change Log:
+;;
+;; 2011/01/04 dadams
+;;     Removed autoload cookies (non-interactive commands).
+;; 2004/09/26 dadams
+;;     Renamed convert-sequence-to-ring to ring-convert-sequence-to-ring
+;; 2004/09/08 dadams
+;;     Reversed argument order: ring-member, ring-next, ring-previous.
+;; 2004/09/04 dadams
+;;     Added: convert-sequence-to-ring, ring-insert+extend.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(require 'ring) ;; ring-length, ring-ref, ring-remove, ring-insert
+
+;;;;;;;;;;;;;;;;;
+
+
+(defun ring-member (ring item)
+  "Return index of ITEM if on RING, else nil.  Comparison via `equal'.
+The index is 0-based."
+  (let ((ind 0)
+        (len (1- (ring-length ring)))
+        (memberp nil))
+    (while (and (<= ind len)
+                (not (setq memberp (equal item (ring-ref ring ind)))))
+      (setq ind (1+ ind)))
+    (and memberp ind)))
+
+(defun ring-next (ring item)
+  "Return the next item in the RING, after ITEM.
+Raise error if ITEM is not in the RING."
+  (let ((curr-index (ring-member ring item)))
+    (unless curr-index (error "Item is not in the ring: `%s'" item))
+    (ring-ref ring (ring-plus1 curr-index (ring-length ring)))))
+
+(defun ring-previous (ring item)
+  "Return the previous item in the RING, before ITEM.
+Raise error if ITEM is not in the RING."
+  (let ((curr-index (ring-member ring item)))
+    (unless curr-index (error "Item is not in the ring: `%s'" item))
+    (ring-ref ring (ring-minus1 curr-index (ring-length ring)))))
+
+
+(defun ring-insert+extend (ring item &optional grow-p)
+  "Like ring-insert, but if GROW-P is non-nil, then enlarge ring.
+Insert onto ring RING the item ITEM, as the newest (last) item.
+If the ring is full, behavior depends on GROW-P:
+  If GROW-P is non-nil, enlarge the ring to accommodate the new item.
+  If GROW-P is nil, dump the oldest item to make room for the new."
+  (let* ((vec (cdr (cdr ring)))
+         (veclen (length vec))
+         (hd (car ring))
+         (ringlen (ring-length ring)))
+    (prog1
+        (cond ((and grow-p (= ringlen veclen)) ; Full ring.  Enlarge it.
+               (setq veclen (1+ veclen))
+               (setcdr ring (cons (setq ringlen (1+ ringlen))
+                                  (setq vec (vconcat vec (vector item)))))
+               (setcar ring hd))
+              (t (aset vec (mod (+ hd ringlen) veclen) item)))
+      (if (= ringlen veclen)
+          (setcar ring (ring-plus1 hd veclen))
+        (setcar (cdr ring) (1+ ringlen))))))
+
+(defun ring-remove+insert+extend (ring item &optional grow-p)
+  "`ring-remove' ITEM from RING, then `ring-insert+extend' it.
+This ensures that there is only one ITEM on RING.
+
+If the RING is full, behavior depends on GROW-P:
+  If GROW-P is non-nil, enlarge the ring to accommodate the new ITEM.
+  If GROW-P is nil, dump the oldest item to make room for the new."
+  (let (ind)
+    (while (setq ind (ring-member ring item)) (ring-remove ring ind)))
+  (ring-insert+extend ring item grow-p))
+
+(defun ring-convert-sequence-to-ring (seq)
+  "Convert sequence SEQ to a ring.  Return the ring.
+If SEQ is already a ring, return it."
+  (if (ring-p seq)
+      seq
+    (let* ((size (length seq))
+           (ring (make-ring size))
+           (count 0))
+      (while (< count size)
+        (if (or (ring-empty-p ring)
+                (not (equal (ring-ref ring 0) (elt seq count))))
+            (ring-insert-at-beginning ring (elt seq count)))
+        (setq count (1+ count)))
+      ring)))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'ring+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; ring+.el ends here
diff --git a/auto-install/synonyms.el b/auto-install/synonyms.el
new file mode 100644
index 0000000..7646e64
--- /dev/null
+++ b/auto-install/synonyms.el
@@ -0,0 +1,1414 @@
+;;; synonyms.el --- Look up synonyms for a word or phrase in a thesaurus.
+;;
+;; Filename: synonyms.el
+;; Description: Look up synonyms for a word or phrase in a thesaurus.
+;; Author: Drew Adams
+;; Maintainer: Drew Adams
+;; Copyright (C) 2005-2011, Drew Adams, all rights reserved.
+;; Created: Tue Dec 20 14:39:26 2005
+;; Version: 1.0
+;; Last-Updated: Sat Jul 30 11:36:00 2011 (-0700)
+;;           By: dradams
+;;     Update #: 2497
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/synonyms.el
+;; Keywords: text, dictionary, thesaurus, spelling, apropos, help
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
+;;
+;; Features that might be required by this library:
+;;
+;;   `thingatpt', `thingatpt+'.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;  Look up synonyms for a word or phrase in a thesaurus.
+;;
+;;
+;;  Getting Started
+;;  ---------------
+;;
+;;  To use library Synonyms, you will need the Moby Thesaurus II file,
+;;  `mthesaur.txt', available here:
+;;
+;;    ftp://ibiblio.org/pub/docs/books/gutenberg/etext02/mthes10.zip
+;;
+;;  Put this in your initialization file (~/.emacs):
+;;
+;;    ;; The file names are absolute, not relative, locations
+;;    ;;     - e.g. /foobar/mthesaur.txt.cache, not mthesaur.txt.cache
+;;    (setq synonyms-file        )
+;;    (setq synonyms-cache-file  )
+;;    (require 'synonyms)
+;;
+;;  As an alternative to the first two lines, you can use Customize to
+;;  set `synonyms-file' and `synonyms-cache-file' persistently.  The
+;;  second of these files is created by this library, to serve as a
+;;  synonym cache for completion.
+;;
+;;  The main command is `synonyms'.  It prompts you for a word or
+;;  phrase to look up in the thesaurus.  The synonyms found are then
+;;  displayed in buffer *Synonyms*.  For example, `M-x synonyms RET
+;;  democracy' displays synonyms for `democracy'.
+;;
+;;  If you do not define `synonyms-file' and `synonyms-cache-file'
+;;  prior to using command `synonyms', that command will prompt you to
+;;  define them.  If you want to use the same values during subsequent
+;;  Emacs sessions, then you should use `M-x customize-option' to save
+;;  those newly defined values.
+;;
+;;
+;;  Some Definitions
+;;  ----------------
+;;
+;;  The thesaurus is divided into "entries", which are like glossary
+;;  entries: each entry is followed by associated words and phrases,
+;;  which, for lack of a better word, I refer to as "synonyms".  For
+;;  example, `democracy' is an entry, and it is followed by its
+;;  synonyms.  Some synonyms are not also entries.  For example,
+;;  `patriarchy' is in the thesaurus as a synonym but not as an entry.
+;;
+;;  Note: What I call "synonyms" here are not necessarily synonyms, in
+;;  the sense of having the same or even similar meanings.  They are
+;;  simply terms collected together with the same thesaurus entry
+;;  because they are related in some way - the grouping is what
+;;  defines their relation.
+;;
+;;  In Moby Thesaurus II, the meanings of synonyms in the same group
+;;  do have something in common, but this might be simply the fact
+;;  that they are terms of a similar kind.  For example, the
+;;  "synonyms" following the `democracy' thesaurus entry are words
+;;  such as `dictatorship' and `autocracy'.  These are different forms
+;;  of the same general thing: government - they are certainly not
+;;  synonymous with each other or with the entry `democracy'.
+;;
+;;
+;;  Searching the Thesaurus
+;;  -----------------------
+;;
+;;  The default input value for command `synonyms' is the word under
+;;  the cursor. Alternatively, if a region is active and you are in
+;;  Transient Mark mode (recommended), then it is the text in the
+;;  region (selection).
+;;
+;;  Your input is actually treated as a regular expression (regexp),
+;;  so you can also input patterns like `for.*ion', which will match
+;;  thesaurus entries `formation', `formulation', `fornication',
+;;  `fortification', and `forward motion'.  Note that the last of
+;;  these is a phrase rather than a single word.
+;;
+;;  Using a regexp as input is a powerful way to search, but be aware
+;;  that it can be costly in CPU time and computer memory if the
+;;  regexp is not appropriate.  The regexp `.*' will, for example,
+;;  likely use up available memory before being able to return the
+;;  entire thesaurus (it's very large).  You can always use `C-g' to
+;;  interrupt a thesaurus search if you mistakenly use an inefficient
+;;  regexp.
+;;
+;;
+;;  Using a Prefix Argument To Do More
+;;  ----------------------------------
+;;
+;;  You can use a prefix argument to modify searching and the
+;;  presentation of search results, as follows:
+;;
+;;    `C-u'     - Search for additional synonyms, in two senses:
+;;
+;;                1) Return also synonyms that are matched partially
+;;                   by the input.
+;;
+;;                2) Search the entire thesaurus for input matches,
+;;                   even if the input matches a thesaurus entry.
+;;
+;;    `M--'     - Append the search results to any previous search
+;;                results, in buffer *Synonyms*.  (Normally, the new
+;;                results replace any previous results.)
+;;
+;;    `C-u C-u' - `C-u' plus `M--': Search more and append results.
+;;
+;;  If you find yourself often using a particular prefix argument (for
+;;  example, to append results), then you might want to instead change
+;;  the default behavior to reflect this preference.  Options
+;;  `synonyms-match-more-flag' and `synonyms-append-result-flag'
+;;  correspond to using `C-u' and `M--', respectively.  In fact, a
+;;  prefix argument simply toggles the value of the corresponding
+;;  option for the duration of the command.  So, for example, if
+;;  `synonyms-append-result-flag' is t and you use `M--', then results
+;;  will not be appended.
+;;
+;;  When partially matching input (`C-u', sense #1), complete synonyms
+;;  are matched against your input.  This means that you generally
+;;  need not add a preceding or trailing `.*' to try to match a
+;;  complete synonym.  For example, input `format' will match the
+;;  complete synonyms `conformation', `efformation', `format',
+;;  `formation', `formative', `formational', `information',
+;;  `informative', `informational', `malformation', `deformation',
+;;  `reformation', `transformation', `reformatory', and so on - there
+;;  is no need to input `.*format.*' to match the same synonyms.
+;;
+;;  To better understand the meaning of #2 above for `C-u' (to
+;;  continue the search even if your input matches an entry), try, for
+;;  example, `C-u M-x synonyms RET widespread'.  You'll see not only
+;;  the main synonyms listed for `widespread' as an entry, but also
+;;  lots of different meanings of `widespread', judging by the entries
+;;  for which it is listed as a synonym:
+;;
+;;    `accepted', `ample', `broad', `broadcast', `capacious',
+;;    `catholic', `commodious', `commonness', `conventional',
+;;    `currency', `current', `customary', `deep', `deltoid',
+;;    `diffuse', `discrete', `dispersed', `disseminated',
+;;    `dissipated', `distributed', `epidemic', `established',
+;;    `everyday', `expansive', `extended', `extensive', `familiar',
+;;    `fan shaped', `far flung', `far reaching', `flaring', `full',
+;;    `general', `indiscriminate', `infinite', `large scale',
+;;    `liberal', `normal', `normality', `open', `ordinary',
+;;    `outstretched', `pervasive', `popular', `prescribed',
+;;    `prescriptive', `prevailing', `prevalence', `prevalent',
+;;    `public', `rampant', `received', `regnant', `regular',
+;;    `regulation', `reign', `rife', `roomy', `ruling', `run',
+;;    `scattered', `set', spacious`', `sparse', `splay', `sporadic',
+;;    `sprawling', `spread', `standard', `stock', `straggling',
+;;    `stretched out', `sweeping', `time-honored', `traditional',
+;;    `universal', `usual', `vast', `voluminous', `wholesale', `wide
+;;    open', `wide', and `wonted'.
+;;
+;;  These are just the entries! Each of these is of course followed by
+;;  its own synonyms - perhaps 100 or 300, including `widespread'.
+;;
+;;  This list of entries is not the same list as the synonyms for
+;;  entry `widespread'.  There are words and phrases here that are not
+;;  in the latter list, and vice versa.  For example, the former (but
+;;  not the latter) list includes `full'; the latter (but not the
+;;  former) list includes `wide-reaching'.
+;;
+;;  The latter are the words most closely related to `widespread'.
+;;  The list above are the other thesaurus entries (corresponding to
+;;  main categories) to which `widespread' is most closely related.
+;;  Looking at all of the synonym groups in which `widespread' appears
+;;  can tell you additional information about its meanings - and it
+;;  can provide additional synonyms for `widespread'.
+;;
+;;
+;;  Using Completion with Synonyms
+;;  ------------------------------
+;;
+;;  You can complete words and phrases in the minibuffer, as input to
+;;  command `synonyms'.  You can use library Synonyms together with
+;;  library Icicles to complete a partial word in a text buffer into a
+;;  word or phrase in the thesaurus.  If you use both libraries then
+;;  load Icicles after Synonyms.  For more information on Icicles, see
+;;  `http://www.emacswiki.org/cgi-bin/wiki/icicles.el'.
+;;
+;;  ** Minibuffer Input Completion **
+;;
+;;  You can enter any text to match against thesaurus synonyms.  When
+;;  you are prompted by command `synonyms' to enter this text, you can
+;;  also use input completion to complete to a thesaurus synonym.
+;;  That is, even though you can enter any text (including a regexp),
+;;  completion will only complete to synonyms in the thesaurus.
+;;
+;;  If you load library Icicles, then a more powerful version of
+;;  command `synonyms' is used.  In particular, it lets you:
+;;
+;;   - Use `S-TAB' during completion to see the list of all synonyms
+;;     (thesaurus terms) that match your minibuffer input so far.
+;;
+;;   - Use `[next]', and `[prior]' (usually keys `Page Down' and `Page
+;;     Up') during completion to cycle through the completion
+;;     candidates (synonyms) that match your input.
+;;
+;;   - Use `C-o', `C-[next]', and `[C-prior]' during completion to
+;;     display the synonyms of the current completion candidate.
+;;
+;;  ** Completing Buffer Text Using the Thesaurus **
+;;
+;;  Icicles also provides two commands for using completion to insert
+;;  thesaurus entries in a buffer:
+;;
+;;   - `icicle-complete-thesaurus-entry' completes a word in a text
+;;     buffer to any word or phrase in the thesaurus.  I bind it to
+;;     `C-c /'.
+;;
+;;   - `icicle-insert-thesaurus-entry' inserts thesaurus words and
+;;     phrases in a text buffer.  It is a multi-command, which means
+;;     that, within a single call to it, you can insert any number of
+;;     thesaurus entries, in succession.  If you want to, you can
+;;     write an entire book using a single call to
+;;     `icicle-insert-thesaurus-entry'!
+;;
+;;
+;;  Browsing the Thesaurus
+;;  ----------------------
+;;
+;;  Besides using command `synonyms' to search for synonyms, you can
+;;  use Synonyms to browse the thesaurus.  This is really just the
+;;  same thing, but key and mouse bindings are provided in buffer
+;;  *Synonyms*, so you need not input anything - just point and click
+;;  the hyperlinks.  Buffer *Synonyms* is in Synonyms major mode,
+;;  which provides a few additional features.
+;;
+;;  You can still choose to search for additional synonyms or append
+;;  search results, without bothering with a prefix argument, by using
+;;  modifier keys (Control, Meta) with a mouse click.
+;;
+;;  Another way of browsing is to revisit previous search-result
+;;  pages.  You can do this using commands `synonyms-history-backward'
+;;  and `synonyms-history-forward'.  In buffer *Synonyms*, these are
+;;  bound to the following key sequences, for convenience:
+;;
+;;    `l', `p', `mouse-4' - `synonyms-history-backward'
+;;    `r', `n', `mouse-5' - `synonyms-history-forward'
+;;
+;;  The `l' and `r' bindings correspond to the history bindings in
+;;  Info.  The `p' and `n' bindings stand for "previous" and "next".
+;;  The bindings to additional mouse buttons correspond to typical
+;;  bindings for Back and Forward in Web browsers.
+;;
+;;  In addition to these bindings, the same history commands can be
+;;  accessed by clicking links [Back] and [Forward] with `mouse-2'.
+;;
+;;  If you have previously used the append option (via, for example,
+;;  `M-mouse2'), so that there are multiple search results in buffer
+;;  *Synonyms*, then using a history command simply takes you to the
+;;  preceding (for [Back]) or following (for [Forward]) result in the
+;;  buffer, measured from the current cursor position.  Depending on
+;;  the cursor position, this might be different from the previous or
+;;  next search made previously.
+;;
+;;  This is for convenience, but it is also more efficient in the case
+;;  of a regexp search that takes a long time.  Except for this
+;;  special treatment of appended results, whenever you navigate the
+;;  search-results history you are actually searching again for a
+;;  synonym you sought previously.  The case of appended results is
+;;  analogous to accessing a Web browser cache when navigating the
+;;  history.
+;;
+;;  You can of course use modifier keys (Control, Meta) while you
+;;  click links [Back] and [Forward], to impose their usual behavior:
+;;  search for additional synonyms or append search results, or both.
+;;
+;;  Finally, some people prefer menus, so there is a Synonyms menu-bar
+;;  menu when you are in Synonyms mode, complete with all of the
+;;  functionalities described above.
+;;
+;;  For more information on the browsing possibilities in buffer
+;;  *Synonyms*, use `?' in Synonyms mode.
+;;
+;;
+;;  Dictionary Definitions, Antonyms, etc.
+;;  --------------------------------------
+;;
+;;  Synonyms works with a large but simple database of groups of words
+;;  and phrases that are synonyms of each other.  This database does
+;;  not provide definitions of words or phrases; it simply groups
+;;  them.  Command `synonym-definition' (aka `dictionary-definition')
+;;  lets you look up a word or phrase (or a regexp) using one or more
+;;  dictionaries on the Web.  That is usually the best source for this
+;;  kind of information, but you obviously need an Internet connection
+;;  to use this command.
+;;
+;;  Options (variables) `synonyms-dictionary-url' and
+;;  `synonyms-dictionary-alternate-url' are URLs you can set to point
+;;  to the dictionaries of your choice.  The default value of
+;;  `synonyms-dictionary-alternate-url' looks up the search term in
+;;  multiple dictionaries, and it lets you use wildcards.  Use `C-h v
+;;  synonyms-dictionary-alternate-url' for more information.  The
+;;  default value of `synonyms-dictionary-url' usually provides a
+;;  quicker answer.  Both of these URLs also give you access to
+;;  additional information about the search term (antonyms, etymology,
+;;  even pronunciation).
+;;
+;;  In buffer *Synonyms*, you can simply hit `d' followed by `RET' or
+;;  `mouse-2' to look up a term that is in the buffer.  Just as for
+;;  looking up a synonym by clicking `mouse-2', if you select text
+;;  (region), then that text is looked up.
+;;
+;;
+;;  A Cache File of Synonyms
+;;  ------------------------
+;;
+;;  The very first time you use Synonyms, a large list of synonyms
+;;  will be compiled and written to a cache file.  This is slow - it
+;;  takes 2-3 minutes - but it is only a one-time cost.  From then on,
+;;  whenever you first use Synonyms during an Emacs session, the cache
+;;  file will be read (quickly), to create the list of synonyms that
+;;  are used for minibuffer completion.
+;;
+;;
+;;  Using Other Thesauri, Dictionaries, and so on - CSV data
+;;  --------------------------------------------------------
+;;
+;;  There is nothing in library Synonyms that ties it to the Moby
+;;  Thesaurus II thesaurus.  All of its functionality will work with
+;;  any file of comma-separated values.  Each line of such a file is
+;;  interpreted as a synonym group, as understood here, and the first
+;;  word or phrase on each line is interpreted as a thesaurus entry,
+;;  as understood here.  This means only that search results are
+;;  organized into sections with entry headers.
+;;
+;;  If, for example, you had a CSV file of personal contacts, where
+;;  the first term in each line was a last name or a company name,
+;;  then you could use library Synonyms to query it, producing the
+;;  same kind of output as for the thesaurus.
+;;
+;;  One thing to keep in mind if you try to use library Synonyms with
+;;  a different CSV file is that there are several different CSV-file
+;;  syntaxes.  The one that Synonyms is built to use is a simple one,
+;;  with no quote marks around entries and no embedded quote marks
+;;  within entries.
+;;
+;;  Similarly, there is nothing here that limits the functionality to
+;;  English.  If you had a thesaurus in another language, it should
+;;  work as well.
+;;
+;;  Currently, Synonyms works with a single raw synonyms file
+;;  (thesaurus) and a corresponding single cache file (for
+;;  completion).  However, it would be easy to extend the
+;;  functionality to use multiple thesauri or, in general, multiple
+;;  CSV files.  Suggestions of requirements (e.g. ways to select a
+;;  thesaurus for particular passages of text) are welcome.
+ 
+;;
+;;
+;;  Things Defined Here
+;;  -------------------
+;;
+;;  Faces defined here -
+;;
+;;    `synonyms-heading', `synonyms-search-text',
+;;    `synonyms-mouse-face'.
+;;
+;;
+;;  User options (variables) defined here -
+;;
+;;    `synonyms-append-result-flag', `synonyms-cache-file',
+;;    `synonyms-file', `synonyms-fill-column',
+;;    `synonyms-match-more-flag', `synonyms-mode-hook',
+;;    `synonyms-use-cygwin-flag'.
+;;
+;;  Commands defined here -
+;;
+;;    `dictionary-definition', `synonyms', `synonyms-append-result',
+;;    `synonyms-append-result-no-read', `synonyms-definition',
+;;    `synonyms-definition-mouse', `synonyms-definition-no-read',
+;;    `synonyms-ensure-synonyms-read-from-cache',
+;;    `synonyms-history-backward', `synonyms-history-forward',
+;;    `synonyms-make-obarray', `synonyms-match-more',
+;;    `synonyms-match-more-no-read',
+;;    `synonyms-match-more+append-result',
+;;    `synonyms-match-more+append-result-no-read', `synonyms-mode',
+;;    `synonyms-mouse', `synonyms-mouse-append-result',
+;;    `synonyms-mouse-match-more',
+;;    `synonyms-mouse-match-more+append-result', `synonyms-no-read',
+;;    `synonyms-write-synonyms-to-cache'.
+;;
+;;  Non-interactive functions defined here -
+;;
+;;    `synonyms-action', `synonyms-add-history-links',
+;;    `synonyms-default-regexp', `synonyms-define-cache-file',
+;;    `synonyms-define-synonyms-file', `synonyms-format-entries',
+;;    `synonyms-format-entry', `synonyms-format-finish',
+;;    `synonyms-format-synonyms',
+;;    `synonyms-hack-backslashes-if-cygwin', `synonyms-lookup',
+;;    `synonyms-nearest-word', `synonyms-file-readable-p',
+;;    `synonyms-search-entries', `synonyms-search-synonyms',
+;;    `synonyms-show-synonyms', `synonyms-file-writable-p'.
+;;
+;;  Internal variables defined here -
+;;
+;;    `synonyms-history', `synonyms-history-forward',
+;;    `synonyms-list-for-obarray', `synonyms-mode-map',
+;;    `synonyms-obarray', `synonyms-search-text'.
+;;
+;;  Key bindings made here - see `synonyms-mode'.  All key bindings
+;;  are local to Synonyms mode; no global bindings are made here.
+ 
+;;
+;;
+;;  Acknowledgements
+;;  ----------------
+;;
+;;  The basic functionality provided here was derived from library
+;;  `mthesaur.el', by Tad Ashlock .  That
+;;  library, in turn, was inspired by library `thesaurus.el', by Ray
+;;  Nickson.  Thanks also to those who sent helpful bug reports.
+;;
+;;
+;;  Note on MS Windows Emacs 20 and Cygwin `grep'
+;;  ---------------------------------------------
+;;
+;;  There is apparently a bug in the Emacs (at least versions 20-22) C
+;;  code that implements function `call-process' on MS Windows.  When
+;;  using native Windows Emacs with Cygwin commands, such as `grep',
+;;  the C code removes a level of backslashes in some cases, so string
+;;  arguments supplied to `call-process' need to have twice as many
+;;  backslashes as they should need in those cases.  It is for this
+;;  reason that option `synonyms-use-cygwin-flag' is supplied here.
+;;  When that option is non-nil, backslashes in regexps are hacked to
+;;  do the right thing.  (In Emacs 20, this means doubling the
+;;  backslashes; in Emacs 21-22, this means doubling them unless there
+;;  are spaces in the search string.)
+;;
+;;
+;;  Maybe To Do?
+;;  ------------
+;;
+;;  1. It would be ideal to have not only synonym information but also
+;;     definitions, antonyms, more general and more specific terms,
+;;     filtering by part of speech (verb vs adjective etc.), and so
+;;     on.  A good example of what I'd really like to have is provided
+;;     by the free Windows program WordWeb (available here:
+;;     http://wordweb.info/).  Combining that functionality with
+;;     Icicles completion features would provide a great tool, IMO.
+;;
+;;     `synonyms-definition*' goes a long way toward providing this,
+;;     and perhaps it is the best way to go, since there is so much
+;;     more definitional info on the Web.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change Log:
+;;
+;; 2011/07/30 dadams
+;;     Moved Icicles code to icicles-cmd2.el.  Removed soft-require of icicles.el.
+;; 2011/02/11 dadams
+;;     Better defaults for faces, for dark backgrounds.
+;; 2011/01/04 dadams
+;;     Added autoload cookies (for defgroup, defface, defcustom, and commands).
+;; 2010/08/20 dadams
+;;     synonyms - non-Icicles version: Made ARG optional too.
+;;     synonyms(-no-read|-history-(backward|forward)):
+;;       Use ARG, not current-prefix-arg.
+;; 2010/01/12 dadams
+;;     synonyms-history-(backward|forward): save-excursion + set-buffer -> with-current-buffer.
+;; 2007/12/05 dadams
+;;     synonyms-obarray: Removed * doc-string prefix.
+;; 2007/02/10 dadams
+;;     icicle-sort-case-insensitively -> icicle-case-insensitive-string-less-p.
+;; 2006/12/22 dadams
+;;     Renamed group synonyms to Synonyms.  :group 'icicles -> :group 'Icicles.
+;; 2006/03/31 dadams
+;;     synonyms-write-synonyms-to-cache: Use prin1 instead of pp.
+;; 2006/03/17 dadams
+;;     synonyms-file-(read|writ)able-p: Put non-empty string condition first.
+;; 2006/03/14 dadams
+;;     synonyms-file-(read|writ)able-p: Make sure also not a directory.
+;; 2006/03/12 dadams
+;;     synonyms-ensure-synonyms-read-from-cache, synonyms-define-synonyms-file: 
+;;       Set synonyms(-cache)-file to expanded version.
+;; 2006/03/01 dadams
+;;     Updated Commentary to mention Icicles completion of synonyms.
+;; 2006/02/02 dadams
+;;     synonyms-define-cache-file: Fixed typo.
+;; 2006/01/28 dadams
+;;     synonyms-define-cache-file: wrap file-name-directory in expand-file-name.
+;; 2006/01/19 dadams
+;;     synonyms-format-finish: Minor tweak to regexp: space and tab, but not newline or formfeed.
+;; 2006/01/18 dadams
+;;     Added dictionary definition lookup:
+;;       Added: synonyms-dictionary(-alternate)-url, synonyms-definition*.
+;;       Bound synonyms-definition-*. 
+;; 2006/01/14 dadams
+;;     Bug fixes -
+;;     Make sure file name is expanded (thanks to Nikos Apostolakis): 
+;;       synonyms-search-(entries|synonyms): Expand file name.
+;;       synonyms-define-*-file: Set variable after expanding file name.
+;;       synonyms-format-entry, synonyms-history-*, synonyms-add-history-links:
+;;         Raise error if search finds nothing.
+;;     synonyms-hack-backslashes-if-cygwin: Don't double if spaces and not Emacs 20.
+;;       Renamed synonyms-double-backslashes-if-cygwin to synonyms-hack-backslashes-if-cygwin.
+;;     synonyms-mode-map: swapped bindings for C-mouse-2 and C-down-mouse-2, for Emacs 22.
+;; 2006/01/11 dadams
+;;     Fixed typo: require 'synonyms. (Thanks to Nikos Apostolakis.)
+;; 2006/01/07 dadams
+;;     Added :link.
+;; 2006/01/04 dadams
+;;     synonyms-format-finish: Don't skip numbered header, so highlight multiple synonyms in entry.
+;; 2006/01/02 dadams
+;;     Added: synonyms-define-cache-file, synonyms-define-synonyms-file,
+;;            synonyms-file-readable-p, synonyms-file-writable-p.
+;;     synonyms-make-obarray: Use synonyms-define-synonyms-file.
+;;                            Use synonyms-mode, to get modified syntax (bug fix).
+;;     synonyms-write-synonyms-to-cache: Use synonyms-define-cache-file.
+;;     synonyms-ensure-synonyms-read-from-cache: Use synonyms-file-readable-p.
+;;     synonyms(-cache)-file: Use empty string as initial value.
+;;     Thanks to Alex Schroeder [alex@emacswiki.org] for suggestion to prompt for file names.
+;; 2005/12/31 dadams
+;;     Added menu-bar Synonyms menu.
+;;     Renamed synonyms-read-synonyms-from-cache to synonyms-ensure-synonyms-read-from-cache.
+;;       Call it from synonyms, not from synonyms-mode.
+;;     Defined synonyms-mode-map per convention.
+;;     synonyms-match-more, synonyms-append-result, synonyms-match-more+append-result:
+;;       Use synonyms, not synonyms-no-read.
+;;     Added: synonyms-*-no-read.  Bound those, not the new read versions.
+;; 2005/12/29 dadams
+;;     Treat modifiers with clicks on [Back] and [Forward] links.
+;;     synonyms-history-(backward|forward): Add prefix arg.  Bind options.
+;;     synonyms-mode, synonyms-lookup: Disable undo.
+;; 2005/12/28 dadams
+;;     Added: synonyms-history-(backward|forward), synonyms-add-history-links, synonyms-link.
+;;     Added: [Back] and [Forward] links.
+;;     synonyms-show-synonyms: Put cursor on first synonym.
+;;     synonyms-mouse, synonyms-lookup: Removed save-excursion.
+;;     synonyms-mouse: Treat clicks on [Back] and [Forward] links too.
+;;     synonyms-format-finish: Added save-excursion for last part: filling and adding mouse-face.
+;;     synonyms-nearest-word: Remove text properties.
+;;     synonyms: Use synonym-action.
+;;     synonyms-lookup: When no synonyms found, remove search-text from history.
+;;     Require cl.el when compile.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; ;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;; push, pop
+
+(require 'thingatpt+ nil t) ;; (no error if not found): word-nearest-point
+(require 'thingatpt nil t)  ;; (no error if not found): word-at-point
+
+;; Note: You might get byte-compiler warnings that variables `appendp'
+;;       and `morep' are free: .  This is OK.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+
+ 
+;;; Faces (alphabetical) -----------------------------------
+
+;;;###autoload
+(defgroup Synonyms nil
+  "Commands to look up synonyms in a thesaurus."
+  :prefix "synonyms-"
+  :group 'convenience :group 'help :group 'apropos :group 'matching
+  :link `(url-link :tag "Send Bug Report"
+          ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
+synonyms.el bug: \
+&body=Describe bug here, starting with `emacs -q'.  \
+Don't forget to mention your Emacs and library versions."))
+  :link '(url-link :tag "Other Libraries by Drew"
+          "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
+  :link '(url-link :tag "Download" "http://www.emacswiki.org/cgi-bin/wiki/synonyms.el")
+  :link '(url-link :tag "Description" "http://www.emacswiki.org/cgi-bin/wiki/Synonyms")
+  :link '(emacs-commentary-link :tag "Commentary" "synonyms"))
+
+;;;###autoload
+(defface synonyms-heading '((((background dark)) (:foreground "Yellow"))
+                            (t (:foreground "Blue")))
+  "*Face for different synonym types."
+  :group 'Synonyms :group 'faces)
+
+;;;###autoload
+(defface synonyms-search-text '((t (:foreground "Red")))
+  "*Face for the term whose synonyms were sought."
+  :group 'Synonyms :group 'faces)
+
+;;;###autoload
+(defface synonyms-link '((((background dark)) (:foreground "Yellow" :underline t))
+                         (t (:foreground "Blue" :underline t)))
+  "*Face for history links."
+  :group 'Synonyms :group 'faces)
+
+;;;###autoload
+(defface synonyms-mouse-face '((((background dark)) (:background "DarkCyan"))
+                               (t (:background "Cyan")))
+  "*Mouse face for the term whose synonyms were sought."
+  :group 'Synonyms :group 'faces)
+
+
+
+ 
+;;; User Options (alphabetical) ----------------------------
+
+;;;###autoload
+(defcustom synonyms-append-result-flag nil
+  "*t means that `synonyms' appends search result to previous results.
+No other value, besides t, has this effect.
+
+This can be overridden by using a negative prefix argument,
+for example, `M--'.  If you use `C-u C-u', then both this and
+`synonyms-match-more-flag' are overridden."
+  :type 'boolean :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-cache-file ""
+  "*Location to write cache file containing synonyms.
+Written to save the list of synonyms used for completion.
+This is an absolute (complete-path) location, including the file name."
+  :type '(file :must-match t) :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-file ""
+  "*Location of thesaurus file `mthesaur.txt'.
+This is an absolute (complete-path) location, including the file name."
+  :type '(file :must-match t) :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-fill-column 80
+  "*Synonyms* buffer text is wrapped (filled) to this many columns."
+  :type 'integer :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-match-more-flag nil
+  "*t means additional thesaurus entries can be matched by `synonyms'.
+No other value, besides t, has this effect.
+
+A value of t means two things:
+ 1) Input can match parts of synonyms, in addition to whole synonyms.
+ 2) All synonyms are shown, even if input matches a thesaurus entry.
+
+This can be overridden by using a positive prefix argument,
+  for example, `C-u'.  If you use `C-u C-u', then both this and
+`synonyms-append-result-flag' are overridden."
+  :type 'boolean :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-mode-hook nil
+  "*Normal hook run when entering Thesaurus mode."
+  :type 'hook :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-use-cygwin-flag nil
+  "*Non-nil means to double backslashes in arguments to `call-process'.
+There is apparently a bug in the Emacs (at least versions 20-22) C
+code that implements function `call-process' on MS Windows.  When
+using native Windows Emacs with Cygwin commands, such as `grep', the C
+code removes a level of backslashes, so string arguments supplied to
+`call-process' need to have twice as many backslashes as they should
+need.  If you are using Emacs on Windows and Cygwin `grep', then you
+probably will want to use a non-nil value for
+`synonyms-use-cygwin-flag'."
+  :type 'boolean :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-dictionary-url "http://dictionary.reference.com/search?q="
+  "*URL of a Web dictionary lookup.  Text to look up is appended to this.
+See also `synonyms-dictionaries-url'."
+  :type 'string :group 'Synonyms)
+
+;;;###autoload
+(defcustom synonyms-dictionary-alternate-url "http://www.onelook.com/?ls=b&w="
+  "*URL of a Web dictionary lookup.  Text to look up is appended to this.
+The default value, \"http://www.onelook.com/?ls=b&w=\" lets you use `?'
+and `*' as wildcards in the terms you look up.  These are not used as
+regexp wildcards, however.  `?' stands for any single character, and
+`*' stands for any sequence of characters.  In terms of regexp syntax,
+`?' here is equivalent to the regexp `.', and `*' is equivalent to the
+regexp `.*'.  See http://www.onelook.com/?c=faq#patterns for more
+information on the allowed wildcard patterns.
+See also `synonyms-dictionary-url'."
+  :type 'string :group 'Synonyms)
+ 
+;;; Internal variables (alphabetical) ----------------------
+
+(defvar synonyms-history nil "Minibuffer history list for thesaurus lookup.")
+
+(defvar synonyms-history-forward nil
+  "Minibuffer history list for thesaurus lookup using `synonyms-history-backward'.")
+
+(defvar synonyms-list-for-obarray nil "List of synonyms to be used for completion")
+
+(defvar synonyms-mode-map nil "Keymap for `synonyms-mode'.")
+
+(unless synonyms-mode-map
+  (let ((map  (make-sparse-keymap "Synonyms")))
+    (define-key map [(?d) (mouse-2)] 'synonyms-definition-mouse)
+    (define-key map "d\r"            'synonyms-definition-no-read)
+    (define-key map "s"              'synonyms)
+    (define-key map [S-return]       'synonyms)
+    (define-key map "\r"             'synonyms-no-read)
+    (define-key map [C-return]       'synonyms-match-more-no-read)
+    (define-key map [M-return]       'synonyms-append-result-no-read)
+    (define-key map [C-M-return]     'synonyms-match-more+append-result-no-read)
+    (define-key map [mouse-2]        'synonyms-mouse)
+    (define-key map [C-mouse-2]      'undefined)
+    (define-key map [C-down-mouse-2] 'synonyms-mouse-match-more) ; Get rid of `facemenu-mouse-menu'
+    (define-key map [M-mouse-2]      'synonyms-mouse-append-result)
+    (define-key map [C-M-mouse-2]    'synonyms-mouse-match-more+append-result)
+    (define-key map "l"              'synonyms-history-backward) ; As in Info
+    (define-key map "p"              'synonyms-history-backward) ; As in previous
+    (define-key map "r"              'synonyms-history-forward) ; As in Info
+    (define-key map "n"              'synonyms-history-forward) ; As in next
+    (define-key map [mouse-4]        'synonyms-history-backward)
+    (define-key map [mouse-5]        'synonyms-history-forward)
+    (define-key map " "              'scroll-up) ; SPC
+    (define-key map "\^?"            'scroll-down) ; DEL
+    (define-key map "?"              'describe-mode)
+    (define-key map "q"              'quit-window)
+    (define-key map [menu-bar]             (make-sparse-keymap))
+    (define-key map [menu-bar synonyms]    (cons "Synonyms" map))
+    (define-key map [synonyms-help]        '("Help" . describe-mode))
+    (define-key map [synonyms-separator-2] '("--"))
+    (define-key map [synonyms-next]        '("Show Next" . synonyms-history-forward))
+    (put 'synonyms-history-forward 'menu-enable 'synonyms-history-forward)
+    (define-key map [synonyms-previous]    '("Show Previous" . synonyms-history-backward))
+    (put 'synonyms-history-backward 'menu-enable '(and synonyms-history (cdr synonyms-history)))
+    (define-key map [synonyms-separator]   '("--"))
+    (define-key map [synonyms-more-append]
+      '("Find (Max), Append Results" . synonyms-match-more+append-result))
+    (define-key map [synonyms-append]
+      '("Find, Append Results" . synonyms-append-result))
+    (define-key map [synonyms-more]        '("Find (Max)" . synonyms-match-more))
+    (define-key map [synonyms-synonyms]    '("Find" . synonyms))
+    (setq synonyms-mode-map  map)))
+
+;; 103307 is the smallest prime > 103304, which is the number of synonyms.
+(defvar synonyms-obarray (make-vector 103307 0)
+  "Obarray of synonyms.  Used for completion.")
+
+(defvar synonyms-search-text nil "Current text being looked up (matched).")
+
+
+
+ 
+;;; Functions ----------------------------------------------
+
+;;;###autoload
+(define-derived-mode synonyms-mode text-mode "Synonyms"
+  "Major mode for browsing thesaurus entries (synonyms).
+Like Text mode but with these additional key bindings:
+
+ \\\\[synonyms-mouse],     \\[synonyms-no-read],     \\[synonyms] - \
+Look up synonyms for a word or phrase
+ \\[synonyms-mouse-match-more],   \\[synonyms-match-more]   - Like \\[synonyms-no-read], but \
+try to match more terms
+ \\[synonyms-mouse-append-result],   \\[synonyms-append-result]   - Like \\[synonyms-no-read], but \
+add result to previous result
+ \\[synonyms-mouse-match-more+append-result], \\[synonyms-match-more+append-result] - Like \
+\\[synonyms-match-more] and \\[synonyms-append-result] combined
+
+ \\[scroll-up] - Scroll down through the buffer of synonyms
+ \\[scroll-down] - Scroll up through the buffer of synonyms
+ \\[describe-mode]   - Display this help
+ \\[quit-window]   - Quit Synonyms mode
+
+Of the various key bindings that look up synonyms, the most flexible
+is \\[synonyms] - it prompts you for the search string to match.  This
+can be a regular expression (regexp).  The other lookup bindings are
+for convenience - just click.
+
+In Synonyms mode, Transient Mark mode is enabled.
+
+Options `synonyms-match-more-flag' and `synonyms-append-result-flag'
+affect synonym matching and the results.  For convenience, \\[synonyms-mouse-match-more],
+\\[synonyms-mouse-append-result], and \\[synonyms-mouse-match-more+append-result] \
+toggle the effect of those options for the
+duration of the command.
+
+Note that even though Synonyms mode is similar to Text mode, buffer
+`*Synonyms*' is read-only, by default - use `C-x C-q' to toggle.
+
+Turning on Synonyms mode runs the normal hooks `text-mode-hook' and
+`synonyms-mode-hook' (in that order)."
+
+  ;; Synonyms to account for:
+  ;; `$', `1', `0': $100-a-plate dinner; `2': catch-22, V-2; `3': 3-D; `9': strontium 90.
+  ;; To match `$', you will of course need to escape it: `\$'.
+  (modify-syntax-entry ?- "w" synonyms-mode-syntax-table) ; Make hyphen (-) a word character.
+  (modify-syntax-entry ?1 "w" synonyms-mode-syntax-table) ; Make numerals 1,2,3,9,0 word characters.
+  (modify-syntax-entry ?2 "w" synonyms-mode-syntax-table)
+  (modify-syntax-entry ?3 "w" synonyms-mode-syntax-table)
+  (modify-syntax-entry ?9 "w" synonyms-mode-syntax-table)
+  (modify-syntax-entry ?0 "w" synonyms-mode-syntax-table)
+  (modify-syntax-entry ?$ "w" synonyms-mode-syntax-table) ; Make dollar ($) a word character.
+  (buffer-disable-undo)
+  (setq fill-column  synonyms-fill-column)
+  (set (make-local-variable 'transient-mark-mode) t))
+
+;;;###autoload
+(defun synonyms-ensure-synonyms-read-from-cache ()
+  "Ensure synonyms are in `synonyms-obarray', from `synonyms-cache-file'.
+If this file does not yet exist, then it and the obarray are created.
+Creating the obarray for the first time takes 2-3 minutes.
+This does nothing if the obarray is already complete."
+  (interactive)
+  (unless (intern-soft "synonym" synonyms-obarray) ; Do nothing if already complete.
+    (setq synonyms-list-for-obarray  () ; Just to make sure.
+          synonyms-cache-file        (expand-file-name synonyms-cache-file))
+    (if (synonyms-file-readable-p synonyms-cache-file)
+        (let ((list-buf  (find-file-noselect synonyms-cache-file 'nowarn 'raw))
+              (obarray   synonyms-obarray))
+          (unwind-protect
+               (setq synonyms-list-for-obarray  (read list-buf))
+            (kill-buffer list-buf)))
+      (synonyms-make-obarray)           ; Create obarray from scratch
+      (synonyms-write-synonyms-to-cache)))) ; and write it out, for next time.
+
+;;;###autoload
+(defun synonyms-make-obarray ()
+  "Fill `synonyms-obarray' with the available synonyms."
+  (interactive)
+  (unless (intern-soft "synonym" synonyms-obarray) ; Do nothing if already complete.
+    (synonyms-define-synonyms-file)
+    (with-temp-message "Building synonyms list for completion.  This will take a few minutes..."
+      (let ((thesaurus-buf  (find-file-noselect synonyms-file 'nowarn 'raw))
+            synonym)
+        (unwind-protect
+             (save-current-buffer
+               (set-buffer thesaurus-buf)
+               (goto-char (point-min))
+               (synonyms-mode)          ; To use the modified syntax table.
+               (while (re-search-forward "\\(\\(\\w\\|[ ]\\)+\\)\\(,\\|$\\)" nil t)
+                 (setq synonym  (buffer-substring (match-beginning 1) (match-end 1)))
+                 (intern synonym synonyms-obarray)))
+          (kill-buffer thesaurus-buf))))))
+
+(defun synonyms-define-synonyms-file ()
+  "Prompt user to define `synonyms-file', unless it is readable."
+  (setq synonyms-file  (expand-file-name synonyms-file))
+  (unless (synonyms-file-readable-p synonyms-file)
+    (while (not (synonyms-file-readable-p synonyms-file))
+      (setq synonyms-file  (read-file-name "Thesaurus file: " nil nil 'confirm "mthesaur.txt")))
+    (custom-set-variables (list 'synonyms-file
+                                (setq synonyms-file  (expand-file-name synonyms-file))
+                                'now))))
+
+;;;###autoload
+(defun synonyms-write-synonyms-to-cache ()
+  "Write synonyms in `synonyms-obarray' to file `synonyms-cache-file'."
+  (interactive)
+  (synonyms-define-cache-file)
+  (with-temp-message "Writing synonyms cache file..."
+    (with-temp-file synonyms-cache-file
+      (mapatoms (lambda (symb) (push symb synonyms-list-for-obarray)) synonyms-obarray)
+      (prin1 synonyms-list-for-obarray (current-buffer)))))
+
+(defun synonyms-define-cache-file ()
+  "Prompt user to define `synonyms-cache-file', unless it is writable."
+  (unless (synonyms-file-writable-p synonyms-cache-file)
+    (while (not (synonyms-file-writable-p synonyms-cache-file))
+      (setq synonyms-cache-file
+            (read-file-name "Cache file: "
+                            (expand-file-name (file-name-directory synonyms-file)) nil nil
+                            (concat (file-name-nondirectory synonyms-file) ".cache"))))
+    (custom-set-variables (list 'synonyms-cache-file
+                                (setq synonyms-cache-file  (expand-file-name synonyms-cache-file))
+                                'now))))
+
+(defun synonyms-file-readable-p (file)
+  "Return non-nil if FILE (a string) names a readable file."
+  (and (not (string= "" file)) (file-readable-p file) (not (file-directory-p file))))
+
+(defun synonyms-file-writable-p (file)
+  "Return non-nil if FILE (a string) names a writable file."
+  (and (not (string= "" file)) (file-writable-p file) (not (file-directory-p file))))
+
+(defun synonyms (&optional arg regexp)
+  "Show synonyms that match a regular expression (e.g. a word or phrase).
+You are prompted for the regexp.  By default, it is the text
+of the region, if it is active and `transient-mark-mode' is enabled,
+or the nearest word to the cursor, if not.
+
+Option `synonyms-match-more-flag' non-nil means additional thesaurus
+  entries can be matched.  This can be more time-consuming.  It means
+  two things:
+
+  1) Input can match parts of synonyms, in addition to whole synonyms.
+  2) All synonyms are shown, even if input matches a thesaurus entry.
+
+Option `synonyms-append-result-flag' non-nil means to append search
+  result to previous results.
+
+A prefix argument toggles the meaning of each of those options for the
+duration of the command:
+
+  If `C-u' or `C-u C-u', then toggle `synonyms-match-more-flag'.
+  If negative or `C-u C-u', then toggle `synonyms-append-result-flag'.
+
+\(`C-u C-u' thus means toggle both options.)
+
+When called from Lisp, optional second argument REGEXP is the regexp
+to match (no prompting)."
+  (interactive "P")
+  (synonyms-ensure-synonyms-read-from-cache) ; Fill `synonyms-obarray', for use in completion.
+  (let* ((num-arg              (prefix-numeric-value arg))
+         (morep                (eq synonyms-match-more-flag (atom arg)))
+         (appendp              (eq synonyms-append-result-flag (and (wholenump num-arg)
+                                                                    (/= 16 num-arg))))
+         (default-search-text  (or regexp (synonyms-default-regexp)))
+         (search-text          (or regexp
+                                   (let ((case-fold-search  t)) ; Case-insensitive completion.
+                                     (completing-read
+                                      "Show synonyms for word or phrase (regexp): "
+                                      synonyms-obarray nil nil nil 'synonyms-history
+                                      default-search-text)))))
+    (synonyms-action search-text)))
+
+(defun synonyms-action (search-text)
+  "Helper function for command `synonyms'.
+APPENDP and MOREP are free here."
+  (setq synonyms-search-text  search-text) ; Save it.
+  (when (string= "" search-text) (error "No text to look up"))
+  (unless (member search-text synonyms-history) (push search-text synonyms-history))
+  ;; Change `.' to `[^,]' in `search-text', so we don't mix terms.
+  (setq search-text  (replace-regexp-in-string "\\." "[^,]" search-text nil t))
+  (synonyms-lookup search-text (and (boundp 'appendp) appendp) (and (boundp 'morep) morep)))
+
+;;;###autoload
+(defun synonyms-no-read (arg)
+  "Same as command `synonyms', but uses the default input text (regexp)."
+  (interactive "P")
+  (let* ((num-arg      (prefix-numeric-value arg))
+         (morep        (eq synonyms-match-more-flag (atom arg)))
+         (appendp      (eq synonyms-append-result-flag (and (wholenump num-arg) (/= 16 num-arg))))
+         (search-text  (synonyms-default-regexp)))
+    (setq synonyms-search-text  search-text) ; Save it.
+    (when (string= "" search-text) (error "No text to look up"))
+    (unless (member search-text synonyms-history) (push search-text synonyms-history))
+    ;; Change `.' to `[^,]' in `search-text', so we don't mix terms.
+    (setq search-text  (replace-regexp-in-string "\\." "[^,]" search-text nil t))
+    (synonyms-lookup search-text appendp morep)))
+
+;;;###autoload
+(defun synonyms-match-more ()
+  "Same as using `synonyms' with `synonyms-match-more-flag' = t."
+  (interactive)
+  (let ((synonyms-match-more-flag  t))
+    (synonyms)))
+
+;;;###autoload
+(defun synonyms-match-more-no-read (arg)
+  "Same as using `synonyms' with `synonyms-match-more-flag' = t."
+  (interactive "P")
+  (let ((synonyms-match-more-flag  t))
+    (synonyms-no-read arg)))
+
+;;;###autoload
+(defun synonyms-append-result ()
+  "Same as using `synonyms' with `synonyms-append-result-flag' = t."
+  (interactive)
+  (let ((synonyms-append-result-flag  t))
+    (synonyms)))
+
+;;;###autoload
+(defun synonyms-append-result-no-read (arg)
+  "Same as using `synonyms' with `synonyms-append-result-flag' = t."
+  (interactive "P")
+  (let ((synonyms-append-result-flag  t))
+    (synonyms-no-read arg)))
+
+;;;###autoload
+(defun synonyms-match-more+append-result ()
+  "Like `synonyms-match-more-flag' = `synonyms-append-result-flag' = t."
+  (interactive)
+  (let ((synonyms-match-more-flag     t)
+        (synonyms-append-result-flag  t))
+    (synonyms)))
+
+;;;###autoload
+(defun synonyms-match-more+append-result-no-read (arg)
+  "Like `synonyms-match-more-flag' = `synonyms-append-result-flag' = t."
+  (interactive "P")
+  (let ((synonyms-match-more-flag     t)
+        (synonyms-append-result-flag  t))
+    (synonyms-no-read arg)))
+
+;;;###autoload
+(defun synonyms-mouse (event arg)
+  "Show synonyms that match a regular expression (e.g. a word or phrase).
+The regexp to match is the synonym or region clicked with mouse-2.  If
+the region is active, but a synonym elsewhere is clicked, that synonym
+is used, not the selected text.
+
+You can either click a listed synonym, to see its synonyms, or select
+one or more words and click the selection, to see matching synonyms.
+To quickly select a series of words: double-click mouse-1 to select
+the first word, then click mouse-3 to extend the selection to the last
+word.
+
+Selection is useful when you want to see synonyms of a similar term.
+For example, instead of clicking the listed synonym `bleeding heart', you
+might select `heart' and click that.
+
+The prefix argument acts the same as for command `synonyms'.
+
+If you click a history link with mouse-2, previously retrieved search
+results are revisited."
+  (interactive "e\nP")
+  (set-buffer (window-buffer (posn-window (event-end event))))
+  (let ((beg     (region-beginning))
+        (end     (region-end))
+        (active  mark-active))
+    (goto-char (posn-point (event-end event)))
+    (cond ((get-text-property (point) 'back-link) (synonyms-history-backward nil))
+          ((get-text-property (point) 'forward-link) (synonyms-history-forward nil))
+          (t (if (and active (> (point) beg) (< (point) end))
+                 (goto-char end)
+               (deactivate-mark))       ; User did not click inside region, so deactivate it.
+             (synonyms-no-read arg)))))
+
+;;;###autoload
+(defun synonyms-mouse-match-more (event arg)
+  "Same as `synonyms-mouse' with `synonyms-match-more-flag' = t."
+  (interactive "e\nP")
+  (let ((synonyms-match-more-flag  t))
+    (synonyms-mouse event arg)))
+
+;;;###autoload
+(defun synonyms-mouse-append-result (event arg)
+  "Same as `synonyms-mouse' with `synonyms-append-result-flag' = t."
+  (interactive "e\nP")
+  (let ((synonyms-append-result-flag  t))
+    (synonyms-mouse event arg)))
+
+;;;###autoload
+(defun synonyms-mouse-match-more+append-result (event arg)
+  "Like `synonyms-match-more-flag' = `synonyms-append-result-flag' = t."
+  (interactive "e\nP")
+  (let ((synonyms-match-more-flag     t)
+        (synonyms-append-result-flag  t))
+    (synonyms-mouse event arg)))
+
+(defun synonyms-default-regexp ()
+  "Return the default regexp for `synonym' and `synonyms-mouse'.
+If the region is active in `transient-mark-mode', use its text.
+Else, if this is *Synonyms* buffer, use the synonym under the cursor.
+Else use the word nearest the cursor.
+
+An active region has no effect except in `transient-mark-mode'."
+  (if (and mark-active transient-mark-mode) ; Use region text, if active.
+      (buffer-substring-no-properties (point) (mark))
+    (if (eq major-mode 'synonyms-mode)  ; Use mouse-face text, if in synonyms-mode.
+        (let (beg end)
+          (when (and (not (eobp)) (get-text-property (point) 'mouse-face))
+            (setq end  (point)
+                  beg  (1+ (point))))
+          (when (and (not (bobp)) (get-text-property (1- (point)) 'mouse-face))
+            (setq end  (1- (point))
+                  beg  (point)))
+          (if (null beg)
+              (synonyms-nearest-word)   ; Punt - no mouse-face, for some reason.
+            (setq beg  (previous-single-property-change beg 'mouse-face)
+                  end  (or (next-single-property-change end 'mouse-face) (point-max)))
+            (replace-regexp-in-string   ; Replace newlines with spaces, except at the
+             "\\(^ \\| $\\)" ""         ; beginning and end.
+             (replace-regexp-in-string "[\n]" " " (buffer-substring-no-properties beg end) nil t)
+             nil t)))
+      (synonyms-nearest-word))))
+
+(defun synonyms-nearest-word ()
+  "Word nearest the cursor."
+  (let ((word  (if (fboundp 'word-nearest-point)
+                   (word-nearest-point) ; In `thingatpt+.el'.
+                 (word-at-point))))     ; In `thingatpt.el'.
+    (set-text-properties 0 (length word) nil word) ; Remove all text properties.
+    word))
+
+(defun synonyms-lookup (search-text appendp morep)
+  "Search the thesaurus for SEARCH-TEXT.
+APPEND-P non-nil means to append search result to previous results.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  (save-selected-window
+    (with-temp-message
+        (format "Looking up %s synonyms for \"%s\"%s..." (if morep "(max)" "")
+                (replace-regexp-in-string (regexp-quote "[^,]") "." search-text nil t)
+                (if appendp " (appending)" ""))
+      (let ((temp-buf  (generate-new-buffer " *Temp*")))
+        (unwind-protect
+             (progn
+               (set-buffer temp-buf)
+               (buffer-disable-undo)    ; Make sure (should already be, because of *Temp* name).
+               (erase-buffer)
+               (let ((entry-p  (synonyms-search-entries search-text temp-buf morep)))
+                 ;; For `morep' search, we don't stop even if we find an entry.
+                 (unless (if morep
+                             (or (synonyms-search-synonyms search-text temp-buf t) entry-p)
+                           (or entry-p (synonyms-search-synonyms search-text temp-buf nil)))
+                   (pop synonyms-history) ; Remove it from search history, so we don't try again.
+                   (error "No synonyms found for `%s'" search-text))
+                 (let ((results-buf  (get-buffer-create "*Synonyms*")))
+                   (synonyms-format-synonyms search-text morep)
+                   (synonyms-show-synonyms temp-buf results-buf appendp)
+                   (message nil))))
+          (kill-buffer temp-buf))))))
+
+(defun synonyms-search-entries (search-text buf morep)
+  "Search thesaurus entries (headings) for SEARCH-TEXT.
+Put result in buffer BUF.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  (call-process "grep" nil buf nil "-i" (synonyms-hack-backslashes-if-cygwin
+                                         (if morep
+                                             (format "^\\w*%s\\w*," search-text)
+                                           (format "^%s," search-text)))
+                (expand-file-name synonyms-file))
+  (not (zerop (count-lines (point-min) (point-max)))))
+
+(defun synonyms-search-synonyms (search-text buf morep)
+  "Search thesaurus body for SEARCH-TEXT.
+SEARCH-TEXT is a regexp that can match any part of a thesaurus term.
+Put result in buffer BUF.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  (call-process "grep" nil buf nil "-i" (synonyms-hack-backslashes-if-cygwin
+                                         (if morep
+                                             (format ",\\w*%s\\w*\\(,\\|$\\)" search-text)
+                                           (format ",%s\\(,\\|$\\)" search-text)))
+                (expand-file-name synonyms-file))
+  (not (zerop (count-lines (point-min) (point-max)))))
+
+(defun synonyms-hack-backslashes-if-cygwin (string)
+  "Double each backslash in STRING, unless it contains SPC characters.
+More precisely, if `synonyms-use-cygwin-flag' is non-nil and this is
+Emacs 20 or there are no spaces in STRING, then double any backslashes
+in STRING.
+
+This is an ugly hack made necessary because of bugs in Emacs C code."
+  (when (and synonyms-use-cygwin-flag
+             (or (= emacs-major-version 20) (not (string-match " " string))))
+    (setq string  (replace-regexp-in-string "[\\]" "\\\\" string nil t)))  
+  string)
+
+(defun synonyms-format-synonyms (search-text morep)
+  "Format synonyms that match SEARCH-TEXT.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  (goto-char (point-min))
+  (let ((entries-count  (count-lines (point-min) (point-max))))
+    (if (= entries-count 1)
+        (synonyms-format-entry search-text t morep)
+      (synonyms-format-entries search-text entries-count morep))
+    (synonyms-format-finish search-text morep)))
+
+(defun synonyms-format-entry (search-text single-p morep)
+  "Format a single thesaurus entry that matches SEARCH-TEXT.
+SINGLE-P non-nil means there is only one entry."
+  (beginning-of-line)
+  (let ((beg      (point))
+        (orig     (if morep             ; Use saved search text.
+                      (format "\\w*\\(%s\\)\\w*" synonyms-search-text)
+                    (format "\\(%s\\)" synonyms-search-text)))
+        (entry-p  nil)
+        term end)
+    (when single-p (insert "Synonyms for "))
+    (setq term  (point))
+    (when (looking-at orig) (setq entry-p t))
+    (unless (search-forward "," nil t) (error "Bad thesaurus file - no commas"))
+    (setq end  (match-beginning 0))
+    (replace-match ":\n\n" nil t)
+    (cond (single-p
+           (add-text-properties beg term '(face synonyms-heading))
+           (add-text-properties term end (if entry-p
+                                             '(face synonyms-search-text
+                                               mouse-face synonyms-mouse-face)
+                                           '(face synonyms-heading)))
+           (add-text-properties end (+ 2 end) '(face synonyms-heading)))
+          (t
+           (add-text-properties beg (1+ end) '(face synonyms-heading))
+           (save-excursion
+             (forward-line -2)
+             (save-restriction
+               (narrow-to-region (point) (save-excursion (end-of-line) (backward-char) (point)))
+               (unless (search-forward ". " nil t)
+                 (error "Badly formatted numeric entry - no period"))
+               (add-text-properties (point) (point-max) '(mouse-face synonyms-mouse-face))
+               (when (looking-at orig)
+                 (add-text-properties (match-beginning 1) (match-end 1)
+                                      '(face synonyms-search-text)))))))
+    (forward-line)))
+
+(defun synonyms-format-entries (search-text entries-count morep)
+  "Format thesaurus entries that have synonyms matching SEARCH TEXT.
+ENTRIES-COUNT is the number of entries.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  (let ((countdown  entries-count)
+        (beg        (point))
+        (part1      "Synonyms for ")
+        (part2      ":\n"))
+    (insert part1 synonyms-search-text part2)
+    (add-text-properties beg (setq beg  (+ beg (length part1))) '(face synonyms-heading))
+    (add-text-properties beg (setq beg  (+ beg (length synonyms-search-text)))
+                         '(face synonyms-search-text mouse-face synonyms-mouse-face))
+    (add-text-properties beg (+ beg (length part2)) '(face synonyms-heading))
+    (while (> countdown 0)
+      (setq countdown  (1- countdown))
+      (insert (format "\n\%s. " (- entries-count countdown)))
+      (synonyms-format-entry search-text nil morep))))
+
+(defun synonyms-format-finish (search-text morep)
+  "Finish formatting synonyms matching SEARCH-TEXT.
+MORE-P non-nil means additional thesaurus entries can be matched."
+  ;; Put a space after each comma.
+  (goto-char (point-min))
+  (forward-line)                        ; First line might have [^,] in it.
+  (while (search-forward "," nil t) (replace-match ", " nil t))
+  (goto-char (point-min))
+  (let ((case-fold-search       t)
+        (new-search-text        (if morep
+                                    (format "\\(^\\|, \\)\\w*\\(%s\\)\\w*\\($\\|,\\)" search-text)
+                                  (format "\\(^\\|, \\)\\(%s\\)\\($\\|,\\)" search-text)))
+        (no-numbered-headers-p  (not (re-search-forward "^[0-9]+[.]" nil t))))
+    (goto-char (point-min))
+    (forward-line)
+    (while (re-search-forward new-search-text nil t)
+      (add-text-properties (match-beginning 2) (match-end 2) '(face synonyms-search-text))
+      (goto-char (match-end 2)))
+    ;; Do `synonyms-mode' here too, so hyphen will be a word char.
+    ;; IS THERE A WAY TO DO A LET to change the syntax of hyphen, instead of entering mode?
+    (synonyms-mode)
+    (save-excursion
+      (goto-char (point-min))
+      (forward-line)
+      (while (re-search-forward "\\(^\\|, \\)\\(\\(\\w\\|[\\t ]\\)+\\)\\($\\|,\\)" nil t)
+        (add-text-properties (match-beginning 2) (match-end 2) '(mouse-face synonyms-mouse-face))
+        (goto-char (match-end 2)))
+      (fill-region (point-min) (point-max)))
+    (synonyms-add-history-links)))
+
+(defun synonyms-add-history-links ()
+  "Add Back and Forward chronological navigation links"
+  (save-excursion
+    (unless (re-search-backward "Synonyms for") (error "No \"Synonyms for\" text"))
+    (end-of-line)
+    (insert (make-string (- fill-column 16 (point)) ?\ ) "[")
+    (let ((beg      (point))
+          (Back     "Back")
+          (spacer   "]  [")
+          (Forward  "Forward"))
+      (insert Back)
+      (add-text-properties beg (point)
+                           '(face synonyms-link mouse-face synonyms-mouse-face back-link t
+                             help-echo "mouse-2, RET: Go backward in synonyms search history"))
+      (insert spacer Forward)
+      (add-text-properties (+ beg (length Back) (length spacer)) (point)
+                           '(face synonyms-link mouse-face synonyms-mouse-face forward-link t
+                             help-echo "mouse-2, RET: Go forward in synonyms search history"))
+      (insert "]"))))
+
+(defun synonyms-show-synonyms (temp-buf results-buf appendp)
+  "Display search results from buffer TEMP-BUF in buffer RESULTS-BUF.
+If APPEND-P is non-nil and RESULTS-BUF is not empty, then insert a
+separator line between previous search results and the current results."
+  (set-buffer results-buf)
+  (setq buffer-read-only  nil)
+  (unless (= (point-min) (point-max))
+    (if (not appendp)
+        (erase-buffer)
+      (goto-char (point-max))
+      (let ((beg  (point)))
+        (insert "\n" (make-string (1- (window-width)) ?_) "\n\n\n")
+        (add-text-properties beg (point) '(face synonyms-heading)))))
+  (let ((start-result  (point)))
+    (insert-buffer temp-buf)
+    (select-window (display-buffer results-buf))
+    (goto-char start-result)
+    (forward-line 2)                    ; Put cursor on first synonym.
+    (when (looking-at "^[0-9]. ") (goto-char (match-end 0)))
+    (recenter 2)
+    (synonyms-mode)
+    (setq buffer-read-only  t)))
+
+;;;###autoload
+(defun synonyms-history-backward (arg)
+  "Run `synonyms' on a previous argument, moving backward in the history.
+A prefix argument has the same meaning as for command `synonyms'."
+  (interactive "P")
+  (unless (cdr synonyms-history) (error "Cannot move backward in history"))
+  (push (pop synonyms-history) synonyms-history-forward) ; Put current on forward list.
+  (let* ((num-arg  (prefix-numeric-value arg))
+         (morep    (eq synonyms-match-more-flag (atom arg)))
+         (appendp  (eq synonyms-append-result-flag (and (wholenump num-arg) (/= 16 num-arg)))))
+    
+    ;; Visit last.  If *Synonyms* has appended search results, go to the previous one, from (point).
+    (if (not (get-buffer "*Synonyms*"))
+        (synonyms-action (car synonyms-history))
+      (let ((divider  (with-current-buffer "*Synonyms*" (re-search-backward "^___" nil t))))
+        (if (not divider)
+            (synonyms-action (car synonyms-history))
+          (set-buffer "*Synonyms*")
+          (goto-char divider)
+          (unless (re-search-backward "^Synonyms for \\([^:]+\\):" nil t)
+            (error "Cannot find previous synonyms page"))
+          (goto-char (match-beginning 1))
+          (recenter 0)
+          (message "%s" (buffer-substring (match-beginning 1) (match-end 1))))))))
+
+;;;###autoload
+(defun synonyms-history-forward (arg)
+  "Run `synonyms' on a previous argument, moving forward in the history.
+A prefix argument has the same meaning as for command `synonyms'."
+  (interactive "P")
+  (unless synonyms-history-forward (error "Cannot move forward in history"))
+  (push (pop synonyms-history-forward) synonyms-history) ; Put current on backward list.
+  (let* ((num-arg  (prefix-numeric-value arg))
+         (morep    (eq synonyms-match-more-flag (atom arg)))
+         (appendp  (eq synonyms-append-result-flag (and (wholenump num-arg) (/= 16 num-arg)))))
+
+    ;; Visit current.  If *Synonyms* has appended search results, go to the next one, from (point).
+    (if (not (get-buffer "*Synonyms*"))
+        (synonyms-action (car synonyms-history))
+      (let ((divider  (with-current-buffer "*Synonyms*" (re-search-forward "^___" nil t))))
+        (if (not divider)
+            (synonyms-action (car synonyms-history))
+          (set-buffer "*Synonyms*")
+          (goto-char divider)
+          (unless (re-search-forward "^Synonyms for \\([^:]+\\):" nil t)
+            (error "Cannot find next synonyms page"))
+          (goto-char (match-beginning 1))
+          (recenter 0)
+          (message "%s" (buffer-substring (match-beginning 1) (match-end 1))))))))
+
+;;;###autoload
+(defalias 'dictionary-definition 'synonyms-definition)
+;;;###autoload
+(defun synonyms-definition (search-text alternate-p)
+  "Look up the definition of a word or phrase using online dictionaries.
+The dictionary used is `synonyms-dictionary-url'.
+With prefix arg, look up the definition in the alternate dictionary,
+`synonyms-dictionary-alternate-url'."
+  (interactive (list (completing-read "Look up definition of word or phrase (regexp): "
+                                      synonyms-obarray nil nil nil 'synonyms-history
+                                      (synonyms-default-regexp))
+                     current-prefix-arg))
+  (synonyms-ensure-synonyms-read-from-cache) ; Fill `synonyms-obarray', for use in completion.
+  (browse-url (concat  (if alternate-p synonyms-dictionary-alternate-url synonyms-dictionary-url)
+                       search-text)))
+
+;;;###autoload
+(defun synonyms-definition-no-read (alternate-p)
+  "Look up the definition of a word or phrase using online dictionaries.
+The dictionary used is `synonyms-dictionary-url'.
+With prefix arg, look up the definition in the alternate dictionary,
+`synonyms-dictionary-alternate-url'."
+  (interactive "P")
+  (synonyms-definition (synonyms-default-regexp) alternate-p))
+
+;;;###autoload
+(defun synonyms-definition-mouse (event alternate-p)
+  "Look up the definition of a word or phrase using online dictionaries.
+The dictionary used is `synonyms-dictionary-url'.
+With prefix arg, look up the definition in the alternate dictionary,
+`synonyms-dictionary-alternate-url'."
+  (interactive "e\nP")
+  (set-buffer (window-buffer (posn-window (event-end event))))
+  (let ((beg     (region-beginning))
+        (end     (region-end))
+        (active  mark-active))
+    (goto-char (posn-point (event-end event)))
+    (cond ((get-text-property (point) 'back-link) (synonyms-history-backward nil))
+          ((get-text-property (point) 'forward-link) (synonyms-history-forward nil))
+          (t (if (and active (> (point) beg) (< (point) end))
+                 (goto-char end)
+               (deactivate-mark))       ; User did not click inside region, so deactivate it.
+             (synonyms-definition (synonyms-default-regexp) alternate-p)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'synonyms)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; synonyms.el ends here
diff --git a/auto-install/vline.el b/auto-install/vline.el
new file mode 100644
index 0000000..5cbc860
--- /dev/null
+++ b/auto-install/vline.el
@@ -0,0 +1,379 @@
+;;; vline.el --- show vertical line (column highlighting) mode.
+
+;; Copyright (C) 2002, 2008, 2009, 2010 by Taiki SUGAWARA 
+
+;; Author: Taiki SUGAWARA 
+;; Keywords: faces, editing, emulating
+;; Version: 1.10
+;; Time-stamp: <2010-02-02 19:37:18 UTC taiki>
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/vline.el
+;; URL: http://bitbucket.org/buzztaiki/elisp/src/tip/vline.el
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Usage
+;; put followings your .emacs
+;;   (require 'vline)
+;;
+;; if you display a vertical line, type M-x vline-mode. `vline-mode' doesn't
+;; effect other buffers, because it is a buffer local minor mode. if you hide
+;; a vertical line, type M-x vline-mode again.
+;;
+;; if you display a vertical line in all buffers, type M-x vline-global-mode.
+;;
+;; `vline-style' provides a display style of vertical line. see
+;; `vline-style' docstring.
+;;
+;; if you don't want to visual line highlighting (ex. for performance
+;; issue), please to set `vline-visual' to nil.
+;;
+;; if you don't want to use timer (ex. you want to highlight column
+;; during moving cursors), please to set `vline-use-timer' to nil.
+
+;;; Changes
+;; 2010-02-02 taiki
+;; improve performance.
+
+;; 2009-08-26 taiki
+;; support org-mode, outline-mode
+
+;; 2009-08-18 taiki
+;; add autoload cookies.
+
+;; 2009-08-18 taiki
+;; fix last line highlighting probrem.
+
+;; 2009-08-18 taiki
+;; support visual line highlighting.
+;; - Added face vline-visual.
+;; - Added defcustom vline-visual-face.
+;; - Added defcustom vline-visual.
+;;
+;; 2009-08-17 taiki
+;; fix continuas line problem.
+;; - Don't display vline when cursor into fringe
+;; - Don't expand eol more than window width.
+;;
+;; 2008-10-22 taiki
+;; fix coding-system problem.
+;; - Added vline-multiwidth-space-list
+;; - Use ucs code-point for japanese fullwidth space.
+;; 
+;; 2008-01-22 taiki
+;; applied patch from Lennart Borgman
+;; - Added :group 'vline
+;; - Added defcustom vline-current-window-only
+;; - Added header items to simplify for users
+
+;;; TODO:
+;; - track window-scroll-functions, window-size-change-functions.
+;; - consider other minor modes (using {after,before}-string overlay).
+;; - don't use {post,after}-command-hook for performance??
+
+;;; Code:
+
+(defvar vline-overlay-table-size 200)
+(defvar vline-overlay-table (make-vector vline-overlay-table-size nil))
+(defvar vline-line-char ?|)
+(defvar vline-multiwidth-space-list
+  (list
+   ?\t
+   (decode-char 'ucs #x3000)		; japanese fullwidth space
+   ))
+(defvar vline-timer nil)
+
+(defcustom vline-style 'face
+  "This variable holds vertical line display style.
+Available values are followings:
+`face'	    : use face.
+`compose'   : use composit char.
+`mixed'	    : use face and composit char."
+  :type '(radio
+	  (const face)
+	  (const compose)
+	  (const mixed))
+  :group 'vline)
+
+
+(defface vline
+  '((t (:background "light steel blue")))
+  "A default face for vertical line highlighting."
+  :group 'vline)
+
+(defface vline-visual
+  '((t (:background "gray90")))
+  "A default face for vertical line highlighting in visual lines."
+  :group 'vline)
+
+(defcustom vline-face 'vline
+  "A face for vertical line highlighting."
+  :type 'face
+  :group 'vline)
+
+(defcustom vline-visual-face 'vline-visual
+  "A face for vertical line highlighting in visual lines."
+  :type 'face
+  :group 'vline)
+
+(defcustom vline-current-window-only nil
+  "If non-nil then highlight column in current window only.
+If the buffer is shown in several windows then highlight column only
+in the currently selected window."
+  :type 'boolean
+  :group 'vline)
+
+(defcustom vline-visual t
+  "If non-nil then highlight column in visual lines.
+If you specified `force' then use force visual line highlighting even
+if `truncate-lines' is non-nil."
+  :type '(radio
+	  (const nil)
+	  (const t)
+	  (const force))
+  :group 'vline)
+
+(defcustom vline-use-timer t
+  "If non-nil then vline use idle timer instead
+of (post|after)-command-hook."
+  :type 'boolean
+  :group 'vline)
+
+(defcustom vline-idle-time 0.02
+  "Idle time for highlighting column."
+  :type 'number
+  :group 'vline)
+
+;;;###autoload
+(define-minor-mode vline-mode
+  "Display vertical line mode."
+  :global nil
+  :lighter " VL"
+  :group 'vline
+  (if vline-mode
+      (progn
+	(add-hook 'pre-command-hook 'vline-pre-command-hook nil t)
+	(if vline-use-timer
+	    (vline-set-timer)
+	  (add-hook 'post-command-hook 'vline-post-command-hook nil t)))
+    (vline-cancel-timer)
+    (vline-clear)
+    (remove-hook 'pre-command-hook 'vline-pre-command-hook t)
+    (remove-hook 'post-command-hook 'vline-post-command-hook t)))
+
+;;;###autoload
+(define-global-minor-mode vline-global-mode
+  vline-mode
+  (lambda ()
+    (unless (minibufferp)
+      (vline-mode 1)))
+  :group 'vline)
+
+(defun vline-pre-command-hook ()
+  (when (and vline-mode (not (minibufferp)))
+    (vline-clear)))
+
+(defun vline-post-command-hook ()
+  (when (and vline-mode (not (minibufferp)))
+    (vline-show)))
+
+(defun vline-set-timer ()
+  (setq vline-timer
+	(run-with-idle-timer
+	 vline-idle-time t 'vline-timer-callback)))
+
+(defun vline-cancel-timer ()
+  (when (timerp vline-timer)
+    (cancel-timer vline-timer)))
+
+(defun vline-timer-callback ()
+  (when (and vline-mode (not (minibufferp)))
+    (vline-show)))
+
+(defun vline-clear ()
+  (mapcar (lambda (ovr)
+	    (and ovr (delete-overlay ovr)))
+	  vline-overlay-table))
+
+(defsubst vline-into-fringe-p ()
+  (eq (nth 1 (posn-at-point)) 'right-fringe))
+
+(defsubst vline-visual-p ()
+  (or (eq vline-visual 'force)
+      (and (not truncate-lines)
+	   vline-visual)))
+  
+(defsubst vline-current-column ()
+  (if (or (not (vline-visual-p))
+	  ;; margin for full-width char
+	  (< (1+ (current-column)) (window-width)))
+      (current-column)
+    ;; hmm.. posn-at-point is not consider tab width.
+    (- (current-column)
+       (save-excursion
+	 (vertical-motion 0)
+	 (current-column)))))
+
+(defsubst vline-move-to-column (col &optional bol-p)
+  (if (or (not (vline-visual-p))
+	  ;; margin for full-width char
+	  (< (1+ (current-column)) (window-width)))
+      (move-to-column col)
+    (unless bol-p
+      (vertical-motion 0))
+    (let ((bol-col (current-column)))
+      (- (move-to-column (+ bol-col col))
+	 bol-col))))
+
+(defsubst vline-invisible-p (pos)
+  (let ((inv (get-char-property pos 'invisible)))
+    (and inv
+	 (or (eq buffer-invisibility-spec t)
+	     (memq inv buffer-invisibility-spec)
+	     (assq inv buffer-invisibility-spec)))))
+
+(defsubst vline-forward (n)
+  (unless (memq n '(-1 0 1))
+    (error "n(%s) must be 0 or 1" n))
+  (if (not (vline-visual-p))
+      (progn
+	(forward-line n)
+	;; take care of org-mode, outline-mode
+	(when (and (not (bobp))
+		   (vline-invisible-p (1- (point))))
+	  (goto-char (1- (point))))
+	(when (vline-invisible-p (point))
+	  (if (< n 0)
+	      (while (and (not (bobp)) (vline-invisible-p (point)))
+		(goto-char (previous-char-property-change (point))))
+	    (while (and (not (bobp)) (vline-invisible-p (point)))
+	      (goto-char (next-char-property-change (point))))
+	    (forward-line 1))))
+    (vertical-motion n)))
+
+(defun vline-face (visual-p)
+  (if visual-p
+      vline-visual-face
+    vline-face))
+
+(defun vline-show (&optional point)
+  (vline-clear)
+  (save-window-excursion
+    (save-excursion
+      (if point
+	  (goto-char point)
+	(setq point (point)))
+      (let* ((column (vline-current-column))
+	     (lcolumn (current-column))
+	     (i 0)
+	     (compose-p (memq vline-style '(compose mixed)))
+	     (face-p (memq vline-style '(face mixed)))
+	     (line-char (if compose-p vline-line-char ? ))
+	     (line-str (make-string 1 line-char))
+	     (visual-line-str line-str)
+	     (in-fringe-p (vline-into-fringe-p)))
+	(when face-p
+	  (setq line-str (propertize line-str 'face (vline-face nil)))
+	  (setq visual-line-str (propertize visual-line-str 'face (vline-face t))))
+	(goto-char (window-end nil t))
+	(vline-forward 0)
+	(while (and (not in-fringe-p)
+		    (< i (window-height))
+		    (< i (length vline-overlay-table))
+		    (not (bobp)))
+	  (let ((cur-column (vline-move-to-column column t))
+		(cur-lcolumn (current-column)))
+	    ;; non-cursor line only (workaround of eol probrem.
+	    (unless (= (point) point)
+	      ;; if column over the cursor's column (when tab or wide char is appered.
+	      (when (> cur-column column)
+		(let ((lcol (current-column)))
+		  (backward-char)
+		  (setq cur-column (- cur-column (- lcol (current-column))))))
+	      (let* ((ovr (aref vline-overlay-table i))
+		     (visual-p (or (< lcolumn (current-column))
+				   (> lcolumn (+ (current-column)
+						 (- column cur-column)))))
+		     ;; consider a newline, tab and wide char.
+		     (str (concat (make-string (- column cur-column) ? )
+				  (if visual-p visual-line-str line-str)))
+		     (char (char-after)))
+		;; create overlay if not found.
+		(unless ovr
+		  (setq ovr (make-overlay 0 0))
+		  (overlay-put ovr 'rear-nonsticky t)
+		  (aset vline-overlay-table i ovr))
+
+		;; initialize overlay.
+		(overlay-put ovr 'face nil)
+		(overlay-put ovr 'before-string nil)
+		(overlay-put ovr 'after-string nil)
+		(overlay-put ovr 'invisible nil)
+		(overlay-put ovr 'window
+			     (if vline-current-window-only
+				 (selected-window)
+			       nil))
+
+		(cond
+		 ;; multiwidth space
+		 ((memq char vline-multiwidth-space-list)
+		  (setq str
+			(concat str
+				(make-string (- (save-excursion (forward-char)
+								(current-column))
+						(current-column)
+						(string-width str))
+					     ? )))
+		  (move-overlay ovr (point) (1+ (point)))
+		  (overlay-put ovr 'invisible t)
+		  (overlay-put ovr 'after-string str))
+		 ;; eol
+		 ((eolp)
+		  (move-overlay ovr (point) (point))
+		  (overlay-put ovr 'after-string str)
+		  ;; don't expand eol more than window width
+		  (when (and (not truncate-lines)
+			     (>= (1+ column) (window-width))
+			     (>= column (vline-current-column))
+			     (not (vline-into-fringe-p)))
+		    (delete-overlay ovr)))
+		 (t
+		  (cond
+		   (compose-p
+		    (let (str)
+		      (when char
+			(setq str (compose-chars
+				   char
+				   (cond ((= (char-width char) 1)
+					  '(tc . tc))
+					 ((= cur-column column)
+					  '(tc . tr))
+					 (t
+					  '(tc . tl)))
+				   line-char))
+			(when face-p
+			  (setq str (propertize str 'face (vline-face visual-p))))
+			(move-overlay ovr (point) (1+ (point)))
+			(overlay-put ovr 'invisible t)
+			(overlay-put ovr 'after-string str))))
+		   (face-p
+		    (move-overlay ovr (point) (1+ (point)))
+		    (overlay-put ovr 'face (vline-face visual-p))))))))
+	    (setq i (1+ i))
+	    (vline-forward -1)))))))
+
+(provide 'vline)
+
+;;; vline.el ends here
diff --git a/auto-install/xquery-mode.el b/auto-install/xquery-mode.el
new file mode 100644
index 0000000..edec052
--- /dev/null
+++ b/auto-install/xquery-mode.el
@@ -0,0 +1,231 @@
+;;; xquery-mode.el --- A simple mode for editing xquery programs
+;; Time-stamp: <2005-03-26 18:05:39 sacharya>
+
+;;; Copyright (C) 2005 Suraj Acharya
+
+;; Author: Suraj Acharya 
+
+;; This file is not part of GNU Emacs.
+
+;; xquery-mode.el is free software; you can redistribute it
+;; and/or modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2, or
+;; (at your option) any later version.:
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;; 
+
+(require 'nxml-mode)
+
+;;; Code:
+(define-generic-mode 'xquery-mode
+  '(("(:" . ":)") (""))
+  '("xquery" "version" "encoding" "at" "module" "namespace" "child" "descendant" "parent" "attribute" "self" "descendant-or-self" "ancestor" "following-sibling" "preceding-sibling" "following" "preceding" "ancestor-or-self" "declare" "function" "option" "ordering" "ordered" "unordered" "default" "order" "external" "or" "and" "div" "idiv" "mod" "in"  "construction" "satisfies" "return" "then" "else" "boundary-space" "base-uri" "preserve" "strip" "copy-namespaces" "no-preserve" "inherit" "no-inherit" "to" "where" "collation" "intersect" "union" "except" "as" "case" "instance" "of" "castable" "item" "element" "schema-element" "schema-attribute" "processing-instruction" "comment" "text" "empty" "import" "schema" "is" "eq" "ne" "gt" "ge" "lt" "le" "some" "every" "for" "let" "cast" "treat" "validate" "document-node" "document" "node" "if" "typeswitch" "by" "stable" "ascending" "descending" "greatest" "least" "variable") ;keywords
+  '(("\\(\\$\\w+\\)" 1 font-lock-variable-name-face) ;; \\(\\s_\\|\\w\\)
+    ("\\(\\w*:?\\w+\\)\\s *(" 1 font-lock-function-name-face)
+    ("\\(<\\)\\(/?\\)\\(\\w*\\)\\(:?\\)\\(\\w+\\).*?\\(/?\\)\\(>\\)" 
+     (1 'nxml-tag-delimiter-face) 
+     (2 'nxml-tag-slash-face)
+     (3 'nxml-element-prefix-face) 
+     (4 'nxml-element-colon-face)
+     (5 'nxml-element-local-name-face)
+     (6 'nxml-tag-slash-face)
+     (7 'nxml-tag-delimiter-face) 
+     )
+    ("\\(\\w*\\)\\(:?\\)\\(\\w+\\)=\\([\"']\\)\\(.*?\\)\\([\"']\\)" 
+     (1 'nxml-attribute-prefix-face) 
+     (2 'nxml-attribute-colon-face)
+     (3 'nxml-attribute-local-name-face) 
+     (4 'nxml-attribute-value-delimiter-face)
+     (5 'nxml-attribute-value-face)
+     (6 'nxml-attribute-value-delimiter-face))
+    ("\\(/\\)\\(\\w*\\)\\(:?\\)\\(\\w+\\)" 
+     (1 font-lock-constant-face)
+     (2 font-lock-constant-face) 
+     (3 font-lock-constant-face)
+     (4 font-lock-constant-face)
+     )
+    ("as\\s +\\(\\w*:?\\w+\\)" 
+     (1 font-lock-type-face)
+     )
+    ) ;font-lock-list
+  '(".xq\\'") ;auto-mode-list
+  '(xquery-set-indent-function xquery-set-up-syntax-table)         ;function list
+  "A Major mode for editing xquery."
+  )
+
+
+
+(defun xquery-set-indent-function ()
+  "Set the indent function for xquery mode."
+  (setq nxml-prolog-end (point-min))
+  (setq nxml-scan-end (copy-marker (point-min) nil))
+  (set (make-local-variable 'indent-line-function) 'xquery-indent-line)
+  (make-local-variable 'forward-sexp-function)
+  (setq forward-sexp-function 'xquery-forward-sexp)
+  (local-set-key "/" 'nxml-electric-slash)
+  )
+
+(defun xquery-forward-sexp (&optional arg)
+  "Xquery forward s-expresssion.
+This function is not very smart, it tries to use
+`nxml-forward-balanced-item' if it sees '>' or '<' characters in
+the direction you are going, and uses the regular `forward-sexp'
+otherwise. "
+  (if (> arg 0)
+      (progn                                 
+        (if (looking-at "[ \t]*<")
+            (nxml-forward-balanced-item arg)
+          (let ((forward-sexp-function nil)) (forward-sexp arg))))
+    (if (looking-back ">[ \t]*")
+        (nxml-forward-balanced-item arg)
+                (let ((forward-sexp-function nil)) (forward-sexp arg))))
+  )
+
+
+(defun xquery-set-up-syntax-table ()
+  "Allow the hypen character to be recognized as part of a xquery symbol."
+  (modify-syntax-entry ?- "w" (syntax-table))
+  (modify-syntax-entry ?/ "." (syntax-table))
+  ;; set-up the syntax table correctly for parentheis type characters
+  (modify-syntax-entry ?\{ "(}" (syntax-table))
+  (modify-syntax-entry ?\} "){" (syntax-table))
+  (modify-syntax-entry ?\[ "(]" (syntax-table))
+  (modify-syntax-entry ?\] ")]" (syntax-table))
+  (modify-syntax-entry ?\< "(>1" (syntax-table))
+  (modify-syntax-entry ?\> ")<4" (syntax-table))
+  ;; xquery comments are like (: :)
+  (modify-syntax-entry ?\( "()1" (syntax-table)) 
+  (modify-syntax-entry ?\) ")(4" (syntax-table))
+;;   (modify-syntax-entry ?\: ".23" (syntax-table))
+  )
+
+
+
+(defun xquery-indent-line ()
+  "Indent current line as xquery code."
+  (interactive)
+   (let ((savep (> (current-column) (current-indentation)))
+	 (indent (condition-case err (max (xquery-calculate-indentation) 0)
+		   (error (message "%S" err)))))
+     (if savep
+	 (save-excursion (indent-line-to indent))
+       (indent-line-to indent))))
+
+(defvar xquery-start-block-regexp "[ \t]*\\((\|{\\|for\\|let\\|where\\|return\\|if\\|else\\|typeswitch\\|declare[ \t]+function\\|.*[({]$\\)"
+  "A regular expression which indicates that a xquery block is starting.")
+
+(defvar xquery-flwr-block-regexp "[ \t]*\\(for\\|let\\|where\\|return\\|order\\|stable\\s *order\\)")
+
+(defvar xquery-indent-size 2
+  "The size of each indent level.")
+
+(defvar xquery-indent-debug nil)
+
+(defun xquery-toggle-debug-indent ()
+  "Toggle the debug flag used in `xquery-calculate-indentation'. "
+  (interactive)
+  (setq xquery-indent-debug (not xquery-indent-debug))
+  (message (concat "xquery-indent-debug is " (if xquery-indent-debug "en" "dis") "abled"))
+  )
+
+(defun xquery-calculate-indentation ()
+   "Return the column to which the current line should be indented."
+  (beginning-of-line)
+  (if (bobp)
+      0 ; First line is always non-indented
+    (skip-chars-forward " \t")
+    (cond
+     ;; do nothing if this is a comment
+     ((eq (get-text-property (point) 'face) 'font-lock-comment-face) (current-indentation))
+
+     ((looking-at "\\( is valid.
+  # Authors can use an empty index to indicate where a generated index should
+  # appear.
+  db.index =
+    
+    ## An index to a book or part of a book
+    [
+      s:pattern [
+        name = "Root must have version"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "/db:index"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "@version"
+            "The root element must have a version attribute."
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element index {
+      db.index.attlist,
+      db.index.info,
+      db.all.blocks*,
+      (db.indexdiv* | db.indexentry* | db.segmentedlist)
+    }
+}
+div {
+  db.setindex.status.attribute = db.status.attribute
+  db.setindex.role.attribute = attribute role { text }
+  db.setindex.attlist =
+    db.setindex.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.label.attribute?
+    & db.setindex.status.attribute?
+    & db.index.type.attribute?
+  db.setindex.info = db._info
+  db.setindex =
+    
+    ## An index to a set of books
+    [
+      s:pattern [
+        name = "Root must have version"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "/db:setindex"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "@version"
+            "The root element must have a version attribute."
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element setindex {
+      db.setindex.attlist,
+      db.setindex.info,
+      db.all.blocks*,
+      (db.indexdiv* | db.indexentry*)
+    }
+}
+div {
+  db.indexdiv.status.attribute = db.status.attribute
+  db.indexdiv.role.attribute = attribute role { text }
+  db.indexdiv.attlist =
+    db.indexdiv.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.label.attribute?
+    & db.indexdiv.status.attribute?
+  db.indexdiv.info = db._info.title.req
+  db.indexdiv =
+    
+    ## A division in an index
+    element indexdiv {
+      db.indexdiv.attlist,
+      db.indexdiv.info,
+      db.all.blocks*,
+      (db.indexentry+ | db.segmentedlist)
+    }
+}
+div {
+  db.indexentry.role.attribute = attribute role { text }
+  db.indexentry.attlist =
+    db.indexentry.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.indexentry =
+    
+    ## An entry in an index
+    element indexentry {
+      db.indexentry.attlist,
+      db.primaryie,
+      (db.seeie | db.seealsoie)*,
+      (db.secondaryie, (db.seeie | db.seealsoie | db.tertiaryie)*)*
+    }
+}
+div {
+  db.primaryie.role.attribute = attribute role { text }
+  db.primaryie.attlist =
+    db.primaryie.role.attribute?
+    & db.common.attributes
+    & db.linkends.attribute?
+  db.primaryie =
+    
+    ## A primary term in an index entry, not in the text
+    element primaryie { db.primaryie.attlist, db.all.inlines* }
+}
+div {
+  db.secondaryie.role.attribute = attribute role { text }
+  db.secondaryie.attlist =
+    db.secondaryie.role.attribute?
+    & db.common.attributes
+    & db.linkends.attribute?
+  db.secondaryie =
+    
+    ## A secondary term in an index entry, rather than in the text
+    element secondaryie { db.secondaryie.attlist, db.all.inlines* }
+}
+div {
+  db.tertiaryie.role.attribute = attribute role { text }
+  db.tertiaryie.attlist =
+    db.tertiaryie.role.attribute?
+    & db.common.attributes
+    & db.linkends.attribute?
+  db.tertiaryie =
+    
+    ## A tertiary term in an index entry, rather than in the text
+    element tertiaryie { db.tertiaryie.attlist, db.all.inlines* }
+}
+div {
+  db.seeie.role.attribute = attribute role { text }
+  db.seeie.attlist =
+    db.seeie.role.attribute?
+    & db.common.attributes
+    & db.linkend.attribute?
+  db.seeie =
+    
+    ## A See
+    ## entry in an index, rather than in the text
+    element seeie { db.seeie.attlist, db.all.inlines* }
+}
+div {
+  db.seealsoie.role.attribute = attribute role { text }
+  db.seealsoie.attlist =
+    db.seealsoie.role.attribute?
+    & db.common.attributes
+    & db.linkends.attribute?
+  db.seealsoie =
+    
+    ## A See also
+    ##  entry in an index, rather than in the text
+    element seealsoie { db.seealsoie.attlist, db.all.inlines* }
+}
+db.toc.pagenum.attribute =
+  
+  ## Indicates the page on which this element occurs in some version of the printed document
+  attribute pagenum { text }
+div {
+  db.toc.role.attribute = attribute role { text }
+  db.toc.attlist =
+    db.toc.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.toc.info = db._info.title.only
+  db.toc =
+    
+    ## A table of contents
+    [
+      s:pattern [
+        name = "Root must have version"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "/db:toc"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "@version"
+            "The root element must have a version attribute."
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element toc {
+      db.toc.attlist,
+      db.toc.info,
+      db.all.blocks*,
+      (db.tocdiv | db.tocentry)*
+    }
+}
+div {
+  db.tocdiv.role.attribute = attribute role { text }
+  db.tocdiv.pagenum.attribute = db.toc.pagenum.attribute
+  db.tocdiv.attlist =
+    db.tocdiv.role.attribute?
+    & db.common.attributes
+    & db.tocdiv.pagenum.attribute?
+    & db.linkend.attribute?
+  db.tocdiv.info = db._info
+  db.tocdiv =
+    
+    ## A division in a table of contents
+    element tocdiv {
+      db.tocdiv.attlist,
+      db.tocdiv.info,
+      db.all.blocks*,
+      (db.tocdiv | db.tocentry)+
+    }
+}
+div {
+  db.tocentry.role.attribute = attribute role { text }
+  db.tocentry.pagenum.attribute = db.toc.pagenum.attribute
+  db.tocentry.attlist =
+    db.tocentry.role.attribute?
+    & db.common.attributes
+    & db.tocentry.pagenum.attribute?
+    & db.linkend.attribute?
+  db.tocentry =
+    
+    ## A component title in a table of contents
+    element tocentry { db.tocentry.attlist, db.all.inlines* }
+}
+db.task.info = db._info.title.req
+div {
+  db.task.role.attribute = attribute role { text }
+  db.task.attlist =
+    db.task.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.task =
+    
+    ## A task to be completed
+    element task {
+      db.task.attlist,
+      db.task.info,
+      db.tasksummary?,
+      db.taskprerequisites?,
+      db.procedure,
+      db.example*,
+      db.taskrelated?
+    }
+}
+div {
+  db.tasksummary.role.attribute = attribute role { text }
+  db.tasksummary.attlist =
+    db.tasksummary.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.tasksummary.info = db._info.title.only
+  db.tasksummary =
+    
+    ## A summary of a task
+    element tasksummary {
+      db.tasksummary.attlist, db.tasksummary.info, db.all.blocks+
+    }
+}
+div {
+  db.taskprerequisites.role.attribute = attribute role { text }
+  db.taskprerequisites.attlist =
+    db.taskprerequisites.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.taskprerequisites.info = db._info.title.only
+  db.taskprerequisites =
+    
+    ## The prerequisites for a task
+    element taskprerequisites {
+      db.taskprerequisites.attlist,
+      db.taskprerequisites.info,
+      db.all.blocks+
+    }
+}
+div {
+  db.taskrelated.role.attribute = attribute role { text }
+  db.taskrelated.attlist =
+    db.taskrelated.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.taskrelated.info = db._info.title.only
+  db.taskrelated =
+    
+    ## Information related to a task
+    element taskrelated {
+      db.taskrelated.attlist, db.taskrelated.info, db.all.blocks+
+    }
+}
+db.area.units.enumeration =
+  
+  ## Coordinates expressed as a pair of CALS graphic coordinates.
+  "calspair"
+  | 
+    ## Coordinates expressed as a line and column.
+    "linecolumn"
+  | 
+    ## Coordinates expressed as a pair of lines and columns.
+    "linecolumnpair"
+  | 
+    ## Coordinates expressed as a line range.
+    "linerange"
+db.area.units-enum.attribute =
+  
+  ## Identifies the units used in the coords attribute The default units vary according to the type of callout specified: calspair
+  ##  for graphics and linecolumn
+  ##  for line-oriented elements.
+  attribute units { db.area.units.enumeration }?
+db.area.units-other.attributes =
+  
+  ## Indicates that non-standard units are used for this area
+  ## . In this case otherunits
+  ##  must be specified.
+  attribute units {
+    
+    ## Coordinates expressed in some non-standard units.
+    "other"
+  }?,
+  
+  ## Identifies the units used in the coords
+  ##  attribute when the units
+  ##  attribute is other
+  ## . This attribute is forbidden otherwise.
+  attribute otherunits { xsd:NMTOKEN }
+db.area.units.attribute =
+  db.area.units-enum.attribute | db.area.units-other.attributes
+div {
+  db.calloutlist.role.attribute = attribute role { text }
+  db.calloutlist.attlist =
+    db.calloutlist.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.calloutlist.info = db._info.title.only
+  db.calloutlist =
+    
+    ## A list of callout
+    ## s
+    element calloutlist {
+      db.calloutlist.attlist,
+      db.calloutlist.info,
+      db.all.blocks*,
+      db.callout+
+    }
+}
+div {
+  db.callout.role.attribute = attribute role { text }
+  db.callout.arearefs.attribute =
+    
+    ## Identifies the areas described by this callout.
+    attribute arearefs { xsd:IDREFS }
+  db.callout.attlist =
+    db.callout.role.attribute?
+    & db.common.attributes
+    & db.callout.arearefs.attribute
+  db.callout =
+    
+    ## A called out
+    ##  description of a marked Area
+    element callout { db.callout.attlist, db.all.blocks+ }
+}
+div {
+  db.programlistingco.role.attribute = attribute role { text }
+  db.programlistingco.attlist =
+    db.programlistingco.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.programlistingco.info = db._info.title.forbidden
+  db.programlistingco =
+    
+    ## A program listing with associated areas used in callouts
+    element programlistingco {
+      db.programlistingco.attlist,
+      db.programlistingco.info,
+      db.areaspec,
+      db.programlisting,
+      db.calloutlist*
+    }
+}
+div {
+  db.areaspec.role.attribute = attribute role { text }
+  db.areaspec.attlist =
+    db.areaspec.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.area.units.attribute
+  db.areaspec =
+    
+    ## A collection of regions in a graphic or code example
+    element areaspec { db.areaspec.attlist, (db.area | db.areaset)+ }
+}
+div {
+  db.area.role.attribute = attribute role { text }
+  db.area.linkends.attribute =
+    
+    ## Point to the callout
+    ## s which refer to this area. (This provides bidirectional linking which may be useful in online presentation.)
+    attribute linkends { xsd:IDREFS }
+  db.area.label.attribute =
+    
+    ## Specifies an identifying number or string that may be used in presentation. The area label might be drawn on top of the figure, for example, at the position indicated by the coords attribute.
+    attribute label { text }
+  db.area.coords.attribute =
+    
+    ## Provides the coordinates of the area. The coordinates must be interpreted using the units
+    ##  specified.
+    attribute coords { text }
+  db.area.attlist =
+    db.area.role.attribute?
+    & db.common.idreq.attributes
+    & db.area.units.attribute
+    & (db.area.linkends.attribute | db.href.attributes)?
+    & db.area.label.attribute?
+    & db.area.coords.attribute
+  db.area =
+    
+    ## A region defined for a Callout in a graphic or code example
+    element area { db.area.attlist, db.alt? }
+}
+div {
+  # The only difference is that xml:id is optional
+  db.area.inareaset.attlist =
+    db.area.role.attribute?
+    & db.common.attributes
+    & db.area.units.attribute
+    & (db.area.linkends.attribute | db.href.attributes)?
+    & db.area.label.attribute?
+    & db.area.coords.attribute
+  db.area.inareaset =
+    
+    ## A region defined for a Callout in a graphic or code example
+    element area { db.area.inareaset.attlist, db.alt? }
+}
+div {
+  db.areaset.role.attribute = attribute role { text }
+  db.areaset.linkends.attribute = db.linkends.attribute
+  db.areaset.label.attribute = db.label.attribute
+  db.areaset.attlist =
+    db.areaset.role.attribute?
+    & db.common.idreq.attributes
+    & db.area.units.attribute
+    & (db.areaset.linkends.attribute | db.href.attributes)?
+    & db.areaset.label.attribute?
+  db.areaset =
+    
+    ## A set of related areas in a graphic or code example
+    element areaset { db.areaset.attlist, db.area.inareaset+ }
+}
+div {
+  db.screenco.role.attribute = attribute role { text }
+  db.screenco.attlist =
+    db.screenco.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.screenco.info = db._info.title.forbidden
+  db.screenco =
+    
+    ## A screen with associated areas used in callouts
+    element screenco {
+      db.screenco.attlist,
+      db.screenco.info,
+      db.areaspec,
+      db.screen,
+      db.calloutlist*
+    }
+}
+div {
+  db.imageobjectco.role.attribute = attribute role { text }
+  db.imageobjectco.attlist =
+    db.imageobjectco.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.imageobjectco.info = db._info.title.forbidden
+  db.imageobjectco =
+    
+    ## A wrapper for an image object with callouts
+    element imageobjectco {
+      db.imageobjectco.attlist,
+      db.imageobjectco.info,
+      db.areaspec,
+      db.imageobject+,
+      db.calloutlist*
+    }
+}
+div {
+  db.co.role.attribute = attribute role { text }
+  db.co.linkends.attribute = db.linkends.attribute
+  db.co.label.attribute = db.label.attribute
+  db.co.attlist =
+    db.co.role.attribute?
+    & db.common.idreq.attributes
+    & db.co.linkends.attribute?
+    & db.co.label.attribute?
+  db.co =
+    
+    ## The location of a callout embedded in text
+    element co { db.co.attlist, empty }
+}
+div {
+  db.coref.role.attribute = attribute role { text }
+  db.coref.label.attribute = db.label.attribute
+  db.coref.attlist =
+    db.coref.role.attribute?
+    & db.common.attributes
+    & db.linkend.attribute
+    & db.coref.label.attribute?
+  db.coref =
+    
+    ## A cross reference to a co
+    element coref { db.coref.attlist, empty }
+}
+div {
+  db.productionset.role.attribute = attribute role { text }
+  db.productionset.attlist =
+    db.productionset.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.productionset.info = db._info.title.only
+  db.productionset =
+    
+    ## A set of EBNF productions
+    element productionset {
+      db.productionset.attlist,
+      db.productionset.info,
+      (db.production | db.productionrecap)+
+    }
+}
+div {
+  db.production.role.attribute = attribute role { text }
+  db.production.attlist =
+    db.production.role.attribute?
+    & db.common.idreq.attributes
+    & db.common.linking.attributes
+  db.production =
+    
+    ## A production in a set of EBNF productions
+    element production {
+      db.production.attlist, db.lhs, db.rhs, db.constraint*
+    }
+}
+div {
+  db.lhs.role.attribute = attribute role { text }
+  db.lhs.attlist =
+    db.lhs.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.lhs =
+    
+    ## The left-hand side of an EBNF production
+    element lhs { db.lhs.attlist, text }
+}
+div {
+  db.rhs.role.attribute = attribute role { text }
+  db.rhs.attlist =
+    db.rhs.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.rhs =
+    
+    ## The right-hand side of an EBNF production
+    element rhs {
+      db.rhs.attlist,
+      (text | db.nonterminal | db.lineannotation | db.sbr)*
+    }
+}
+div {
+  db.nonterminal.role.attribute = attribute role { text }
+  db.nonterminal.def.attribute =
+    
+    ## Specifies a URI that points to a production
+    ## where the nonterminal
+    ##  is defined
+    attribute def { xsd:anyURI }
+  db.nonterminal.attlist =
+    db.nonterminal.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.nonterminal.def.attribute
+  db.nonterminal =
+    
+    ## A non-terminal in an EBNF production
+    element nonterminal { db.nonterminal.attlist, text }
+}
+div {
+  db.constraint.role.attribute = attribute role { text }
+  db.constraint.attlist =
+    db.constraint.role.attribute?
+    & db.common.attributes
+    & db.common.req.linking.attributes
+  db.constraint =
+    
+    ## A constraint in an EBNF production
+    element constraint { db.constraint.attlist, empty }
+}
+div {
+  db.productionrecap.role.attribute = attribute role { text }
+  db.productionrecap.attlist =
+    db.productionrecap.role.attribute?
+    & db.common.attributes
+    & db.common.req.linking.attributes
+  db.productionrecap =
+    
+    ## A cross-reference to an EBNF production
+    element productionrecap { db.productionrecap.attlist, empty }
+}
+div {
+  db.constraintdef.role.attribute = attribute role { text }
+  db.constraintdef.attlist =
+    db.constraintdef.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.constraintdef.info = db._info.title.only
+  db.constraintdef =
+    
+    ## The definition of a constraint in an EBNF production
+    element constraintdef {
+      db.constraintdef.attlist, db.constraintdef.info, db.all.blocks+
+    }
+}
+db.char.attribute =
+  
+  ## Specifies the alignment character when align
+  ##  is set to char
+  ## .
+  attribute char { text }
+db.charoff.attribute =
+  
+  ## Specifies the percentage of the column's total width that should appear to the left of the first occurance of the character identified in char
+  ##  when align
+  ##  is set to char
+  ## .
+  attribute charoff {
+    xsd:decimal { minExclusive = "0" maxExclusive = "100" }
+  }
+db.frame.attribute =
+  
+  ## Specifies how the table is to be framed. Note that there is no way to obtain a border on only the starting edge (left, in left-to-right writing systems) of the table.
+  attribute frame {
+    
+    ## Frame all four sides of the table. In some environments with limited control over table border formatting, such as HTML, this may imply additional borders.
+    "all"
+    | 
+      ## Frame only the bottom of the table.
+      "bottom"
+    | 
+      ## Place no border on the table. In some environments with limited control over table border formatting, such as HTML, this may disable other borders as well.
+      "none"
+    | 
+      ## Frame the left and right sides of the table.
+      "sides"
+    | 
+      ## Frame the top of the table.
+      "top"
+    | 
+      ## Frame the top and bottom of the table.
+      "topbot"
+  }
+db.colsep.attribute =
+  
+  ## Specifies the presence or absence of the column separator
+  attribute colsep {
+    
+    ## No column separator rule.
+    "0"
+    | 
+      ## Provide a column separator rule on the right
+      "1"
+  }
+db.rowsep.attribute =
+  
+  ## Specifies the presence or absence of the row separator
+  attribute rowsep {
+    
+    ## No row separator rule.
+    "0"
+    | 
+      ## Provide a row separator rule below
+      "1"
+  }
+db.orient.attribute =
+  
+  ## Specifies the orientation of the table
+  attribute orient {
+    
+    ## 90 degrees counter-clockwise from the rest of the text flow.
+    "land"
+    | 
+      ## The same orientation as the rest of the text flow.
+      "port"
+  }
+db.tabstyle.attribute =
+  
+  ## Specifies the table style
+  attribute tabstyle { text }
+db.rowheader.attribute =
+  
+  ## Indicates whether or not the entries in the first column should be considered row headers
+  attribute rowheader {
+    
+    ## Indicates that entries in the first column of the table are functionally row headers (analogous to the way that a thead provides column headers).
+    "firstcol"
+    | 
+      ## Indicates that entries in the first column have no special significance with respect to column headers.
+      "norowheader"
+  }
+db.align.attribute =
+  
+  ## Specifies the horizontal alignment of text in an entry.
+  attribute align {
+    
+    ## Centered.
+    "center"
+    | 
+      ## Aligned on a particular character.
+      "char"
+    | 
+      ## Left and right justified.
+      "justify"
+    | 
+      ## Left justified.
+      "left"
+    | 
+      ## Right justified.
+      "right"
+  }
+db.valign.attribute =
+  
+  ## Specifies the vertical alignment of text in an entry.
+  attribute valign {
+    
+    ## Aligned on the bottom of the entry.
+    "bottom"
+    | 
+      ## Aligned in the middle.
+      "middle"
+    | 
+      ## Aligned at the top of the entry.
+      "top"
+  }
+db.specify-col-by-colname.attributes =
+  
+  ## Specifies a column specification by name.
+  attribute colname { text }
+db.specify-col-by-namest.attributes =
+  
+  ## Specifies a starting column by name.
+  attribute namest { text }
+db.specify-span-by-spanspec.attributes =
+  
+  ## Specifies a span by name.
+  attribute spanname { text }
+db.specify-span-directly.attributes =
+  
+  ## Specifies a starting column by name.
+  attribute namest { text }
+  & 
+    ## Specifies an ending column by name.
+    attribute nameend { text }
+db.column-spec.attributes =
+  db.specify-col-by-colname.attributes
+  | db.specify-col-by-namest.attributes
+  | db.specify-span-by-spanspec.attributes
+  | db.specify-span-directly.attributes
+db.colname.attribute =
+  
+  ## Provides a name for a column specification.
+  attribute colname { text }
+db.spanname.attribute =
+  
+  ## Provides a name for a span specification.
+  attribute spanname { text }
+div {
+  db.tgroup.role.attribute = attribute role { text }
+  db.tgroup.tgroupstyle.attribute =
+    
+    ## Additional style information for downstream processing; typically the name of a style.
+    attribute tgroupstyle { text }
+  db.tgroup.cols.attribute =
+    
+    ## The number of columns in the table. Must be an integer greater than zero.
+    attribute cols { xsd:positiveInteger }
+  db.tgroup.attlist =
+    db.tgroup.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.char.attribute?
+    & db.charoff.attribute?
+    & db.tgroup.tgroupstyle.attribute?
+    & db.tgroup.cols.attribute
+    & db.colsep.attribute?
+    & db.rowsep.attribute?
+    & db.align.attribute?
+  db.tgroup =
+    
+    ## A wrapper for the main content of a table, or part of a table
+    element tgroup {
+      db.tgroup.attlist,
+      db.colspec*,
+      db.spanspec*,
+      db.cals.thead?,
+      db.cals.tfoot?,
+      db.cals.tbody
+    }
+}
+div {
+  db.colspec.role.attribute = attribute role { text }
+  db.colspec.colnum.attribute =
+    
+    ## The number of the column to which this specification applies. Must be greater than any preceding column number. Defaults to one more than the number of the preceding column, if there is one, or one.
+    attribute colnum { xsd:positiveInteger }
+  db.colspec.colwidth.attribute =
+    
+    ## Specifies the width of the column.
+    attribute colwidth { text }
+  db.colspec.attlist =
+    db.colspec.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.colspec.colnum.attribute?
+    & db.char.attribute?
+    & db.colsep.attribute?
+    & db.colspec.colwidth.attribute?
+    & db.charoff.attribute?
+    & db.colname.attribute?
+    & db.rowsep.attribute?
+    & db.align.attribute?
+  db.colspec =
+    
+    ## Specifications for a column in a table
+    element colspec { db.colspec.attlist, empty }
+}
+div {
+  db.spanspec.role.attribute = attribute role { text }
+  db.spanspec.namest.attribute =
+    
+    ## Specifies a starting column by name.
+    attribute namest { text }
+  db.spanspec.nameend.attribute =
+    
+    ## Specifies an ending column by name.
+    attribute nameend { text }
+  db.spanspec.attlist =
+    db.spanspec.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.spanname.attribute
+    & db.spanspec.namest.attribute
+    & db.spanspec.nameend.attribute
+    & db.char.attribute?
+    & db.colsep.attribute?
+    & db.charoff.attribute?
+    & db.rowsep.attribute?
+    & db.align.attribute?
+  db.spanspec =
+    
+    ## Formatting information for a spanned column in a table
+    element spanspec { db.spanspec.attlist, empty }
+}
+div {
+  db.cals.thead.role.attribute = attribute role { text }
+  db.cals.thead.attlist =
+    db.cals.thead.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+  db.cals.thead =
+    
+    ## A table header consisting of one or more rows
+    element thead { db.cals.thead.attlist, db.colspec*, db.row+ }
+}
+div {
+  db.cals.tfoot.role.attribute = attribute role { text }
+  db.cals.tfoot.attlist =
+    db.cals.tfoot.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+  db.cals.tfoot =
+    
+    ## A table footer consisting of one or more rows
+    element tfoot { db.cals.tfoot.attlist, db.colspec*, db.row+ }
+}
+div {
+  db.cals.tbody.role.attribute = attribute role { text }
+  db.cals.tbody.attlist =
+    db.cals.tbody.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+  db.cals.tbody =
+    
+    ## A wrapper for the rows of a table or informal table
+    element tbody { db.cals.tbody.attlist, db.row+ }
+}
+div {
+  db.row.role.attribute = attribute role { text }
+  db.row.attlist =
+    db.row.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.rowsep.attribute?
+    & db.valign.attribute?
+  db.row =
+    
+    ## A row in a table
+    element row { db.row.attlist, (db.entry | db.entrytbl)+ }
+}
+div {
+  db.entry.role.attribute = attribute role { text }
+  db.entry.morerows.attribute =
+    
+    ## Specifies the number of additional rows which this entry occupies. Defaults to zero.
+    attribute morerows { xsd:integer }
+  db.entry.rotate.attribute =
+    
+    ## Specifies the rotation of this entry. A value of 1 (true) rotates the cell 90 degrees counter-clockwise. A value of 0 (false) leaves the cell unrotated.
+    attribute rotate {
+      
+      ## Do not rotate the cell.
+      "0"
+      | 
+        ## Rotate the cell 90 degrees counter-clockwise.
+        "1"
+    }
+  db.entry.attlist =
+    db.entry.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+    & db.char.attribute?
+    & db.colsep.attribute?
+    & db.charoff.attribute?
+    & db.entry.morerows.attribute?
+    & db.column-spec.attributes?
+    & db.rowsep.attribute?
+    & db.entry.rotate.attribute?
+    & db.align.attribute?
+  db.entry =
+    
+    ## A cell in a table
+    element entry {
+      db.entry.attlist, (db.all.inlines* | db.all.blocks*)
+    }
+}
+div {
+  db.entrytbl.role.attribute = attribute role { text }
+  db.entrytbl.tgroupstyle.attribute =
+    
+    ## Additional style information for downstream processing; typically the name of a style.
+    attribute tgroupstyle { text }
+  db.entrytbl.cols.attribute =
+    
+    ## The number of columns in the entry table. Must be an integer greater than zero.
+    attribute cols { xsd:positiveInteger }
+  db.entrytbl.attlist =
+    db.entrytbl.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.char.attribute?
+    & db.charoff.attribute?
+    & db.column-spec.attributes?
+    & db.entrytbl.tgroupstyle.attribute?
+    & db.entrytbl.cols.attribute?
+    & db.colsep.attribute?
+    & db.rowsep.attribute?
+    & db.align.attribute?
+  db.entrytbl =
+    
+    ## A subtable appearing in place of an Entry in a table
+    element entrytbl {
+      db.entrytbl.attlist,
+      db.colspec*,
+      db.spanspec*,
+      db.cals.entrytbl.thead?,
+      db.cals.entrytbl.tbody
+    }
+}
+div {
+  db.cals.entrytbl.thead.role.attribute = attribute role { text }
+  db.cals.entrytbl.thead.attlist =
+    db.cals.entrytbl.thead.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+  db.cals.entrytbl.thead =
+    
+    ## A table header consisting of one or more rows
+    element thead {
+      db.cals.entrytbl.thead.attlist, db.colspec*, db.entrytbl.row+
+    }
+}
+div {
+  db.cals.entrytbl.tbody.role.attribute = attribute role { text }
+  db.cals.entrytbl.tbody.attlist =
+    db.cals.entrytbl.tbody.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.valign.attribute?
+  db.cals.entrytbl.tbody =
+    
+    ## A wrapper for the rows of a table or informal table
+    element tbody { db.cals.entrytbl.tbody.attlist, db.entrytbl.row+ }
+}
+div {
+  db.entrytbl.row.role.attribute = attribute role { text }
+  db.entrytbl.row.attlist =
+    db.entrytbl.row.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.rowsep.attribute?
+    & db.valign.attribute?
+  db.entrytbl.row =
+    
+    ## A row in a table
+    element row { db.entrytbl.row.attlist, db.entry+ }
+}
+div {
+  db.cals.table.role.attribute = attribute role { text }
+  db.cals.table.label.attribute = db.label.attribute
+  db.cals.table.attlist =
+    db.cals.table.role.attribute?
+    & db.cals.table.label.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.tabstyle.attribute?
+    & db.floatstyle.attribute?
+    & db.orient.attribute?
+    & db.colsep.attribute?
+    & db.rowsep.attribute?
+    & db.frame.attribute?
+    & db.pgwide.attribute?
+    & 
+      ## Indicates if the short or long title should be used in a List of Tables
+      attribute shortentry {
+        
+        ## Indicates that the full title should be used.
+        "0"
+        | 
+          ## Indicates that the short short title (titleabbrev) should be used.
+          "1"
+      }?
+    & 
+      ## Indicates if the table should appear in a List of Tables
+      attribute tocentry {
+        
+        ## Indicates that the table should not occur in the List of Tables.
+        "0"
+        | 
+          ## Indicates that the table should appear in the List of Tables.
+          "1"
+      }?
+    & db.rowheader.attribute?
+  db.cals.table.info = db._info.title.onlyreq
+  db.cals.table =
+    
+    ## A formal table in a document
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:example)"
+            "example must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:figure)"
+            "figure must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:equation)"
+            "equation must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:informaltable)"
+            "informaltable must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element table {
+      db.cals.table.attlist,
+      db.cals.table.info,
+      (db.alt? & db.indexing.inlines* & db.textobject*),
+      (db.mediaobject+ | db.tgroup+),
+      db.caption?
+    }
+}
+div {
+  db.cals.informaltable.role.attribute = attribute role { text }
+  db.cals.informaltable.attlist =
+    db.cals.informaltable.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.tabstyle.attribute?
+    & db.floatstyle.attribute?
+    & db.orient.attribute?
+    & db.colsep.attribute?
+    & db.rowsep.attribute?
+    & db.frame.attribute?
+    & db.pgwide.attribute?
+    & db.rowheader.attribute?
+  db.cals.informaltable.info = db._info.title.forbidden
+  db.cals.informaltable =
+    
+    ## A table without a title
+    element informaltable {
+      db.cals.informaltable.attlist,
+      db.cals.informaltable.info,
+      (db.alt? & db.indexing.inlines* & db.textobject*),
+      (db.mediaobject+ | db.tgroup+),
+      db.caption?
+    }
+}
+db.html.coreattrs =
+  
+  ## This attribute assigns a class name or set of class names to an element. Any number of elements may be assigned the same class name or names. Multiple class names must be separated by white space characters.
+  attribute class { text }?
+  & 
+    ## This attribute specifies style information for the current element.
+    attribute style { text }?
+  & 
+    ## This attribute offers advisory information about the element for which it is set.
+    attribute title { text }?
+db.html.i18n =
+  
+  ## This attribute specifies the base language of an element's attribute values and text content. The default value of this attribute is unknown.
+  attribute lang { text }?
+db.html.events =
+  
+  ## Occurs when the pointing device button is clicked over an element.
+  attribute onclick { text }?
+  & 
+    ## Occurs when the pointing device button is double clicked over an element.
+    attribute ondblclick { text }?
+  & 
+    ## Occurs when the pointing device button is pressed over an element.
+    attribute onmousedown { text }?
+  & 
+    ## Occurs when the pointing device button is released over an element.
+    attribute onmouseup { text }?
+  & 
+    ## Occurs when the pointing device is moved onto an element.
+    attribute onmouseover { text }?
+  & 
+    ## Occurs when the pointing device is moved while it is over an element.
+    attribute onmousemove { text }?
+  & 
+    ## Occurs when the pointing device is moved away from an element.
+    attribute onmouseout { text }?
+  & 
+    ## Occurs when a key is pressed and released over an element.
+    attribute onkeypress { text }?
+  & 
+    ## Occurs when a key is pressed down over an element.
+    attribute onkeydown { text }?
+  & 
+    ## Occurs when a key is released over an element.
+    attribute onkeyup { text }?
+db.html.attrs =
+  db.common.attributes
+  & db.html.coreattrs
+  & db.html.i18n
+  & db.html.events
+db.html.cellhalign =
+  
+  ## Specifies the alignment of data and the justification of text in a cell.
+  attribute align {
+    
+    ## Left-flush data/Left-justify text. This is the default value for table data.
+    "left"
+    | 
+      ## Center data/Center-justify text. This is the default value for table headers.
+      "center"
+    | 
+      ## Right-flush data/Right-justify text.
+      "right"
+    | 
+      ## Double-justify text.
+      "justify"
+    | 
+      ## Align text around a specific character. If a user agent doesn't support character alignment, behavior in the presence of this value is unspecified.
+      "char"
+  }?
+  & 
+    ## This attribute specifies a single character within a text fragment to act as an axis for alignment. The default value for this attribute is the decimal point character for the current language as set by the lang attribute (e.g., the period in English and the comma in French). User agents are not required to support this attribute.
+    attribute char { text }?
+  & 
+    ## When present, this attribute specifies the offset to the first occurrence of the alignment character on each line. If a line doesn't include the alignment character, it should be horizontally shifted to end at the alignment position. When charoff is used to set the offset of an alignment character, the direction of offset is determined by the current text direction (set by the dir attribute). In left-to-right texts (the default), offset is from the left margin. In right-to-left texts, offset is from the right margin. User agents are not required to support this attribute.
+    attribute charoff {
+      xsd:integer
+      | xsd:string { pattern = "[0-9]+%" }
+    }?
+db.html.cellvalign =
+  
+  ## Specifies the vertical position of data within a cell.
+  attribute valign {
+    
+    ## Cell data is flush with the top of the cell.
+    "top"
+    | 
+      ## Cell data is centered vertically within the cell. This is the default value.
+      "middle"
+    | 
+      ## Cell data is flush with the bottom of the cell.
+      "bottom"
+    | 
+      ## All cells in the same row as a cell whose valign attribute has this value should have their textual data positioned so that the first text line occurs on a baseline common to all cells in the row. This constraint does not apply to subsequent text lines in these cells.
+      "baseline"
+  }?
+db.html.table.attributes =
+  
+  ## Provides a summary of the table's purpose and structure for user agents rendering to non-visual media such as speech and Braille.
+  attribute summary { text }?
+  & 
+    ## Specifies the desired width of the entire table and is intended for visual user agents. When the value is a percentage value, the value is relative to the user agent's available horizontal space. In the absence of any width specification, table width is determined by the user agent.
+    attribute width {
+      xsd:integer
+      | xsd:string { pattern = "[0-9]+%" }
+    }?
+  & 
+    ## Specifies the width (in pixels only) of the frame around a table.
+    attribute border { xsd:nonNegativeInteger }?
+  & 
+    ## Specifies which sides of the frame surrounding a table will be visible.
+    attribute frame {
+      
+      ## No sides. This is the default value.
+      "void"
+      | 
+        ## The top side only.
+        "above"
+      | 
+        ## The bottom side only.
+        "below"
+      | 
+        ## The top and bottom sides only.
+        "hsides"
+      | 
+        ## The left-hand side only.
+        "lhs"
+      | 
+        ## The right-hand side only.
+        "rhs"
+      | 
+        ## The right and left sides only.
+        "vsides"
+      | 
+        ## All four sides.
+        "box"
+      | 
+        ## All four sides.
+        "border"
+    }?
+  & 
+    ## Specifies which rules will appear between cells within a table. The rendering of rules is user agent dependent.
+    attribute rules {
+      
+      ## No rules. This is the default value.
+      "none"
+      | 
+        ## Rules will appear between row groups (see thead, tfoot, and tbody) and column groups (see colgroup and col) only.
+        "groups"
+      | 
+        ## Rules will appear between rows only.
+        "rows"
+      | 
+        ## Rules will appear between columns only.
+        "cols"
+      | 
+        ## Rules will appear between all rows and columns.
+        "all"
+    }?
+  & 
+    ## Specifies how much space the user agent should leave between the left side of the table and the left-hand side of the leftmost column, the top of the table and the top side of the topmost row, and so on for the right and bottom of the table. The attribute also specifies the amount of space to leave between cells.
+    attribute cellspacing {
+      xsd:integer
+      | xsd:string { pattern = "[0-9]+%" }
+    }?
+  & 
+    ## Specifies the amount of space between the border of the cell and its contents. If the value of this attribute is a pixel length, all four margins should be this distance from the contents. If the value of the attribute is a percentage length, the top and bottom margins should be equally separated from the content based on a percentage of the available vertical space, and the left and right margins should be equally separated from the content based on a percentage of the available horizontal space.
+    attribute cellpadding {
+      xsd:integer
+      | xsd:string { pattern = "[0-9]+%" }
+    }?
+db.html.tablecell.attributes =
+  
+  ## Provides an abbreviated form of the cell's content and may be rendered by user agents when appropriate in place of the cell's content. Abbreviated names should be short since user agents may render them repeatedly. For instance, speech synthesizers may render the abbreviated headers relating to a particular cell before rendering that cell's content.
+  attribute abbr { text }?
+  & 
+    ## This attribute may be used to place a cell into conceptual categories that can be considered to form axes in an n-dimensional space. User agents may give users access to these categories (e.g., the user may query the user agent for all cells that belong to certain categories, the user agent may present a table in the form of a table of contents, etc.). Please consult an HTML reference for more details.
+    attribute axis { text }?
+  & 
+    ## Specifies the list of header cells that provide header information for the current data cell. The value of this attribute is a space-separated list of cell names; those cells must be named by setting their id attribute. Authors generally use the headers attribute to help non-visual user agents render header information about data cells (e.g., header information is spoken prior to the cell data), but the attribute may also be used in conjunction with style sheets.
+    attribute headers { text }?
+  & 
+    ## Specifies the set of data cells for which the current header cell provides header information. This attribute may be used in place of the headers attribute, particularly for simple tables.
+    attribute scope {
+      
+      ## The current cell provides header information for the rest of the row that contains it
+      "row"
+      | 
+        ## The current cell provides header information for the rest of the column that contains it.
+        "col"
+      | 
+        ## The header cell provides header information for the rest of the row group that contains it.
+        "rowgroup"
+      | 
+        ## The header cell provides header information for the rest of the column group that contains it.
+        "colgroup"
+    }?
+  & 
+    ## Specifies the number of rows spanned by the current cell. The default value of this attribute is one (1
+    ## ). The value zero (0
+    ## ) means that the cell spans all rows from the current row to the last row of the table section (thead
+    ## , tbody
+    ## , or tfoot
+    ## ) in which the cell is defined.
+    attribute rowspan { xsd:nonNegativeInteger }?
+  & 
+    ## Specifies the number of columns spanned by the current cell. The default value of this attribute is one (1
+    ## ). The value zero (0
+    ## ) means that the cell spans all columns from the current column to the last column of the column group (colgroup
+    ## ) in which the cell is defined.
+    attribute colspan { xsd:nonNegativeInteger }?
+db.html.table.info = db._info.title.forbidden
+db.html.table.model =
+  db.html.table.info?,
+  db.html.caption,
+  (db.html.col* | db.html.colgroup*),
+  db.html.thead?,
+  db.html.tfoot?,
+  (db.html.tbody+ | db.html.tr+)
+db.html.informaltable.info = db._info.title.forbidden
+db.html.informaltable.model =
+  db.html.informaltable.info?,
+  (db.html.col* | db.html.colgroup*),
+  db.html.thead?,
+  db.html.tfoot?,
+  (db.html.tbody+ | db.html.tr+)
+div {
+  db.html.table.role.attribute = attribute role { text }
+  db.html.table.label.attribute = db.label.attribute
+  db.html.table.attlist =
+    db.html.attrs
+    & db.html.table.attributes
+    & db.html.table.role.attribute?
+    & db.html.table.label.attribute?
+    & db.orient.attribute?
+    & db.pgwide.attribute?
+    & db.tabstyle.attribute?
+    & db.floatstyle.attribute?
+  db.html.table =
+    
+    ## A formal (captioned) HTML table in a document
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:example)"
+            "example must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:figure)"
+            "figure must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:equation)"
+            "equation must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:informaltable)"
+            "informaltable must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:table"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of table"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element table { db.html.table.attlist, db.html.table.model }
+}
+div {
+  db.html.informaltable.attlist =
+    db.html.attrs & db.html.table.attributes
+  db.html.informaltable =
+    
+    ## An HTML table without a title
+    element informaltable {
+      db.html.informaltable.attlist, db.html.informaltable.model
+    }
+}
+div {
+  db.html.caption.attlist = db.html.attrs
+  db.html.caption =
+    
+    ## An HTML table caption
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:example)"
+            "example must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:figure)"
+            "figure must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:table)"
+            "table must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:equation)"
+            "equation must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:sidebar)"
+            "sidebar must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:task)"
+            "task must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caption"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of caption"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element caption { db.html.caption.attlist, db.all.inlines* }
+}
+div {
+  db.html.col.attlist =
+    db.html.attrs
+    & 
+      ## This attribute, whose value must be an integer > 0, specifies the number of columns spanned
+      ##  by the col
+      ##  element; the col
+      ##  element shares its attributes with all the columns it spans. The default value for this attribute is 1 (i.e., a single column). If the span attribute is set to N > 1, the current col
+      ##  element shares its attributes with the next N-1 columns.
+      attribute span { xsd:nonNegativeInteger }?
+    & 
+      ## Specifies a default width for each column spanned by the current col
+      ##  element. It has the same meaning as the width
+      ##  attribute for the colgroup
+      ##  element and overrides it.
+      attribute width { text }?
+    & db.html.cellhalign
+    & db.html.cellvalign
+  db.html.col =
+    
+    ## Specifications for a column in an HTML table
+    element col { db.html.col.attlist, empty }
+}
+div {
+  db.html.colgroup.attlist =
+    db.html.attrs
+    & 
+      ## This attribute, which must be an integer > 0, specifies the number of columns in a column group. In the absence of a span attribute, each colgroup
+      ##  defines a column group containing one column. If the span attribute is set to N > 0, the current colgroup
+      ##  element defines a column group containing N columns. User agents must ignore this attribute if the colgroup
+      ##  element contains one or more col
+      ##  elements.
+      attribute span { xsd:nonNegativeInteger }?
+    & 
+      ## This attribute specifies a default width for each column in the current column group. In addition to the standard pixel, percentage, and relative values, this attribute allows the special form 0*
+      ##  (zero asterisk) which means that the width of the each column in the group should be the minimum width necessary to hold the column's contents. This implies that a column's entire contents must be known before its width may be correctly computed. Authors should be aware that specifying 0*
+      ##  will prevent visual user agents from rendering a table incrementally. This attribute is overridden for any column in the column group whose width is specified via a col
+      ##  element.
+      attribute width { text }?
+    & db.html.cellhalign
+    & db.html.cellvalign
+  db.html.colgroup =
+    
+    ## A group of columns in an HTML table
+    element colgroup { db.html.colgroup.attlist, db.html.col* }
+}
+div {
+  db.html.thead.attlist =
+    db.html.attrs & db.html.cellhalign & db.html.cellvalign
+  db.html.thead =
+    
+    ## A table header consisting of one or more rows in an HTML table
+    element thead { db.html.thead.attlist, db.html.tr+ }
+}
+div {
+  db.html.tfoot.attlist =
+    db.html.attrs & db.html.cellhalign & db.html.cellvalign
+  db.html.tfoot =
+    
+    ## A table footer consisting of one or more rows in an HTML table
+    element tfoot { db.html.tfoot.attlist, db.html.tr+ }
+}
+div {
+  db.html.tbody.attlist =
+    db.html.attrs & db.html.cellhalign & db.html.cellvalign
+  db.html.tbody =
+    
+    ## A wrapper for the rows of an HTML table or informal HTML table
+    element tbody { db.html.tbody.attlist, db.html.tr+ }
+}
+div {
+  db.html.tr.attlist =
+    db.html.attrs & db.html.cellhalign & db.html.cellvalign
+  db.html.tr =
+    
+    ## A row in an HTML table
+    element tr { db.html.tr.attlist, (db.html.th | db.html.td)+ }
+}
+div {
+  db.html.th.attlist =
+    db.html.attrs
+    & db.html.tablecell.attributes
+    & db.html.cellhalign
+    & db.html.cellvalign
+  db.html.th =
+    
+    ## A table header entry in an HTML table
+    element th {
+      db.html.th.attlist, (db.all.inlines* | db.all.blocks*)
+    }
+}
+div {
+  db.html.td.attlist =
+    db.html.attrs
+    & db.html.tablecell.attributes
+    & db.html.cellhalign
+    & db.html.cellvalign
+  db.html.td =
+    
+    ## A table entry in an HTML table
+    element td {
+      db.html.td.attlist, (db.all.inlines* | db.all.blocks*)
+    }
+}
+div {
+  db.msgset.role.attribute = attribute role { text }
+  db.msgset.attlist =
+    db.msgset.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgset.info = db._info.title.only
+  db.msgset =
+    
+    ## A detailed set of messages, usually error messages
+    element msgset {
+      db.msgset.attlist,
+      db.msgset.info,
+      (db.msgentry+ | db.simplemsgentry+)
+    }
+}
+div {
+  db.msgentry.role.attribute = attribute role { text }
+  db.msgentry.attlist =
+    db.msgentry.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgentry =
+    
+    ## A wrapper for an entry in a message set
+    element msgentry {
+      db.msgentry.attlist, db.msg+, db.msginfo?, db.msgexplan*
+    }
+}
+div {
+  db.simplemsgentry.role.attribute = attribute role { text }
+  db.simplemsgentry.msgaud.attribute =
+    
+    ## The audience to which the message relevant
+    attribute msgaud { text }
+  db.simplemsgentry.msgorig.attribute =
+    
+    ## The origin of the message
+    attribute msgorig { text }
+  db.simplemsgentry.msglevel.attribute =
+    
+    ## The level of importance or severity of a message
+    attribute msglevel { text }
+  db.simplemsgentry.attlist =
+    db.simplemsgentry.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.simplemsgentry.msgaud.attribute?
+    & db.simplemsgentry.msgorig.attribute?
+    & db.simplemsgentry.msglevel.attribute?
+  db.simplemsgentry =
+    
+    ## A wrapper for a simpler entry in a message set
+    element simplemsgentry {
+      db.simplemsgentry.attlist, db.msgtext, db.msgexplan+
+    }
+}
+div {
+  db.msg.role.attribute = attribute role { text }
+  db.msg.attlist =
+    db.msg.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msg.info = db._info.title.only
+  db.msg =
+    
+    ## A message in a message set
+    element msg {
+      db.msg.attlist, db.msg.info, db.msgmain, (db.msgsub | db.msgrel)*
+    }
+}
+div {
+  db.msgmain.role.attribute = attribute role { text }
+  db.msgmain.attlist =
+    db.msgmain.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgmain.info = db._info.title.only
+  db.msgmain =
+    
+    ## The primary component of a message in a message set 
+    element msgmain { db.msgmain.attlist, db.msgmain.info, db.msgtext }
+}
+div {
+  db.msgsub.role.attribute = attribute role { text }
+  db.msgsub.attlist =
+    db.msgsub.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgsub.info = db._info.title.only
+  db.msgsub =
+    
+    ## A subcomponent of a message in a message set
+    element msgsub { db.msgsub.attlist, db.msgsub.info, db.msgtext }
+}
+div {
+  db.msgrel.role.attribute = attribute role { text }
+  db.msgrel.attlist =
+    db.msgrel.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgrel.info = db._info.title.only
+  db.msgrel =
+    
+    ## A related component of a message in a message set
+    element msgrel { db.msgrel.attlist, db.msgrel.info, db.msgtext }
+}
+div {
+  db.msgtext.role.attribute = attribute role { text }
+  db.msgtext.attlist =
+    db.msgtext.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgtext =
+    
+    ## The actual text of a message component in a message set
+    element msgtext { db.msgtext.attlist, db.all.blocks+ }
+}
+div {
+  db.msginfo.role.attribute = attribute role { text }
+  db.msginfo.attlist =
+    db.msginfo.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msginfo =
+    
+    ## Information about a message in a message set
+    element msginfo {
+      db.msginfo.attlist, (db.msglevel | db.msgorig | db.msgaud)*
+    }
+}
+div {
+  db.msglevel.role.attribute = attribute role { text }
+  db.msglevel.attlist =
+    db.msglevel.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msglevel =
+    
+    ## The level of importance or severity of a message in a message set
+    element msglevel { db.msglevel.attlist, db._text }
+}
+div {
+  db.msgorig.role.attribute = attribute role { text }
+  db.msgorig.attlist =
+    db.msgorig.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgorig =
+    
+    ## The origin of a message in a message set
+    element msgorig { db.msgorig.attlist, db._text }
+}
+div {
+  db.msgaud.role.attribute = attribute role { text }
+  db.msgaud.attlist =
+    db.msgaud.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgaud =
+    
+    ## The audience to which a message in a message set is relevant
+    element msgaud { db.msgaud.attlist, db._text }
+}
+div {
+  db.msgexplan.role.attribute = attribute role { text }
+  db.msgexplan.attlist =
+    db.msgexplan.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.msgexplan.info = db._info.title.only
+  db.msgexplan =
+    
+    ## Explanatory material relating to a message in a message set
+    element msgexplan {
+      db.msgexplan.attlist, db.msgexplan.info, db.all.blocks+
+    }
+}
+div {
+  db.qandaset.role.attribute = attribute role { text }
+  db.qandaset.defaultlabel.enumeration =
+    
+    ## No labels
+    "none"
+    | 
+      ## Numeric labels
+      "number"
+    | 
+      ## "Q:" and "A:" labels
+      "qanda"
+  db.qandaset.defaultlabel.attribute =
+    
+    ## Specifies the default labelling
+    attribute defaultlabel { db.qandaset.defaultlabel.enumeration }
+  db.qandaset.attlist =
+    db.qandaset.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.qandaset.defaultlabel.attribute?
+  db.qandaset.info = db._info.title.only
+  db.qandaset =
+    
+    ## A question-and-answer set
+    element qandaset {
+      db.qandaset.attlist,
+      db.qandaset.info,
+      db.all.blocks*,
+      (db.qandadiv+ | db.qandaentry+)
+    }
+}
+div {
+  db.qandadiv.role.attribute = attribute role { text }
+  db.qandadiv.attlist =
+    db.qandadiv.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.qandadiv.info = db._info.title.only
+  db.qandadiv =
+    
+    ## A titled division in a QandASet
+    element qandadiv {
+      db.qandadiv.attlist,
+      db.qandadiv.info,
+      db.all.blocks*,
+      (db.qandadiv+ | db.qandaentry+)
+    }
+}
+div {
+  db.qandaentry.role.attribute = attribute role { text }
+  db.qandaentry.attlist =
+    db.qandaentry.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.qandaentry.info = db._info.title.only
+  db.qandaentry =
+    
+    ## A question/answer set within a QandASet
+    element qandaentry {
+      db.qandaentry.attlist, db.qandaentry.info, db.question, db.answer*
+    }
+}
+div {
+  db.question.role.attribute = attribute role { text }
+  db.question.attlist =
+    db.question.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.question =
+    
+    ## A question in a QandASet
+    element question { db.question.attlist, db.label?, db.all.blocks+ }
+}
+div {
+  db.answer.role.attribute = attribute role { text }
+  db.answer.attlist =
+    db.answer.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.answer =
+    
+    ## An answer to a question posed in a QandASet
+    element answer { db.answer.attlist, db.label?, db.all.blocks+ }
+}
+div {
+  db.label.role.attribute = attribute role { text }
+  db.label.attlist =
+    db.label.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.label =
+    
+    ## A label on a Question or Answer
+    element label { db.label.attlist, db._text }
+}
+db.math.inlines = db.inlineequation
+db.equation.content = (db.mediaobject+ | db.mathphrase+) | db._any.mml+
+db.inlineequation.content =
+  (db.inlinemediaobject+ | db.mathphrase+) | db._any.mml+
+div {
+  db.equation.role.attribute = attribute role { text }
+  db.equation.label.attribute = db.label.attribute
+  db.equation.attlist =
+    db.equation.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.equation.label.attribute?
+    & db.pgwide.attribute?
+    & db.floatstyle.attribute?
+  db.equation.info = db._info.title.only
+  db.equation =
+    
+    ## A displayed mathematical equation
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:example)"
+            "example must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:figure)"
+            "figure must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:table)"
+            "table must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:equation)"
+            "equation must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:equation"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of equation"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element equation {
+      db.equation.attlist,
+      db.equation.info,
+      db.alt?,
+      db.equation.content,
+      db.caption?
+    }
+}
+div {
+  db.informalequation.role.attribute = attribute role { text }
+  db.informalequation.attlist =
+    db.informalequation.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.informalequation.info = db._info.title.forbidden
+  db.informalequation =
+    
+    ## A displayed mathematical equation without a title
+    element informalequation {
+      db.informalequation.attlist,
+      db.informalequation.info,
+      db.alt?,
+      db.equation.content,
+      db.caption?
+    }
+}
+div {
+  db.inlineequation.role.attribute = attribute role { text }
+  db.inlineequation.attlist =
+    db.inlineequation.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.inlineequation =
+    
+    ## A mathematical equation or expression occurring inline
+    element inlineequation {
+      db.inlineequation.attlist, db.alt?, db.inlineequation.content
+    }
+}
+div {
+  db.mathphrase.role.attribute = attribute role { text }
+  db.mathphrase.attlist =
+    db.mathphrase.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.mathphrase =
+    
+    ## A mathematical phrase, an expression that can be represented with ordinary text and a small amount of markup
+    element mathphrase {
+      db.mathphrase.attlist,
+      (db._text | db.ubiq.inlines | db._emphasis)*
+    }
+}
+div {
+  db.imagedata.mathml.role.attribute = attribute role { text }
+  db.imagedata.mathml.attlist =
+    db.imagedata.mathml.role.attribute?
+    & db.common.attributes
+    & 
+      ## Specifies that the format of the data is MathML
+      attribute format {
+        
+        ## Specifies MathML.
+        "mathml"
+      }?
+    & db.imagedata.align.attribute?
+    & db.imagedata.valign.attribute?
+    & db.imagedata.width.attribute?
+    & db.imagedata.contentwidth.attribute?
+    & db.imagedata.scalefit.attribute?
+    & db.imagedata.scale.attribute?
+    & db.imagedata.depth.attribute?
+    & db.imagedata.contentdepth.attribute?
+  db.imagedata.mathml.info = db._info.title.forbidden
+  db.imagedata.mathml =
+    
+    ## A MathML expression in a media object
+    element imagedata {
+      db.imagedata.mathml.attlist,
+      db.imagedata.mathml.info,
+      db._any.mml+
+    }
+}
+div {
+  db._any.mml =
+    
+    ## Any element from the MathML namespace
+    element mml:* { (db._any.attribute | text | db._any)* }
+}
+div {
+  db.imagedata.svg.role.attribute = attribute role { text }
+  db.imagedata.svg.attlist =
+    db.imagedata.svg.role.attribute?
+    & db.common.attributes
+    & 
+      ## Specifies that the format of the data is SVG
+      attribute format {
+        
+        ## Specifies SVG.
+        "svg"
+      }?
+    & db.imagedata.align.attribute?
+    & db.imagedata.valign.attribute?
+    & db.imagedata.width.attribute?
+    & db.imagedata.contentwidth.attribute?
+    & db.imagedata.scalefit.attribute?
+    & db.imagedata.scale.attribute?
+    & db.imagedata.depth.attribute?
+    & db.imagedata.contentdepth.attribute?
+  db.imagedata.svg.info = db._info.title.forbidden
+  db.imagedata.svg =
+    
+    ## An SVG drawing in a media object
+    element imagedata {
+      db.imagedata.svg.attlist, db.imagedata.svg.info, db._any.svg+
+    }
+}
+div {
+  db._any.svg =
+    
+    ## Any element from the SVG namespace
+    element svg:* { (db._any.attribute | text | db._any)* }
+}
+db.markup.inlines =
+  db.tag
+  | db.markup
+  | db.token
+  | db.symbol
+  | db.literal
+  | db.code
+  | db.constant
+  | db.email
+  | db.uri
+div {
+  db.markup.role.attribute = attribute role { text }
+  db.markup.attlist =
+    db.markup.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.markup =
+    
+    ## A string of formatting markup in text that is to be represented literally
+    element markup { db.markup.attlist, db._text }
+}
+div {
+  db.tag.role.attribute = attribute role { text }
+  db.tag.class.enumeration =
+    
+    ## An attribute
+    "attribute"
+    | 
+      ## An attribute value
+      "attvalue"
+    | 
+      ## An element
+      "element"
+    | 
+      ## An empty element tag
+      "emptytag"
+    | 
+      ## An end tag
+      "endtag"
+    | 
+      ## A general entity
+      "genentity"
+    | 
+      ## The local name part of a qualified name
+      "localname"
+    | 
+      ## A namespace
+      "namespace"
+    | 
+      ## A numeric character reference
+      "numcharref"
+    | 
+      ## A parameter entity
+      "paramentity"
+    | 
+      ## A processing instruction
+      "pi"
+    | 
+      ## The prefix part of a qualified name
+      "prefix"
+    | 
+      ## An SGML comment
+      "comment"
+    | 
+      ## A start tag
+      "starttag"
+    | 
+      ## An XML processing instruction
+      "xmlpi"
+  db.tag.class.attribute =
+    
+    ## Identifies the nature of the tag content
+    attribute class { db.tag.class.enumeration }
+  db.tag.namespace.attribute =
+    
+    ## Identifies the namespace of the tag content
+    attribute namespace { xsd:anyURI }
+  db.tag.attlist =
+    db.tag.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.tag.class.attribute?
+    & db.tag.namespace.attribute?
+  db.tag =
+    
+    ## A component of XML (or SGML) markup
+    element tag { db.tag.attlist, db._text }
+}
+div {
+  db.symbol.class.attribute =
+    
+    ## Identifies the class of symbol
+    attribute class {
+      
+      ## The value is a limit of some kind
+      "limit"
+    }
+  db.symbol.role.attribute = attribute role { text }
+  db.symbol.attlist =
+    db.symbol.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.symbol.class.attribute?
+  db.symbol =
+    
+    ## A name that is replaced by a value before processing
+    element symbol { db.symbol.attlist, db._text }
+}
+div {
+  db.token.role.attribute = attribute role { text }
+  db.token.attlist =
+    db.token.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.token =
+    
+    ## A unit of information
+    element token { db.token.attlist, db._text }
+}
+div {
+  db.literal.role.attribute = attribute role { text }
+  db.literal.attlist =
+    db.literal.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.literal =
+    
+    ## Inline text that is some literal value
+    element literal { db.literal.attlist, db._text }
+}
+div {
+  code.language.attribute =
+    
+    ## Identifies the (computer) language of the code fragment
+    attribute language { text }
+  db.code.role.attribute = attribute role { text }
+  db.code.attlist =
+    db.code.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & code.language.attribute?
+  db.code =
+    
+    ## An inline code fragment
+    element code {
+      db.code.attlist, (db.programming.inlines | db._text)*
+    }
+}
+div {
+  db.constant.class.attribute =
+    
+    ## Identifies the class of constant
+    attribute class {
+      
+      ## The value is a limit of some kind
+      "limit"
+    }
+  db.constant.role.attribute = attribute role { text }
+  db.constant.attlist =
+    db.constant.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.constant.class.attribute?
+  db.constant =
+    
+    ## A programming or system constant
+    element constant { db.constant.attlist, db._text }
+}
+div {
+  db.productname.role.attribute = attribute role { text }
+  db.productname.class.enumeration =
+    
+    ## A name with a copyright
+    "copyright"
+    | 
+      ## A name with a registered copyright
+      "registered"
+    | 
+      ## A name of a service
+      "service"
+    | 
+      ## A name which is trademarked
+      "trade"
+  db.productname.class.attribute =
+    
+    ## Specifies the class of product name
+    attribute class { db.productname.class.enumeration }
+  db.productname.attlist =
+    db.productname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.productname.class.attribute?
+  db.productname =
+    
+    ## The formal name of a product
+    element productname { db.productname.attlist, db._text }
+}
+div {
+  db.productnumber.role.attribute = attribute role { text }
+  db.productnumber.attlist =
+    db.productnumber.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.productnumber =
+    
+    ## A number assigned to a product
+    element productnumber { db.productnumber.attlist, db._text }
+}
+div {
+  db.database.class.enumeration =
+    
+    ## An alternate or secondary key
+    "altkey"
+    | 
+      ## A constraint
+      "constraint"
+    | 
+      ## A data type
+      "datatype"
+    | 
+      ## A field
+      "field"
+    | 
+      ## A foreign key
+      "foreignkey"
+    | 
+      ## A group
+      "group"
+    | 
+      ## An index
+      "index"
+    | 
+      ## The first or primary key
+      "key1"
+    | 
+      ## An alternate or secondary key
+      "key2"
+    | 
+      ## A name
+      "name"
+    | 
+      ## The primary key
+      "primarykey"
+    | 
+      ## A (stored) procedure
+      "procedure"
+    | 
+      ## A record
+      "record"
+    | 
+      ## A rule
+      "rule"
+    | 
+      ## The secondary key
+      "secondarykey"
+    | 
+      ## A table
+      "table"
+    | 
+      ## A user
+      "user"
+    | 
+      ## A view
+      "view"
+  db.database.class.attribute =
+    
+    ## Identifies the class of database artifact
+    attribute class { db.database.class.enumeration }
+  db.database.role.attribute = attribute role { text }
+  db.database.attlist =
+    db.database.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.database.class.attribute?
+  db.database =
+    
+    ## The name of a database, or part of a database
+    element database { db.database.attlist, db._text }
+}
+div {
+  db.application.class.enumeration =
+    
+    ## A hardware application
+    "hardware"
+    | 
+      ## A software application
+      "software"
+  db.application.class.attribute =
+    
+    ## Identifies the class of application
+    attribute class { db.application.class.enumeration }
+  db.application.role.attribute = attribute role { text }
+  db.application.attlist =
+    db.application.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.application.class.attribute?
+  db.application =
+    
+    ## The name of a software program
+    element application { db.application.attlist, db._text }
+}
+div {
+  db.hardware.role.attribute = attribute role { text }
+  db.hardware.attlist =
+    db.hardware.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.hardware =
+    
+    ## A physical part of a computer system
+    element hardware { db.hardware.attlist, db._text }
+}
+db.gui.inlines =
+  db.guiicon
+  | db.guibutton
+  | db.guimenuitem
+  | db.guimenu
+  | db.guisubmenu
+  | db.guilabel
+  | db.menuchoice
+  | db.mousebutton
+div {
+  db.guibutton.role.attribute = attribute role { text }
+  db.guibutton.attlist =
+    db.guibutton.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guibutton =
+    
+    ## The text on a button in a GUI
+    element guibutton {
+      db.guibutton.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.guiicon.role.attribute = attribute role { text }
+  db.guiicon.attlist =
+    db.guiicon.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guiicon =
+    
+    ## Graphic and/or text appearing as a icon in a GUI
+    element guiicon {
+      db.guiicon.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.guilabel.role.attribute = attribute role { text }
+  db.guilabel.attlist =
+    db.guilabel.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guilabel =
+    
+    ## The text of a label in a GUI
+    element guilabel {
+      db.guilabel.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.guimenu.role.attribute = attribute role { text }
+  db.guimenu.attlist =
+    db.guimenu.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guimenu =
+    
+    ## The name of a menu in a GUI
+    element guimenu {
+      db.guimenu.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.guimenuitem.role.attribute = attribute role { text }
+  db.guimenuitem.attlist =
+    db.guimenuitem.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guimenuitem =
+    
+    ## The name of a terminal menu item in a GUI
+    element guimenuitem {
+      db.guimenuitem.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.guisubmenu.role.attribute = attribute role { text }
+  db.guisubmenu.attlist =
+    db.guisubmenu.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.guisubmenu =
+    
+    ## The name of a submenu in a GUI
+    element guisubmenu {
+      db.guisubmenu.attlist,
+      (db._text | db.accel | db.superscript | db.subscript)*
+    }
+}
+div {
+  db.menuchoice.role.attribute = attribute role { text }
+  db.menuchoice.attlist =
+    db.menuchoice.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.menuchoice =
+    
+    ## A selection or series of selections from a menu
+    element menuchoice {
+      db.menuchoice.attlist,
+      db.shortcut?,
+      (db.guibutton
+       | db.guiicon
+       | db.guilabel
+       | db.guimenu
+       | db.guimenuitem
+       | db.guisubmenu)+
+    }
+}
+div {
+  db.mousebutton.role.attribute = attribute role { text }
+  db.mousebutton.attlist =
+    db.mousebutton.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.mousebutton =
+    
+    ## The conventional name of a mouse button
+    element mousebutton { db.mousebutton.attlist, db._text }
+}
+db.keyboard.inlines =
+  db.keycombo
+  | db.keycap
+  | db.keycode
+  | db.keysym
+  | db.shortcut
+  | db.accel
+div {
+  db.keycap.function.enumeration =
+    
+    ## The "Alt" key
+    "alt"
+    | 
+      ## The "Backspace" key
+      "backspace"
+    | 
+      ## The "Command" key
+      "command"
+    | 
+      ## The "Control" key
+      "control"
+    | 
+      ## The "Delete" key
+      "delete"
+    | 
+      ## The down arrow
+      "down"
+    | 
+      ## The "End" key
+      "end"
+    | 
+      ## The "Enter" or "Return" key
+      "enter"
+    | 
+      ## The "Escape" key
+      "escape"
+    | 
+      ## The "Home" key
+      "home"
+    | 
+      ## The "Insert" key
+      "insert"
+    | 
+      ## The left arrow
+      "left"
+    | 
+      ## The "Meta" key
+      "meta"
+    | 
+      ## The "Option" key
+      "option"
+    | 
+      ## The page down key
+      "pagedown"
+    | 
+      ## The page up key
+      "pageup"
+    | 
+      ## The right arrow
+      "right"
+    | 
+      ## The "Shift" key
+      "shift"
+    | 
+      ## The spacebar
+      "space"
+    | 
+      ## The "Tab" key
+      "tab"
+    | 
+      ## The up arrow
+      "up"
+  db.keycap.function-enum.attribute =
+    
+    ## Identifies the function key
+    attribute function { db.keycap.function.enumeration }?
+  db.keycap.function-other.attributes =
+    
+    ## Identifies the function key
+    attribute function {
+      
+      ## Indicates a non-standard function key
+      "other"
+    }?,
+    
+    ## Specifies a keyword that identifies the non-standard key
+    attribute otherfunction { text }
+  db.keycap.function.attrib =
+    db.keycap.function-enum.attribute
+    | db.keycap.function-other.attributes
+  db.keycap.role.attribute = attribute role { text }
+  db.keycap.attlist =
+    db.keycap.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.keycap.function.attrib
+  db.keycap =
+    
+    ## The text printed on a key on a keyboard
+    element keycap { db.keycap.attlist, db._text }
+}
+div {
+  db.keycode.role.attribute = attribute role { text }
+  db.keycode.attlist =
+    db.keycode.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.keycode =
+    
+    ## The internal, frequently numeric, identifier for a key on a keyboard
+    element keycode { db.keycode.attlist, db._text }
+}
+db.keycombination.contentmodel =
+  (db.keycap | db.keycombo | db.keysym) | db.mousebutton
+div {
+  db.keycombo.action.enumeration =
+    
+    ## A (single) mouse click.
+    "click"
+    | 
+      ## A double mouse click.
+      "double-click"
+    | 
+      ## A mouse or key press.
+      "press"
+    | 
+      ## Sequential clicks or presses.
+      "seq"
+    | 
+      ## Simultaneous clicks or presses.
+      "simul"
+  db.keycombo.action-enum.attribute =
+    
+    ## Identifies the nature of the action taken. If keycombo
+    ##  contains more than one element, simul
+    ##  is the default, otherwise there is no default.
+    attribute action { db.keycombo.action.enumeration }?
+  db.keycombo.action-other.attributes =
+    
+    ## Identifies the nature of the action taken
+    attribute action {
+      
+      ## Indicates a non-standard action
+      "other"
+    }?,
+    
+    ## Identifies the non-standard action in some unspecified way.
+    attribute otheraction { text }
+  db.keycombo.action.attrib =
+    db.keycombo.action-enum.attribute
+    | db.keycombo.action-other.attributes
+  db.keycombo.role.attribute = attribute role { text }
+  db.keycombo.attlist =
+    db.keycombo.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.keycombo.action.attrib
+  db.keycombo =
+    
+    ## A combination of input actions
+    element keycombo {
+      db.keycombo.attlist, db.keycombination.contentmodel+
+    }
+}
+div {
+  db.keysym.role.attribute = attribute role { text }
+  db.keysym.attlist =
+    db.keysym.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.keysym =
+    
+    ## The symbolic name of a key on a keyboard
+    element keysym { db.keysym.attlist, db._text }
+}
+div {
+  db.accel.role.attribute = attribute role { text }
+  db.accel.attlist =
+    db.accel.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.accel =
+    
+    ## A graphical user interface (GUI) keyboard shortcut
+    element accel { db.accel.attlist, db._text }
+}
+div {
+  db.shortcut.action.attrib = db.keycombo.action.attrib
+  db.shortcut.role.attribute = attribute role { text }
+  db.shortcut.attlist =
+    db.shortcut.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.shortcut.action.attrib
+  db.shortcut =
+    
+    ## A key combination for an action that is also accessible through a menu
+    element shortcut {
+      db.shortcut.attlist, db.keycombination.contentmodel+
+    }
+}
+db.os.inlines =
+  db.prompt
+  | db.envar
+  | db.filename
+  | db.command
+  | db.computeroutput
+  | db.userinput
+db.computeroutput.inlines =
+  (text | db.ubiq.inlines | db.os.inlines | db.technical.inlines)
+  | db.co
+  | db.markup.inlines
+db.userinput.inlines =
+  (text | db.ubiq.inlines | db.os.inlines | db.technical.inlines)
+  | db.co
+  | db.markup.inlines
+  | db.gui.inlines
+  | db.keyboard.inlines
+db.prompt.inlines = db._text | db.co
+div {
+  db.prompt.role.attribute = attribute role { text }
+  db.prompt.attlist =
+    db.prompt.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.prompt =
+    
+    ## A character or string indicating the start of an input field in a  computer display
+    element prompt { db.prompt.attlist, db.prompt.inlines* }
+}
+div {
+  db.envar.role.attribute = attribute role { text }
+  db.envar.attlist =
+    db.envar.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.envar =
+    
+    ## A software environment variable
+    element envar { db.envar.attlist, db._text }
+}
+div {
+  db.filename.class.enumeration =
+    
+    ## A device
+    "devicefile"
+    | 
+      ## A directory
+      "directory"
+    | 
+      ## A filename extension
+      "extension"
+    | 
+      ## A header file (as for a programming language)
+      "headerfile"
+    | 
+      ## A library file
+      "libraryfile"
+    | 
+      ## A partition (as of a hard disk)
+      "partition"
+    | 
+      ## A symbolic link
+      "symlink"
+  db.filename.class.attribute =
+    
+    ## Identifies the class of filename
+    attribute class { db.filename.class.enumeration }
+  db.filename.path.attribute =
+    
+    ## Specifies the path of the filename
+    attribute path { text }
+  db.filename.role.attribute = attribute role { text }
+  db.filename.attlist =
+    db.filename.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.filename.path.attribute?
+    & db.filename.class.attribute?
+  db.filename =
+    
+    ## The name of a file
+    element filename { db.filename.attlist, db._text }
+}
+div {
+  db.command.role.attribute = attribute role { text }
+  db.command.attlist =
+    db.command.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.command =
+    
+    ## The name of an executable program or other software command
+    element command { db.command.attlist, db._text }
+}
+div {
+  db.computeroutput.role.attribute = attribute role { text }
+  db.computeroutput.attlist =
+    db.computeroutput.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.computeroutput =
+    
+    ## Data, generally text, displayed or presented by a computer
+    element computeroutput {
+      db.computeroutput.attlist, db.computeroutput.inlines*
+    }
+}
+div {
+  db.userinput.role.attribute = attribute role { text }
+  db.userinput.attlist =
+    db.userinput.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.userinput =
+    
+    ## Data entered by the user
+    element userinput { db.userinput.attlist, db.userinput.inlines* }
+}
+div {
+  db.cmdsynopsis.role.attribute = attribute role { text }
+  db.cmdsynopsis.sepchar.attribute =
+    
+    ## Specifies the character that should separate the command and its top-level arguments
+    attribute sepchar { text }
+  db.cmdsynopsis.cmdlength.attribute =
+    
+    ## Indicates the displayed length of the command; this information may be used to intelligently indent command synopses which extend beyond one line
+    attribute cmdlength { text }
+  db.cmdsynopsis.label.attribute = db.label.attribute
+  db.cmdsynopsis.attlist =
+    db.cmdsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.cmdsynopsis.sepchar.attribute?
+    & db.cmdsynopsis.cmdlength.attribute?
+    & db.cmdsynopsis.label.attribute?
+  db.cmdsynopsis.info = db._info.title.forbidden
+  db.cmdsynopsis =
+    
+    ## A syntax summary for a software command
+    element cmdsynopsis {
+      db.cmdsynopsis.attlist,
+      db.cmdsynopsis.info,
+      (db.command | db.arg | db.group | db.sbr)+,
+      db.synopfragment*
+    }
+}
+db.rep.enumeration =
+  
+  ## Can not be repeated.
+  "norepeat"
+  | 
+    ## Can be repeated.
+    "repeat"
+db.rep.attribute =
+  
+  ## Indicates whether or not repetition is possible.
+  [ a:defaultValue = "norepeat" ] attribute rep { db.rep.enumeration }
+db.choice.enumeration =
+  
+  ## Formatted to indicate that it is optional.
+  "opt"
+  | 
+    ## Formatted without indication.
+    "plain"
+  | 
+    ## Formatted to indicate that it is required.
+    "req"
+db.choice.opt.attribute =
+  
+  ## Indicates optionality.
+  [ a:defaultValue = "opt" ] attribute choice { db.choice.enumeration }
+db.choice.req.attribute =
+  
+  ## Indicates optionality.
+  [ a:defaultValue = "req" ] attribute choice { db.choice.enumeration }
+div {
+  db.arg.role.attribute = attribute role { text }
+  db.arg.rep.attribute = db.rep.attribute
+  db.arg.choice.attribute = db.choice.opt.attribute
+  db.arg.attlist =
+    db.arg.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.arg.rep.attribute?
+    & db.arg.choice.attribute?
+  db.arg =
+    
+    ## An argument in a CmdSynopsis
+    element arg {
+      db.arg.attlist,
+      (db._text
+       | db.arg
+       | db.group
+       | db.option
+       | db.synopfragmentref
+       | db.sbr)*
+    }
+}
+div {
+  db.group.role.attribute = attribute role { text }
+  db.group.rep.attribute = db.rep.attribute
+  db.group.choice.attribute = db.choice.opt.attribute
+  db.group.attlist =
+    db.group.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.group.rep.attribute?
+    & db.group.choice.attribute?
+  db.group =
+    
+    ## A group of elements in a CmdSynopsis
+    element group {
+      db.group.attlist,
+      (db.arg
+       | db.group
+       | db.option
+       | db.synopfragmentref
+       | db.replaceable
+       | db.sbr)+
+    }
+}
+div {
+  db.sbr.role.attribute = attribute role { text }
+  db.sbr.attlist = db.sbr.role.attribute? & db.common.attributes
+  db.sbr =
+    
+    ## An explicit line break in a command synopsis
+    element sbr { db.sbr.attlist, empty }
+}
+div {
+  db.synopfragment.role.attribute = attribute role { text }
+  db.synopfragment.attlist =
+    db.synopfragment.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.synopfragment =
+    
+    ## A portion of a CmdSynopsis broken out from the main body of the synopsis
+    element synopfragment {
+      db.synopfragment.attlist, (db.arg | db.group)+
+    }
+}
+div {
+  db.synopfragmentref.role.attribute = attribute role { text }
+  db.synopfragmentref.attlist =
+    db.synopfragmentref.role.attribute?
+    & db.common.attributes
+    & db.linkend.attribute
+  db.synopfragmentref =
+    
+    ## A reference to a fragment of a command synopsis
+    [
+      s:pattern [
+        name = "Synopsis fragment type constraint"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:synopfragmentref"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test =
+              "local-name(//*[@xml:id=current()/@linkend]) = 'synopfragment' and namespace-uri(//*[@xml:id=current()/@linkend]) = 'http://docbook.org/ns/docbook'"
+            "@linkend on synopfragmentref must point to a synopfragment."
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element synopfragmentref { db.synopfragmentref.attlist, text }
+}
+db.programming.inlines =
+  db.function
+  | db.parameter
+  | db.varname
+  | db.returnvalue
+  | db.type
+  | db.classname
+  | db.exceptionname
+  | db.interfacename
+  | db.methodname
+  | db.modifier
+  | db.initializer
+  | db.oo.inlines
+db.oo.inlines = db.ooclass | db.ooexception | db.oointerface
+db.synopsis.blocks =
+  (db.funcsynopsis
+   | db.classsynopsis
+   | db.methodsynopsis
+   | db.constructorsynopsis
+   | db.destructorsynopsis
+   | db.fieldsynopsis)
+  | db.cmdsynopsis
+div {
+  db.synopsis.role.attribute = attribute role { text }
+  db.synopsis.label.attribute = db.label.attribute
+  db.synopsis.attlist =
+    db.synopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.verbatim.attributes
+    & db.synopsis.label.attribute?
+  db.synopsis =
+    
+    ## A general-purpose element for representing the syntax of commands or functions
+    element synopsis { db.synopsis.attlist, db.verbatim.contentmodel }
+}
+div {
+  db.funcsynopsis.role.attribute = attribute role { text }
+  db.funcsynopsis.attlist =
+    db.funcsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+  db.funcsynopsis.info = db._info.title.forbidden
+  db.funcsynopsis =
+    
+    ## The syntax summary for a function definition
+    element funcsynopsis {
+      db.funcsynopsis.attlist,
+      db.funcsynopsis.info,
+      (db.funcsynopsisinfo | db.funcprototype)+
+    }
+}
+div {
+  db.funcsynopsisinfo.role.attribute = attribute role { text }
+  db.funcsynopsisinfo.attlist =
+    db.funcsynopsisinfo.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.verbatim.attributes
+  db.funcsynopsisinfo =
+    
+    ## Information supplementing the FuncDefs of a FuncSynopsis
+    element funcsynopsisinfo {
+      db.funcsynopsisinfo.attlist, db.verbatim.contentmodel
+    }
+}
+div {
+  db.funcprototype.role.attribute = attribute role { text }
+  db.funcprototype.attlist =
+    db.funcprototype.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.funcprototype =
+    
+    ## The prototype of a function
+    element funcprototype {
+      db.funcprototype.attlist,
+      db.modifier*,
+      db.funcdef,
+      (db.void | db.varargs | (db.paramdef+, db.varargs?)),
+      db.modifier*
+    }
+}
+div {
+  db.funcdef.role.attribute = attribute role { text }
+  db.funcdef.attlist =
+    db.funcdef.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.funcdef =
+    
+    ## A function (subroutine) name and its return type
+    element funcdef {
+      db.funcdef.attlist, (db._text | db.type | db.function)*
+    }
+}
+div {
+  db.function.role.attribute = attribute role { text }
+  db.function.attlist =
+    db.function.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.function =
+    
+    ## The name of a function or subroutine, as in a programming language
+    element function { db.function.attlist, db._text }
+}
+div {
+  db.void.role.attribute = attribute role { text }
+  db.void.attlist =
+    db.void.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.void =
+    
+    ## An empty element in a function synopsis indicating that the function in question takes no arguments
+    element void { db.void.attlist, empty }
+}
+div {
+  db.varargs.role.attribute = attribute role { text }
+  db.varargs.attlist =
+    db.varargs.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.varargs =
+    
+    ## An empty element in a function synopsis indicating a variable number of arguments
+    element varargs { db.varargs.attlist, empty }
+}
+div {
+  db.paramdef.role.attribute = attribute role { text }
+  db.paramdef.choice.enumeration =
+    
+    ## Formatted to indicate that it is optional.
+    "opt"
+    | 
+      ## Formatted to indicate that it is required.
+      "req"
+  db.paramdef.choice.attribute =
+    
+    ## Indicates optionality.
+    [ a:defaultValue = "opt" ]
+    attribute choice { db.paramdef.choice.enumeration }
+  db.paramdef.attlist =
+    db.paramdef.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.paramdef.choice.attribute?
+  db.paramdef =
+    
+    ## Information about a function parameter in a programming language
+    element paramdef {
+      db.paramdef.attlist,
+      (db._text
+       | db.initializer
+       | db.type
+       | db.parameter
+       | db.funcparams)*
+    }
+}
+div {
+  db.funcparams.role.attribute = attribute role { text }
+  db.funcparams.attlist =
+    db.funcparams.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.funcparams =
+    
+    ## Parameters for a function referenced through a function pointer in a synopsis
+    element funcparams { db.funcparams.attlist, db._text }
+}
+div {
+  db.classsynopsis.role.attribute = attribute role { text }
+  db.classsynopsis.class.enumeration =
+    
+    ## This is the synopsis of a class
+    "class"
+    | 
+      ## This is the synopsis of an interface
+      "interface"
+  db.classsynopsis.class.attribute =
+    
+    ## Specifies the nature of the synopsis
+    attribute class { db.classsynopsis.class.enumeration }
+  db.classsynopsis.attlist =
+    db.classsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+    & db.classsynopsis.class.attribute?
+  db.classsynopsis =
+    
+    ## The syntax summary for a class definition
+    element classsynopsis {
+      db.classsynopsis.attlist,
+      db.oo.inlines+,
+      (db.classsynopsisinfo
+       | db.methodsynopsis
+       | db.constructorsynopsis
+       | db.destructorsynopsis
+       | db.fieldsynopsis)*
+    }
+}
+div {
+  db.classsynopsisinfo.role.attribute = attribute role { text }
+  db.classsynopsisinfo.attlist =
+    db.classsynopsisinfo.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.verbatim.attributes
+  db.classsynopsisinfo =
+    
+    ## Information supplementing the contents of a ClassSynopsis
+    element classsynopsisinfo {
+      db.classsynopsisinfo.attlist, db.verbatim.contentmodel
+    }
+}
+div {
+  db.ooclass.role.attribute = attribute role { text }
+  db.ooclass.attlist =
+    db.ooclass.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.ooclass =
+    
+    ## A class in an object-oriented programming language
+    element ooclass {
+      db.ooclass.attlist, (db.package | db.modifier)*, db.classname
+    }
+}
+div {
+  db.oointerface.role.attribute = attribute role { text }
+  db.oointerface.attlist =
+    db.oointerface.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.oointerface =
+    
+    ## An interface in an object-oriented programming language
+    element oointerface {
+      db.oointerface.attlist,
+      (db.package | db.modifier)*,
+      db.interfacename
+    }
+}
+div {
+  db.ooexception.role.attribute = attribute role { text }
+  db.ooexception.attlist =
+    db.ooexception.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.ooexception =
+    
+    ## An exception in an object-oriented programming language
+    element ooexception {
+      db.ooexception.attlist,
+      (db.package | db.modifier)*,
+      db.exceptionname
+    }
+}
+db.modifier.xml.space.attribute =
+  
+  ## Can be used to indicate that whitespace in the modifier should be preserved (for multi-line annotations, for example).
+  attribute xml:space {
+    
+    ## Extra whitespace and line breaks must be preserved.
+    [
+      # Ideally the definition of xml:space used on modifier would be
+      # different from the definition used on the verbatim elements. The
+      # verbatim elements forbid the use of xml:space="default" which
+      # wouldn't be a problem on modifier. But doing that causes the
+      # generated XSD schemas to be broken so I'm just reusing the existing
+      # definition for now. It won't be backwards incompatible to fix this
+      # problem in the future.
+      #    | ## Extra whitespace and line breaks are not preserved.
+      #      "default"
+      
+    ]
+    "preserve"
+  }
+div {
+  db.modifier.role.attribute = attribute role { text }
+  db.modifier.attlist =
+    db.modifier.xml.space.attribute?
+    & db.modifier.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.modifier =
+    
+    ## Modifiers in a synopsis
+    element modifier { db.modifier.attlist, db._text }
+}
+div {
+  db.interfacename.role.attribute = attribute role { text }
+  db.interfacename.attlist =
+    db.interfacename.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.interfacename =
+    
+    ## The name of an interface
+    element interfacename { db.interfacename.attlist, db._text }
+}
+div {
+  db.exceptionname.role.attribute = attribute role { text }
+  db.exceptionname.attlist =
+    db.exceptionname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.exceptionname =
+    
+    ## The name of an exception
+    element exceptionname { db.exceptionname.attlist, db._text }
+}
+div {
+  db.fieldsynopsis.role.attribute = attribute role { text }
+  db.fieldsynopsis.attlist =
+    db.fieldsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+  db.fieldsynopsis =
+    
+    ## The name of a field in a class definition
+    element fieldsynopsis {
+      db.fieldsynopsis.attlist,
+      db.modifier*,
+      db.type?,
+      db.varname,
+      db.initializer?
+    }
+}
+div {
+  db.initializer.role.attribute = attribute role { text }
+  db.initializer.attlist =
+    db.initializer.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.initializer =
+    
+    ## The initializer for a FieldSynopsis
+    element initializer { db.initializer.attlist, db._text }
+}
+div {
+  db.constructorsynopsis.role.attribute = attribute role { text }
+  db.constructorsynopsis.attlist =
+    db.constructorsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+  db.constructorsynopsis =
+    
+    ## A syntax summary for a constructor
+    element constructorsynopsis {
+      db.constructorsynopsis.attlist,
+      db.modifier*,
+      db.methodname?,
+      (db.methodparam+ | db.void?),
+      db.exceptionname*
+    }
+}
+div {
+  db.destructorsynopsis.role.attribute = attribute role { text }
+  db.destructorsynopsis.attlist =
+    db.destructorsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+  db.destructorsynopsis =
+    
+    ## A syntax summary for a destructor
+    element destructorsynopsis {
+      db.destructorsynopsis.attlist,
+      db.modifier*,
+      db.methodname?,
+      (db.methodparam+ | db.void?),
+      db.exceptionname*
+    }
+}
+div {
+  db.methodsynopsis.role.attribute = attribute role { text }
+  db.methodsynopsis.attlist =
+    db.methodsynopsis.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.language.attribute?
+  db.methodsynopsis =
+    
+    ## A syntax summary for a method
+    element methodsynopsis {
+      db.methodsynopsis.attlist,
+      db.modifier*,
+      (db.type | db.void)?,
+      db.methodname,
+      (db.methodparam+ | db.void),
+      db.exceptionname*,
+      db.modifier*
+    }
+}
+div {
+  db.methodname.role.attribute = attribute role { text }
+  db.methodname.attlist =
+    db.methodname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.methodname =
+    
+    ## The name of a method
+    element methodname { db.methodname.attlist, db._text }
+}
+div {
+  db.methodparam.role.attribute = attribute role { text }
+  db.methodparam.rep.attribute = db.rep.attribute
+  db.methodparam.choice.attribute = db.choice.req.attribute
+  db.methodparam.attlist =
+    db.methodparam.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.methodparam.rep.attribute?
+    & db.methodparam.choice.attribute?
+  db.methodparam =
+    
+    ## Parameters to a method
+    element methodparam {
+      db.methodparam.attlist,
+      db.modifier*,
+      db.type?,
+      ((db.modifier*, db.parameter, db.initializer?) | db.funcparams),
+      db.modifier*
+    }
+}
+div {
+  db.varname.role.attribute = attribute role { text }
+  db.varname.attlist =
+    db.varname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.varname =
+    
+    ## The name of a variable
+    element varname { db.varname.attlist, db._text }
+}
+div {
+  db.returnvalue.role.attribute = attribute role { text }
+  db.returnvalue.attlist =
+    db.returnvalue.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.returnvalue =
+    
+    ## The value returned by a function
+    element returnvalue { db.returnvalue.attlist, db._text }
+}
+div {
+  db.type.role.attribute = attribute role { text }
+  db.type.attlist =
+    db.type.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.type =
+    
+    ## The classification of a value
+    element type { db.type.attlist, db._text }
+}
+div {
+  db.classname.role.attribute = attribute role { text }
+  db.classname.attlist =
+    db.classname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.classname =
+    
+    ## The name of a class, in the object-oriented programming sense
+    element classname { db.classname.attlist, db._text }
+}
+div {
+  db.programlisting.role.attribute = attribute role { text }
+  db.programlisting.width.attribute = db.width.characters.attribute
+  db.programlisting.attlist =
+    db.programlisting.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.verbatim.attributes
+    & db.programlisting.width.attribute?
+  db.programlisting =
+    
+    ## A literal listing of all or part of a program
+    element programlisting {
+      db.programlisting.attlist, db.verbatim.contentmodel
+    }
+}
+db.admonition.blocks =
+  db.caution | db.important | db.note | db.tip | db.warning
+db.admonition.contentmodel = db._info.title.only, db.all.blocks+
+div {
+  db.caution.role.attribute = attribute role { text }
+  db.caution.attlist =
+    db.caution.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.caution =
+    
+    ## A note of caution
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caution"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of caution"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caution"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of caution"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caution"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of caution"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caution"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of caution"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:caution"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of caution"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element caution { db.caution.attlist, db.admonition.contentmodel }
+}
+div {
+  db.important.role.attribute = attribute role { text }
+  db.important.attlist =
+    db.important.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.important =
+    
+    ## An admonition set off from the text
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:important"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of important"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:important"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of important"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:important"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of important"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:important"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of important"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:important"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of important"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element important {
+      db.important.attlist, db.admonition.contentmodel
+    }
+}
+div {
+  db.note.role.attribute = attribute role { text }
+  db.note.attlist =
+    db.note.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.note =
+    
+    ## A message set off from the text
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:note"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of note"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:note"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of note"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:note"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of note"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:note"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of note"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:note"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of note"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element note { db.note.attlist, db.admonition.contentmodel }
+}
+div {
+  db.tip.role.attribute = attribute role { text }
+  db.tip.attlist =
+    db.tip.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.tip =
+    
+    ## A suggestion to the user, set off from the text
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:tip"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of tip"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:tip"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of tip"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:tip"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of tip"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:tip"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of tip"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:tip"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of tip"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element tip { db.tip.attlist, db.admonition.contentmodel }
+}
+div {
+  db.warning.role.attribute = attribute role { text }
+  db.warning.attlist =
+    db.warning.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.warning =
+    
+    ## An admonition set off from the text
+    [
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:warning"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:caution)"
+            "caution must not occur in the descendants of warning"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:warning"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:important)"
+            "important must not occur in the descendants of warning"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:warning"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:note)"
+            "note must not occur in the descendants of warning"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:warning"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:tip)"
+            "tip must not occur in the descendants of warning"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+      s:pattern [
+        name = "Element exclusion"
+        "\x{a}" ~
+        "          "
+        s:rule [
+          context = "db:warning"
+          "\x{a}" ~
+          "            "
+          s:assert [
+            test = "not(.//db:warning)"
+            "warning must not occur in the descendants of warning"
+          ]
+          "\x{a}" ~
+          "          "
+        ]
+        "\x{a}" ~
+        "        "
+      ]
+    ]
+    element warning { db.warning.attlist, db.admonition.contentmodel }
+}
+db.error.inlines =
+  db.errorcode | db.errortext | db.errorname | db.errortype
+div {
+  db.errorcode.role.attribute = attribute role { text }
+  db.errorcode.attlist =
+    db.errorcode.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.errorcode =
+    
+    ## An error code
+    element errorcode { db.errorcode.attlist, db._text }
+}
+div {
+  db.errorname.role.attribute = attribute role { text }
+  db.errorname.attlist =
+    db.errorname.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.errorname =
+    
+    ## An error name
+    element errorname { db.errorname.attlist, db._text }
+}
+div {
+  db.errortext.role.attribute = attribute role { text }
+  db.errortext.attlist =
+    db.errortext.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.errortext =
+    
+    ## An error message.
+    element errortext { db.errortext.attlist, db._text }
+}
+div {
+  db.errortype.role.attribute = attribute role { text }
+  db.errortype.attlist =
+    db.errortype.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.errortype =
+    
+    ## The classification of an error message
+    element errortype { db.errortype.attlist, db._text }
+}
+db.systemitem.inlines = db._text | db.co
+div {
+  db.systemitem.class.enumeration =
+    
+    ## A daemon or other system process (syslogd)
+    "daemon"
+    | 
+      ## A domain name (example.com)
+      "domainname"
+    | 
+      ## An ethernet address (00:05:4E:49:FD:8E)
+      "etheraddress"
+    | 
+      ## An event of some sort (SIGHUP)
+      "event"
+    | 
+      ## An event handler of some sort (hangup)
+      "eventhandler"
+    | 
+      ## A filesystem (ext3)
+      "filesystem"
+    | 
+      ## A fully qualified domain name (my.example.com)
+      "fqdomainname"
+    | 
+      ## A group name (wheel)
+      "groupname"
+    | 
+      ## An IP address (127.0.0.1)
+      "ipaddress"
+    | 
+      ## A library (libncurses)
+      "library"
+    | 
+      ## A macro
+      "macro"
+    | 
+      ## A netmask (255.255.255.192)
+      "netmask"
+    | 
+      ## A newsgroup (comp.text.xml)
+      "newsgroup"
+    | 
+      ## An operating system name (Hurd)
+      "osname"
+    | 
+      ## A process (gnome-cups-icon)
+      "process"
+    | 
+      ## A protocol (ftp)
+      "protocol"
+    | 
+      ## A resource
+      "resource"
+    | 
+      ## A server (mail.example.com)
+      "server"
+    | 
+      ## A service (ppp)
+      "service"
+    | 
+      ## A system name (hephaistos)
+      "systemname"
+    | 
+      ## A user name (ndw)
+      "username"
+  db.systemitem.class.attribute =
+    
+    ## Identifies the nature of the system item
+    attribute class { db.systemitem.class.enumeration }
+  db.systemitem.role.attribute = attribute role { text }
+  db.systemitem.attlist =
+    db.systemitem.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+    & db.systemitem.class.attribute?
+  db.systemitem =
+    
+    ## A system-related item or term
+    element systemitem { db.systemitem.attlist, db.systemitem.inlines* }
+}
+div {
+  db.option.role.attribute = attribute role { text }
+  db.option.attlist =
+    db.option.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.option =
+    
+    ## An option for a software command
+    element option { db.option.attlist, db._text }
+}
+div {
+  db.optional.role.attribute = attribute role { text }
+  db.optional.attlist =
+    db.optional.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.optional =
+    
+    ## Optional information
+    element optional { db.optional.attlist, db._text }
+}
+div {
+  db.property.role.attribute = attribute role { text }
+  db.property.attlist =
+    db.property.role.attribute?
+    & db.common.attributes
+    & db.common.linking.attributes
+  db.property =
+    
+    ## A unit of data associated with some part of a computer system
+    element property { db.property.attlist, db._text }
+}
+div {
+  db.xi.include.attlist =
+    attribute href {
+      xsd:anyURI { pattern = "[^#]+" }
+    }?,
+    [ a:defaultValue = "xml" ] attribute parse { "xml" | "text" }?,
+    attribute xpointer { text }?,
+    attribute encoding { text }?,
+    attribute accept { text }?,
+    attribute accept-language { text }?
+  db.xi.include =
+    
+    ## An XInclude
+    element xi:include { db.xi.include.attlist, db.xi.fallback? }
+}
+div {
+  # The fallback element has no attributes
+  db.xi.fallback =
+    
+    ## An XInclude fallback
+    element xi:fallback { db.all.blocks+ | db.all.inlines+ | db._any* }
+}
diff --git a/emacs-egrep b/emacs-egrep
new file mode 160000
index 0000000..2d7b110
--- /dev/null
+++ b/emacs-egrep
@@ -0,0 +1 @@
+Subproject commit 2d7b110770b5d9d8f5b2bb4b0959e261820b0efb
diff --git a/load-dir.el b/load-dir.el
new file mode 100644
index 0000000..1ac7ed2
--- /dev/null
+++ b/load-dir.el
@@ -0,0 +1,74 @@
+(defvar file-loadable-regexp
+ (replace-regexp-in-string
+  "\\." "\\\\."
+  (let (string
+        (suffix-list (get-load-suffixes)))
+    (concat (car suffix-list) "$"
+            (dolist (extension (cdr suffix-list) string)
+              (setq string (concat "\\|" extension "$" string))))))
+  "Regular expression that matches any file name with a file
+extension returned by `get-load-suffixes'.")
+
+(defun file-loadable-p (file)
+ "Return t if FILE is an Emacs lisp file.
+More precisely, return t if the file name extension matches
+`file-loadable-regexp'"
+(string-match file-loadable-regexp file))
+
+(defun load-dir (&optional directory recurse)
+ "Load all Emacs Lisp files in DIRECTORY.
+
+Load files whose file name satisfies predicate `file-loadable-p'.
+Non-interactively, DIRECTORY must be specified.  If both compiled
+and uncompiled versions of the same file exist, only load the
+compiled file.  If optional argument RECURSE is non-nil, (or,
+interactively, with prefix argument) recursively load
+subdirectories."
+ (interactive "P")
+ ;; The idea here is to allow a prefix arg to specify recursion, but
+ ;; also to read from the minibuffer the directory name; yet in
+ ;; non-interactive use to only need the one directory-name argument,
+ ;; as in: (load-dir "~/foo")
+ (let* ((recurse (if recurse recurse (when current-prefix-arg t)))
+        (directory (if (stringp directory) directory
+                     (when (called-interactively-p 'any)
+                       (read-directory-name
+                        (concat (if recurse "Recursively l" "L")
+                                "oad all Emacs lisp files from directory: ")
+                        default-directory default-directory t)))))
+   ;; For non-interactive use
+   (when (not (called-interactively-p 'any))
+     (unless directory
+       (error "Must specify a directory to when called non-interactively")))
+   (unless (file-directory-p directory)
+     (error "%s is not a directory" directory))
+   (let ((file-list
+          (directory-files (expand-file-name directory)
+                           t directory-files-no-dot-files-regexp)))
+     (dolist (file file-list)
+       (cond
+        ((and
+          ;; This will include gzipped elisp files
+          (file-loadable-p file)
+          ;; Ignore symlinks to nonexistent targets.
+          (file-exists-p file)
+          ;; Don't try to load directies whose names end in ".el"
+          ;; etc., as if they were files.  Note that we do not
+          ;; predicate on "permission denied" problems, instead
+          ;; letting things fail in that case so the user knows.
+          (not (file-directory-p file))
+          ;; If there exist both compiled and uncompiled versions of
+          ;; the same library, only load the compiled one.  (This is
+          ;; why we let-bind the `file-list'.)  This could perhaps be
+          ;; factored out, and currently still double-loads gzipped
+          ;; libraries.
+          (not (and (string= (file-name-extension file t) ".el")
+                    (member
+                     (concat (file-name-sans-extension file) ".elc")
+                     file-list))))
+         (load file))
+        ((and (file-directory-p file)
+              recurse)
+         (load-dir file t)))))))
+
+(provide 'load-dir)
diff --git a/magit b/magit
new file mode 160000
index 0000000..0b1a72a
--- /dev/null
+++ b/magit
@@ -0,0 +1 @@
+Subproject commit 0b1a72a364ca12dc5c90609333aca768a14503e9
diff --git a/nxhtml/README.txt b/nxhtml/README.txt
new file mode 100644
index 0000000..cf4952e
--- /dev/null
+++ b/nxhtml/README.txt
@@ -0,0 +1,46 @@
+To install nXhtml put this in your .emacs:
+
+   (load "YOUR-PATH-TO/nxhtml/autostart.el")
+
+where autostart.el is the file in the same directory as this
+readme.txt file.
+
+Note 1: If you are using Emacs+EmacsW32 then nXhtml is already
+        installed.
+
+Note 2: If you are using Emacs 22 then you need to install nXml
+        separately. (It is included in Emacs 23.)
+
+Note 3: You may optionally also byte compile nXhtml from the nXhtml
+        menu (recommended).
+
+
+
+Files that are now in Emacs' development (CVS/Bazaar) repository
+================================================================
+
+Some files that were previously distributed with nXhtml are now in
+Emacs' development repository.  Distributing them also with nXhtml is
+a bad idea since that can lead to that the wrong file is loaded.  They
+are therefore not distributed with nXhtml anymore.
+
+Instead you can (if you do not have the files in your Emacs) in many
+cases use the version from the repository.  To do that you can
+currently start from
+
+  http://cvs.savannah.gnu.org/viewvc/emacs/emacs/lisp/
+
+Files you can download and use this way are for example
+
+  js.el (JavaScript, formerly called espresso.el)
+  htmlfontify.el
+
+If you do that I suggest that you put these files in a special
+directory and add that to load-path in your .emacs and make that
+adding to load-path depend on your Emacs version so that they will not
+be loaded when you have upgraded your Emacs.
+
+Note that if you want to use nxml-mode (and it is not in your Emacs)
+you should not download it from Emacs' development directory. Instead go to
+
+  http://www.thaiopensource.com/download/
diff --git a/nxhtml/alts/find-recursive-orig.el b/nxhtml/alts/find-recursive-orig.el
new file mode 100644
index 0000000..509a038
--- /dev/null
+++ b/nxhtml/alts/find-recursive-orig.el
@@ -0,0 +1,137 @@
+;; find-recursive.el -- Find files recursively into a directory
+;;
+;; Copyright (C) 2001 Ovidiu Predescu
+;;
+;; Author: Ovidiu Predescu 
+;; Date: March 26, 2001
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2
+;; of the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;
+;; Setup: put this file in your Lisp path and add the following line in
+;; your .emacs:
+;;
+;; (require 'find-recursive)
+;;
+
+(require 'cl)
+
+(defcustom find-recursive-exclude-files '(".*.class$" ".*~$" ".*.elc$")
+  "List of regular expressions of files to be excluded when recursively searching for files."
+  :type '(repeat (string :tag "File regexp")))
+
+(defun find-file-recursively (file-regexp directory)
+  (interactive "sFile name to search for recursively: \nDIn directory: ")
+  (let ((directory (if (equal (substring directory -1) "/")
+                       directory
+                     (concat directory "/")))
+        (matches
+         (find-recursive-filter-out
+          find-recursive-exclude-files
+          (find-recursive-directory-relative-files directory "" file-regexp))))
+    (cond ((eq (length matches) 0) (message "No file(s) found!"))
+           ((eq (length matches) 1)
+            (find-file (concat directory (car matches))))
+           (t
+            (run-with-timer 0.001 nil
+                            (lambda ()
+                              (dispatch-event
+                               (make-event 'key-press '(key tab)))))
+            (let ((file (completing-read "Choose file: "
+                                           (mapcar 'list matches)
+                                           nil t)))
+                (if (or (eq file nil) (equal file ""))
+                    (message "No file selected.")
+                  (find-file (concat directory file))))))))
+
+(defun find-recursive-directory-relative-files (directory
+                                          relative-directory
+                                          file-regexp)
+  (let* ((full-dir (concat directory "/" relative-directory))
+         (matches
+          (mapcar
+           (function (lambda (x)
+                       (concat relative-directory x)))
+           (find-recursive-filter-out '(nil)
+                                (directory-files full-dir nil
+                                                 file-regexp nil t))))
+         (inner
+          (mapcar
+           (function
+            (lambda (dir)
+              (find-recursive-directory-relative-files directory
+                                                 (concat relative-directory
+                                                         dir "/")
+                                                 file-regexp)))
+           (find-recursive-filter-out '(nil "\\." "\\.\\.")
+                                (directory-files full-dir nil ".*"
+                                                 nil 'directories)))))
+    (mapcar (function (lambda (dir) (setq matches (append matches dir))))
+            inner)
+    matches))
+
+(defun find-recursive-filter-out (remove-list list)
+  "Remove all the elements in *remove-list* from *list*"
+  (if (eq list nil)
+      nil
+    (let ((elem (car list))
+          (rest (cdr list)))
+      (if (some
+           (lambda (regexp)
+             (if (or (eq elem nil) (eq regexp nil))
+                 nil
+               (not (eq (string-match regexp elem) nil))))
+           remove-list)
+          (find-recursive-filter-out remove-list rest)
+        (cons elem (find-recursive-filter-out remove-list rest))))))
+
+(defvar find-recursive-running-xemacs (string-match "XEmacs\\|Lucid" emacs-version))
+
+(if find-recursive-running-xemacs
+    nil
+  (defadvice directory-files (after
+                              directory-files-xemacs
+                              (dirname &optional full match nosort files-only)
+                              activate)
+    "Add an additional argument, FILES-ONLY to the list of arguments
+for GNU Emacs. If the symbol is t, then only the files in the
+directory will be returned. If FILES-ONLY is nil, then both files and
+directories are selected. If FILES-ONLY is not nil and not t, then
+only sundirectories are returned."
+    (setq ad-return-value
+          (cond ((null files-only) ad-return-value)
+                ((eq files-only t)
+                 (find-recursive-remove-if (lambda (f)
+                                             (file-directory-p
+                                              (concat dirname "/" f)))
+                                           ad-return-value))
+                (t
+                 (find-recursive-remove-if (lambda (f)
+                                             (not (file-directory-p
+                                                   (concat dirname "/" f))))
+                                           ad-return-value)))))
+
+  (defun find-recursive-remove-if (func list)
+    "Removes all elements satisfying FUNC from LIST."
+    (let ((result nil))
+      (while list
+        (if (not (funcall func (car list)))
+            (setq result (cons (car list) result)))
+        (setq list (cdr list)))
+      (nreverse result))))
+
+(global-set-key [(control x) (meta f)] 'find-file-recursively)
+
+(provide 'find-recursive)
diff --git a/nxhtml/alts/javascript-mozlab.el b/nxhtml/alts/javascript-mozlab.el
new file mode 100644
index 0000000..bcec39b
--- /dev/null
+++ b/nxhtml/alts/javascript-mozlab.el
@@ -0,0 +1,712 @@
+;;; javascript.el --- Major mode for editing JavaScript source text
+
+;; Copyright (C) 2006 Karl Landström
+
+;; Author: Karl Landström 
+;; Maintainer: Karl Landström 
+;; Version: 2.0 Beta 8
+;; Date: 2006-12-26
+;; Keywords: languages, oop
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; The main features of this JavaScript mode are syntactic
+;; highlighting (enabled with `font-lock-mode' or
+;; `global-font-lock-mode'), automatic indentation and filling of
+;; comments.
+;;
+;; This package has (only) been tested with GNU Emacs 21.4 (the latest
+;; stable release).
+;;
+;; Installation:
+;;
+;; Put this file in a directory where Emacs can find it (`C-h v
+;; load-path' for more info). Then add the following lines to your
+;; Emacs initialization file:
+;; 
+;;    (add-to-list 'auto-mode-alist '("\\.js\\'" . javascript-mode))
+;;    (autoload 'javascript-mode "javascript" nil t)
+;;    
+;; General Remarks:
+;; 
+;; This mode assumes that block comments are not nested inside block
+;; comments and that strings do not contain line breaks.
+;; 
+;; Exported names start with "javascript-" whereas private names start
+;; with "js-".
+;; 
+;; Changes:
+;;
+;; See javascript.el.changelog.
+
+;;; Code:
+
+(require 'cc-mode)
+(require 'font-lock)
+(require 'newcomment)
+
+(defgroup javascript nil 
+  "Customization variables for `javascript-mode'."
+  :tag "JavaScript"
+  :group 'languages)
+
+(defcustom javascript-indent-level 4
+  "Number of spaces for each indentation step."
+  :type 'integer
+  :group 'javascript)
+
+(defcustom javascript-auto-indent-flag t
+  "Automatic indentation with punctuation characters. If non-nil, the
+current line is indented when certain punctuations are inserted."
+  :type 'boolean
+  :group 'javascript)
+
+
+;; --- Keymap ---
+
+(defvar javascript-mode-map nil 
+  "Keymap used in JavaScript mode.")
+
+(unless javascript-mode-map 
+  (setq javascript-mode-map (make-sparse-keymap)))
+
+(when javascript-auto-indent-flag
+  (mapc (lambda (key) 
+	  (define-key javascript-mode-map key 'javascript-insert-and-indent))
+	'("{" "}" "(" ")" ":" ";" ",")))
+
+(defun javascript-insert-and-indent (key)
+  "Run command bound to key and indent current line. Runs the command
+bound to KEY in the global keymap and indents the current line."
+  (interactive (list (this-command-keys)))
+  (call-interactively (lookup-key (current-global-map) key))
+  (indent-according-to-mode))
+
+
+;; --- Syntax Table And Parsing ---
+
+(defvar javascript-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (c-populate-syntax-table table)
+
+    ;; The syntax class of underscore should really be `symbol' ("_")
+    ;; but that makes matching of tokens much more complex as e.g.
+    ;; "\\" matches part of e.g. "_xyz" and "xyz_abc". Defines
+    ;; it as word constituent for now.
+    (modify-syntax-entry ?_ "w" table)
+
+    table)
+  "Syntax table used in JavaScript mode.")
+
+
+(defun js-re-search-forward-inner (regexp &optional bound count)
+  "Auxiliary function for `js-re-search-forward'."
+  (let ((parse)
+        (saved-point (point-min)))
+    (while (> count 0)
+      (re-search-forward regexp bound)
+      (setq parse (parse-partial-sexp saved-point (point)))
+      (cond ((nth 3 parse)
+             (re-search-forward 
+              (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) 
+              (save-excursion (end-of-line) (point)) t))
+            ((nth 7 parse)
+             (forward-line))
+            ((or (nth 4 parse)
+                 (and (eq (char-before) ?\/) (eq (char-after) ?\*)))
+             (re-search-forward "\\*/"))
+            (t
+             (setq count (1- count))))
+      (setq saved-point (point))))
+  (point))
+
+
+(defun js-re-search-forward (regexp &optional bound noerror count)
+  "Search forward but ignore strings and comments. Invokes
+`re-search-forward' but treats the buffer as if strings and
+comments have been removed."
+  (let ((saved-point (point))
+        (search-expr 
+         (cond ((null count)
+                '(js-re-search-forward-inner regexp bound 1))
+               ((< count 0)
+                '(js-re-search-backward-inner regexp bound (- count)))
+               ((> count 0)
+                '(js-re-search-forward-inner regexp bound count)))))
+    (condition-case err
+        (eval search-expr)
+      (search-failed
+       (goto-char saved-point)
+       (unless noerror
+         (error (error-message-string err)))))))
+
+
+(defun js-re-search-backward-inner (regexp &optional bound count)
+  "Auxiliary function for `js-re-search-backward'."
+  (let ((parse)
+        (saved-point (point-min)))
+    (while (> count 0)
+      (re-search-backward regexp bound)
+      (when (and (> (point) (point-min))
+                 (save-excursion (backward-char) (looking-at "/[/*]")))
+        (forward-char))
+      (setq parse (parse-partial-sexp saved-point (point)))
+      (cond ((nth 3 parse)
+             (re-search-backward
+              (concat "\\([^\\]\\|^\\)" (string (nth 3 parse))) 
+              (save-excursion (beginning-of-line) (point)) t))
+            ((nth 7 parse) 
+             (goto-char (nth 8 parse)))
+            ((or (nth 4 parse)
+                 (and (eq (char-before) ?/) (eq (char-after) ?*)))
+             (re-search-backward "/\\*"))
+            (t
+             (setq count (1- count))))))
+  (point))
+
+
+(defun js-re-search-backward (regexp &optional bound noerror count)
+  "Search backward but ignore strings and comments. Invokes
+`re-search-backward' but treats the buffer as if strings and
+comments have been removed."
+  (let ((saved-point (point))
+        (search-expr 
+         (cond ((null count)
+                '(js-re-search-backward-inner regexp bound 1))
+               ((< count 0)
+                '(js-re-search-forward-inner regexp bound (- count)))
+               ((> count 0)
+                '(js-re-search-backward-inner regexp bound count)))))
+    (condition-case err
+        (eval search-expr)
+      (search-failed
+       (goto-char saved-point)
+       (unless noerror
+         (error (error-message-string err)))))))
+
+
+(defun js-continued-var-decl-list-p ()
+  "Return non-nil if point is inside a continued variable declaration
+list."
+  (interactive)
+  (let ((start (save-excursion (js-re-search-backward "\\" nil t))))
+    (and start
+	 (save-excursion (re-search-backward "\n" start t))
+	 (not (save-excursion 
+		(js-re-search-backward 
+		 ";\\|[^, \t][ \t]*\\(/[/*]\\|$\\)" start t))))))
+
+
+;; --- Font Lock ---
+
+(defun js-inside-param-list-p ()
+  "Return non-nil if point is inside a function parameter list."
+  (condition-case err
+      (save-excursion
+	(up-list -1)
+	(and (looking-at "(")
+	     (progn (backward-word 1)
+		    (or (looking-at "function")
+			(progn (backward-word 1) (looking-at "function"))))))
+    (error nil)))
+
+
+(defconst js-function-heading-1-re 
+  "^[ \t]*function[ \t]+\\(\\w+\\)"
+  "Regular expression matching the start of a function header.")
+
+(defconst js-function-heading-2-re 
+  "^[ \t]*\\(\\w+\\)[ \t]*:[ \t]*function\\>"
+  "Regular expression matching the start of a function entry in
+  an associative array.")
+
+(defconst js-keyword-re
+  (regexp-opt '("abstract" "break" "case" "catch" "class" "const"
+                "continue" "debugger" "default" "delete" "do" "else" 
+                "enum" "export" "extends" "final" "finally" "for" 
+                "function" "goto" "if" "implements" "import" "in" 
+                "instanceof" "interface" "native" "new" "package" 
+                "private" "protected" "public" "return" "static" 
+                "super" "switch" "synchronized" "this" "throw" 
+                "throws" "transient" "try" "typeof" "var" "void" 
+                "volatile" "while" "with"
+                "let") 'words)
+  "Regular expression matching any JavaScript keyword.")
+
+(defconst js-basic-type-re
+  (regexp-opt '("boolean" "byte" "char" "double" "float" "int" "long"
+                "short" "void") 'words)
+  "Regular expression matching any predefined type in JavaScript.")
+
+(defconst js-constant-re
+  (regexp-opt '("false" "null" "true") 'words)
+  "Regular expression matching any future reserved words in JavaScript.")
+
+
+(defconst js-font-lock-keywords-1
+  (list 
+   "\\" 
+   (list js-function-heading-1-re 1 font-lock-function-name-face)
+   (list js-function-heading-2-re 1 font-lock-function-name-face)
+   (list "[=(][ \t]*\\(/.*?[^\\]/\\w*\\)" 1 font-lock-string-face))
+  "Level one font lock.")
+
+(defconst js-font-lock-keywords-2
+  (append js-font-lock-keywords-1
+          (list (list js-keyword-re 1 font-lock-keyword-face)
+                (cons js-basic-type-re font-lock-type-face)
+                (cons js-constant-re font-lock-constant-face)))
+  "Level two font lock.")
+
+
+;; Limitations with variable declarations: There seems to be no
+;; sensible way to highlight variables occuring after an initialized
+;; variable in a variable list. For instance, in
+;;
+;;    var x, y = f(a, b), z
+;;
+;; z will not be highlighted.
+
+(defconst js-font-lock-keywords-3
+  (append 
+   js-font-lock-keywords-2
+   (list 
+
+    ;; variable declarations
+    (list
+     (concat "\\<\\(const\\|var\\)\\>\\|" js-basic-type-re)
+     (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)"
+	   nil
+	   nil
+	   '(1 font-lock-variable-name-face)))
+
+    ;; continued variable declaration list
+    (list
+     (concat "^[ \t]*\\w+[ \t]*\\([,;=]\\|/[/*]\\|$\\)")
+     (list "\\(\\w+\\)[ \t]*\\([=;].*\\|,\\|/[/*]\\|$\\)"
+	   '(if (save-excursion (backward-char) (js-continued-var-decl-list-p))
+		(backward-word 1) 
+	      (end-of-line))
+	   '(end-of-line)
+	   '(1 font-lock-variable-name-face)))
+
+    ;; formal parameters
+    (list
+     (concat "\\\\([ \t]+\\w+\\)?[ \t]*([ \t]*\\w")
+     (list "\\(\\w+\\)\\([ \t]*).*\\)?"
+	   '(backward-char)
+	   '(end-of-line)
+	   '(1 font-lock-variable-name-face)))
+    
+    ;; continued formal parameter list
+    (list
+     (concat "^[ \t]*\\w+[ \t]*[,)]")
+     (list "\\w+"
+	   '(if (save-excursion (backward-char) (js-inside-param-list-p))
+		(backward-word 1) 
+	      (end-of-line))
+	   '(end-of-line)
+	   '(0 font-lock-variable-name-face)))))
+  "Level three font lock.")
+
+(defconst js-font-lock-keywords
+  '(js-font-lock-keywords-3 js-font-lock-keywords-1 js-font-lock-keywords-2
+                            js-font-lock-keywords-3)
+  "See `font-lock-keywords'.")
+
+
+;; --- Indentation ---
+
+(defconst js-possibly-braceless-keyword-re
+  (regexp-opt
+   '("catch" "do" "else" "finally" "for" "if" "try" "while" "with" "let")
+   'words)
+  "Regular expression matching keywords that are optionally
+  followed by an opening brace.")
+
+(defconst js-indent-operator-re
+  (concat "[-+*/%<>=&^|?:.]\\([^-+*/]\\|$\\)\\|"
+          (regexp-opt '("in" "instanceof") 'words))
+  "Regular expression matching operators that affect indentation
+  of continued expressions.")
+
+
+(defun js-looking-at-operator-p ()
+  "Return non-nil if text after point is an operator (that is not
+a comma)."
+  (save-match-data
+    (and (looking-at js-indent-operator-re)
+         (or (not (looking-at ":"))
+             (save-excursion
+               (and (js-re-search-backward "[?:{]\\|\\" nil t)
+                    (looking-at "?")))))))
+
+
+(defun js-continued-expression-p ()
+  "Returns non-nil if the current line continues an expression."
+  (save-excursion
+    (back-to-indentation)
+    (or (js-looking-at-operator-p)
+        (and (js-re-search-backward "\n" nil t)
+	     (progn 
+	       (skip-chars-backward " \t")
+	       (backward-char)
+	       (and (> (point) (point-min))
+                    (save-excursion (backward-char) (not (looking-at "[/*]/")))
+                    (js-looking-at-operator-p)
+		    (and (progn (backward-char)
+				(not (looking-at "++\\|--\\|/[/*]"))))))))))
+
+
+(defun js-end-of-do-while-loop-p ()
+  "Returns non-nil if word after point is `while' of a do-while
+statement, else returns nil. A braceless do-while statement
+spanning several lines requires that the start of the loop is
+indented to the same column as the current line."
+  (interactive)
+  (save-excursion
+    (save-match-data
+      (when (looking-at "\\s-*\\")
+	(if (save-excursion 
+	      (skip-chars-backward "[ \t\n]*}")
+	      (looking-at "[ \t\n]*}"))
+	    (save-excursion 
+	      (backward-list) (backward-word 1) (looking-at "\\"))
+	  (js-re-search-backward "\\" (point-at-bol) t)
+	  (or (looking-at "\\")
+	      (let ((saved-indent (current-indentation)))
+		(while (and (js-re-search-backward "^[ \t]*\\<" nil t)
+			    (/= (current-indentation) saved-indent)))
+		(and (looking-at "[ \t]*\\")
+		     (not (js-re-search-forward 
+			   "\\" (point-at-eol) t))
+		     (= (current-indentation) saved-indent)))))))))
+
+
+(defun js-ctrl-statement-indentation ()
+  "Returns the proper indentation of the current line if it
+starts the body of a control statement without braces, else
+returns nil."
+  (save-excursion
+    (back-to-indentation)
+    (when (save-excursion
+            (and (not (looking-at "[{]"))
+                 (progn
+                   (js-re-search-backward "[[:graph:]]" nil t)
+                   (forward-char)
+                   (when (= (char-before) ?\)) (backward-list))
+                   (skip-syntax-backward " ")
+                   (skip-syntax-backward "w")
+                   (looking-at js-possibly-braceless-keyword-re))
+                 (not (js-end-of-do-while-loop-p))))
+      (save-excursion
+        (goto-char (match-beginning 0))
+        (+ (current-indentation) javascript-indent-level)))))
+
+
+(defun js-proper-indentation (parse-status)
+  "Return the proper indentation for the current line."
+  (save-excursion
+    (back-to-indentation)
+    (let ((ctrl-stmt-indent (js-ctrl-statement-indentation))
+          (same-indent-p (looking-at "[]})]\\|\\\\|\\"))
+          (continued-expr-p (js-continued-expression-p)))
+      (cond (ctrl-stmt-indent)
+	    ((js-continued-var-decl-list-p)
+	     (js-re-search-backward "\\" nil t)
+	     (+ (current-indentation) javascript-indent-level))
+            ((nth 1 parse-status)
+             (goto-char (nth 1 parse-status))
+             (if (looking-at "[({[][ \t]*\\(/[/*]\\|$\\)")
+                 (progn
+                   (skip-syntax-backward " ")
+                   (when (= (char-before) ?\)) (backward-list))
+                   (back-to-indentation)
+                   (cond (same-indent-p
+                          (current-column))
+                         (continued-expr-p
+                          (+ (current-column) (* 2 javascript-indent-level)))
+                         (t
+                          (+ (current-column) javascript-indent-level))))
+               (unless same-indent-p
+                 (forward-char)
+                 (skip-chars-forward " \t"))
+               (current-column)))
+	    (continued-expr-p javascript-indent-level)
+            (t 0)))))
+
+
+(defun javascript-indent-line ()
+  "Indent the current line as JavaScript source text."
+  (interactive)
+  (let ((parse-status 
+         (save-excursion (parse-partial-sexp (point-min) (point-at-bol))))
+        (offset (- (current-column) (current-indentation))))
+    (when (not (nth 8 parse-status))
+      (indent-line-to (js-proper-indentation parse-status))
+      (when (> offset 0) (forward-char offset)))))
+
+
+;; --- Filling ---
+
+;; FIXME: It should be possible to use the more sofisticated function
+;; `c-fill-paragraph' in `cc-cmds.el' instead. However, just setting
+;; `fill-paragraph-function' to `c-fill-paragraph' does not work;
+;; inside `c-fill-paragraph', `fill-paragraph-function' evaluates to
+;; nil!?
+
+(defun js-backward-paragraph ()
+  "Move backward to start of paragraph. Postcondition: Point is at
+beginning of buffer or the previous line contains only whitespace."
+  (forward-line -1)
+  (while (not (or (bobp) (looking-at "^[ \t]*$")))
+    (forward-line -1))
+  (when (not (bobp)) (forward-line 1)))
+
+
+(defun js-forward-paragraph ()
+  "Move forward to end of paragraph. Postcondition: Point is at
+end of buffer or the next line contains only whitespace."
+  (forward-line 1)
+  (while (not (or (eobp) (looking-at "^[ \t]*$")))
+    (forward-line 1))
+  (when (not (eobp)) (backward-char 1)))
+ 
+
+(defun js-fill-block-comment-paragraph (parse-status justify)
+  "Fill current paragraph as a block comment. PARSE-STATUS is the
+result of `parse-partial-regexp' from beginning of buffer to
+point. JUSTIFY has the same meaning as in `fill-paragraph'."
+  (let ((offset (save-excursion 
+                  (goto-char (nth 8 parse-status)) (current-indentation))))
+    (save-excursion
+      (save-restriction
+        (narrow-to-region (save-excursion 
+                            (goto-char (nth 8 parse-status)) (point-at-bol))
+                          (save-excursion 
+			    (goto-char (nth 8 parse-status))
+			    (re-search-forward "*/")))
+        (narrow-to-region (save-excursion 
+                            (js-backward-paragraph)
+                            (when (looking-at "^[ \t]*$") (forward-line 1))
+                            (point))
+                          (save-excursion 
+                            (js-forward-paragraph) 
+                            (when (looking-at "^[ \t]*$") (backward-char))
+                            (point)))
+        (goto-char (point-min))
+        (while (not (eobp))
+          (delete-horizontal-space)
+          (forward-line 1))
+        (let ((fill-column (- fill-column offset))
+              (fill-paragraph-function nil))
+          (fill-paragraph justify))
+
+        ;; In Emacs 21.4 as opposed to CVS Emacs 22,
+        ;; `fill-paragraph' seems toadd a newline at the end of the
+        ;; paragraph. Remove it!
+        (goto-char (point-max))
+        (when (looking-at "^$") (backward-delete-char 1))
+
+        (goto-char (point-min))
+        (while (not (eobp))
+          (indent-to offset)
+          (forward-line 1))))))
+
+
+(defun js-sline-comment-par-start ()
+  "Return point at the beginning of the line where the current
+single-line comment paragraph starts."
+  (save-excursion
+    (beginning-of-line)
+    (while (and (not (bobp)) 
+                (looking-at "^[ \t]*//[ \t]*[[:graph:]]"))
+      (forward-line -1))
+    (unless (bobp) (forward-line 1))
+    (point)))
+
+
+(defun js-sline-comment-par-end ()
+  "Return point at end of current single-line comment paragraph."
+  (save-excursion
+    (beginning-of-line)
+    (while (and (not (eobp)) 
+                (looking-at "^[ \t]*//[ \t]*[[:graph:]]"))
+      (forward-line 1))
+    (unless (bobp) (backward-char))
+    (point)))
+
+
+(defun js-sline-comment-offset (line)
+  "Return the column at the start of the current single-line
+comment paragraph."
+  (save-excursion 
+    (goto-line line)
+    (re-search-forward "//" (point-at-eol))
+    (goto-char (match-beginning 0))
+    (current-column)))
+
+
+(defun js-sline-comment-text-offset (line)
+  "Return the column at the start of the text of the current
+single-line comment paragraph."
+  (save-excursion
+    (goto-line line)
+    (re-search-forward "//[ \t]*" (point-at-eol))
+    (current-column)))
+
+
+(defun js-at-empty-sline-comment-p ()
+  "Return non-nil if inside an empty single-line comment."
+  (and (save-excursion
+         (beginning-of-line)
+         (not (looking-at "^.*//.*[[:graph:]]")))
+       (save-excursion
+         (re-search-backward "//" (point-at-bol) t))))
+
+         
+(defun js-fill-sline-comments (parse-status justify)
+  "Fill current paragraph as a sequence of single-line comments.
+PARSE-STATUS is the result of `parse-partial-regexp' from
+beginning of buffer to point. JUSTIFY has the same meaning as in
+`fill-paragraph'."
+  (when (not (js-at-empty-sline-comment-p))
+    (let* ((start (js-sline-comment-par-start))
+           (start-line (1+ (count-lines (point-min) start)))
+           (end (js-sline-comment-par-end))
+           (offset (js-sline-comment-offset start-line))
+           (text-offset (js-sline-comment-text-offset start-line)))
+      (save-excursion
+        (save-restriction
+          (narrow-to-region start end)
+          (goto-char (point-min))
+          (while (re-search-forward "^[ \t]*//[ \t]*" nil t)
+            (replace-match "")
+            (forward-line 1))
+          (let ((fill-paragraph-function nil)
+                (fill-column (- fill-column text-offset)))
+            (fill-paragraph justify))
+
+          ;; In Emacs 21.4 as opposed to CVS Emacs 22,
+          ;; `fill-paragraph' seems toadd a newline at the end of the
+          ;; paragraph. Remove it!
+          (goto-char (point-max))
+          (when (looking-at "^$") (backward-delete-char 1))
+
+          (goto-char (point-min))
+          (while (not (eobp))
+            (indent-to offset)
+            (insert "//")
+            (indent-to text-offset)
+            (forward-line 1)))))))
+  
+
+(defun js-trailing-comment-p (parse-status)
+  "Return non-nil if inside a trailing comment. PARSE-STATUS is
+the result of `parse-partial-regexp' from beginning of buffer to
+point."
+  (save-excursion 
+    (when (nth 4 parse-status)
+      (goto-char (nth 8 parse-status))
+      (skip-chars-backward " \t")
+      (not (bolp)))))
+
+
+(defun js-block-comment-p (parse-status)
+  "Return non-nil if inside a block comment. PARSE-STATUS is the
+result of `parse-partial-regexp' from beginning of buffer to
+point."
+  (save-excursion 
+    (save-match-data
+      (when (nth 4 parse-status)
+        (goto-char (nth 8 parse-status))
+        (looking-at "/\\*")))))
+
+
+(defun javascript-fill-paragraph (&optional justify)
+  "If inside a comment, fill the current comment paragraph.
+Trailing comments are ignored."
+  (interactive)
+  (let ((parse-status (parse-partial-sexp (point-min) (point))))
+    (when (and (nth 4 parse-status) 
+               (not (js-trailing-comment-p parse-status)))
+      (if (js-block-comment-p parse-status)
+          (js-fill-block-comment-paragraph parse-status justify)
+        (js-fill-sline-comments parse-status justify))))
+  t)
+
+
+;; --- Imenu ---
+
+(defconst js-imenu-generic-expression 
+  (list
+   (list
+    nil 
+    "function\\s-+\\(\\w+\\)\\s-*("
+    1))
+  "Regular expression matching top level procedures. Used by imenu.")
+
+
+;; --- Main Function ---
+
+;;;###autoload
+(defun javascript-mode ()
+  "Major mode for editing JavaScript source text.
+
+Key bindings:
+
+\\{javascript-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+
+  (use-local-map javascript-mode-map)
+  (set-syntax-table javascript-mode-syntax-table)
+  (set (make-local-variable 'indent-line-function) 'javascript-indent-line)
+  (set (make-local-variable 'font-lock-defaults) (list js-font-lock-keywords))
+
+  (set (make-local-variable 'parse-sexp-ignore-comments) t) 
+
+  ;; Comments
+  (setq comment-start "// ")
+  (setq comment-end "")
+  (set (make-local-variable 'fill-paragraph-function) 
+       'javascript-fill-paragraph)
+
+  ;; Make c-mark-function work
+  (setq c-nonsymbol-token-regexp "!=\\|%=\\|&[&=]\\|\\*[/=]\\|\\+[+=]\\|-[=-]\\|/[*/=]\\|<\\(?:<=\\|[<=]\\)\\|==\\|>\\(?:>\\(?:>=\\|[=>]\\)\\|[=>]\\)\\|\\^=\\||[=|]\\|[]!%&(-,./:-?[{-~^-]"
+        c-stmt-delim-chars "^;{}?:"
+        c-syntactic-ws-end "[ \n	
+\f/]"
+        c-syntactic-eol "\\(\\s \\|/\\*\\([^*\n
+]\\|\\*[^/\n
+]\\)*\\*/\\)*\\(\\(/\\*\\([^*\n
+]\\|\\*[^/\n
+]\\)*\\|\\\\\\)?$\\|//\\)")
+
+  ;; Imenu
+  (setq imenu-case-fold-search nil)
+  (set (make-local-variable 'imenu-generic-expression)
+       js-imenu-generic-expression)
+
+  (setq major-mode 'javascript-mode)
+  (setq mode-name "JavaScript")
+  (run-hooks 'javascript-mode-hook))
+
+
+(provide 'javascript-mode)
+;;; javascript.el ends here
diff --git a/nxhtml/alts/smarty-mode-vdebout.el b/nxhtml/alts/smarty-mode-vdebout.el
new file mode 100644
index 0000000..94d7352
--- /dev/null
+++ b/nxhtml/alts/smarty-mode-vdebout.el
@@ -0,0 +1,2715 @@
+;;; smarty-mode.el --- major mode for editing Smarty templates
+
+;; Author:       Vincent DEBOUT 
+;; Maintainer:	Vincent DEBOUT 
+;; Keywords:	languages smarty templates
+;; WWW:		http://deboutv.free.fr/lisp/smarty/
+
+;;; License
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2
+;; of the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+;;; History
+
+;; $Log: smarty-mode.el,v $
+;; Revision 1.6  2006/12/16 19:54:26  vincent
+;; Update release version
+;;
+;; Revision 1.5  2006/12/16 19:53:00  vincent
+;; Fix bug #15
+;;
+;; Revision 1.4  2006/12/16 14:59:46  vincent
+;; Fix bugs for release
+;;
+;; Revision 1.3  2006/11/19 12:29:53  vincent
+;; Fix highlight bug, add templates
+;;
+;; Revision 1.2  2006/11/12 11:44:18  vincent
+;; First release commit
+;;
+
+(defconst smarty-version "0.0.4"
+  "Smarty Mode version number.")
+
+(defconst smarty-time-stamp "2006-12-16"
+  "Smarty Mode time stamp for last update.")
+
+(require 'font-lock)
+(require 'cc-mode)
+(require 'custom)
+(require 'etags)
+(eval-when-compile
+(require 'regexp-opt))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Customization
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defgroup smarty nil
+  "Customizations for Smarty mode."
+  :prefix "smarty-"
+  :group 'languages)
+
+(defgroup smarty-mode nil
+  "Customizations for Smarty mode."
+  :group 'smarty)
+
+(defcustom smarty-electric-mode t
+  "*Non-nil enables electrification (automatic template generation).
+If nil, template generators can still be invoked through key bindings and
+menu.  Is indicated in the modeline by \"/e\" after the mode name and can be
+toggled by `\\[smarty-electric-mode]'."
+  :type 'boolean
+  :group 'smarty-mode)
+
+(defcustom smarty-stutter-mode t
+  "*Non-nil enables stuttering.
+Is indicated in the modeline by \"/s\" after the mode name and can be toggled
+by `\\[smarty-stutter-mode]'."
+  :type 'boolean
+  :group 'smarty-mode)
+
+(defgroup smarty-menu nil
+  "Customizations for menues."
+  :group 'smarty)
+
+(defcustom smarty-source-file-menu t
+  "*Non-nil means add a menu of all source files in current directory."
+  :type 'boolean
+  :group 'smarty-menu)
+
+(defgroup smarty-highlight nil
+  "Customizations for highlight."
+  :group 'smarty)
+
+(defcustom smarty-highlight-plugin-functions t
+  "*Non-nil means highlight the plugin functions in the buffer."
+  :type 'boolean
+  :group 'smarty-highlight)
+
+(defgroup smarty-template nil
+  "Customizations for templates."
+  :group 'smarty)
+
+(defgroup smarty-header nil
+  "Customizations for header template."
+  :group 'smarty-template)
+
+(defcustom smarty-file-header ""
+  "*String or file to insert as file header.
+If the string specifies an existing file name, the contents of the file is
+inserted, otherwise the string itself is inserted as file header.
+Type `C-j' for newlines.
+If the header contains RCS keywords, they may be written as Keyword
+if the header needs to be version controlled.
+
+The following keywords for template generation are supported:
+      : replaced by the name of the buffer
+        : replaced by the user name and email address
+                  \(`user-full-name',`mail-host-address', `user-mail-address')
+         : replaced by user login name (`user-login-name')
+       : replaced by contents of option `smarty-company-name'
+          : replaced by the current date
+          : replaced by the current year
+     : replaced by copyright string (`smarty-copyright-string')
+        : final cursor position."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-file-footer ""
+  "*String or file to insert as file footer.
+If the string specifies an existing file name, the contents of the file is
+inserted, otherwise the string itself is inserted as file footer (i.e. at
+the end of the file).
+Type `C-j' for newlines.
+The same keywords as in option `smarty-file-header' can be used."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-company-name ""
+  "*Name of company to insert in file header.
+See option `smarty-file-header'."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-copyright-string ""
+  "*Copyright string to insert in file header.
+Can be multi-line string (type `C-j' for newline) and contain other file
+header keywords (see option `smarty-file-header')."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-date-format "%Y-%m-%d"
+  "*Specifies the date format to use in the header.
+This string is passed as argument to the command `format-time-string'.
+For more information on format strings, see the documentation for the
+`format-time-string' command (C-h f `format-time-string')."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-modify-date-prefix-string ""
+  "*Prefix string of modification date in Smarty file header.
+If actualization of the modification date is called (menu,
+`\\[smarty-template-modify]'), this string is searched and the rest
+of the line replaced by the current date."
+  :type 'string
+  :group 'smarty-header)
+
+(defcustom smarty-modify-date-on-saving nil
+  "*Non-nil means update the modification date when the buffer is saved.
+Calls function `\\[smarty-template-modify]').
+
+NOTE: Activate the new setting in a Smarty buffer by using the menu entry
+      \"Activate Options\"."
+  :type 'boolean
+  :group 'smarty-header)
+
+(defgroup smarty-misc nil
+  "Miscellaneous customizations."
+  :group 'smarty)
+
+(defcustom smarty-left-delimiter "{"
+  "Left escaping delimiter."
+  :type 'string
+  :group 'smarty-misc)
+
+(defcustom smarty-right-delimiter "}"
+  "Right escaping delimiter."
+  :type 'string
+  :group 'smarty-misc)
+
+(defcustom smarty-intelligent-tab t
+  "*Non-nil means `TAB' does indentation, word completion and tab insertion.
+That is, if preceding character is part of a word then complete word,
+else if not at beginning of line then insert tab,
+else if last command was a `TAB' or `RET' then dedent one step,
+else indent current line (i.e. `TAB' is bound to `smarty-electric-tab').
+If nil, TAB always indents current line (i.e. `TAB' is bound to
+`indent-according-to-mode').
+
+NOTE: Activate the new setting in a Smarty buffer by using the menu entry
+      \"Activate Options\"."
+  :type 'boolean
+  :group 'smarty-misc)
+
+(defcustom smarty-word-completion-in-minibuffer t
+  "*Non-nil enables word completion in minibuffer (for template prompts).
+
+NOTE: Activate the new setting by restarting Emacs."
+  :type 'boolean
+  :group 'smarty-misc)
+
+(defcustom smarty-word-completion-case-sensitive nil
+  "*Non-nil means word completion using `TAB' is case sensitive.
+That is, `TAB' completes words that start with the same letters and case.
+Otherwise, case is ignored."
+  :type 'boolean
+  :group 'smarty-misc)
+
+;; Functions
+
+(defun smarty-customize ()
+  "Call the customize function with `smarty' as argument."
+  (interactive)
+  (customize-browse 'smarty))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Variables
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-menu-max-size 20
+  "*Specifies the maximum size of a menu before splitting it into submenues.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Menu tools functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-menu-split (list title)
+  "Split menu LIST into several submenues, if number of
+elements > `smarty-menu-max-size'."
+  (if (> (length list) smarty-menu-max-size)
+      (let ((remain list)
+	    (result '())
+	    (sublist '())
+	    (menuno 1)
+	    (i 0))
+	(while remain
+	  (setq sublist (cons (car remain) sublist))
+	  (setq remain (cdr remain))
+	  (setq i (+ i 1))
+	  (if (= i smarty-menu-max-size)
+	      (progn
+		(setq result (cons (cons (format "%s %s" title menuno)
+					 (nreverse sublist)) result))
+		(setq i 0)
+		(setq menuno (+ menuno 1))
+		(setq sublist '()))))
+	(and sublist
+	     (setq result (cons (cons (format "%s %s" title menuno)
+				      (nreverse sublist)) result)))
+	(nreverse result))
+    list))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Source file menu
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-sources-menu nil)
+
+;; Create the source menu
+(defun smarty-add-source-files-menu ()
+  "Scan directory for all Smarty source files and generate menu.
+The directory of the current source file is scanned."
+  (interactive)
+  (message "Scanning directory for source files ...")
+  (let ((newmap (current-local-map))
+	(file-list (smarty-get-source-files))
+	menu-list found)
+    ;; Create list for menu
+    (setq found nil)
+    (while file-list
+      (setq found t)
+      (setq menu-list (cons (vector (car file-list)
+				   (list 'find-file (car file-list)) t)
+			   menu-list))
+      (setq file-list (cdr file-list)))
+    (setq menu-list (smarty-menu-split menu-list "Sources"))
+    (when found (setq menu-list (cons "--" menu-list)))
+    (setq menu-list (cons ["*Rescan*" smarty-add-source-files-menu t] menu-list))
+    (setq menu-list (cons "Sources" menu-list))
+    ;; Create menu
+    (easy-menu-add menu-list)
+    (easy-menu-define smarty-sources-menu newmap
+		      "Smarty source files menu" menu-list))
+  (message ""))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Smarty menu
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-create-mode-menu ()
+  "Create Smarty Mode menu."
+  `("Smarty"
+    ("Templates"
+     ("Built-in Functions"
+      ["capture" smarty-template-capture t]
+      ["config_load" smarty-template-config-load t]
+      ["else" smarty-template-else t]
+      ["elseif" smarty-template-elseif t]
+      ["foreach" smarty-template-foreach t]
+      ["foreachelse" smarty-template-foreachelse t]
+      ["if" smarty-template-if t]
+      ["include" smarty-template-include t]
+      ["include_php" smarty-template-include-php t]
+      ["insert" smarty-template-insert t]
+      ["ldelim" smarty-template-ldelim t]
+      ["literal" smarty-template-literal t]
+      ["php" smarty-template-php t]
+      ["rdelim" smarty-template-rdelim t]
+      ["section" smarty-template-section t]
+      ["sectionelse" smarty-template-sectionelse t]
+      ["strip" smarty-template-strip t])
+     ("Custom Functions"
+      ["assign" smarty-template-assign t]
+      ["counter" smarty-template-counter t]
+      ["cycle" smarty-template-cycle t]
+      ["debug" smarty-template-debug t]
+      ["eval" smarty-template-eval t]
+      ["fetch"  smarty-template-fetch t]
+      ["html_checkboxes" smarty-template-html-checkboxes t]
+      ["html_image" smarty-template-html-image t]
+      ["html_options" smarty-template-html-options t]
+      ["html_radios" smarty-template-html-radios t]
+      ["html_select_date" smarty-template-html-select-date t]
+      ["html_select_time" smarty-template-html-select-time t]
+      ["html_table" smarty-template-html-table t]
+      ["mailto" smarty-template-mailto t]
+      ["math" smarty-template-math t]
+      ["popup" smarty-template-popup t]
+      ["popup_init" smarty-template-popup-init t]
+      ["textformat" smarty-template-textformat t])
+     ("Variable Modifiers"
+      ["capitalize" smarty-template-capitalize t]
+      ["cat" smarty-template-cat t]
+      ["count_characters" smarty-template-count-characters t]
+      ["count_paragraphs" smarty-template-count-paragraphs t]
+      ["count_sentences" smarty-template-count-sentences t]
+      ["count_words" smarty-template-count-words t]
+      ["date_format" smarty-template-date-format t]
+      ["default" smarty-template-default t]
+      ["escape" smarty-template-escape t]
+      ["indent" smarty-template-indent t]
+      ["lower" smarty-template-lower t]
+      ["nl2br" smarty-template-nl2br t]
+      ["regex_replace" smarty-template-regex-replace t]
+      ["replace" smarty-template-replace t]
+      ["spacify" smarty-template-spacify t]
+      ["string_format" smarty-template-string-format t]
+      ["strip" smarty-template-vstrip t]
+      ["strip_tags" smarty-template-strip-tags t]
+      ["truncate" smarty-template-truncate t]
+      ["upper" smarty-template-upper t]
+      ["wordwrap" smarty-template-wordwrap t])
+     ("Plugins (Functions)"
+      ("SmartyFormtool"
+       ["formtool_checkall" smarty-template-formtool-checkall t]
+       ["formtool_copy" smarty-template-formtool-copy t]
+       ["formtool_count_chars" smarty-template-formtool-count-chars t]
+       ["formtool_init" smarty-template-formtool-init t]
+       ["formtool_move" smarty-template-formtool-move t]
+       ["formtool_moveall" smarty-template-formtool-moveall t]
+       ["formtool_movedown" smarty-template-formtool-movedown t]
+       ["formtool_moveup" smarty-template-formtool-moveup t]
+       ["formtool_remove" smarty-template-formtool-remove t]
+       ["formtool_rename" smarty-template-formtool-rename t]
+       ["formtool_save" smarty-template-formtool-save t]
+       ["formtool_selectall" smarty-template-formtool-selectall t])
+      ("SmartyPaginate"
+       ["paginate_first" smarty-template-paginate-first t]
+       ["paginate_last" smarty-template-paginate-last t]
+       ["paginate_middle" smarty-template-paginate-middle t]
+       ["paginate_next" smarty-template-paginate-next t]
+       ["paginate_prev" smarty-template-paginate-prev t])
+      ("SmartyValidate"
+       ["validate" smarty-template-validate t]))
+     ("Plugins (Variable Modifiers)"
+      ("AlternativeDateModifierPlugin"
+       ["date_format2" smarty-template-date-formatto t])
+      ("B2Smilies"
+       ["B2Smilies" smarty-template-btosmilies t])
+      ("BBCodePlugin"
+       ["bbcode2html" smarty-template-bbcodetohtml t])
+      )
+     "--"
+     ["Insert Header" smarty-template-header t]
+     ["Insert Footer" smarty-template-footer t]
+     ["Insert Date" smarty-template-insert-date t]
+     ["Modify Date" smarty-template-modify t])
+    "--"
+    ["Show Messages" smarty-show-messages :keys "C-c M-m"]
+    ["Smarty Mode Documentation" smarty-doc-mode :keys "C-c C-h"]
+    ["Version" smarty-version :keys "C-c C-v"]
+    "--"
+    ("Options"
+     ("Mode"
+      ["Electric Mode"
+       (progn (customize-set-variable 'smarty-electric-mode
+				      (not smarty-electric-mode))
+	      (smarty-mode-line-update))
+       :style toggle :selected smarty-electric-mode :keys "C-c C-m C-e"]
+      ["Stutter Mode"
+       (progn (customize-set-variable 'smarty-stutter-mode
+				      (not smarty-stutter-mode))
+	      (smarty-mode-line-update))
+       :style toggle :selected smarty-stutter-mode :keys "C-c C-m C-s"]
+      "--"
+      ["Customize Group..." (customize-group 'smarty-mode) t])
+     ("Menu"
+      ["Source Menu"
+       (customize-set-variable 'smarty-source-file-menu
+			       (not smarty-source-file-menu))
+       :style toggle :selected smarty-source-file-menu]
+      "--"
+      ["Customize Group..." (customize-group 'smarty-menu) t])
+     ("Highlight"
+      ["Highlight plugin functions"
+       (progn (customize-set-variable 'smarty-highlight-plugin-functions
+				      (not smarty-highlight-plugin-functions)))
+       :style toggle :selected smarty-highlight-plugin-functions]
+      "--"
+      ["Customize Group..." (customize-group 'smarty-highlight) t])
+     ("Template"
+      ("Header"
+       ["Header template..."
+	(customize-option 'smarty-file-header) t]
+       ["Footer template..."
+	(customize-option 'smarty-file-footer) t]
+       ["Company..."
+	(customize-option 'smarty-company-name) t]
+       ["Copyright..."
+	(customize-option 'smarty-copyright-string) t]
+       ["Date format..."
+	(customize-option 'smarty-date-format) t]
+       ["Modify date prefix..."
+	(customize-option 'smarty-modify-date-prefix-string) t]
+       ["Modify date on saving"
+	(customize-set-variable 'smarty-modify-date-on-saving
+				(not smarty-modify-date-on-saving))
+	:style toggle :selected smarty-modify-date-on-saving]
+       "--"
+       ["Customize Group..." (customize-group 'smarty-header) t])
+      "--"
+      ["Customize Group..." (customize-group 'smarty-template) t])
+     ("Miscellaneous"
+      ["Left delimiter..."
+       (customize-option 'smarty-left-delimiter) t]
+      ["Right delimiter..."
+       (customize-option 'smarty-right-delimiter) t]
+      ["Use Intelligent Tab"
+       (progn (customize-set-variable 'smarty-intelligent-tab
+				      (not smarty-intelligent-tab))
+	      (smarty-activate-customizations))
+       :style toggle :selected smarty-intelligent-tab]
+      ["Word Completion in Minibuffer"
+       (progn (customize-set-variable 'smarty-word-completion-in-minibuffer
+				      (not smarty-word-completion-in-minibuffer))
+	      (message "Activate new setting by saving options and restarting Emacs"))
+       :style toggle :selected smarty-word-completion-in-minibuffer]
+      ["Completion is case sensitive"
+       (customize-set-variable 'smarty-word-completion-case-sensitive
+			       (not smarty-word-completion-case-sensitive))
+       :style toggle :selected smarty-word-completion-case-sensitive]
+      "--"
+      ["Customize Group..." (customize-group 'smarty-misc) t])
+     "--"
+     ["Save Options" customize-save-customized t]
+     ["Activate Options" smarty-activate-customizations t]
+     ["Browse Options..." smarty-customize t])))
+
+(defvar smarty-mode-menu-list (smarty-create-mode-menu)
+  "Smarty Mode menu.")
+
+(defvar smarty-mode-map nil
+  "Keymap for Smarty Mode.")
+
+(defun smarty-update-mode-menu ()
+  "Update Smarty Mode menu."
+  (interactive)
+  (easy-menu-remove smarty-mode-menu-list)
+  (setq smarty-mode-menu-list (smarty-create-mode-menu))
+  (easy-menu-add smarty-mode-menu-list)
+  (easy-menu-define smarty-mode-menu smarty-mode-map
+		    "Menu keymap for Smarty Mode." smarty-mode-menu-list))
+
+
+
+
+(defvar smarty-mode-hook nil)
+
+(defvar smarty-functions nil
+  "List of Smarty functions.")
+
+(defvar smarty-functions-regexp nil
+  "Regexp for Smarty functions.")
+
+(defconst smarty-01-functions
+  '("capture" "config_load" "foreach" "foreachelse" "include" 
+    "include_php" "insert" "if" "elseif" "else" "ldelim" "rdelim"
+    "literal" "php" "section" "sectionelse" "strip" "assign" "counter"
+    "cycle" "debug" "eval" "fetch" "html_checkboxes" "html_image"
+    "html_options" "html_radios" "html_select_date" "html_select_time"
+    "html_table" "math" "mailto" "popup_init" "popup" "textformat")
+  "Smarty built-in & custom functions.")
+
+(defvar smarty-modifiers nil
+  "List of Smarty variable modifiers.")
+
+(defvar smarty-modifiers-regexp nil
+  "Regexp for Smarty variable modifiers.")
+
+(defconst smarty-01-modifiers
+  '("capitalize" "cat" "count_characters" "count_paragraphs"
+    "count_sentences" "count_words" "date_format" "default"
+    "escape" "indent" "lower" "nl2br" "regex_replace" "replace"
+    "spacify" "string_format" "strip" "strip_tags" "truncate"
+    "upper" "wordwrap")
+  "Smarty variable modifiers.")
+
+(defvar smarty-plugins-functions nil
+  "List of Smarty functions.")
+
+(defvar smarty-plugins-functions-regexp nil
+  "Regexp for Smarty functions.")
+
+(defconst smarty-01-plugins-functions
+  '("validate" "formtool_checkall" "formtool_copy" "formtool_count_chars"
+    "formtool_init" "formtool_move" "formtool_moveall"
+    "formtool_movedown" "formtool_moveup" "formtool_remove"
+    "formtool_rename" "formtool_save" "formtool_selectall"
+    "paginate_first" "paginate_last" "paginate_middle" 
+    "paginate_next" "paginate_prev")
+  "Smarty plugins functions.")
+
+(defvar smarty-plugins-modifiers nil
+  "List of Smarty variable modifiers.")
+
+(defvar smarty-plugins-modifiers-regexp nil
+  "Regexp for Smarty functions.")
+
+(defconst smarty-01-plugins-modifiers
+  '("B2Smilies" "bbcode2html" "date_format2")
+  "Smarty plugins modifiers.")
+
+(defconst smarty-constants
+  (eval-when-compile
+	(regexp-opt
+	 '("TRUE" "FALSE" "NULL") t))
+  "Smarty constants.")
+	   
+	
+;; Syntax table creation
+(defvar smarty-mode-syntax-table nil
+  "Syntax table for smarty-mode.")
+
+(defvar smarty-mode-ext-syntax-table nil
+  "Syntax table extended by `_' used in `smarty-mode' buffers.")
+
+(defun smarty-create-syntax-table ()
+  (if smarty-mode-syntax-table
+      ()
+    (setq smarty-mode-syntax-table (make-syntax-table))
+    
+    ;; Make | a punctuation character
+    (modify-syntax-entry ?| "." smarty-mode-syntax-table)
+    ;; Make " a punctuation character so highlighing works withing html strings
+    (modify-syntax-entry ?\" "." smarty-mode-syntax-table)
+    ;; define parentheses to match
+    (modify-syntax-entry ?\( "()"   smarty-mode-syntax-table)
+    (modify-syntax-entry ?\) ")("   smarty-mode-syntax-table)
+    (modify-syntax-entry ?\[ "(]"   smarty-mode-syntax-table)
+    (modify-syntax-entry ?\] ")["   smarty-mode-syntax-table)
+    (modify-syntax-entry ?\{ "(}"   smarty-mode-syntax-table)
+    (modify-syntax-entry ?\} "){"   smarty-mode-syntax-table)
+    )
+  (set-syntax-table smarty-mode-syntax-table)
+  ;; extended syntax table including '_' (for simpler search regexps)
+  (setq smarty-mode-ext-syntax-table (copy-syntax-table smarty-mode-syntax-table))
+  (modify-syntax-entry ?_ "w" smarty-mode-ext-syntax-table))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; File/directory manipulation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-directory-files (directory &optional full match)
+  "Call `directory-files' if DIRECTORY exists, otherwise generate error
+message."
+  (if (not (file-directory-p directory))
+      (smarty-warning-when-idle "No such directory: \"%s\"" directory)
+    (let ((dir (directory-files directory full match)))
+      (setq dir (delete "." dir))
+      (setq dir (delete ".." dir))
+      dir)))
+
+(defun smarty-get-source-files (&optional full directory)
+  "Get list of SMARTY source files in DIRECTORY or current directory."
+  (let ((mode-alist auto-mode-alist)
+	filename-regexp)
+    ;; create regular expressions for matching file names
+    (setq filename-regexp "\\`[^.].*\\(")
+    (while mode-alist
+      (when (eq (cdar mode-alist) 'smarty-mode)
+	(setq filename-regexp
+	      (concat filename-regexp (caar mode-alist) "\\|")))
+      (setq mode-alist (cdr mode-alist)))
+    (setq filename-regexp
+	  (concat (substring filename-regexp 0
+			     (string-match "\\\\|$" filename-regexp)) "\\)"))
+    ;; find files
+    (smarty-directory-files
+     (or directory default-directory) full filename-regexp)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Messages reporting
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-warnings nil
+  "Warnings to tell the user during start up.")
+
+(defun smarty-run-when-idle (secs repeat function)
+  "Wait until idle, then run FUNCTION."
+  (if (fboundp 'start-itimer)
+      (start-itimer "smarty-mode" function secs repeat t)
+;    (run-with-idle-timer secs repeat function)))
+    ;; explicitely activate timer (necessary when Emacs is already idle)
+    (aset (run-with-idle-timer secs repeat function) 0 nil)))
+
+(defun smarty-warning-when-idle (&rest args)
+  "Wait until idle, then print out warning STRING and beep."
+  (if noninteractive
+      (smarty-warning (apply 'format args) t)
+    (unless smarty-warnings
+      (smarty-run-when-idle .1 nil 'smarty-print-warnings))
+    (setq smarty-warnings (cons (apply 'format args) smarty-warnings))))
+
+(defun smarty-warning (string &optional nobeep)
+  "Print out warning STRING and beep."
+  (message (concat "WARNING:  " string))
+  (unless (or nobeep noninteractive) (beep)))
+
+(defun smarty-print-warnings ()
+  "Print out messages in variable `smarty-warnings'."
+  (let ((no-warnings (length smarty-warnings)))
+    (setq smarty-warnings (nreverse smarty-warnings))
+    (while smarty-warnings
+      (message (concat "WARNING:  " (car smarty-warnings)))
+      (setq smarty-warnings (cdr smarty-warnings)))
+    (beep)
+    (when (> no-warnings 1)
+      (message "WARNING:  See warnings in message buffer (type `C-c M-m')."))))
+
+(defun smarty-show-messages ()
+  "Get *Messages* buffer to show recent messages."
+  (interactive)
+  (display-buffer " *Message-Log*"))
+
+(defun smarty-version ()
+  "Echo the current version of Smarty Mode in the minibuffer."
+  (interactive)
+  (message "Smarty Mode %s (%s)" smarty-version smarty-time-stamp)
+  (smarty-keep-region-active))
+
+;; active regions
+(defun smarty-keep-region-active ()
+  "Do whatever is necessary to keep the region active in XEmacs.
+Ignore byte-compiler warnings you might see."
+  (and (boundp 'zmacs-region-stays)
+       (setq zmacs-region-stays t)))
+
+(defmacro smarty-prepare-search-1 (&rest body)
+  "Enable case insensitive search and switch to syntax table that includes '_',
+then execute BODY, and finally restore the old environment.  Used for
+consistent searching."
+  `(let ((case-fold-search t)		; case insensitive search
+	 (current-syntax-table (syntax-table))
+	 result
+	 (restore-prog			; program to restore enviroment
+	  '(progn
+	     ;; restore syntax table
+	     (set-syntax-table current-syntax-table))))
+     ;; use extended syntax table
+     (set-syntax-table smarty-mode-ext-syntax-table)
+     ;; execute BODY safely
+     (setq result
+	   (condition-case info
+	       (progn ,@body)
+	     (error (eval restore-prog)	; restore environment on error
+		    (error (cadr info))))) ; pass error up
+     ;; restore environment
+     (eval restore-prog)
+     result))
+
+(defmacro smarty-prepare-search-2 (&rest body)
+  "Enable case insensitive search, switch to syntax table that includes '_',
+and remove `intangible' overlays, then execute BODY, and finally restore the
+old environment.  Used for consistent searching."
+  `(let ((case-fold-search t)		; case insensitive search
+	 (current-syntax-table (syntax-table))
+	 result overlay-all-list overlay-intangible-list overlay
+	 (restore-prog			; program to restore enviroment
+	  '(progn
+	     ;; restore syntax table
+	     (set-syntax-table current-syntax-table)
+	     ;; restore `intangible' overlays
+	     (when (fboundp 'overlay-lists)
+	       (while overlay-intangible-list
+		 (overlay-put (car overlay-intangible-list) 'intangible t)
+		 (setq overlay-intangible-list
+		       (cdr overlay-intangible-list)))))))
+     ;; use extended syntax table
+     (set-syntax-table smarty-mode-ext-syntax-table)
+     ;; remove `intangible' overlays
+     (when (fboundp 'overlay-lists)
+       (setq overlay-all-list (overlay-lists))
+       (setq overlay-all-list
+	     (append (car overlay-all-list) (cdr overlay-all-list)))
+       (while overlay-all-list
+	 (setq overlay (car overlay-all-list))
+	 (when (memq 'intangible (overlay-properties overlay))
+	   (setq overlay-intangible-list
+		 (cons overlay overlay-intangible-list))
+	   (overlay-put overlay 'intangible nil))
+	 (setq overlay-all-list (cdr overlay-all-list))))
+     ;; execute BODY safely
+     (setq result
+	   (condition-case info
+	       (progn ,@body)
+	     (error (eval restore-prog)	; restore environment on error
+		    (error (cadr info))))) ; pass error up
+     ;; restore environment
+     (eval restore-prog)
+     result))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;  Enabling/disabling
+
+(defun smarty-mode-line-update ()
+  "Update the modeline string for Smarty major mode."
+  (setq mode-name (concat "Smarty"
+			  (and (or smarty-electric-mode smarty-stutter-mode) "/")
+			  (and smarty-electric-mode "e")
+			  (and smarty-stutter-mode "s")))
+  (force-mode-line-update t))
+
+(defun smarty-electric-mode (arg)
+  "Toggle Smarty electric mode.
+Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
+  (interactive "P")
+  (setq smarty-electric-mode
+	(cond ((or (not arg) (zerop arg)) (not smarty-electric-mode))
+	      ((> arg 0) t) (t nil)))
+  (smarty-mode-line-update))
+
+(defun smarty-stutter-mode (arg)
+  "Toggle Smarty stuttering mode.
+Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
+  (interactive "P")
+  (setq smarty-stutter-mode
+	(cond ((or (not arg) (zerop arg)) (not smarty-stutter-mode))
+	      ((> arg 0) t) (t nil)))
+  (smarty-mode-line-update))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Smarty code delimitation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-in-literal ()
+  "Determine if point is in a Smarty literal."
+  (save-excursion
+    (let ((here (point))
+	  start state)
+      (beginning-of-line)
+      (setq start (point))
+      (goto-char here)
+      (setq state (parse-partial-sexp start (point)))
+      (cond
+       ((nth 3 state) 'string)
+       ((nth 4 state) 'comment)
+       (t nil)))))
+
+(defun smarty-in-comment-p ()
+  "Check if point is in a comment."
+  (let ((result nil) (here (point-marker)) found)
+    (save-excursion
+      (setq found (re-search-backward (regexp-quote (concat smarty-left-delimiter "*")) nil t))
+      (when found
+	(setq result (re-search-forward (regexp-quote (concat "*" smarty-right-delimiter)) here t))
+	(setq result (not result))))
+    result))
+
+(defun smarty-after-ldelim ()
+  "Check that the previous character is the left delimiter."
+  (let ((here (point-marker)) ldelim-found ldelim-point)
+    (save-excursion
+      (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
+      (re-search-forward (regexp-quote smarty-left-delimiter) here t)
+      (setq ldelim-point (point-marker))
+      (goto-char here)
+      (if (and (= here ldelim-point) ldelim-found)
+	  t
+	nil))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Words to expand
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-words-init ()
+  "Initialize reserved words."
+  (setq smarty-functions smarty-01-functions)
+  (setq smarty-modifiers smarty-01-modifiers)
+  (setq smarty-plugins-functions smarty-01-plugins-functions)
+  (setq smarty-plugins-modifiers smarty-01-plugins-modifiers)
+  (setq smarty-functions-regexp (concat "\\<\\(" (regexp-opt smarty-functions) "\\)\\>"))
+  (setq smarty-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-modifiers) "\\)\\>"))
+  (setq smarty-plugins-functions-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-functions) "\\)\\>"))
+  (setq smarty-plugins-modifiers-regexp (concat "\\<\\(" (regexp-opt smarty-plugins-modifiers) "\\)\\>"))
+  (smarty-abbrev-list-init))
+
+(defvar smarty-abbrev-list nil
+  "Predefined abbreviations for Smarty.")
+
+(defun smarty-abbrev-list-init ()
+  (setq smarty-abbrev-list
+	(append
+	 (list nil) smarty-functions
+	 (list nil) smarty-modifiers
+	 (list nil) smarty-plugins-functions
+	 (list nil) smarty-plugins-modifiers)))
+
+(defvar smarty-expand-upper-case nil)
+
+(defun smarty-try-expand-abbrev (old)
+  "Try expanding abbreviations from `smarty-abbrev-list'."
+  (unless old
+    (he-init-string (he-dabbrev-beg) (point))
+    (setq he-expand-list
+	  (let ((abbrev-list smarty-abbrev-list)
+		(sel-abbrev-list '()))
+	    (while abbrev-list
+	   ;   (if (stringp (car abbrev-list))
+		;  (insert (concat " " (car abbrev-list))))
+	      (when (or (not (stringp (car abbrev-list)))
+			(string-match
+			 (concat "^" he-search-string) (car abbrev-list)))
+		(setq sel-abbrev-list
+		      (cons (car abbrev-list) sel-abbrev-list)))
+	      (setq abbrev-list (cdr abbrev-list)))
+	    (nreverse sel-abbrev-list))))
+  (while (and he-expand-list
+	      (or (not (stringp (car he-expand-list)))
+		  (he-string-member (car he-expand-list) he-tried-table t)))
+    (unless (stringp (car he-expand-list))
+      (setq smarty-expand-upper-case (car he-expand-list)))
+    (setq he-expand-list (cdr he-expand-list)))
+  (if (null he-expand-list)
+      (progn (when old (he-reset-string))
+	     nil)
+    (he-substitute-string
+     (if smarty-expand-upper-case
+	 (upcase (car he-expand-list))
+       (car he-expand-list))
+     t)
+    (setq he-expand-list (cdr he-expand-list))
+    t))
+
+;; initialize reserved words for Smarty Mode
+(smarty-words-init)
+
+;; function for expanding abbrevs and dabbrevs
+(defun smarty-expand-abbrev (arg))
+(fset 'smarty-expand-abbrev (make-hippie-expand-function
+			   '(try-expand-dabbrev
+			     try-expand-dabbrev-all-buffers
+			     smarty-try-expand-abbrev)))
+
+;; function for expanding parenthesis
+(defun smarty-expand-paren (arg))
+(fset 'smarty-expand-paren (make-hippie-expand-function
+			  '(try-expand-list
+			    try-expand-list-all-buffers)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Stuttering
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-electric-tab (&optional prefix-arg)
+  "If preceding character is part of a word or a paren then hippie-expand,
+else if right of non whitespace on line then insert tab,
+else if last command was a tab or return then dedent one step or if a comment
+toggle between normal indent and inline comment indent,
+else indent `correctly'."
+  (interactive "*P")
+  (smarty-prepare-search-2
+   (cond
+    ;; expand word
+    ((= (char-syntax (preceding-char)) ?w)
+     (let ((case-fold-search (not smarty-word-completion-case-sensitive))
+	   (case-replace nil)
+	   (hippie-expand-only-buffers
+	    (or (and (boundp 'hippie-expand-only-buffers)
+		     hippie-expand-only-buffers)
+		'(smarty-mode))))
+       (smarty-expand-abbrev prefix-arg)))
+    ;; expand parenthesis
+    ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
+     (let ((case-fold-search (not smarty-word-completion-case-sensitive))
+	   (case-replace nil))
+       (smarty-expand-paren prefix-arg))))
+   (setq this-command 'smarty-electric-tab)))
+
+(defun smarty-electric-space (count)
+  "Expand abbreviations and self-insert space(s)."
+  (interactive "p")
+  (let ((here (point-marker)) ldelim-found ldelim-point rdelim-found rdelim-point
+	delete-a)
+    (setq ldelim-found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
+    (re-search-forward (regexp-quote smarty-left-delimiter) here t)
+    (setq ldelim-point (point-marker))
+    (goto-char here)
+    (setq rdelim-found (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t))
+    (re-search-forward (regexp-quote (concat " " smarty-right-delimiter)) here t)
+    (setq rdelim-point (point-marker))
+    (goto-char here)
+  (cond ((and (= here ldelim-point) ldelim-found) (insert (concat "ldelim" smarty-right-delimiter)))
+	((and (= here rdelim-point) rdelim-found) 
+	 (re-search-backward (regexp-quote (concat " " smarty-right-delimiter)) nil t)
+	 (delete-char 1)
+	 (insert (concat " " smarty-left-delimiter "rdelim"))
+	 (goto-char here))
+	((smarty-in-comment-p)
+	 (self-insert-command count)
+	 (cond ((>= (current-column) (+ 2 end-comment-column))
+		(backward-char 1)
+		(skip-chars-backward "^ \t\n")
+		(indent-new-comment-line)
+		(skip-chars-forward "^ \t\n")
+		(forward-char 1))
+	       ((>= (current-column) end-comment-column)
+		(indent-new-comment-line))
+	       (t nil)))
+	((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z))
+	     (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z))
+	     (and (>= (preceding-char) ?0) (<= (preceding-char) ?9)))
+	 (progn 
+	   (setq here (point-marker))
+	   (insert " ")
+	   (setq delete-a t)
+	   (if (re-search-backward "|" nil t)
+	       (progn 
+		 (setq found (re-search-forward (regexp-quote "B2Smilies") here t))
+		 (if (and found (= here (point-marker)))
+		     (replace-match "btosmilies")
+		   (setq found (re-search-forward (regexp-quote "bbcode2html") here t))
+		   (if (and found (= here (point-marker)))
+		       (replace-match "bbcodetohtml")
+		     (setq found (re-search-forward (regexp-quote "date_format2") here t))
+		     (if (and found (= here (point-marker)))
+			 (replace-match "date_formatto")
+		       (goto-char here)
+		       (setq delete-a nil)
+		       (delete-char 1)))))
+	     (goto-char here)
+	     (setq delete-a nil)
+	     (delete-char 1)))
+	 (smarty-prepare-search-1 (expand-abbrev))
+	 (self-insert-command count)
+	 (if (and delete-a (looking-at " "))
+	     (delete-char 1)))
+	(t (self-insert-command count)))))
+
+(defun smarty-electric-open-bracket (count) 
+  "'(' --> '(', '((' --> '[', '[(' --> '{'"
+  (interactive "p")
+  (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
+      (if (= (preceding-char) ?\()
+	  (progn (delete-char -1) (insert-char ?\[ 1))
+	(if (= (preceding-char) ?\[)
+	    (progn (delete-char -1) (insert-char ?\{ 1))
+	  (insert-char ?\( 1)))
+    (self-insert-command count)))
+
+(defun smarty-electric-close-bracket (count) 
+  "')' --> ')', '))' --> ']', '])' --> '}'"
+  (interactive "p")
+  (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
+      (progn
+	(if (= (preceding-char) ?\))
+	    (progn (delete-char -1) (insert-char ?\] 1))
+	  (if (= (preceding-char) ?\])
+	      (progn (delete-char -1) (insert-char ?} 1))
+	    (insert-char ?\) 1)))
+	(blink-matching-open))
+    (self-insert-command count)))
+
+(defun smarty-electric-star (count) 
+  "After a left delimiter add a right delemiter to close the comment"
+  (interactive "p")
+  (let ((here (point-marker)) found)
+    (if (and smarty-stutter-mode (= count 1) (not (smarty-in-literal)))
+	(progn
+	  (setq found (re-search-backward (regexp-quote smarty-left-delimiter) nil t))
+	  (re-search-forward (regexp-quote smarty-left-delimiter) here t)
+	  (if (not (and (= here (point-marker)) found))
+	      (progn (goto-char here)
+		     (self-insert-command count))
+	    (self-insert-command count)
+	    (insert " ")
+	    (setq here (point-marker))
+	    (insert " *")
+	    (insert smarty-right-delimiter)
+	    (goto-char here)))
+      (self-insert-command count))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Electrification
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst smarty-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]"
+  "Syntax of prompt inserted by template generators.")
+
+(defvar smarty-template-invoked-by-hook nil
+  "Indicates whether a template has been invoked by a hook or by key or menu.
+Used for undoing after template abortion.")
+
+(defun smarty-minibuffer-tab (&optional prefix-arg)
+  "If preceding character is part of a word or a paren then hippie-expand,
+else insert tab (used for word completion in Smarty minibuffer)."
+  (interactive "P")
+  (cond
+   ;; expand word
+   ((= (char-syntax (preceding-char)) ?w)
+    (let ((case-fold-search (not smarty-word-completion-case-sensitive))
+	  (case-replace nil)
+	  (hippie-expand-only-buffers
+	   (or (and (boundp 'hippie-expand-only-buffers)
+		    hippie-expand-only-buffers)
+	       '(smarty-mode))))
+      (smarty-expand-abbrev prefix-arg)))
+   ;; expand parenthesis
+   ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
+    (let ((case-fold-search (not smarty-word-completion-case-sensitive))
+	  (case-replace nil))
+      (smarty-expand-paren prefix-arg)))
+   ;; insert tab
+   (t (insert-tab))))
+
+;; correct different behavior of function `unread-command-events' in XEmacs
+(defun smarty-character-to-event (arg))
+(defalias 'smarty-character-to-event
+  (if (fboundp 'character-to-event) 'character-to-event 'identity))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Abbrev ook bindings
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-mode-abbrev-table nil
+  "Abbrev table to use in `smarty-mode' buffers.")
+
+(defun smarty-mode-abbrev-table-init ()
+  "Initialize `smarty-mode-abbrev-table'."
+  (when smarty-mode-abbrev-table (clear-abbrev-table smarty-mode-abbrev-table))
+  (define-abbrev-table 'smarty-mode-abbrev-table
+    (append
+     '(
+       ("capture" "" smarty-template-capture-hook 0)
+       ("config_load" "" smarty-template-config-load-hook 0)
+       ("else" "" smarty-template-else-hook 0)
+       ("elseif" "" smarty-template-elseif-hook 0)
+       ("foreach" "" smarty-template-foreach-hook 0)
+       ("foreachelse" "" smarty-template-foreachelse-hook 0)
+       ("if" "" smarty-template-if-hook 0)
+       ("include" "" smarty-template-include-hook 0)
+       ("include_php" "" smarty-template-include-php-hook 0)
+       ("insert" "" smarty-template-insert-hook 0)
+       ("ldelim" "" smarty-template-ldelim-hook 0)
+       ("literal" "" smarty-template-literal-hook 0)
+       ("php" "" smarty-template-php-hook 0)
+       ("rdelim" "" smarty-template-rdelim-hook 0)
+       ("section" "" smarty-template-section-hook 0)
+       ("sectionelse" "" smarty-template-sectionelse-hook 0)
+       ("strip" "" smarty-template-strip-hook 0)
+       ("assign" "" smarty-template-assign-hook 0)
+       ("counter" "" smarty-template-counter-hook 0)
+       ("cycle" "" smarty-template-cycle-hook 0)
+       ("debug" "" smarty-template-debug-hook 0)
+       ("eval" "" smarty-template-eval-hook 0)
+       ("fetch" ""  smarty-template-fetch-hook 0)
+       ("html_checkboxes" "" smarty-template-html-checkboxes-hook 0)
+       ("html_image" "" smarty-template-html-image-hook 0)
+       ("html_options" "" smarty-template-html-options-hook 0)
+       ("html_radios" "" smarty-template-html-radios-hook 0)
+       ("html_select_date" "" smarty-template-html-select-date-hook 0)
+       ("html_select_time" "" smarty-template-html-select-time-hook 0)
+       ("html_table" "" smarty-template-html-table-hook 0)
+       ("mailto" "" smarty-template-mailto-hook 0)
+       ("math" "" smarty-template-math-hook 0)
+       ("popup" "" smarty-template-popup-hook 0)
+       ("popup_init" "" smarty-template-popup-init-hook 0)
+       ("textformat" "" smarty-template-textformat-hook 0)
+       ("capitalize" "" smarty-template-capitalize-hook 0)
+       ("cat" "" smarty-template-cat-hook 0)
+       ("count_characters" "" smarty-template-count-characters-hook 0)
+       ("count_paragraphs" "" smarty-template-count-paragraphs-hook 0)
+       ("count_sentences" "" smarty-template-count-sentences-hook 0)
+       ("count_words" "" smarty-template-count-words-hook 0)
+       ("date_format" "" smarty-template-date-format-hook 0)
+       ("default" "" smarty-template-default-hook 0)
+       ("escape" "" smarty-template-escape-hook 0)
+       ("indent" "" smarty-template-indent-hook 0)
+       ("lower" "" smarty-template-lower-hook 0)
+       ("nl2br" "" smarty-template-nl2br-hook 0)
+       ("regex_replace" "" smarty-template-regex-replace-hook 0)
+       ("replace" "" smarty-template-replace-hook 0)
+       ("spacify" "" smarty-template-spacify-hook 0)
+       ("string_format" "" smarty-template-string-format-hook 0)
+       ("strip" "" smarty-template-vstrip-hook 0)
+       ("strip_tags" "" smarty-template-strip-tags-hook 0)
+       ("truncate" "" smarty-template-truncate-hook 0)
+       ("upper" "" smarty-template-upper-hook 0)
+       ("wordwrap" "" smarty-template-wordwrap-hook 0)
+       ("validate" "" smarty-template-validate-hook 0)
+       ("formtool_checkall" "" smarty-template-formtool-checkall-hook 0)
+       ("formtool_copy" "" smarty-template-formtool-copy-hook 0)
+       ("formtool_count_chars" "" smarty-template-formtool-count-chars-hook 0)
+       ("formtool_init" "" smarty-template-formtool-init-hook 0)
+       ("formtool_move" "" smarty-template-formtool-move-hook 0)
+       ("formtool_moveall" "" smarty-template-formtool-moveall-hook 0)
+       ("formtool_movedown" "" smarty-template-formtool-movedown-hook 0)
+       ("formtool_moveup" "" smarty-template-formtool-moveup-hook 0)
+       ("formtool_remove" "" smarty-template-formtool-remove-hook 0)
+       ("formtool_rename" "" smarty-template-formtool-rename-hook 0)
+       ("formtool_save" "" smarty-template-formtool-save-hook 0)
+       ("formtool_selectall" "" smarty-template-formtool-selectall-hook 0)
+       ("paginate_first" "" smarty-template-paginate-first-hook 0)
+       ("paginate_last" "" smarty-template-paginate-last-hook 0)
+       ("paginate_middle" "" smarty-template-paginate-middle-hook 0)
+       ("paginate_next" "" smarty-template-paginate-next-hook 0)
+       ("paginate_prev" "" smarty-template-paginate-prev-hook 0)
+       ("btosmilies" "" smarty-template-btosmilies-hook 0)
+       ("bbcodetohtml" "" smarty-template-bbcodetohtml-hook 0)
+       ("date_formatto" "" smarty-template-date-formatto-hook 0)))))
+
+;; initialize abbrev table for Smarty Mode
+(smarty-mode-abbrev-table-init)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Abbrev hooks
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-hooked-abbrev (func)
+  "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev,
+but not if inside a comment or quote)."
+  (if (or (smarty-in-literal)
+	  (smarty-in-comment-p))
+      (progn
+	(insert " ")
+	(unexpand-abbrev)
+	(delete-char -1))
+    (if (not smarty-electric-mode)
+	(progn
+	  (insert " ")
+	  (unexpand-abbrev)
+	  (backward-word 1)
+	  (delete-char 1))
+      (let ((invoke-char last-command-char)
+	    (abbrev-mode -1)
+	    (smarty-template-invoked-by-hook t))
+	(let ((caught (catch 'abort
+			(funcall func))))
+	  (when (stringp caught) (message caught)))
+	(when (= invoke-char ?-) (setq abbrev-start-location (point)))
+	;; delete CR which is still in event queue
+	(if (fboundp 'enqueue-eval-event)
+	    (enqueue-eval-event 'delete-char -1)
+	  (setq unread-command-events	; push back a delete char
+		(list (smarty-character-to-event ?\177))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Fontification
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-font-lock-keywords-1
+  (list
+   
+   ;; Fontify built-in functions
+   (cons
+	(concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-functions-regexp)
+	'(1 font-lock-keyword-face))
+
+   (cons
+	(concat "\\<\\(" smarty-constants "\\)\\>")
+	'font-lock-constant-face)
+
+   (cons (concat "\\(" (regexp-quote (concat smarty-left-delimiter "*")) "\\(\\s-\\|\\w\\|\\s.\\|\\s_\\|\\s(\\|\\s)\\|\\s\\\\)*" (regexp-quote (concat "*" smarty-right-delimiter)) "\\)") 
+	 'font-lock-comment-face)
+
+   )
+  "Subdued level highlighting for Smarty mode.") 
+
+(defconst smarty-font-lock-keywords-2
+  (append
+   smarty-font-lock-keywords-1  
+   (list
+
+	;; Fontify variable names (\\sw\\|\\s_\\) matches any word character +
+	;; underscore
+	'("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face)) ; $variable
+	'("->\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; ->variable
+	'("\\.\\(\\(?:\\sw\\|\\s_\\)+\\)" (1 font-lock-variable-name-face t t)) ; .variable
+	'("->\\(\\(?:\\sw\\|\\s_\\)+\\)\\s-*(" (1 font-lock-function-name-face t t)) ; ->function_call
+	'("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)(" (1 font-lock-function-name-face)) ; word(
+	'("\\<\\(\\(?:\\sw\\|\\s_\\)+\\s-*\\)[[]" (1 font-lock-variable-name-face)) ; word[
+	'("\\<[0-9]+" . default)			; number (also matches word)
+
+	;; Fontify strings
+	;;'("\"\\([^\"]*\\)\"[^\"]+" (1 font-lock-string-face t t))
+	))
+  
+   "Medium level highlighting for Smarty mode.")
+
+(defconst smarty-font-lock-keywords-3
+  (append
+   smarty-font-lock-keywords-2
+   (list
+    ;; Fontify modifiers
+    (cons (concat "|\\(" smarty-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face))
+    (cons (concat "|\\(" smarty-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face))
+    
+    ;; Fontify config vars
+    (cons (concat (regexp-quote smarty-left-delimiter) "\\(#\\(?:\\sw\\|\\s_\\)+#\\)") '(1 font-lock-constant-face))))
+  "Balls-out highlighting for Smarty mode.")
+
+(defconst smarty-font-lock-keywords-4
+  (append
+   smarty-font-lock-keywords-3
+   (list
+    ;; Fontify plugin functions
+    (cons
+     (concat (regexp-quote smarty-left-delimiter) "[/]*" smarty-plugins-functions-regexp)
+     '(1 font-lock-keyword-face))
+
+    (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)[:|]+") '(1 font-lock-function-name-face))
+    (cons (concat "|\\(" smarty-plugins-modifiers-regexp "\\)" (regexp-quote smarty-right-delimiter)) '(1 font-lock-function-name-face)))))
+
+(defvar smarty-font-lock-keywords smarty-font-lock-keywords-3
+  "Default highlighting level for Smarty mode")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Mode map
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar smarty-template-map nil
+  "Keymap for Smarty templates.")
+
+(defun smarty-template-map-init ()
+  "Initialize `smarty-template-map'."
+  (setq smarty-template-map (make-sparse-keymap))
+  ;; key bindings for Smarty templates
+  (define-key smarty-template-map "\C-ba" 'smarty-template-capture)
+  (define-key smarty-template-map "\C-bc" 'smarty-template-config-load)
+  (define-key smarty-template-map "\C-b\M-e" 'smarty-template-else)
+  (define-key smarty-template-map "\C-b\C-e" 'smarty-template-elseif)
+  (define-key smarty-template-map "\C-b\C-f" 'smarty-template-foreach)
+  (define-key smarty-template-map "\C-b\M-f" 'smarty-template-foreachelse)
+  (define-key smarty-template-map "\C-bf" 'smarty-template-if)
+  (define-key smarty-template-map "\C-b\C-i" 'smarty-template-include)
+  (define-key smarty-template-map "\C-b\M-i" 'smarty-template-include-php)
+  (define-key smarty-template-map "\C-bi" 'smarty-template-insert)
+  (define-key smarty-template-map "\C-bl" 'smarty-template-ldelim)
+  (define-key smarty-template-map "\C-b\C-l" 'smarty-template-literal)
+  (define-key smarty-template-map "\C-bp" 'smarty-template-php)
+  (define-key smarty-template-map "\C-br" 'smarty-template-rdelim)
+  (define-key smarty-template-map "\C-b\C-s" 'smarty-template-section)
+  (define-key smarty-template-map "\C-b\M-s" 'smarty-template-sectionelse)
+  (define-key smarty-template-map "\C-bs" 'smarty-template-strip)
+  (define-key smarty-template-map "\C-ca" 'smarty-template-assign)
+  (define-key smarty-template-map "\C-co" 'smarty-template-counter)
+  (define-key smarty-template-map "\C-cc" 'smarty-template-cycle)
+  (define-key smarty-template-map "\C-cd" 'smarty-template-debug)
+  (define-key smarty-template-map "\C-ce" 'smarty-template-eval)
+  (define-key smarty-template-map "\C-cf" 'smarty-template-fetch)
+  (define-key smarty-template-map "\C-c\C-hc" 'smarty-template-html-checkboxes)
+  (define-key smarty-template-map "\C-c\C-hi" 'smarty-template-html-image)
+  (define-key smarty-template-map "\C-c\C-ho" 'smarty-template-html-options)
+  (define-key smarty-template-map "\C-c\C-hr" 'smarty-template-html-radios)
+  (define-key smarty-template-map "\C-c\C-hd" 'smarty-template-html-select-date)
+  (define-key smarty-template-map "\C-c\C-hm" 'smarty-template-html-select-time)
+  (define-key smarty-template-map "\C-c\C-ht" 'smarty-template-html-table)
+  (define-key smarty-template-map "\C-ci" 'smarty-template-mailto)
+  (define-key smarty-template-map "\C-ch" 'smarty-template-math)
+  (define-key smarty-template-map "\C-c\C-p" 'smarty-template-popup)
+  (define-key smarty-template-map "\C-c\M-p" 'smarty-template-popup-init)
+  (define-key smarty-template-map "\C-ct" 'smarty-template-textformat)
+  (define-key smarty-template-map "\C-vp" 'smarty-template-capitalize)
+  (define-key smarty-template-map "\C-vc" 'smarty-template-cat)
+  (define-key smarty-template-map "\C-v\C-cc" 'smarty-template-count-characters)
+  (define-key smarty-template-map "\C-v\C-cp" 'smarty-template-count-paragraphs)
+  (define-key smarty-template-map "\C-v\C-cs" 'smarty-template-count-sentences)
+  (define-key smarty-template-map "\C-v\C-cw" 'smarty-template-count-words)
+  (define-key smarty-template-map "\C-vf" 'smarty-template-date-format)
+  (define-key smarty-template-map "\C-vd" 'smarty-template-default)
+  (define-key smarty-template-map "\C-ve" 'smarty-template-escape)
+  (define-key smarty-template-map "\C-vi" 'smarty-template-indent)
+  (define-key smarty-template-map "\C-vl" 'smarty-template-lower)
+  (define-key smarty-template-map "\C-vn" 'smarty-template-nl2br)
+  (define-key smarty-template-map "\C-vx" 'smarty-template-regex-replace)
+  (define-key smarty-template-map "\C-v\C-p" 'smarty-template-replace)
+  (define-key smarty-template-map "\C-vy" 'smarty-template-spacify)
+  (define-key smarty-template-map "\C-vs" 'smarty-template-string-format)
+  (define-key smarty-template-map "\C-v\C-s" 'smarty-template-vstrip)
+  (define-key smarty-template-map "\C-v\M-s" 'smarty-template-strip-tags)
+  (define-key smarty-template-map "\C-vt" 'smarty-template-truncate)
+  (define-key smarty-template-map "\C-vu" 'smarty-template-upper)
+  (define-key smarty-template-map "\C-vw" 'smarty-template-wordwrap)
+  (define-key smarty-template-map "\C-h" 'smarty-template-header)
+  (define-key smarty-template-map "\C-f" 'smarty-template-footer)
+  (define-key smarty-template-map "\C-di" 'smarty-template-insert-date)
+  (define-key smarty-template-map "\C-dm" 'smarty-template-modify))
+
+;; initialize template map for Smarty Mode
+(smarty-template-map-init)
+
+(defun smarty-mode-map-init ()
+  "Initialize `smarty-mode-map'."
+  (setq smarty-mode-map (make-sparse-keymap))
+  ;; template key bindings
+  (define-key smarty-mode-map "\C-c\C-t"   smarty-template-map)
+  ;; mode specific key bindings
+  (define-key smarty-mode-map "\C-c\C-m\C-e"  'smarty-electric-mode)
+  (define-key smarty-mode-map "\C-c\C-m\C-s"  'smarty-stutter-mode)
+  (define-key smarty-mode-map "\C-c\C-s\C-u"  'smarty-add-source-files-menu)
+  (define-key smarty-mode-map "\C-c\M-m"   'smarty-show-messages)
+  (define-key smarty-mode-map "\C-c\C-h"   'smarty-doc-mode)
+  (define-key smarty-mode-map "\C-c\C-v"   'smarty-version)
+  ;; electric key bindings
+  (when smarty-intelligent-tab
+    (define-key smarty-mode-map "\t" 'smarty-electric-tab))
+  (define-key smarty-mode-map " " 'smarty-electric-space)
+  (define-key smarty-mode-map "(" 'smarty-electric-open-bracket)
+  (define-key smarty-mode-map ")" 'smarty-electric-close-bracket)
+  (define-key smarty-mode-map "*" 'smarty-electric-star))
+
+;; initialize mode map for Smarty Mode
+(smarty-mode-map-init)
+
+(defvar smarty-minibuffer-local-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (when smarty-word-completion-in-minibuffer
+      (define-key map "\t" 'smarty-minibuffer-tab))
+    map)
+  "Keymap for minibuffer used in Smarty Mode.")
+
+(mapcar
+ (function
+  (lambda (sym)
+    (put sym 'delete-selection t)	; for `delete-selection-mode' (Emacs)
+    (put sym 'pending-delete t)))	; for `pending-delete-mode' (XEmacs)
+ '(smarty-electric-space
+   smarty-electric-tab
+   smarty-electric-open-bracket
+   smarty-electric-close-bracket
+   smarty-electric-star))
+
+;;;###autoload
+(defun smarty-mode ()
+  "Smarty Mode
+***********
+
+Smarty Mode is a GNU XEmacs major mode for editing Smarty templates.
+
+1 Introduction
+**************
+
+Smarty-Mode is a mode allowing easy edit of Smarty templates:
+highlight, templates, navigation into source files...
+
+
+
+Features (new features in bold) :
+
+   * Completion
+
+   * Customizable
+
+   * Highlight
+
+   * Menu
+
+   * Stuttering
+
+   * Templates
+        - Built-in Functions
+
+        - User Functions
+
+        - Variable Modifiers
+
+        - Plugin (Functions)
+             * Smarty Formtool
+
+             * Smarty Paginate
+
+             * Smarty Validate
+
+        - Plugin (Variable Modifiers)
+             * AlternativeDateModifierPlugin
+
+             * B2Smilies
+
+             * BBCodePlugin
+
+        - Fonctions Non-Smarty
+
+
+
+This manual describes Smarty Mode version 0.0.4.
+
+2 Installation
+**************
+
+2.1 Requirements
+================
+
+Smarty Mode is a XEmacs major mode that needs the following
+software/packages:
+
+   * XEmacs (http://www.xemacs.org/).
+
+   * `font-lock' mode generaly installed with XEmacs.
+
+   * `assoc' mode generaly installed with XEmacs.
+
+   * `easymenu' mode generaly installed with XEmacs.
+
+   * `hippie-exp' mode generaly installed with XEmacs.
+
+Before continuing, you must be sure to have all this packages
+installed.
+
+2.2 Download
+============
+
+Two internet address to download Smarty Mode :
+
+   * Principal: Smarty-Mode 0.0.4
+     (http://deboutv.free.fr/lisp/smarty/download/smarty-0.0.4.tar.gz)
+     (http://deboutv.free.fr/lisp/smarty/)
+
+   * Secondary: Smarty-Mode 0.0.4
+     (http://www.morinie.fr/lisp/smarty/download/smarty-0.0.4.tar.gz)
+     (http://www.morinie.fr/lisp/smarty/)
+
+   * Old releases: Smarty-Mode
+     (http://deboutv.free.fr/lisp/smarty/download.php)
+     (http://deboutv.free.fr/lisp/smarty/)
+
+2.3 Installation
+================
+
+2.3.1 Installation
+------------------
+
+To install Smarty Mode you need to choose an installation directory
+(for example `/usr/local/share/lisp' or `c:\lisp'). The administrator
+must have the write rights on this directory.
+
+With your favorite unzip software, unzip the archive in the
+installation directory.
+
+Example:
+     cd /usr/local/share/lisp
+     tar zxvf smarty-0.0.4.tar.gz
+Now you have a `smarty' directory in the installation directory. This
+directory contains 2 files `smarty-mode.el' and `smarty-mode.elc' and
+another directory `docs' containing the documentation.
+
+You need to configure XEmacs. open you initialization file `init.el'
+(open the file or start XEmacs then choose the Options menu and Edit
+Init File). Add the following lines (the installation directory in
+this example is `/usr/local/share/lisp') :
+
+     (setq load-path
+           (append (list \"/usr/local/share/lisp/\") load-path))
+     (autoload 'smarty-mode \"smarty-mode\" \"Smarty Mode\" t)
+
+2.3.2 Update
+------------
+
+The update is easy. You need to unzip the archive in the installation
+directory to remove the old release.
+
+Example:
+     cd /usr/local/share/lisp
+     rm -rf smarty
+     tar zxvf smarty-0.0.4.tar.gz
+
+2.4 Invoke Smarty-Mode
+======================
+
+You have two possibilities to invoke the Smarty Mode.
+
+   - Manually: At each file opening you need to launch Smarty Mode
+     with the following command:
+
+     `M-x smarty-mode'
+
+   - Automatically: Add the following linesin your initialization
+     file `init.el' :
+
+          (setq auto-mode-alist
+                (append
+                 '((\"\\.tpl$\" . smarty-mode))
+          	 auto-mode-alist))
+
+
+3 Customization
+***************
+
+This chapter describes the differents parameters and functions that
+you can change to customize Smarty Mode.  To do that, open a Smarty
+file, click on the Smarty menu and choose Options then Browse
+Options....
+
+3.1 Parameters
+==============
+
+3.1.1 Mode
+----------
+
+Smarty Mode has 2 modes allowing to simplify the writing of Smarty
+templates. You can enable/disable each mode individually.
+
+`smarty-electric-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable automatic generation of template.
+     If `nil'; template generators can still be invoked through key
+     bindings and menu. Is indicated in the modeline by \"/e\" after
+     the mode name and can be toggled by `smarty-electric-mode'.
+
+`smarty-stutter-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable the stuttering. Is indicated in the
+     modeline by \"/s\" after the mode name and can be toggled by
+     `smarty-stutter-mode'.
+
+3.1.2 Menu
+----------
+
+Smarty Mode has also 1 menu that you can enable/disable. The menu
+Sources is specific to each Smarty files opened.
+
+`smarty-source-file-menu'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the Sources menu is enabled. This menu
+     contains the list of Smarty file located in the current
+     directory. The Sources menu scans the directory when a file is
+     opened.
+
+3.1.3 Menu
+----------
+
+`smarty-highlight-plugin-functions'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the functions described in the smarty
+     plugins are highlighted.
+
+3.1.4 Templates
+---------------
+
+3.1.4.1 Header
+..............
+
+`smarty-file-header'
+     Type: string
+     Default value: `\"\"'
+     Description: String or file to insert as file header. If the
+     string specifies an existing file name the contents of the file
+     is inserted; otherwise the string itself is inserted as file
+     header.
+     Type `C-j' for newlines.
+     The follonwing keywords are supported:
+     : replaced by the file name.
+     : replaced by the user name and email address.
+     : replaced by `user-login-name'.
+     : replaced by `smarty-company-name' content.
+     : replaced by the current date.
+     : replaced by the current year.
+     : replaced by `smarty-copyright-string' content.
+     : final cursor position.
+
+`smarty-file-footer'
+     Type: string
+     Default value: `\"\"'
+     Description: String or file to insert as file footer.  See
+     `smarty-file-header'
+
+`smarty-company-name'
+     Type: string
+     Default value: `\"\"'
+     Description: Name of the company to insert in file header.
+
+`smarty-copyright-string'
+     Type: string
+     Default value: `\"\"'
+     Description: Coryright string to insert in file header.
+
+`smarty-date-format'
+     Type: string
+     Default value: `\"%Y-%m-%d\"'
+     Description: Date format.
+
+`smarty-modify-date-prefix-string'
+     Type: string
+     Default value: `\"\"'
+     Description: Prefix string of modification date in Smarty file
+     header.
+
+`smarty-modify-date-on-saving'
+     Type: bool
+     Default value: `nil'
+     Description: If `t'; update the modification date when the
+     buffer is saved.
+
+3.1.5 Miscellaneous
+-------------------
+
+`smarty-left-delimiter'
+     Type: string
+     Default value: `\"\"'
+     Description: Left escaping delimiter for Smarty templates.
+
+`smarty-right-delimiter'
+     Type: string
+     Default value: `\"\"'
+     Description: Right escaping delimiter for Smarty templates.
+
+`smarty-intelligent-tab'
+     Type: bool
+     Default value: `t'
+     Description: If `t'; TAB does indentation; completion and insert
+     tabulations. If `nil'; TAB does only indentation.
+
+`smarty-word-completion-in-minibuffer'
+     Type: bool
+     Default value: `t'
+     Description: If `t'; enable completion in the minibuffer.
+
+`smarty-word-completion-case-sensitive'
+     Type: bool
+     Default value: `nil'
+     Description: If `t'; completion is case sensitive.
+
+3.2 Functions
+=============
+
+3.2.1 Mode
+----------
+
+`smarty-electric-mode'
+     Menu: Smarty -> Options -> Mode -> Electric Mode
+     Keybinding: `C-c C-m C-e'
+     Description: This functions is used to enable/disable the
+     electric mode.
+
+`smarty-stutter-mode'
+     Menu: Smarty -> Options -> Mode -> Stutter Mode
+     Keybinding: `C-c C-m C-s'
+     Description: This function is used to enable/disable the stutter
+     mode.
+
+4 Menus
+*******
+
+There are 2 menus: Smarty and Sources. All theses menus can be
+accessed from the menubar or from the right click. This chapter
+describes each menus.
+
+4.1 Smarty
+==========
+
+This is the main menu of Smarty Mode. It allows an easy access to the
+main features of the Smarty Mode: Templates (see *Note Templates::)
+and Options (see *Note Customization::).
+
+This menu contains also 3 functions that are discussed in the next
+part.
+
+4.1.1 Functions
+---------------
+
+`smarty-show-messages'
+     Menu: Smarty -> Show Messages
+     Keybinding: `C-c M-m'
+     Description: This function opens the *Messages* buffer to
+     display previous error messages.
+
+`smarty-doc-mode'
+     Menu: Smarty -> Smarty Mode Documentation
+     Keybinding: `C-c C-h'
+     Description: This function opens the *Help* buffer and prints in
+     it the Smarty Mode documentation.
+
+`smarty-version'
+     Menu: Smarty -> Version
+     Keybinding: `C-c C-v'
+     Description: This function displays in the minibuffer the
+     current Smarty Mode version with the timestamp.
+
+4.2 Sources
+===========
+
+The Sources menu shows the Smarty files in the current directory. If
+you add or delete a file in the current directory, you need to
+refresh the menu.
+
+4.2.1 Customization
+-------------------
+
+`smarty-source-file-menu'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the Sources menu is enabled. This menu
+     contains the list of Smarty file located in the current
+     directory. The Sources menu scans the directory when a file is
+     opened.
+
+4.2.2 Functions
+---------------
+
+`smarty-add-source-files-menu'
+     Menu: Sources -> *Rescan*
+     Keybinding: `C-c C-s C-u'
+     Description: This function is used to refresh the Sources menu.
+
+5 Stuttering
+************
+
+The stutter mode is a mode that affects a function to a key. For
+example, when you use the `ENTER' key, the associated function will
+create a new line and indent it.
+
+5.1 Customization
+=================
+
+`smarty-stutter-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable the stuttering. Is indicated in the
+     modeline by \"/s\" after the mode name and can be toggled by
+     `smarty-stutter-mode'.
+
+5.2 Functions
+=============
+
+`SPACE'
+     If in comment, indent the comment and add new line if necessary.
+     In other case, add a space.
+
+`('
+     If the previous character is a `(', the `((' will be replaced by
+     `['.
+     If the previous character is a `[', the `[(' will be replaced by
+     `{'.
+     In other case, insert a `('.
+
+`)'
+     If the previous character is a `)', the `))' will be replaced by
+     `]'.
+     If the previous character is a `]', the `])' will be replaced by
+     `}'.
+     In other case, insert a `)'.
+
+6 Templates
+***********
+
+In the Smarty Mode, the Smarty functions (like if, while, for, fopen,
+fclose) are predefined in functions called \"Templates\".
+
+Each template can be invoked by the function name or by using the
+ key after the Smarty function name in the buffer (Note, using
+`M-' disable the template).
+
+A template can be aborted by using the `C-g' or by lefting empty the
+tempate prompt (in the minibuffer).
+
+6.1 Customization
+=================
+
+`smarty-electric-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable automatic generation of template.
+     If `nil'; template generators can still be invoked through key
+     bindings and menu. Is indicated in the modeline by \"/e\" after
+     the mode name and can be toggled by `smarty-electric-mode'.
+
+For a complete description of the template customizable variables,
+see *Note Cu01-Pa01-Template::
+
+6.2 Functions
+=============
+
+6.2.1 Smarty Functions
+----------------------
+
+For Smarty functions, see PDF or HTML documentation.
+
+6.2.2 Non-Smarty Functions
+--------------------------
+
+`smarty-template-header'
+     Menu: Smarty -> Templates -> Insert Header
+     Keybinding: `C-c C-t C-h'
+     Description: This function is used to insert a header in the
+     current buffer.
+
+`smarty-template-footer'
+     Menu: Smarty -> Templates -> Insert Footer
+     Keybinding: `C-c C-t C-f'
+     Description: This function is used to insert a footer in the
+     current buffer.
+
+`smarty-template-insert-date'
+     Menu: Smarty -> Templates -> Insert Date
+     Keybinding: `C-c C-t C-d i'
+     Description: This function is used to insert the date in the
+     current buffer.
+
+`smarty-template-modify'
+     Menu: Smarty -> Templates -> Modify Date
+     Keybinding: `C-c C-t C-d m'
+     Description: This function is used to modify the last
+     modification date in the current buffer.
+
+7 Bugs, Help
+************
+
+   * To report bugs: Bugtracker
+     (http://bugtracker.morinie.fr/lisp/set_project.php?project_id=2)
+
+   * To obtain help you can post on the dedicated forum: Forum
+     (http://forum.morinie.fr/lisp/)
+
+8 Key bindings
+**************
+
+\\{smarty-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'smarty-mode)
+  (setq mode-name "Smarty")
+
+  (smarty-create-syntax-table)
+
+  ;; set maps and tables
+  (use-local-map smarty-mode-map)
+  (set-syntax-table smarty-mode-syntax-table)
+  (setq local-abbrev-table smarty-mode-abbrev-table)
+
+  (set (make-local-variable 'comment-start) (concat smarty-left-delimiter "*"))
+  (set (make-local-variable 'comment-end) (concat "*" smarty-right-delimiter))
+  (set (make-local-variable 'comment-multi-line) t)
+  (set (make-local-variable 'end-comment-column) 80)
+
+  (make-local-variable 'font-lock-defaults)
+  (if smarty-highlight-plugin-functions
+      (setq smarty-font-lock-keywords smarty-font-lock-keywords-4)
+    (setq smarty-font-lock-keywords smarty-font-lock-keywords-3))
+  (setq font-lock-defaults
+		'((smarty-font-lock-keywords)
+		nil ; Keywords only (i.e. no comment or string highlighting
+		t   ; case fold
+		nil ; syntax-alist
+		nil ; syntax-begin
+		))
+  
+  (setq font-lock-maximum-decoration t
+		case-fold-search t)
+
+  ;; add source file menu
+  (if smarty-source-file-menu (smarty-add-source-files-menu))
+  ;; add Smarty menu
+  (easy-menu-add smarty-mode-menu-list)
+  (easy-menu-define smarty-mode-menu smarty-mode-map
+		    "Menu keymap for Smarty Mode." smarty-mode-menu-list)
+
+  (message "Smarty Mode %s.%s" smarty-version
+	   (if noninteractive "" "  See menu for documentation and release notes."))
+  (smarty-mode-line-update)
+  (run-hooks 'smarty-mode-hook))
+
+(defun smarty-doc-mode ()
+  "Display Smarty Mode documentation in *Help* buffer."
+  (interactive)
+  (with-output-to-temp-buffer
+      (if (fboundp 'help-buffer) (help-buffer) "*Help*")
+    (princ mode-name)
+    (princ " mode:\n")
+    (princ (documentation 'smarty-mode))
+    (with-current-buffer standard-output
+      (help-mode))
+    (print-help-return-message)))
+
+(defun smarty-activate-customizations ()
+  "Activate all customizations on local variables."
+  (interactive)
+  (smarty-mode-map-init)
+  (use-local-map smarty-mode-map)
+  (set-syntax-table smarty-mode-syntax-table)
+  (smarty-update-mode-menu)
+  (run-hooks 'menu-bar-update-hook)
+  (smarty-mode-line-update))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Templates
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun smarty-template-field (prompt &optional follow-string optional
+				   begin end is-string string-char default)
+  "Prompt for string and insert it in buffer with optional FOLLOW-STRING.
+If OPTIONAL is nil, the prompt is left if an empty string is inserted.  If
+an empty string is inserted, return nil and call `smarty-template-undo' for
+the region between BEGIN and END.  IS-STRING indicates whether a string
+with double-quotes is to be inserted.  DEFAULT specifies a default string."
+  (let ((position (point))
+	string)
+    (insert "<" prompt ">")
+    (if (not (> (length string-char) 0))
+	(setq string-char "\""))
+    (setq string
+	  (condition-case ()
+	      (read-from-minibuffer (concat prompt ": ")
+				    (or (and is-string (cons (concat string-char string-char) 1)) default)
+				    smarty-minibuffer-local-map)
+	    (quit (if (and optional begin end)
+		      (progn (beep) "")
+		    (keyboard-quit)))))
+    (when (or (not (equal string "")) optional)
+      (delete-region position (point)))
+    (when (and (equal string "") optional begin end)
+      (smarty-template-undo begin end)
+      (message "Template aborted"))
+    (unless (equal string "")
+      (insert string))
+    (when (or (not (equal string "")) (not optional))
+      (insert (or follow-string "")))
+    (if (equal string "") nil string)))
+
+(defun smarty-template-undo (begin end)
+  "Undo aborted template by deleting region and unexpanding the keyword."
+  (cond (smarty-template-invoked-by-hook
+	 (goto-char end)
+	 (insert " ")
+	 (delete-region begin end)
+	 (unexpand-abbrev))
+	(t (delete-region begin end))))
+
+(defun smarty-template-generic-function (label close-label field mandatory-count &optional infinite special-field)
+  "Generic function template 'label field1= field2=..."
+  (interactive)
+  (let ((start (point)) found here result-value elt continue field-count stop prompt)
+    (if smarty-template-invoked-by-hook
+	(setq found (smarty-after-ldelim))
+      (insert smarty-left-delimiter)
+      (setq found t))
+    (insert label)
+    (setq here (point-marker))
+    (insert " ")
+    (when found
+      (setq elt field)
+      (setq continue t)
+      (setq field-count 0)
+      (setq stop nil)
+      (while (and elt continue)
+	(setq prompt (car elt))
+	(when (not special-field)
+	  (insert prompt "="))
+	(setq result-value (smarty-template-field prompt nil t))
+	(if (and (not result-value)
+		 (< field-count mandatory-count))
+	    (progn (setq continue nil)
+		   (delete-region start (point))
+		   (insert (concat label " "))
+		   (setq stop t))
+	  (if (not result-value)
+	      (setq continue nil)
+	    (setq here (point-marker))
+	    (insert " ")))
+	(setq field-count (+ 1 field-count))
+	(setq elt (cdr elt)))
+      (when (and infinite continue)
+	(while continue
+	  (setq result-value (smarty-template-field "var_name" "=" t here))
+	  (if (not result-value)
+	      (setq continue nil)
+	    (setq continue (smarty-template-field "var_value" nil t here))
+	    (setq here (point-marker))
+	    (insert " "))))
+      (when (not stop)
+	(delete-region here (point))
+	(if (> 0 mandatory-count)
+	    (delete-char -1))
+	(if special-field
+	    (delete-char -1))
+	(insert smarty-right-delimiter)
+	(setq here (point-marker))
+	(if close-label
+	    (insert smarty-left-delimiter "/" label smarty-right-delimiter))
+	(goto-char here)))))
+
+(defun smarty-template-generic-modifier (label field mandatory-count)
+  "Generic modifier template '|label:field1:field2..."
+  (interactive)
+  (let ((start (point)) found here result-value elt continue field-count stop prompt)
+    (setq found (re-search-backward (concat (regexp-quote smarty-left-delimiter) "\\$\\(\\w+\\)" (regexp-quote "|")) nil t))
+    (if found
+	(progn
+	  (setq found (re-search-forward (regexp-quote smarty-right-delimiter) start t))
+	  (if (not found)
+	      (progn
+		(goto-char start)
+		(insert label)
+		(setq here (point-marker))
+		(setq elt field)
+		(setq continue t)
+		(setq field-count 0)
+		(setq stop nil)
+		(while (and elt continue)
+		  (setq prompt (car elt))
+		  (insert ":")
+		  (setq result-value (smarty-template-field prompt nil t))
+		  (if (and (not result-value)
+			   (< field-count mandatory-count))
+		      (progn (setq continue nil)
+			     (delete-region start (point))
+			     (insert (concat label " "))
+			     (setq stop t))
+		    (if (not result-value)
+			(setq continue nil)
+		      (setq here (point-marker))
+		      (insert ":")))
+		  (setq field-count (+ 1 field-count))
+		  (setq elt (cdr elt)))
+		(when (not stop)
+		  (delete-region here (point))
+		  (if (not (or (looking-at smarty-right-delimiter)
+			       (looking-at "|")))
+		      (insert smarty-right-delimiter))))
+	    (goto-char start)
+	    (insert label " ")))
+      (goto-char start)
+      (insert label " "))))
+
+(defun smarty-template-capture-hook ()
+  (smarty-hooked-abbrev 'smarty-template-capture))
+(defun smarty-template-config-load-hook ()
+  (smarty-hooked-abbrev 'smarty-template-config-load))
+(defun smarty-template-else-hook ()
+  (smarty-hooked-abbrev 'smarty-template-else))
+(defun smarty-template-elseif-hook ()
+  (smarty-hooked-abbrev 'smarty-template-elseif))
+(defun smarty-template-foreach-hook ()
+  (smarty-hooked-abbrev 'smarty-template-foreach))
+(defun smarty-template-foreachelse-hook ()
+  (smarty-hooked-abbrev 'smarty-template-foreachelse))
+(defun smarty-template-if-hook ()
+  (smarty-hooked-abbrev 'smarty-template-if))
+(defun smarty-template-include-hook ()
+  (smarty-hooked-abbrev 'smarty-template-include))
+(defun smarty-template-include-php-hook ()
+  (smarty-hooked-abbrev 'smarty-template-include-php))
+(defun smarty-template-insert-hook ()
+  (smarty-hooked-abbrev 'smarty-template-insert))
+(defun smarty-template-ldelim-hook ()
+  (smarty-hooked-abbrev 'smarty-template-ldelim))
+(defun smarty-template-literal-hook ()
+  (smarty-hooked-abbrev 'smarty-template-literal))
+(defun smarty-template-php-hook ()
+  (smarty-hooked-abbrev 'smarty-template-php))
+(defun smarty-template-rdelim-hook ()
+  (smarty-hooked-abbrev 'smarty-template-rdelim))
+(defun smarty-template-section-hook ()
+  (smarty-hooked-abbrev 'smarty-template-section))
+(defun smarty-template-sectionelse-hook ()
+  (smarty-hooked-abbrev 'smarty-template-sectionelse))
+(defun smarty-template-strip-hook ()
+  (smarty-hooked-abbrev 'smarty-template-strip))
+
+(defun smarty-template-assign-hook ()
+  (smarty-hooked-abbrev 'smarty-template-assign))
+(defun smarty-template-counter-hook ()
+  (smarty-hooked-abbrev 'smarty-template-counter))
+(defun smarty-template-cycle-hook ()
+  (smarty-hooked-abbrev 'smarty-template-cycle))
+(defun smarty-template-debug-hook ()
+  (smarty-hooked-abbrev 'smarty-template-debug))
+(defun smarty-template-eval-hook ()
+  (smarty-hooked-abbrev 'smarty-template-eval))
+(defun smarty-template-fetch-hook ()
+  (smarty-hooked-abbrev 'smarty-template-fetch))
+(defun smarty-template-html-checkboxes-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-checkboxes))
+(defun smarty-template-html-image-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-image))
+(defun smarty-template-html-options-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-options))
+(defun smarty-template-html-radios-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-radios))
+(defun smarty-template-html-select-date-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-select-date))
+(defun smarty-template-html-select-time-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-select-time))
+(defun smarty-template-html-table-hook ()
+  (smarty-hooked-abbrev 'smarty-template-html-table))
+(defun smarty-template-mailto-hook ()
+  (smarty-hooked-abbrev 'smarty-template-mailto))
+(defun smarty-template-math-hook ()
+  (smarty-hooked-abbrev 'smarty-template-math))
+(defun smarty-template-popup-hook ()
+  (smarty-hooked-abbrev 'smarty-template-popup))
+(defun smarty-template-popup-init-hook ()
+  (smarty-hooked-abbrev 'smarty-template-popup-init))
+(defun smarty-template-textformat-hook ()
+  (smarty-hooked-abbrev 'smarty-template-textformat))
+
+(defun smarty-template-capitalize-hook ()
+  (smarty-hooked-abbrev 'smarty-template-capitalize))
+(defun smarty-template-cat-hook ()
+  (smarty-hooked-abbrev 'smarty-template-cat))
+(defun smarty-template-count-characters-hook ()
+  (smarty-hooked-abbrev 'smarty-template-count-characters))
+(defun smarty-template-count-paragraphs-hook ()
+  (smarty-hooked-abbrev 'smarty-template-count-paragraphs))
+(defun smarty-template-count-sentences-hook ()
+  (smarty-hooked-abbrev 'smarty-template-count-sentences))
+(defun smarty-template-count-words-hook ()
+  (smarty-hooked-abbrev 'smarty-template-count-words))
+(defun smarty-template-date-format-hook ()
+  (smarty-hooked-abbrev 'smarty-template-date-format))
+(defun smarty-template-default-hook ()
+  (smarty-hooked-abbrev 'smarty-template-default))
+(defun smarty-template-escape-hook ()
+  (smarty-hooked-abbrev 'smarty-template-escape))
+(defun smarty-template-indent-hook ()
+  (smarty-hooked-abbrev 'smarty-template-indent))
+(defun smarty-template-lower-hook ()
+  (smarty-hooked-abbrev 'smarty-template-lower))
+(defun smarty-template-nl2br-hook ()
+  (smarty-hooked-abbrev 'smarty-template-nl2br))
+(defun smarty-template-regex-replace-hook ()
+  (smarty-hooked-abbrev 'smarty-template-regex-replace))
+(defun smarty-template-replace-hook ()
+  (smarty-hooked-abbrev 'smarty-template-replace))
+(defun smarty-template-spacify-hook ()
+  (smarty-hooked-abbrev 'smarty-template-spacify))
+(defun smarty-template-string-format-hook ()
+  (smarty-hooked-abbrev 'smarty-template-string-format))
+(defun smarty-template-vstrip-hook ()
+  (smarty-hooked-abbrev 'smarty-template-vstrip))
+(defun smarty-template-strip-tags-hook ()
+  (smarty-hooked-abbrev 'smarty-template-strip-tags))
+(defun smarty-template-truncate-hook ()
+  (smarty-hooked-abbrev 'smarty-template-truncate))
+(defun smarty-template-upper-hook ()
+  (smarty-hooked-abbrev 'smarty-template-upper))
+(defun smarty-template-wordwrap-hook ()
+  (smarty-hooked-abbrev 'smarty-template-wordwrap))
+
+(defun smarty-template-validate-hook ()
+  (smarty-hooked-abbrev 'smarty-template-validate))
+(defun smarty-template-formtool-checkall-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-checkall))
+(defun smarty-template-formtool-copy-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-copy))
+(defun smarty-template-formtool-count-chars-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-count-chars))
+(defun smarty-template-formtool-init-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-init))
+(defun smarty-template-formtool-move-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-move))
+(defun smarty-template-formtool-moveall-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-moveall))
+(defun smarty-template-formtool-movedown-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-movedown))
+(defun smarty-template-formtool-moveup-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-moveup))
+(defun smarty-template-formtool-remove-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-remove))
+(defun smarty-template-formtool-rename-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-rename))
+(defun smarty-template-formtool-save-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-save))
+(defun smarty-template-formtool-selectall-hook ()
+  (smarty-hooked-abbrev 'smarty-template-formtool-selectall))
+(defun smarty-template-paginate-first-hook ()
+  (smarty-hooked-abbrev 'smarty-template-paginate-first))
+(defun smarty-template-paginate-last-hook ()
+  (smarty-hooked-abbrev 'smarty-template-paginate-last))
+(defun smarty-template-paginate-middle-hook ()
+  (smarty-hooked-abbrev 'smarty-template-paginate-middle))
+(defun smarty-template-paginate-next-hook ()
+  (smarty-hooked-abbrev 'smarty-template-paginate-next))
+(defun smarty-template-paginate-prev-hook ()
+  (smarty-hooked-abbrev 'smarty-template-paginate-prev))
+
+(defun smarty-template-btosmilies-hook ()
+  (smarty-hooked-abbrev 'smarty-template-btosmilies))
+(defun smarty-template-bbcodetohtml-hook ()
+  (smarty-hooked-abbrev 'smarty-template-bbcodetohtml))
+(defun smarty-template-date-formatto-hook ()
+  (smarty-hooked-abbrev 'smarty-template-date-formatto))
+
+(defun smarty-template-capture ()
+  "Insert a capture statement."
+  (interactive)
+  (smarty-template-generic-function "capture" t '("name" "assign") 0))
+
+(defun smarty-template-config-load ()
+  "Insert a config_load statement."
+  (interactive)
+  (smarty-template-generic-function "config_load" nil '("file" "section" "scope" "global") 1))
+
+(defun smarty-template-else ()
+  "Insert a else statement."
+  (interactive)
+  (smarty-template-generic-function "else" nil '() 0))
+
+(defun smarty-template-elseif ()
+  "Insert a elseif statement."
+  (interactive)
+  (smarty-template-generic-function "elseif" nil '("condition") 1 nil t))
+
+(defun smarty-template-foreach ()
+  "Insert a foreach statement."
+  (interactive)
+  (smarty-template-generic-function "foreach" t '("from" "item" "key" "name") 2))
+
+(defun smarty-template-foreachelse ()
+  "Insert a foreachelse statement."
+  (interactive)
+  (smarty-template-generic-function "foreachelse" nil '() 0))
+
+(defun smarty-template-if ()
+  "Insert a if statement."
+  (interactive)
+  (smarty-template-generic-function "if" t '("condition") 1 nil t))
+
+(defun smarty-template-include ()
+  "Insert a include statement."
+  (interactive)
+  (smarty-template-generic-function "include" nil '("file" "assign") 1 t))
+
+(defun smarty-template-include-php ()
+  "Insert a include_php statement."
+  (interactive)
+  (smarty-template-generic-function "include_php" nil '("file" "once" "assign") 1))
+
+(defun smarty-template-insert ()
+  "Insert a insert statement."
+  (interactive)
+  (smarty-template-generic-function "insert" nil '("name" "assign" "script") 1 t))
+
+(defun smarty-template-ldelim ()
+  "Insert a ldelim statement."
+  (interactive)
+  (smarty-template-generic-function "ldelim" nil '() 0))
+
+(defun smarty-template-literal ()
+  "Insert a literal statement."
+  (interactive)
+  (smarty-template-generic-function "literal" t '() 0))
+
+(defun smarty-template-php ()
+  "Insert a php statement."
+  (interactive)
+  (smarty-template-generic-function "php" t '() 0))
+
+(defun smarty-template-rdelim ()
+  "Insert a rdelim statement."
+  (interactive)
+  (smarty-template-generic-function "rdelim" nil '() 0))
+
+(defun smarty-template-section ()
+  "Insert a section statement."
+  (interactive)
+  (smarty-template-generic-function "section" t '("name" "loop" "start" "step" "max" "show") 2))
+
+(defun smarty-template-sectionelse ()
+  "Insert a sectionelse statement."
+  (interactive)
+  (smarty-template-generic-function "sectionelse" nil '() 0))
+
+(defun smarty-template-strip ()
+  "Insert a strip statement."
+  (interactive)
+  (smarty-template-generic-function "strip" t '() 0))
+
+
+(defun smarty-template-assign ()
+  "Insert a assign statement."
+  (interactive)
+  (smarty-template-generic-function "assign" nil '("var" "value") 2))
+
+(defun smarty-template-counter ()
+  "Insert a counter statement."
+  (interactive)
+  (smarty-template-generic-function "counter" nil '("name" "start" "skip" "direction" "print" "assign") 0))
+
+(defun smarty-template-cycle ()
+  "Insert a cycle statement."
+  (interactive)
+  (smarty-template-generic-function "cycle" nil '("values" "name" "print" "advance" "delimiter" "assign" "reset") 1))
+
+(defun smarty-template-debug ()
+  "Insert a debug statement."
+  (interactive)
+  (smarty-template-generic-function "debug" nil '("output") 0))
+
+(defun smarty-template-eval ()
+  "Insert a eval statement."
+  (interactive)
+  (smarty-template-generic-function "eval" nil '("var" "assign") 1))
+
+(defun smarty-template-fetch ()
+  "Insert a fetch statement."
+  (interactive)
+  (smarty-template-generic-function "fetch" nil '("file" "assign") 1))
+
+(defun smarty-template-html-checkboxes ()
+  "Insert a html_checkboxes statement."
+  (interactive)
+  (smarty-template-generic-function "html_checkboxes" nil '("name" "values" "output" "selected" "options" "separator" "assign" "labels") 0))
+
+(defun smarty-template-html-image ()
+  "Insert a html_image statement."
+  (interactive)
+  (smarty-template-generic-function "html_image" nil '("file" "height" "width" "basedir" "alt" "href" "path_prefix") 1))
+
+(defun smarty-template-html-options ()
+  "Insert a html_options statement."
+  (interactive)
+  (smarty-template-generic-function "html_options" nil '("name" "values" "output" "selected" "options") 0))
+
+(defun smarty-template-html-radios ()
+  "Insert a html_radios statement."
+  (interactive)
+  (smarty-template-generic-function "html_radios" nil '("name" "values" "output" "selected" "options" "separator" "assign") 0))
+
+(defun smarty-template-html-select-date ()
+  "Insert a html_select_date statement."
+  (interactive)
+  (smarty-template-generic-function "html_select_date" nil '("prefix" "time" "start_year" "end_year" "display_days" "display_months" "display_years" "month_format" "day_format" "day_value_format" "year_as_text" "reverse_years" "field_array" "day_size" "month_size" "year_size" "all_extra" "day_extra" "month_extra" "year_extra" "field_order" "field_separator" "month_value_format" "year_empty" "month_empty" "day_empty") 0))
+
+(defun smarty-template-html-select-time ()
+  "Insert a html_select_time statement."
+  (interactive)
+  (smarty-template-generic-function "html_select_time" nil '("prefix" "time" "display_hours" "display_minutes" "display_seconds" "display_meridian" "use_24_hours" "minute_interval" "second_interval" "field_array" "all_extra" "hour_extra" "minute_extra" "second_extra" "meridian_extra") 0))
+
+(defun smarty-template-html-table ()
+  "Insert a html_table statement."
+  (interactive)
+  (smarty-template-generic-function "html_table" nil '("loop" "cols" "rows" "inner" "caption" "table_attr" "th_attr" "tr_attr" "td_attr" "trailpad" "hdir" "vdir") 1))
+
+(defun smarty-template-mailto ()
+  "Insert a mailto statement."
+  (interactive)
+  (smarty-template-generic-function "mailto" nil '("address" "text" "encode" "cc" "bcc" "subject" "newsgroups" "followupto" "extra") 1))
+
+(defun smarty-template-math ()
+  "Insert a math statement."
+  (interactive)
+  (smarty-template-generic-function "math" nil '("equation" "var" "format" "assign") 2 t))
+
+(defun smarty-template-popup ()
+  "Insert a popup statement."
+  (interactive)
+  (smarty-template-generic-function "popup" nil '("text" "trigger" "sticky" "caption" "fgcolor" "bgcolor" "textcolor" "capcolor" "closecolor" "textfont" "captionfont" "closefont" "textsize" "captionsize" "closesize" "width" "height" "left" "right" "center" "above" "below" "border" "offsetx" "offsety" "fgbackground" "bgbackground" "closetext" "noclose" "status" "autostatus" "autostatuscap" "inarray" "caparray" "capicon" "snapx" "snapy" "fixx" "fixy" "background" "padx" "pady" "fullhtml" "frame" "function" "delay" "hauto" "vauto") 1))
+
+(defun smarty-template-popup-init ()
+  "Insert a popup_init statement."
+  (interactive)
+  (smarty-template-generic-function "popup_init" nil '("src") 1))
+
+(defun smarty-template-textformat ()
+  "Insert a textformat statement."
+  (interactive)
+  (smarty-template-generic-function "textformat" t '("style" "indent" "indent_first" "indent_char" "wrap" "wrap_char" "wrap_cut" "assign") 0))
+
+(defun smarty-template-capitalize ()
+  "Insert a capitalize statement."
+  (interactive)
+  (smarty-template-generic-modifier "capitalize" '("upcase_numeric") 0))
+
+(defun smarty-template-cat ()
+  "Insert a cat statement."
+  (interactive)
+  (smarty-template-generic-modifier "cat" '("value") 0))
+
+(defun smarty-template-count-characters ()
+  "Insert a count_characters statement."
+  (interactive)
+  (smarty-template-generic-modifier "count_characters" '("include_whitespace") 0))
+
+(defun smarty-template-count-paragraphs ()
+  "Insert a count_paragraphs statement."
+  (interactive)
+  (smarty-template-generic-modifier "count_paragraphs" '() 0))
+
+(defun smarty-template-count-sentences ()
+  "Insert a count_sentences statement."
+  (interactive)
+  (smarty-template-generic-modifier "count_sentences" '() 0))
+
+(defun smarty-template-count-words ()
+  "Insert a count_words statement."
+  (interactive)
+  (smarty-template-generic-modifier "count_words" '() 0))
+
+(defun smarty-template-date-format ()
+  "Insert a date_format statement."
+  (interactive)
+  (smarty-template-generic-modifier "date_format" '("format" "default") 0))
+
+(defun smarty-template-default ()
+  "Insert a default statement."
+  (interactive)
+  (smarty-template-generic-modifier "default" '("value") 0))
+
+(defun smarty-template-escape ()
+  "Insert a escape statement."
+  (interactive)
+  (smarty-template-generic-modifier "escape" '("html|htmlall|url|urlpathinfo|quotes|hex|hexentity|javascript|mail" "charset") 0))
+
+(defun smarty-template-indent ()
+  "Insert a indent statement."
+  (interactive)
+  (smarty-template-generic-modifier "indent" '("value" "character") 0))
+
+(defun smarty-template-lower ()
+  "Insert a lower statement."
+  (interactive)
+  (smarty-template-generic-modifier "lower" '() 0))
+
+(defun smarty-template-nl2br ()
+  "Insert a nl2br statement."
+  (interactive)
+  (smarty-template-generic-modifier "nl2br" '() 0))
+
+(defun smarty-template-regex-replace ()
+  "Insert a regex_replace statement."
+  (interactive)
+  (smarty-template-generic-modifier "regex_replace" '("regexp" "string_to_replace") 2))
+
+(defun smarty-template-replace ()
+  "Insert a replace statement."
+  (interactive)
+  (smarty-template-generic-modifier "replace" '("string" "string_to_replace_with") 2))
+
+(defun smarty-template-spacify ()
+  "Insert a spacify statement."
+  (interactive)
+  (smarty-template-generic-modifier "spacify" '("character") 0))
+
+(defun smarty-template-string-format ()
+  "Insert a string_format statement."
+  (interactive)
+  (smarty-template-generic-modifier "string_format" '("format") 1))
+
+(defun smarty-template-vstrip ()
+  "Insert a strip statement."
+  (interactive)
+  (smarty-template-generic-modifier "strip" '() 0))
+
+(defun smarty-template-strip-tags ()
+  "Insert a strip_tags statement."
+  (interactive)
+  (smarty-template-generic-modifier "strip_tags" '("replace_by_space") 0))
+
+(defun smarty-template-truncate ()
+  "Insert a truncate statement."
+  (interactive)
+  (smarty-template-generic-modifier "truncate" '("count" "text_to_replace" "character_boundary" "middle_string") 0))
+
+(defun smarty-template-upper ()
+  "Insert a upper statement."
+  (interactive)
+  (smarty-template-generic-modifier "upper" '() 0))
+
+(defun smarty-template-wordwrap ()
+  "Insert a wordwrap statement."
+  (interactive)
+  (smarty-template-generic-modifier "wordwrap" '("count" "string" "character_boundary") 0))
+
+
+(defun smarty-template-validate ()
+  "Insert a validate statement."
+  (interactive)
+  (smarty-template-generic-function "validate" nil '("field" "criteria" "message" "form" "transform" "trim" "empty" "halt" "assign" "append" "page") 3))
+
+(defun smarty-template-formtool-checkall ()
+  "Insert a formtool_checkall statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_checkall" nil '("name" "class" "style") 1))
+
+(defun smarty-template-formtool-copy ()
+  "Insert a formtool_copy statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_copy" nil '("from" "to" "save" "button_text" "all" "counter" "class" "style") 3))
+
+(defun smarty-template-formtool-count-chars ()
+  "Insert a formtool_count_chars statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_count_chars" nil '("name" "limit" "alert") 3))
+
+(defun smarty-template-formtool-init ()
+  "Insert a formtool_init statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_init" nil '("src") 1))
+
+(defun smarty-template-formtool-move ()
+  "Insert a formtool_move statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_move" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4))
+
+(defun smarty-template-formtool-moveall ()
+  "Insert a formtool_moveall statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_moveall" nil '("from" "to" "save_from" "save_to" "all" "count_to" "count_from" "class" "style") 4))
+
+(defun smarty-template-formtool-movedown ()
+  "Insert a formtool_movedown statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_movedown" nil '("save" "name" "class" "style") 2))
+
+(defun smarty-template-formtool-moveup ()
+  "Insert a formtool_moveup statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_moveup" nil '("save" "name" "class" "style") 2))
+
+(defun smarty-template-formtool-remove ()
+  "Insert a formtool_remove statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_remove" nil '("from" "save" "all" "counter" "class" "style") 2))
+
+(defun smarty-template-formtool-rename ()
+  "Insert a formtool_rename statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_rename" nil '("name" "from" "save" "class" "style") 3))
+
+(defun smarty-template-formtool-save ()
+  "Insert a formtool_save statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_save" nil '("from" "name" "save") 3))
+
+(defun smarty-template-formtool-selectall ()
+  "Insert a formtool_selectall statement."
+  (interactive)
+  (smarty-template-generic-function "formtool_selectall" nil '("name" "class" "style") 1))
+
+(defun smarty-template-paginate-first ()
+  "Insert a paginate_first statement."
+  (interactive)
+  (smarty-template-generic-function "paginate_first" nil '("id" "text") 0))
+
+(defun smarty-template-paginate-last ()
+  "Insert a paginate_last statement."
+  (interactive)
+  (smarty-template-generic-function "paginate_last" nil '("id" "text") 0))
+
+(defun smarty-template-paginate-middle ()
+  "Insert a paginate_middle statement."
+  (interactive)
+  (smarty-template-generic-function "paginate_middle" nil '("id" "format" "prefix" "page_limit" "link_prefix" "link_suffix") 0))
+
+(defun smarty-template-paginate-next ()
+  "Insert a paginate_next statement."
+  (interactive)
+  (smarty-template-generic-function "paginate_next" nil '("id" "text") 0))
+
+(defun smarty-template-paginate-prev ()
+  "Insert a paginate_prev statement."
+  (interactive)
+  (smarty-template-generic-function "paginate_prev" nil '("id" "text") 0))
+
+
+(defun smarty-template-btosmilies ()
+  "Insert a B2Smilies statement."
+  (interactive)
+  (smarty-template-generic-modifier "B2Smilies" '() 0))
+
+(defun smarty-template-bbcodetohtml ()
+  "Insert a bbcode2html statement."
+  (interactive)
+  (smarty-template-generic-modifier "bbcode2html" '() 0))
+
+(defun smarty-template-date-formatto ()
+  "Insert a date_format2 statement."
+  (interactive)
+  (smarty-template-generic-modifier "date_format2" '("format" "default") 0))
+
+;;
+
+(defun smarty-resolve-env-variable (string)
+  "Resolve environment variables in STRING."
+  (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" string)
+    (setq string (concat (match-string 1 string)
+			 (getenv (match-string 2 string))
+			 (match-string 4 string))))
+  string)
+
+(defun smarty-insert-string-or-file (string)
+  "Insert STRING or file contents if STRING is an existing file name."
+  (unless (equal string "")
+    (let ((file-name
+	   (progn (string-match "^\\([^\n]+\\)" string)
+		  (smarty-resolve-env-variable (match-string 1 string)))))
+      (if (file-exists-p file-name)
+	   (forward-char (cadr (insert-file-contents file-name)))
+	(insert string)))))
+
+(defun smarty-template-insert-date ()
+  "Insert date in appropriate format."
+  (interactive)
+  (insert
+   (cond
+    ;; 'american, 'european, 'scientific kept for backward compatibility
+    ((eq smarty-date-format 'american) (format-time-string "%m/%d/%Y" nil))
+    ((eq smarty-date-format 'european) (format-time-string "%d.%m.%Y" nil))
+    ((eq smarty-date-format 'scientific) (format-time-string "%Y/%m/%d" nil))
+    (t (format-time-string smarty-date-format nil)))))
+
+(defun smarty-template-header (&optional file-title)
+  "Insert a Smarty file header."
+  (interactive)
+  (unless (equal smarty-file-header "")
+    (let (pos)
+      (save-excursion
+	(smarty-insert-string-or-file smarty-file-header)
+	(setq pos (point-marker)))
+      (smarty-template-replace-header-keywords
+       (point-min-marker) pos file-title))))
+
+(defun smarty-template-footer ()
+  "Insert a Smarty file footer."
+  (interactive)
+  (unless (equal smarty-file-footer "")
+    (let (pos)
+      (save-excursion
+	(setq pos (point-marker))
+	(smarty-insert-string-or-file smarty-file-footer)
+	(unless (= (preceding-char) ?\n)
+	  (insert "\n")))
+      (smarty-template-replace-header-keywords pos (point-max-marker)))))
+
+(defun smarty-template-replace-header-keywords (beg end &optional file-title is-model)
+  "Replace keywords in header and footer."
+  (let ()
+    (smarty-prepare-search-2
+     (save-excursion
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match (buffer-name) t t))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match smarty-copyright-string t t))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match "" t t)
+	 (insert (user-full-name))
+	 (when user-mail-address (insert "  <" user-mail-address ">")))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match (user-login-name) t t))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match smarty-company-name t t))
+       (goto-char beg)
+       ;; Replace  with $, so that RCS for the source is
+       ;; not over-enthusiastic with replacements
+       (while (search-forward "" end t)
+	 (replace-match "$" nil t))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match "" t t)
+	 (smarty-template-insert-date))
+       (goto-char beg)
+       (while (search-forward "" end t)
+	 (replace-match (format-time-string "%Y" nil) t t))
+       (goto-char beg)
+       (let (string)
+	 (while
+	     (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" end t)
+	   (setq string (read-string (concat (match-string 1) ": ")))
+	   (replace-match string t t)))
+       (goto-char beg)
+       (when (and (not is-model) (search-forward "" end t))
+	 (replace-match "" t t))))))
+
+(provide 'smarty-mode)
+;;; smarty-mode.el ends here
\ No newline at end of file
diff --git a/nxhtml/autostart.el b/nxhtml/autostart.el
new file mode 100644
index 0000000..44a6901
--- /dev/null
+++ b/nxhtml/autostart.el
@@ -0,0 +1,194 @@
+;;; autostart.el --- Load nxhtml
+;;
+;; Author: By: Lennart Borgman
+;; Created: Fri Dec 15 2006
+;; Version:
+;; Last-Updated: 2009-04-30 Thu
+;; Keywords:
+;; Compatibility:
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;; Fix-me: Split out the definitions from this file so it can be
+;; loaded during byte compilation.
+
+;;(eval-when-compile (require 'web-vcs nil t))
+;;(eval-when-compile (require 'nxhtml-web-vcs nil t))
+
+(message "Nxml/Nxhtml Autostart.el loading ...")
+
+(defconst nxhtml-autostart-trace nil)
+(defsubst nxhtml-autostart-trace (format-string &rest args)
+  (when nxhtml-autostart-trace
+    (apply 'message format-string args)))
+
+(defconst nxhtml-load-time-start (float-time))
+
+;; Add this dir to load-path
+(add-to-list 'load-path
+             (file-name-directory (or load-file-name
+                                      (when (boundp 'bytecomp-filename) bytecomp-filename)
+                                      buffer-file-name)))
+
+(require 'nxhtml-base)
+(eval-and-compile (when (fboundp 'nxml-mode)
+                     (load (expand-file-name "etc/schema/schema-path-patch"
+                                             nxhtml-install-dir))))
+
+;; (defun nxhtml-custom-load-and-get-value (symbol)
+;;   (custom-load-symbol symbol)
+;;   (symbol-value symbol))
+
+(defun nxhtml-list-loaded-features (use-message)
+  (interactive (list t))
+  (let ((buf (when use-message ;(called-interactively-p)
+               (get-buffer-create "*nXhtml loaded features*"))))
+    (if buf
+        (with-current-buffer buf (erase-buffer))
+      (message "")
+      (message "=== Loaded at nxhtml/autostart.el end:"))
+    (dolist (feature '(
+                       as-external
+                       html-chklnk
+                       html-imenu
+                       html-move
+                       html-pagetoc
+                       html-quote
+                       html-site
+                       html-toc
+                       html-upl
+                       html-wtoc
+                       inlimg
+                       mumamo
+                       nxhtml-bug
+                       nxhtml-menu
+                       nxhtml-mode
+                       nxhtml-mumamo
+                       nxhtml-strval
+                       nxhtml
+                       nxhtml-js
+                       nxml-where
+                       outline-magic
+                       rngalt
+                       tidy-xhtml
+                       xhtml-help
+                       ))
+      (when (featurep feature)
+        (if buf
+            (with-current-buffer buf
+              (insert (format "(feature '%s)=%s\n" feature (featurep feature))))
+          (message "(feature '%s)=%s" feature (featurep feature)))))
+    (if buf
+        (display-buffer buf)
+      (message ""))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Code that will run on loading this file
+
+(if (< emacs-major-version 23)
+    (unless (featurep 'autostart22)
+      (load (expand-file-name "autostart22" nxhtml-install-dir)))
+  ;; Check that the nxml-mode included with Emacs is used. There
+  ;; has been some problems on Debian with this.
+  (let ((nxml-mode-file (locate-library "nxml-mode"))
+        (help-file      (locate-library "help")))
+    (unless (string= (expand-file-name ".." help-file)
+                     (expand-file-name "../.." nxml-mode-file))
+      (error "Wrong nxml-mode=%s used, please use the one that comes with Emacs" nxml-mode-file))))
+
+(let* ((util-dir (file-name-as-directory (expand-file-name "util" nxhtml-install-dir)))
+       (related-dir (file-name-as-directory (expand-file-name "related" nxhtml-install-dir)))
+       (nxhtml-dir (file-name-as-directory (expand-file-name "nxhtml" nxhtml-install-dir)))
+       ;;(company-dir (file-name-as-directory (expand-file-name "util/nxhtml-company-mode" nxhtml-install-dir)))
+       (tests-dir (file-name-as-directory (expand-file-name "tests" nxhtml-install-dir))))
+  (add-to-list 'load-path nxhtml-dir)
+  (add-to-list 'load-path related-dir)
+  (add-to-list 'load-path util-dir)
+  (add-to-list 'load-path nxhtml-install-dir)
+  ;;(add-to-list 'load-path company-dir)
+  (add-to-list 'load-path tests-dir)
+
+  (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start))
+
+  ;; Autoloading etc
+  ;; (unless (featurep 'web-vcs)
+  ;;   (load (expand-file-name "web-vcs" nxhtml-install-dir) (not nxhtml-autoload-web)))
+
+  ;; (when (catch 'miss
+  ;;         (dolist (file nxhtml-basic-files)
+  ;;           (let ((dl-file (expand-file-name file nxhtml-install-dir)))
+  ;;             (unless (file-exists-p dl-file)
+  ;;               (throw 'miss t))))
+  ;;         nil)
+  ;;   (nxhtml-setup-auto-download nxhtml-install-dir))
+
+  (unless (featurep 'web-autoload)
+    (load (expand-file-name "web-autoload" nxhtml-install-dir) (not nxhtml-autoload-web)))
+
+  (when nxhtml-autoload-web
+    (ad-activate 'require t))
+
+  ;; Fix-me: Why must as-external be loaded? Why doesn't it work in batch?
+  ;;(unless noninteractive (require 'as-external))
+
+  (unless (featurep 'nxhtml-loaddefs)
+    (load (expand-file-name "nxhtml-loaddefs" nxhtml-install-dir) nxhtml-autoload-web))
+  (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start))
+
+  ;; Turn on `nxhtml-menu-mode' unconditionally
+  (nxhtml-autostart-trace "Turn on `nxhtml-menu-mode' unconditionally")
+  (nxhtml-menu-mode 1)
+  (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start))
+
+  ;; Patch the rnc include paths
+  (when (fboundp 'rncpp-patch-xhtml-loader) (rncpp-patch-xhtml-loader))
+  (nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start))
+
+  ;; Load nXhtml
+  (unless (featurep 'nxhtml-autoload)
+    (load (expand-file-name "nxhtml/nxhtml-autoload" nxhtml-install-dir))))
+(nxhtml-autostart-trace "... nXhtml loading %.1f seconds elapsed ..." (- (float-time) nxhtml-load-time-start))
+
+
+(unless (featurep 'nxhtml-autostart)
+  ;; Provide the feature here to avoid loading looping on error.
+  (provide 'nxhtml-autostart)
+
+  ;; Tell what have been loaded of nXhtml:
+  (when nxhtml-autostart-trace (nxhtml-list-loaded-features nil))
+
+  ;; How long time did it all take?
+  (message "Nxml/Nxhtml Autostart.el loaded in %.1f seconds" (- (float-time) nxhtml-load-time-start)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; autostart.el ends here
diff --git a/nxhtml/autostart22.el b/nxhtml/autostart22.el
new file mode 100644
index 0000000..2376d43
--- /dev/null
+++ b/nxhtml/autostart22.el
@@ -0,0 +1,71 @@
+;;; autostart22.el --- Example of autostart file for Emacs22
+;;
+;; Author: Lennart Borgman (lennart O borgman A gmail O com)
+;; Created: 2009-01-01 Thu
+;; Version:
+;; Last-Updated: 2009-01-05 Mon
+;; URL:
+;; Keywords:
+;; Compatibility:
+;;
+;; Features that might be required by this library:
+;;
+;;   This file is for Emacs 22 only.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Change this file according to the path of your nxml-mode dir. If
+;; you do not use nxml-mode then just use autostart.el.
+;;
+;; NOTICE: You need to enter the path to your nxml-mode installation
+;; below.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(let ((debug-on-error t))
+  (if (/= emacs-major-version 22)
+      (message "This file (autostart22.el) is for Emacs 22 only")
+
+    (defalias 'Custom-mode 'custom-mode)
+
+    (let* ((this-file (or load-file-name buffer-file-name))
+           (this-dir (file-name-directory this-file))
+           ;; FIX-ME: Download nXml (since it is not included in Emacs
+           ;; 22) and place the path to rng-auto.el in your downloaded
+           ;; nXml HERE:
+           (rng-auto-file (or (locate-library "rng-auto.el")
+                              "c:/emacs/u/081231/EmacsW32/nxhtml/nxml-mode-20041004/rng-auto.el")))
+      (unless (file-exists-p rng-auto-file)
+        (error "Can't find rng-auto.el, please edit %s" this-file))
+      (load rng-auto-file))))
+
+(provide 'autostart22)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; autostart22.el ends here
diff --git a/nxhtml/emacs22.cmd b/nxhtml/emacs22.cmd
new file mode 100644
index 0000000..d50ac96
--- /dev/null
+++ b/nxhtml/emacs22.cmd
@@ -0,0 +1 @@
+c:\emacs\emacs-22.3\bin\emacs.exe -Q --debug-init -l autostart.el
diff --git a/nxhtml/etc/img/pause/pause.jpg b/nxhtml/etc/img/pause/pause.jpg
new file mode 100644
index 0000000..ff92075
Binary files /dev/null and b/nxhtml/etc/img/pause/pause.jpg differ
diff --git a/nxhtml/etc/img/pause/pause2.jpg b/nxhtml/etc/img/pause/pause2.jpg
new file mode 100644
index 0000000..6411344
Binary files /dev/null and b/nxhtml/etc/img/pause/pause2.jpg differ
diff --git a/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc b/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc
new file mode 100644
index 0000000..aa2eff3
Binary files /dev/null and b/nxhtml/etc/schema/FDA-2009-N-0392-0396.1.doc differ
diff --git a/nxhtml/etc/schema/genshi-old.rnc b/nxhtml/etc/schema/genshi-old.rnc
new file mode 100644
index 0000000..4c92c0a
--- /dev/null
+++ b/nxhtml/etc/schema/genshi-old.rnc
@@ -0,0 +1,27 @@
+namespace py = "http://genshi.edgewall.org/"
+
+genshi.expr-type    = xsd:string { minLength = "1" }
+genshi.with-type    = xsd:string { minLength = "1" }
+genshi.choose-type  = xsd:string
+genshi.def-type   = xsd:string
+genshi.xpath-type = xsd:anyURI
+
+genshi.attrib = attribute py:if        { genshi.expr-type   }?,
+                attribute py:choose    { genshi.choose-type }?,
+                attribute py:when      { genshi.expr-type   }?,
+                attribute py:otherwise { genshi.expr-type   }?,
+                attribute py:for       { genshi.expr-type   }?,
+                attribute py:def       { genshi.def-type    }?,
+                attribute py:match     { genshi.xpath-type  }?,
+                attribute py:with      { genshi.with-type   }?,
+                attribute py:attrs     { genshi.expr-type   }?,
+                attribute py:content   { genshi.expr-type   }?,
+                attribute py:replace   { genshi.expr-type   }?,
+                attribute py:strip     { genshi.expr-type   }?
+
+genshi.if.attlist   = attribute expr { genshi.expr-type }
+genshi.for.attlist  = attribute each { genshi.expr-type }
+genshi.def.attlist  = attribute each { genshi.expr-type }
+genshi.with.attlist = attribute vars { genshi.with-type }
+
+               
diff --git a/nxhtml/etc/schema/genshi-schemas.xml b/nxhtml/etc/schema/genshi-schemas.xml
new file mode 100644
index 0000000..56b0182
--- /dev/null
+++ b/nxhtml/etc/schema/genshi-schemas.xml
@@ -0,0 +1,3 @@
+
+  
+
diff --git a/nxhtml/etc/schema/genshi.rnc b/nxhtml/etc/schema/genshi.rnc
new file mode 100644
index 0000000..3ac1c44
--- /dev/null
+++ b/nxhtml/etc/schema/genshi.rnc
@@ -0,0 +1,84 @@
+default namespace = "http://genshi.edgewall.org/"
+namespace py = "http://genshi.edgewall.org/"
+
+include "xinclude.rnc"
+
+# There's no way to just match the text part against a Genshi Python expression
+# See: http://relaxng.org/compact-tutorial-20030326.html#id2814737
+python.expression = text
+
+genshi.expr-type = xsd:string { minLength = "1" }
+genshi.xpath-type = xsd:anyURI
+
+genshi.attrib =
+   attribute py:if { genshi.expr-type }?,
+   attribute py:choose { text }?,
+   attribute py:when { genshi.expr-type }?,
+   attribute py:otherwise { text }?,
+   attribute py:for { genshi.expr-type }?,
+   attribute py:def { genshi.expr-type }?,
+   attribute py:match { genshi.xpath-type}?,
+   attribute py:with { genshi.expr-type }?,
+   attribute py:attrs { genshi.expr-type }?,
+   attribute py:content { text }?,
+   attribute py:replace { genshi.expr-type }?,
+   attribute py:strip { text }?
+
+genshi.if.attlist  = attribute test { genshi.expr-type }
+genshi.choose.attlist = attribute test { text }
+genshi.when.attlist = attribute test { genshi.expr-type }
+genshi.for.attlist = attribute each { genshi.expr-type }
+genshi.def.attlist = attribute function { genshi.expr-type }
+genshi.with.attlist = attribute vars { genshi.expr-type }
+genshi.replace.attlist = attribute value { genshi.expr-type }
+genshi.match.attlist =
+   attribute path { genshi.xpath-type },
+   attribute buffer { "true" | "false" }?,
+   attribute once { "true" | "false" }?,
+   attribute recursive { "true" | "false" }?
+
+genshi.choose =
+   element py:choose { genshi.choose.attlist,
+      genshi.model
+   }
+genshi.when =
+   element py:when { genshi.when.attlist,
+      genshi.model
+   }
+genshi.otherwise =
+   element py:otherwise {
+      genshi.model
+   }
+genshi.if =
+   element py:if { genshi.if.attlist,
+      genshi.model
+   }
+genshi.for =
+   element py:for { genshi.for.attlist,
+      genshi.model
+   }
+genshi.def =
+   element py:def { genshi.def.attlist,
+      genshi.model
+   }
+genshi.with =
+   element py:with { genshi.with.attlist,
+      genshi.model
+   }
+genshi.match =
+   element py:match { genshi.match.attlist,
+      genshi.model
+   }
+genshi.replace =
+   element py:replace { genshi.replace.attlist,
+      genshi.model
+   }
+
+genshi.allowed.children = text
+
+genshi.class = genshi.if | genshi.choose | genshi.when | genshi.otherwise
+ | genshi.for | genshi.def | genshi.with | genshi.match | genshi.replace
+ | python.expression
+ | xi.include
+
+genshi.model = genshi.class* | genshi.allowed.children*
\ No newline at end of file
diff --git a/nxhtml/etc/schema/mjt.rnc b/nxhtml/etc/schema/mjt.rnc
new file mode 100644
index 0000000..b37f01a
--- /dev/null
+++ b/nxhtml/etc/schema/mjt.rnc
@@ -0,0 +1,74 @@
+include "xhtml-loader.rnc"
+
+MjtAll.attrib =
+  attribute mjt.def { Text.datatype }?,
+  attribute mjt.when { Text.datatype }?,
+  attribute mjt.otherwise { Text.datatype }?,
+  attribute mjt.for { Text.datatype }?,
+  attribute mjt.if { Text.datatype }?,
+  attribute mjt.elif { Text.datatype }?,
+  attribute mjt.else { Text.datatype }?,
+  attribute mjt.script { Text.datatype }?,
+  attribute mjt.choose { Text.datatype }?,
+  attribute mjt.replace { Text.datatype }?,
+  attribute mjt.content { Text.datatype }?,
+  attribute mjt.strip { Text.datatype }?,
+  attribute mjt.src { Text.datatype }?,
+  attribute mjt.style { Text.datatype }?,
+  attribute mjt.class { Text.datatype }?,
+  attribute mjt.id { Text.datatype }?,
+  attribute mjt.attrs { Text.datatype }?,
+  attribute mjt.task { Text.datatype }?
+
+
+a.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?
+area.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?
+form.attlist &=
+  attribute mjt.onreset { Script.datatype }?,
+  attribute mjt.onsubmit { Script.datatype }?
+body.attlist &=
+  attribute mjt.onload { Script.datatype }?,
+  attribute mjt.onunload { Script.datatype }?
+label.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?
+input.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onchange { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?,
+  attribute mjt.onselect { Script.datatype }?
+select.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onchange { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?
+textarea.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onchange { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?,
+  attribute mjt.onselect { Script.datatype }?
+button.attlist &=
+  attribute mjt.onblur { Script.datatype }?,
+  attribute mjt.onfocus { Script.datatype }?
+
+MjtEvents.attrib =
+  attribute mjt.onclick { Script.datatype }?,
+  attribute mjt.ondblclick { Script.datatype }?,
+  attribute mjt.onmousedown { Script.datatype }?,
+  attribute mjt.onmouseup { Script.datatype }?,
+  attribute mjt.onmouseover { Script.datatype }?,
+  attribute mjt.onmousemove { Script.datatype }?,
+  attribute mjt.onmouseout { Script.datatype }?,
+  attribute mjt.onkeypress { Script.datatype }?,
+  attribute mjt.onkeydown { Script.datatype }?,
+  attribute mjt.onkeyup { Script.datatype }?
+
+
+Common.attrib &= MjtAll.attrib
+CommonIdRequired.attrib &= MjtAll.attrib
+
+Common.attrib &= MjtEvents.attrib
+CommonIdRequired.attrib &= MjtEvents.attrib
diff --git a/nxhtml/etc/schema/nxml-erb.patch b/nxhtml/etc/schema/nxml-erb.patch
new file mode 100644
index 0000000..362913b
--- /dev/null
+++ b/nxhtml/etc/schema/nxml-erb.patch
@@ -0,0 +1,37 @@
+--- nxml-mode-orig/xmltok.el	2005-10-16 15:32:53.000000000 -0400
++++ nxml-mode-erb/xmltok.el	2006-09-01 01:02:55.000000000 -0400
+@@ -496,6 +496,9 @@
+ 	  (xmltok+ (xmltok-g markup-declaration "!")
+ 		   (xmltok-g comment-first-dash "-"
+ 			     (xmltok-g comment-open "-") opt) opt))
++         (erb-section
++          (xmltok+ "%"
++                   (xmltok-g erb-section-open "[^%]") opt))
+ 	 (cdata-section
+ 	  (xmltok+ "!"
+ 		  (xmltok-g marked-section-open "\\[")
+@@ -526,6 +529,7 @@
+ 			       ;; by default
+ 			       or cdata-section
+ 			       or comment
++                               or erb-section
+ 			       or processing-instruction))
+     (xmltok-defregexp
+      xmltok-attribute
+@@ -693,6 +697,16 @@
+ 					      nil
+ 					      "]]>")
+ 			'not-well-formed)))
++               ((xmltok-after-lt start erb-section-open)
++		(setq xmltok-type
++		      (if (re-search-forward "[^%]%>" nil t)
++			  'erb-section
++			(xmltok-add-error "No closing %>")
++			(xmltok-add-dependent 'xmltok-unclosed-reparse-p
++					      nil
++					      nil
++					      "%>")
++			'not-well-formed)))
+ 	       ((xmltok-after-lt start processing-instruction-question)
+ 		(xmltok-scan-after-processing-instruction-open))
+ 	       ((xmltok-after-lt start comment-open)
diff --git a/nxhtml/etc/schema/old-genshi.rnc b/nxhtml/etc/schema/old-genshi.rnc
new file mode 100644
index 0000000..6d5562d
--- /dev/null
+++ b/nxhtml/etc/schema/old-genshi.rnc
@@ -0,0 +1,31 @@
+namespace py = "http://genshi.edgewall.org/"
+
+genshi.expr-type    = xsd:string { minLength = "1" }
+genshi.with-type    = xsd:string { minLength = "1" }
+genshi.choose-type  = xsd:string
+genshi.def-type   = xsd:string
+genshi.xpath-type = xsd:anyURI
+
+genshi.attrib = attribute py:if        { genshi.expr-type   }?,
+                attribute py:choose    { genshi.choose-type }?,
+                attribute py:when      { genshi.expr-type   }?,
+                attribute py:otherwise { genshi.expr-type   }?,
+                attribute py:for       { genshi.expr-type   }?,
+                attribute py:def       { genshi.def-type    }?,
+                attribute py:match     { genshi.xpath-type  }?,
+                attribute py:with      { genshi.with-type   }?,
+                attribute py:attrs     { genshi.expr-type   }?,
+                attribute py:content   { genshi.expr-type   }?,
+                attribute py:replace   { genshi.expr-type   }?,
+                attribute py:strip     { genshi.expr-type   }?
+
+genshi.if.attlist   = attribute test { genshi.expr-type }
+genshi.for.attlist  = attribute each { genshi.expr-type }
+genshi.def.attlist  = attribute function { genshi.expr-type }
+genshi.with.attlist = attribute vars { genshi.with-type }
+genshi.match.attlist = attribute path { genshi.xpath-type },
+                       attribute buffer { genshi.expr-type }?,
+                       attribute once { genshi.expr-type }?,
+                       attribute recursive { genshi.expr-type }?
+
+               
diff --git a/nxhtml/etc/schema/old-qtmstr-xhtml.rnc b/nxhtml/etc/schema/old-qtmstr-xhtml.rnc
new file mode 100644
index 0000000..251d1e4
--- /dev/null
+++ b/nxhtml/etc/schema/old-qtmstr-xhtml.rnc
@@ -0,0 +1,61 @@
+namespace py = "http://genshi.edgewall.org/"
+namespace xi = "http://www.w3.org/2001/XInclude"
+
+include "genshi.rnc"
+include "xinclude.rnc"
+include "xhtml-loader.rnc"
+
+start |= head|body|p|\div|h1|h2|h3|h4|h5|h6|hr|pre|dl|ol|ul|table|form
+
+Common.attrib &= genshi.attrib
+head.attlist  &= genshi.attrib
+html.attlist  &= genshi.attrib
+
+Head.class = base | isindex | link | meta | script | title | style |
+             if-head | for-head | def-head | with-head
+
+Head.model = Head.class*
+
+head.content &= Head.model*
+
+if-inline   = element py:if   { genshi.if.attlist, Inline.model }
+if-block    = element py:if   { genshi.if.attlist, Block.model }
+if-head     = element py:if   { genshi.if.attlist, Head.model }
+for-inline  = element py:for  { genshi.for.attlist, Inline.model }
+for-block   = element py:for  { genshi.for.attlist, Block.model }
+for-head    = element py:for  { genshi.for.attlist, Head.model }
+def-inline  = element py:def  { genshi.def.attlist, Inline.model }
+def-block   = element py:def  { genshi.def.attlist, Block.model }
+def-head    = element py:def  { genshi.def.attlist, Head.model }
+with-inline = element py:with { genshi.with.attlist, Inline.model }
+with-block  = element py:with { genshi.with.attlist, Block.model }
+with-head   = element py:with { genshi.with.attlist, Head.model }
+match-inline = element py:match { genshi.match.attlist, Inline.model }
+match-block = element py:match { genshi.match.attlist, Block.model }
+match-head = element py:match { genshi.match.attlist, Head.model }
+
+Inline.class |= if-inline | for-inline | def-inline | with-inline | match-inline
+Block.class  |= if-block | for-block | def-block | with-block | match-block
+
+xi-inline = element xi:include {
+                xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-inline | Inline.model)*
+                }?
+            }
+
+xi-block  = element xi:include { xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-block | Block.model)*
+                }?
+            }
+
+xi-head   = element xi:include { xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-head | Head.model)*
+                }?
+            }
+
+Inline.class |= xi-inline
+Block.class  |= xi-block
+Head.class   |= xi-head
diff --git a/nxhtml/etc/schema/old-xinclude.rnc b/nxhtml/etc/schema/old-xinclude.rnc
new file mode 100644
index 0000000..829c5ac
--- /dev/null
+++ b/nxhtml/etc/schema/old-xinclude.rnc
@@ -0,0 +1,11 @@
+namespace xi = "http://www.w3.org/2001/XInclude"
+namespace local = ""
+
+xinclude.include.attlist =
+    attribute href     { xsd:anyURI }?,
+    attribute parse    { xsd:string }?,
+    attribute xpointer { xsd:string }?,
+    attribute encoding { xsd:string }?,
+    attribute accept   { xsd:string }?,
+    attribute accept-language { xsd:string }?
+
diff --git a/nxhtml/etc/schema/qtmstr-xhtml-old.rnc b/nxhtml/etc/schema/qtmstr-xhtml-old.rnc
new file mode 100644
index 0000000..cc88e76
--- /dev/null
+++ b/nxhtml/etc/schema/qtmstr-xhtml-old.rnc
@@ -0,0 +1,58 @@
+namespace py = "http://genshi.edgewall.org/"
+namespace xi = "http://www.w3.org/2001/XInclude"
+
+include "genshi.rnc"
+include "xinclude.rnc"
+include "xhtml-loader.rnc"
+
+start |= head|body|p|\div|h1|h2|h3|h4|h5|h6|hr|pre|dl|ol|ul|table|form
+
+Common.attrib &= genshi.attrib
+head.attlist  &= genshi.attrib
+html.attlist  &= genshi.attrib
+
+Head.class = base | isindex | link | meta | script | title | style |
+             if-head | for-head | def-head | with-head
+
+Head.model = Head.class*
+
+head.content &= Head.model*
+
+if-inline   = element py:if   { genshi.if.attlist, Inline.model }
+if-block    = element py:if   { genshi.if.attlist, Block.model }
+if-head     = element py:if   { genshi.if.attlist, Head.model }
+for-inline  = element py:for  { genshi.for.attlist, Inline.model }
+for-block   = element py:for  { genshi.for.attlist, Block.model }
+for-head    = element py:for  { genshi.for.attlist, Head.model }
+def-inline  = element py:def  { genshi.def.attlist, Inline.model }
+def-block   = element py:def  { genshi.def.attlist, Block.model }
+def-head    = element py:def  { genshi.def.attlist, Head.model }
+with-inline = element py:with { genshi.with.attlist, Inline.model }
+with-block  = element py:with { genshi.with.attlist, Block.model }
+with-head   = element py:with { genshi.with.attlist, Head.model }
+
+Inline.class |= if-inline | for-inline | def-inline | with-inline
+Block.class  |= if-block | for-block | def-block | with-block
+
+xi-inline = element xi:include {
+                xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-inline | Inline.model)*
+                }?
+            }
+
+xi-block  = element xi:include { xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-block | Block.model)*
+                }?
+            }
+
+xi-head   = element xi:include { xinclude.include.attlist,
+                element xi:fallback { genshi.attrib,
+                    (xi-head | Head.model)*
+                }?
+            }
+
+Inline.class |= xi-inline
+Block.class  |= xi-block
+Head.class   |= xi-head
diff --git a/nxhtml/etc/schema/qtmstr-xhtml.rnc b/nxhtml/etc/schema/qtmstr-xhtml.rnc
new file mode 100644
index 0000000..be91066
--- /dev/null
+++ b/nxhtml/etc/schema/qtmstr-xhtml.rnc
@@ -0,0 +1,66 @@
+default namespace = "http://www.w3.org/1999/xhtml"
+
+include "genshi.rnc"
+include "xhtml-loader.rnc" {
+   start = html | head | head.content | body | frameset | frame | noframes |
+      Block.class | Inline.class | Table.class | Form.extra.class | genshi.class
+   html = element html { html.attlist, (genshi.model | (head, (body | frameset | genshi.model))) }
+   frameset =
+      element frameset {
+         frameset.attlist,
+         (((frameset | frame)+ & noframes?) | genshi.model)
+      }
+   noframes = element noframes { noframes.attlist, (body | genshi.model) }
+   title = element title { title.attlist, (text | genshi.model)* }
+   script = element script { script.attlist, (text | genshi.model)* }
+   style = element style { style.attlist, (text | genshi.model)* }
+   dl = element dl { dl.attlist, ((dt | dd)+ | genshi.model) }
+   ol = element ol { ol.attlist, (li+ | genshi.model) }
+   ul = element ul { ul.attlist, (li+ | genshi.model) }
+   dir = element dir { dir.attlist, (li.noblock+ | genshi.model) }
+   menu = element menu { menu.attlist, (li.noblock+ | genshi.model) }
+   select = element select { select.attlist, ((option | optgroup)+ | genshi.model) }
+   option =
+      element option {
+         Common.attrib,
+         attribute selected { "selected" }?,
+         attribute value { text }?,
+         (text | genshi.model)*
+      }
+   textarea = element textarea { textarea.attlist, (text & genshi.model)* }
+   optgroup = element optgroup { optgroup.attlist, (option+ | genshi.model) }
+   table =
+      element table {
+         table.attlist,
+         (caption? | genshi.model),
+         (col* | colgroup* | genshi.model),
+         (((thead? | genshi.model),
+            (tfoot? | genshi.model),
+            (tbody+ | genshi.model)) | (tr+ | genshi.model))
+      }
+   colgroup = element colgroup { colgroup.attlist, (col* | genshi.model) }
+   tr = element tr { tr.attlist, ((th | td)+ | genshi.model) }
+   tbody = element tbody { tbody.attlist, (tr+ | genshi.model) }
+   thead = element thead { thead.attlist, (tr+ | genshi.model) }
+   tfoot = element tfoot { tfoot.attlist, (tr+ | genshi.model) }
+}
+
+Table.class = caption | colgroup | col | tbody | thead | tfoot | th | tr | td
+Form.extra.class = option | optgroup | legend
+
+Block.class |= genshi.class
+Inline.class |= genshi.class
+head.content &= genshi.class
+
+Core.attrib &= genshi.attrib
+html.attlist  &= genshi.attrib
+head.attlist  &= genshi.attrib
+title.attlist &= genshi.attrib
+base.attlist &= genshi.attrib
+meta.attlist &= genshi.attrib
+script.attlist &= genshi.attrib
+param.attlist &= genshi.attrib
+Edit.attrib &= genshi.attrib
+
+genshi.allowed.children |= html | head | head.content | body | frameset | frame
+ | noframes | Inline.class | Block.class | Table.class | Form.extra.class
diff --git a/nxhtml/etc/schema/schema-path-patch.el b/nxhtml/etc/schema/schema-path-patch.el
new file mode 100644
index 0000000..a6d59fc
--- /dev/null
+++ b/nxhtml/etc/schema/schema-path-patch.el
@@ -0,0 +1,95 @@
+;;; schema-path-patch.el --- Patch schema paths
+;;
+;; Author: Lennart Borgman (lennart O borgman A gmail O com)
+;; Created: 2008-08-08T20:21:31+0200 Fri
+;; Version: 0.2
+;; Last-Updated: 2008-08-19T00:21:25+0200 Mon
+;; URL:
+;; Keywords:
+;; Compatibility:
+;;
+;; Features that might be required by this library:
+;;
+;;   Cannot open load file: schema-path-patch.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Schemas here may include parts from nxml and need to know the path.
+;; This file can be used to patch the paths.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(defvar rncpp-this-dir
+  (file-name-as-directory
+   (file-name-directory
+    (if load-file-name load-file-name buffer-file-name))))
+
+(defun rncpp-get-nxml-schema-dir ()
+  ;; First look for nxml-mode included with Emacs
+  (let ((schema-dir (file-name-as-directory
+                     (expand-file-name "schema" data-directory))))
+    (unless (file-directory-p schema-dir)
+      ;; This is an old nxml-mode, look for its schemas dir.
+      (let ((nxml-mode-dir (file-name-as-directory
+                            (file-name-directory (locate-library "nxml-mode")))))
+        (setq schema-dir (file-name-as-directory
+                          (expand-file-name "schema" nxml-mode-dir)))))
+    (unless (file-directory-p schema-dir)
+      (error "Can't find schema-dir=%s" schema-dir))
+    schema-dir))
+
+;; Use xhtml-loader.rnc (an idea from Bryan Waite):
+(defun rncpp-patch-xhtml-loader ()
+  "Patch xhtml-loader.rnc so genshi and mjt rnc files works."
+  ;;(interactive)
+  (let* ((default-directory rncpp-this-dir)
+         (loader-path (expand-file-name "xhtml-loader.rnc"))
+         (loader-buf (find-buffer-visiting loader-path))
+         (schema-dir (rncpp-get-nxml-schema-dir))
+         (schema-relative-dir (file-relative-name schema-dir))
+         (loader-string (concat "include \""
+                                schema-relative-dir
+                                "xhtml.rnc\"\n")))
+    (when loader-buf (kill-buffer loader-buf))
+    (setq loader-buf (find-file-noselect loader-path))
+    (with-current-buffer loader-buf
+      (unless (file-exists-p loader-path)
+        (insert loader-string))
+      ;; Test if correct
+      (if (string= (buffer-substring-no-properties (point-min) (point-max))
+                       loader-string)
+          (message "xhtml-loader.rnc was ok")
+        (message "Patching xhtml-loader.rnc")
+        (delete-region (point-min) (point-max))
+        (insert loader-string))
+      (basic-save-buffer)
+      (kill-buffer (current-buffer)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; schema-path-patch.el ends here
diff --git a/nxhtml/etc/schema/xhtml-loader.rnc b/nxhtml/etc/schema/xhtml-loader.rnc
new file mode 100644
index 0000000..2a4ac13
--- /dev/null
+++ b/nxhtml/etc/schema/xhtml-loader.rnc
@@ -0,0 +1 @@
+include "../../../../../../../../ntemacs24/etc/schema/xhtml.rnc"
diff --git a/nxhtml/etc/schema/xinclude.rnc b/nxhtml/etc/schema/xinclude.rnc
new file mode 100644
index 0000000..4622126
--- /dev/null
+++ b/nxhtml/etc/schema/xinclude.rnc
@@ -0,0 +1,35 @@
+default namespace = "http://www.w3.org/2001/XInclude"
+namespace xi = "http://www.w3.org/2001/XInclude"
+
+xi.include.attlist =
+   attribute href     { xsd:anyURI }?,
+   attribute parse    { "xml" | "text" }?,
+   attribute xpointer { xsd:string }?,
+   attribute encoding { xsd:string }?,
+   attribute accept   { xsd:string }?,
+   attribute accept-language { xsd:string }?
+
+xi.include.attlist.extra =
+   attribute * - xi.include.attlist { text }*
+
+xi.include =
+   element xi:include {
+      xi.include.attlist,
+      xi.include.attlist.extra,
+      (xi.fallback? | xi.include.extra)*
+   }
+
+xi.include.extra = notAllowed
+
+xi.fallback.attlist =
+   attribute * { text }*
+
+xi.fallback =
+   element xi:fallback {
+      xi.fallback.attlist, 
+      (xi.include | xi.fallback.extra)*
+   }
+
+xi.fallback.extra = notAllowed
+
+xi.class = xi.include | xi.fallback
\ No newline at end of file
diff --git a/nxhtml/etc/templates/rollover-2v.css b/nxhtml/etc/templates/rollover-2v.css
new file mode 100644
index 0000000..ed10a41
--- /dev/null
+++ b/nxhtml/etc/templates/rollover-2v.css
@@ -0,0 +1,25 @@
+ROLLOVER_SPEC a {
+    /* Image */
+    display: block;
+    background: transparent url("IMG_URL") 0 0 no-repeat;
+    overflow: hidden;
+    width: IMG_WIDTHpx;
+    /* Text placement and size, etc */
+    CENTER_OR_PAD;
+    padding-top: PADDING_TOPpx;
+    font-size: FONT_SIZEpx;
+    padding-bottom: PADDING_BOTTOMpx;
+    text-decoration: none;
+    white-space: nowrap;
+    border: none;
+    margin: 0;
+}
+ROLLOVER_SPEC a:hover {
+    background-position: 0 -IMG_HEIGHT_2px;
+}
+ROLLOVER_SPEC li {
+    display: inline;
+    padding: 0;
+    margin: 0;
+    HOR_OR_VER;
+}
diff --git a/nxhtml/etc/uts39/idnchars.txt b/nxhtml/etc/uts39/idnchars.txt
new file mode 100644
index 0000000..4bfe80c
--- /dev/null
+++ b/nxhtml/etc/uts39/idnchars.txt
@@ -0,0 +1,894 @@
+# Recommended Identifier Profiles for IDN
+# File: idnchars.txt
+# Version: 2.0
+# Generated: 2006-08-15, 04:35:10 GMT
+# Checkin: $Revision: 1.11 $
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr39/
+#
+# Allowed as output characters
+
+002D          ; output #      (-)  HYPHEN-MINUS
+0030..0039    ; output # [10] (0..9)  DIGIT ZERO..DIGIT NINE
+0041..005A    ; output # [26] (A..Z)  LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
+0061..007A    ; output # [26] (a..z)  LATIN SMALL LETTER A..LATIN SMALL LETTER Z
+00B7          ; output #      (·)  MIDDLE DOT
+00E0..00F6    ; output # [23] (à..ö)  LATIN SMALL LETTER A WITH GRAVE..LATIN SMALL LETTER O WITH DIAERESIS
+00F8..00FF    ; output #  [8] (ø..ÿ)  LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS
+0101          ; output #      (ā)  LATIN SMALL LETTER A WITH MACRON
+0103          ; output #      (ă)  LATIN SMALL LETTER A WITH BREVE
+0105          ; output #      (ą)  LATIN SMALL LETTER A WITH OGONEK
+0107          ; output #      (ć)  LATIN SMALL LETTER C WITH ACUTE
+0109          ; output #      (ĉ)  LATIN SMALL LETTER C WITH CIRCUMFLEX
+010B          ; output #      (ċ)  LATIN SMALL LETTER C WITH DOT ABOVE
+010D          ; output #      (č)  LATIN SMALL LETTER C WITH CARON
+010F          ; output #      (ď)  LATIN SMALL LETTER D WITH CARON
+0111          ; output #      (đ)  LATIN SMALL LETTER D WITH STROKE
+0113          ; output #      (ē)  LATIN SMALL LETTER E WITH MACRON
+0115          ; output #      (ĕ)  LATIN SMALL LETTER E WITH BREVE
+0117          ; output #      (ė)  LATIN SMALL LETTER E WITH DOT ABOVE
+0119          ; output #      (ę)  LATIN SMALL LETTER E WITH OGONEK
+011B          ; output #      (ě)  LATIN SMALL LETTER E WITH CARON
+011D          ; output #      (ĝ)  LATIN SMALL LETTER G WITH CIRCUMFLEX
+011F          ; output #      (ğ)  LATIN SMALL LETTER G WITH BREVE
+0121          ; output #      (Ä¡)  LATIN SMALL LETTER G WITH DOT ABOVE
+0123          ; output #      (Ä£)  LATIN SMALL LETTER G WITH CEDILLA
+0125          ; output #      (Ä¥)  LATIN SMALL LETTER H WITH CIRCUMFLEX
+0127          ; output #      (ħ)  LATIN SMALL LETTER H WITH STROKE
+0129          ; output #      (Ä©)  LATIN SMALL LETTER I WITH TILDE
+012B          ; output #      (Ä«)  LATIN SMALL LETTER I WITH MACRON
+012D          ; output #      (Ä­)  LATIN SMALL LETTER I WITH BREVE
+012F          ; output #      (į)  LATIN SMALL LETTER I WITH OGONEK
+0131          ; output #      (ı)  LATIN SMALL LETTER DOTLESS I
+0135          ; output #      (ĵ)  LATIN SMALL LETTER J WITH CIRCUMFLEX
+0137..0138    ; output #  [2] (ķ..ĸ)  LATIN SMALL LETTER K WITH CEDILLA..LATIN SMALL LETTER KRA
+013A          ; output #      (ĺ)  LATIN SMALL LETTER L WITH ACUTE
+013C          ; output #      (ļ)  LATIN SMALL LETTER L WITH CEDILLA
+013E          ; output #      (ľ)  LATIN SMALL LETTER L WITH CARON
+0142          ; output #      (ł)  LATIN SMALL LETTER L WITH STROKE
+0144          ; output #      (ń)  LATIN SMALL LETTER N WITH ACUTE
+0146          ; output #      (ņ)  LATIN SMALL LETTER N WITH CEDILLA
+0148          ; output #      (ň)  LATIN SMALL LETTER N WITH CARON
+014B          ; output #      (ŋ)  LATIN SMALL LETTER ENG
+014D          ; output #      (ō)  LATIN SMALL LETTER O WITH MACRON
+014F          ; output #      (ŏ)  LATIN SMALL LETTER O WITH BREVE
+0151          ; output #      (ő)  LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0153          ; output #      (œ)  LATIN SMALL LIGATURE OE
+0155          ; output #      (ŕ)  LATIN SMALL LETTER R WITH ACUTE
+0157          ; output #      (ŗ)  LATIN SMALL LETTER R WITH CEDILLA
+0159          ; output #      (ř)  LATIN SMALL LETTER R WITH CARON
+015B          ; output #      (ś)  LATIN SMALL LETTER S WITH ACUTE
+015D          ; output #      (ŝ)  LATIN SMALL LETTER S WITH CIRCUMFLEX
+015F          ; output #      (ş)  LATIN SMALL LETTER S WITH CEDILLA
+0161          ; output #      (Å¡)  LATIN SMALL LETTER S WITH CARON
+0163          ; output #      (Å£)  LATIN SMALL LETTER T WITH CEDILLA
+0165          ; output #      (Å¥)  LATIN SMALL LETTER T WITH CARON
+0167          ; output #      (ŧ)  LATIN SMALL LETTER T WITH STROKE
+0169          ; output #      (Å©)  LATIN SMALL LETTER U WITH TILDE
+016B          ; output #      (Å«)  LATIN SMALL LETTER U WITH MACRON
+016D          ; output #      (Å­)  LATIN SMALL LETTER U WITH BREVE
+016F          ; output #      (ů)  LATIN SMALL LETTER U WITH RING ABOVE
+0171          ; output #      (ű)  LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0173          ; output #      (ų)  LATIN SMALL LETTER U WITH OGONEK
+0175          ; output #      (ŵ)  LATIN SMALL LETTER W WITH CIRCUMFLEX
+0177          ; output #      (Å·)  LATIN SMALL LETTER Y WITH CIRCUMFLEX
+017A          ; output #      (ź)  LATIN SMALL LETTER Z WITH ACUTE
+017C          ; output #      (ż)  LATIN SMALL LETTER Z WITH DOT ABOVE
+017E          ; output #      (ž)  LATIN SMALL LETTER Z WITH CARON
+0183          ; output #      (ƃ)  LATIN SMALL LETTER B WITH TOPBAR
+0185          ; output #      (ƅ)  LATIN SMALL LETTER TONE SIX
+0188          ; output #      (ƈ)  LATIN SMALL LETTER C WITH HOOK
+018C          ; output #      (ƌ)  LATIN SMALL LETTER D WITH TOPBAR
+0192          ; output #      (ƒ)  LATIN SMALL LETTER F WITH HOOK
+0195          ; output #      (ƕ)  LATIN SMALL LETTER HV
+0199..019B    ; output #  [3] (ƙ..ƛ)  LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE
+019E          ; output #      (ƞ)  LATIN SMALL LETTER N WITH LONG RIGHT LEG
+01A1          ; output #      (Æ¡)  LATIN SMALL LETTER O WITH HORN
+01A3          ; output #      (Æ£)  LATIN SMALL LETTER OI
+01A5          ; output #      (Æ¥)  LATIN SMALL LETTER P WITH HOOK
+01A8          ; output #      (ƨ)  LATIN SMALL LETTER TONE TWO
+01AD          ; output #      (Æ­)  LATIN SMALL LETTER T WITH HOOK
+01B0          ; output #      (ư)  LATIN SMALL LETTER U WITH HORN
+01B4          ; output #      (Æ´)  LATIN SMALL LETTER Y WITH HOOK
+01B6          ; output #      (ƶ)  LATIN SMALL LETTER Z WITH STROKE
+01BD          ; output #      (ƽ)  LATIN SMALL LETTER TONE FIVE
+01CE          ; output #      (ǎ)  LATIN SMALL LETTER A WITH CARON
+01D0          ; output #      (ǐ)  LATIN SMALL LETTER I WITH CARON
+01D2          ; output #      (ǒ)  LATIN SMALL LETTER O WITH CARON
+01D4          ; output #      (ǔ)  LATIN SMALL LETTER U WITH CARON
+01D6          ; output #      (ǖ)  LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+01D8          ; output #      (ǘ)  LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+01DA          ; output #      (ǚ)  LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+01DC..01DD    ; output #  [2] (ǜ..ǝ)  LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE..LATIN SMALL LETTER TURNED E
+01DF          ; output #      (ǟ)  LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
+01E1          ; output #      (Ç¡)  LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
+01E3          ; output #      (Ç£)  LATIN SMALL LETTER AE WITH MACRON
+01E5          ; output #      (Ç¥)  LATIN SMALL LETTER G WITH STROKE
+01E7          ; output #      (ǧ)  LATIN SMALL LETTER G WITH CARON
+01E9          ; output #      (Ç©)  LATIN SMALL LETTER K WITH CARON
+01EB          ; output #      (Ç«)  LATIN SMALL LETTER O WITH OGONEK
+01ED          ; output #      (Ç­)  LATIN SMALL LETTER O WITH OGONEK AND MACRON
+01EF..01F0    ; output #  [2] (ǯ..ǰ)  LATIN SMALL LETTER EZH WITH CARON..LATIN SMALL LETTER J WITH CARON
+01F5          ; output #      (ǵ)  LATIN SMALL LETTER G WITH ACUTE
+01F9          ; output #      (ǹ)  LATIN SMALL LETTER N WITH GRAVE
+01FB          ; output #      (Ç»)  LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
+01FD          ; output #      (ǽ)  LATIN SMALL LETTER AE WITH ACUTE
+01FF          ; output #      (Ç¿)  LATIN SMALL LETTER O WITH STROKE AND ACUTE
+0201          ; output #      (ȁ)  LATIN SMALL LETTER A WITH DOUBLE GRAVE
+0203          ; output #      (ȃ)  LATIN SMALL LETTER A WITH INVERTED BREVE
+0205          ; output #      (ȅ)  LATIN SMALL LETTER E WITH DOUBLE GRAVE
+0207          ; output #      (ȇ)  LATIN SMALL LETTER E WITH INVERTED BREVE
+0209          ; output #      (ȉ)  LATIN SMALL LETTER I WITH DOUBLE GRAVE
+020B          ; output #      (ȋ)  LATIN SMALL LETTER I WITH INVERTED BREVE
+020D          ; output #      (ȍ)  LATIN SMALL LETTER O WITH DOUBLE GRAVE
+020F          ; output #      (ȏ)  LATIN SMALL LETTER O WITH INVERTED BREVE
+0211          ; output #      (ȑ)  LATIN SMALL LETTER R WITH DOUBLE GRAVE
+0213          ; output #      (ȓ)  LATIN SMALL LETTER R WITH INVERTED BREVE
+0215          ; output #      (ȕ)  LATIN SMALL LETTER U WITH DOUBLE GRAVE
+0217          ; output #      (ȗ)  LATIN SMALL LETTER U WITH INVERTED BREVE
+0219          ; output #      (ș)  LATIN SMALL LETTER S WITH COMMA BELOW
+021B          ; output #      (ț)  LATIN SMALL LETTER T WITH COMMA BELOW
+021F          ; output #      (ȟ)  LATIN SMALL LETTER H WITH CARON
+0223          ; output #      (È£)  LATIN SMALL LETTER OU
+0225          ; output #      (È¥)  LATIN SMALL LETTER Z WITH HOOK
+0227          ; output #      (ȧ)  LATIN SMALL LETTER A WITH DOT ABOVE
+0229          ; output #      (È©)  LATIN SMALL LETTER E WITH CEDILLA
+022B          ; output #      (È«)  LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
+022D          ; output #      (È­)  LATIN SMALL LETTER O WITH TILDE AND MACRON
+022F          ; output #      (ȯ)  LATIN SMALL LETTER O WITH DOT ABOVE
+0231          ; output #      (ȱ)  LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
+0233          ; output #      (ȳ)  LATIN SMALL LETTER Y WITH MACRON
+0253..0254    ; output #  [2] (ɓ..ɔ)  LATIN SMALL LETTER B WITH HOOK..LATIN SMALL LETTER OPEN O
+0256..0257    ; output #  [2] (ɖ..ɗ)  LATIN SMALL LETTER D WITH TAIL..LATIN SMALL LETTER D WITH HOOK
+0259          ; output #      (ə)  LATIN SMALL LETTER SCHWA
+025B          ; output #      (ɛ)  LATIN SMALL LETTER OPEN E
+0260          ; output #      (É )  LATIN SMALL LETTER G WITH HOOK
+0263          ; output #      (É£)  LATIN SMALL LETTER GAMMA
+0268..0269    ; output #  [2] (ɨ..ɩ)  LATIN SMALL LETTER I WITH STROKE..LATIN SMALL LETTER IOTA
+026F          ; output #      (ɯ)  LATIN SMALL LETTER TURNED M
+0272          ; output #      (ɲ)  LATIN SMALL LETTER N WITH LEFT HOOK
+0275          ; output #      (ɵ)  LATIN SMALL LETTER BARRED O
+0280          ; output #      (ʀ)  LATIN LETTER SMALL CAPITAL R
+0283          ; output #      (ʃ)  LATIN SMALL LETTER ESH
+0288          ; output #      (ʈ)  LATIN SMALL LETTER T WITH RETROFLEX HOOK
+028A..028B    ; output #  [2] (ʊ..ʋ)  LATIN SMALL LETTER UPSILON..LATIN SMALL LETTER V WITH HOOK
+0292          ; output #      (ʒ)  LATIN SMALL LETTER EZH
+0294          ; output #      (ʔ)  LATIN LETTER GLOTTAL STOP
+0300..033F    ; output # [64] (̀..̿)  COMBINING GRAVE ACCENT..COMBINING DOUBLE OVERLINE
+0342          ; output #      (͂)  COMBINING GREEK PERISPOMENI
+0346..034E    ; output #  [9] (͆..͎)  COMBINING BRIDGE ABOVE..COMBINING UPWARDS ARROW BELOW
+0360..036F    ; output # [16] (͠..ͯ)  COMBINING DOUBLE TILDE..COMBINING LATIN SMALL LETTER X
+0390          ; output #      (ΐ)  GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+03AC..03C1    ; output # [22] (ά..ρ)  GREEK SMALL LETTER ALPHA WITH TONOS..GREEK SMALL LETTER RHO
+03C3..03CE    ; output # [12] (σ..ώ)  GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA WITH TONOS
+0430..045F    ; output # [48] (а..џ)  CYRILLIC SMALL LETTER A..CYRILLIC SMALL LETTER DZHE
+0461          ; output #      (Ñ¡)  CYRILLIC SMALL LETTER OMEGA
+0463          ; output #      (Ñ£)  CYRILLIC SMALL LETTER YAT
+0465          ; output #      (Ñ¥)  CYRILLIC SMALL LETTER IOTIFIED E
+0467          ; output #      (ѧ)  CYRILLIC SMALL LETTER LITTLE YUS
+0469          ; output #      (Ñ©)  CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS
+046B          ; output #      (Ñ«)  CYRILLIC SMALL LETTER BIG YUS
+046D          ; output #      (Ñ­)  CYRILLIC SMALL LETTER IOTIFIED BIG YUS
+046F          ; output #      (ѯ)  CYRILLIC SMALL LETTER KSI
+0471          ; output #      (ѱ)  CYRILLIC SMALL LETTER PSI
+0473          ; output #      (ѳ)  CYRILLIC SMALL LETTER FITA
+0475          ; output #      (ѵ)  CYRILLIC SMALL LETTER IZHITSA
+0477          ; output #      (Ñ·)  CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+0479          ; output #      (ѹ)  CYRILLIC SMALL LETTER UK
+047B          ; output #      (Ñ»)  CYRILLIC SMALL LETTER ROUND OMEGA
+047D          ; output #      (ѽ)  CYRILLIC SMALL LETTER OMEGA WITH TITLO
+047F          ; output #      (Ñ¿)  CYRILLIC SMALL LETTER OT
+0481          ; output #      (ҁ)  CYRILLIC SMALL LETTER KOPPA
+048B          ; output #      (ҋ)  CYRILLIC SMALL LETTER SHORT I WITH TAIL
+048D          ; output #      (ҍ)  CYRILLIC SMALL LETTER SEMISOFT SIGN
+048F          ; output #      (ҏ)  CYRILLIC SMALL LETTER ER WITH TICK
+0491          ; output #      (ґ)  CYRILLIC SMALL LETTER GHE WITH UPTURN
+0493          ; output #      (ғ)  CYRILLIC SMALL LETTER GHE WITH STROKE
+0495          ; output #      (ҕ)  CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK
+0497          ; output #      (җ)  CYRILLIC SMALL LETTER ZHE WITH DESCENDER
+0499          ; output #      (ҙ)  CYRILLIC SMALL LETTER ZE WITH DESCENDER
+049B          ; output #      (қ)  CYRILLIC SMALL LETTER KA WITH DESCENDER
+049D          ; output #      (ҝ)  CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
+049F          ; output #      (ҟ)  CYRILLIC SMALL LETTER KA WITH STROKE
+04A1          ; output #      (Ò¡)  CYRILLIC SMALL LETTER BASHKIR KA
+04A3          ; output #      (Ò£)  CYRILLIC SMALL LETTER EN WITH DESCENDER
+04A5          ; output #      (Ò¥)  CYRILLIC SMALL LIGATURE EN GHE
+04A7          ; output #      (Ò§)  CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK
+04A9          ; output #      (Ò©)  CYRILLIC SMALL LETTER ABKHASIAN HA
+04AB          ; output #      (Ò«)  CYRILLIC SMALL LETTER ES WITH DESCENDER
+04AD          ; output #      (Ò­)  CYRILLIC SMALL LETTER TE WITH DESCENDER
+04AF          ; output #      (Ò¯)  CYRILLIC SMALL LETTER STRAIGHT U
+04B1          ; output #      (Ò±)  CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
+04B3          ; output #      (Ò³)  CYRILLIC SMALL LETTER HA WITH DESCENDER
+04B5          ; output #      (Òµ)  CYRILLIC SMALL LIGATURE TE TSE
+04B7          ; output #      (Ò·)  CYRILLIC SMALL LETTER CHE WITH DESCENDER
+04B9          ; output #      (Ò¹)  CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
+04BB          ; output #      (Ò»)  CYRILLIC SMALL LETTER SHHA
+04BD          ; output #      (Ò½)  CYRILLIC SMALL LETTER ABKHASIAN CHE
+04BF..04C0    ; output #  [2] (ҿ..Ӏ)  CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER..CYRILLIC LETTER PALOCHKA
+04C2          ; output #      (ӂ)  CYRILLIC SMALL LETTER ZHE WITH BREVE
+04C4          ; output #      (ӄ)  CYRILLIC SMALL LETTER KA WITH HOOK
+04C6          ; output #      (ӆ)  CYRILLIC SMALL LETTER EL WITH TAIL
+04C8          ; output #      (ӈ)  CYRILLIC SMALL LETTER EN WITH HOOK
+04CA          ; output #      (ӊ)  CYRILLIC SMALL LETTER EN WITH TAIL
+04CC          ; output #      (ӌ)  CYRILLIC SMALL LETTER KHAKASSIAN CHE
+04CE          ; output #      (ӎ)  CYRILLIC SMALL LETTER EM WITH TAIL
+04D1          ; output #      (ӑ)  CYRILLIC SMALL LETTER A WITH BREVE
+04D3          ; output #      (ӓ)  CYRILLIC SMALL LETTER A WITH DIAERESIS
+04D5          ; output #      (ӕ)  CYRILLIC SMALL LIGATURE A IE
+04D7          ; output #      (ӗ)  CYRILLIC SMALL LETTER IE WITH BREVE
+04D9          ; output #      (ә)  CYRILLIC SMALL LETTER SCHWA
+04DB          ; output #      (ӛ)  CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
+04DD          ; output #      (ӝ)  CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
+04DF          ; output #      (ӟ)  CYRILLIC SMALL LETTER ZE WITH DIAERESIS
+04E1          ; output #      (Ó¡)  CYRILLIC SMALL LETTER ABKHASIAN DZE
+04E3          ; output #      (Ó£)  CYRILLIC SMALL LETTER I WITH MACRON
+04E5          ; output #      (Ó¥)  CYRILLIC SMALL LETTER I WITH DIAERESIS
+04E7          ; output #      (Ó§)  CYRILLIC SMALL LETTER O WITH DIAERESIS
+04E9          ; output #      (Ó©)  CYRILLIC SMALL LETTER BARRED O
+04EB          ; output #      (Ó«)  CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
+04ED          ; output #      (Ó­)  CYRILLIC SMALL LETTER E WITH DIAERESIS
+04EF          ; output #      (Ó¯)  CYRILLIC SMALL LETTER U WITH MACRON
+04F1          ; output #      (Ó±)  CYRILLIC SMALL LETTER U WITH DIAERESIS
+04F3          ; output #      (Ó³)  CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
+04F5          ; output #      (Óµ)  CYRILLIC SMALL LETTER CHE WITH DIAERESIS
+04F9          ; output #      (Ó¹)  CYRILLIC SMALL LETTER YERU WITH DIAERESIS
+0501          ; output #      (ԁ)  CYRILLIC SMALL LETTER KOMI DE
+0503          ; output #      (ԃ)  CYRILLIC SMALL LETTER KOMI DJE
+0505          ; output #      (ԅ)  CYRILLIC SMALL LETTER KOMI ZJE
+0507          ; output #      (ԇ)  CYRILLIC SMALL LETTER KOMI DZJE
+0509          ; output #      (ԉ)  CYRILLIC SMALL LETTER KOMI LJE
+050B          ; output #      (ԋ)  CYRILLIC SMALL LETTER KOMI NJE
+050D          ; output #      (ԍ)  CYRILLIC SMALL LETTER KOMI SJE
+050F          ; output #      (ԏ)  CYRILLIC SMALL LETTER KOMI TJE
+0561..0586    ; output # [38] (ա..ֆ)  ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LETTER FEH
+0591..05A1    ; output # [17] (֑..֡)  HEBREW ACCENT ETNAHTA..HEBREW ACCENT PAZER
+05A3..05B9    ; output # [23] (Ö£..Ö¹)  HEBREW ACCENT MUNAH..HEBREW POINT HOLAM
+05BB..05BD    ; output #  [3] (Ö»..Ö½)  HEBREW POINT QUBUTS..HEBREW POINT METEG
+05BF          ; output #      (Ö¿)  HEBREW POINT RAFE
+05C1..05C2    ; output #  [2] (ׁ..ׂ)  HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C4          ; output #      (ׄ)  HEBREW MARK UPPER DOT
+05D0..05EA    ; output # [27] (א..ת)  HEBREW LETTER ALEF..HEBREW LETTER TAV
+05F0..05F2    ; output #  [3] (װ..ײ)  HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
+0621..063A    ; output # [26] (ء..غ)  ARABIC LETTER HAMZA..ARABIC LETTER GHAIN
+0641..0655    ; output # [21] (ف..ٕ)  ARABIC LETTER FEH..ARABIC HAMZA BELOW
+0660..0669    ; output # [10] (Ù ..Ù©)  ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
+0670..0674    ; output #  [5] (Ù°..Ù´)  ARABIC LETTER SUPERSCRIPT ALEF..ARABIC LETTER HIGH HAMZA
+0679..068D    ; output # [21] (ٹ..ڍ)  ARABIC LETTER TTEH..ARABIC LETTER DDAHAL
+068F..06D3    ; output # [69] (ڏ..ۓ)  ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+06D5..06DC    ; output #  [8] (ە..ۜ)  ARABIC LETTER AE..ARABIC SMALL HIGH SEEN
+06DF..06E8    ; output # [10] (۟..ۨ)  ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH NOON
+06EA..06ED    ; output #  [4] (Ûª..Û­)  ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+06F0..06FC    ; output # [13] (Û°..Û¼)  EXTENDED ARABIC-INDIC DIGIT ZERO..ARABIC LETTER GHAIN WITH DOT BELOW
+0710..072C    ; output # [29] (ܐ..ܬ)  SYRIAC LETTER ALAPH..SYRIAC LETTER TAW
+0730..073F    ; output # [16] (ܰ..ܿ)  SYRIAC PTHAHA ABOVE..SYRIAC RWAHA
+0780..07B1    ; output # [50] (ހ..ޱ)  THAANA LETTER HAA..THAANA LETTER NAA
+0901..0903    ; output #  [3] (ँ..ः)  DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN VISARGA
+0905..0939    ; output # [53] (अ..ह)  DEVANAGARI LETTER A..DEVANAGARI LETTER HA
+093C..094D    ; output # [18] (़..्)  DEVANAGARI SIGN NUKTA..DEVANAGARI SIGN VIRAMA
+0950..0954    ; output #  [5] (ॐ..॔)  DEVANAGARI OM..DEVANAGARI ACUTE ACCENT
+0960..0963    ; output #  [4] (ॠ..ॣ)  DEVANAGARI LETTER VOCALIC RR..DEVANAGARI VOWEL SIGN VOCALIC LL
+0966..096F    ; output # [10] (०..९)  DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
+0981..0983    ; output #  [3] (ঁ..ঃ)  BENGALI SIGN CANDRABINDU..BENGALI SIGN VISARGA
+0985..098C    ; output #  [8] (অ..ঌ)  BENGALI LETTER A..BENGALI LETTER VOCALIC L
+098F..0990    ; output #  [2] (এ..ঐ)  BENGALI LETTER E..BENGALI LETTER AI
+0993..09A8    ; output # [22] (ও..ন)  BENGALI LETTER O..BENGALI LETTER NA
+09AA..09B0    ; output #  [7] (প..র)  BENGALI LETTER PA..BENGALI LETTER RA
+09B2          ; output #      (ল)  BENGALI LETTER LA
+09B6..09B9    ; output #  [4] (শ..হ)  BENGALI LETTER SHA..BENGALI LETTER HA
+09BC          ; output #      (়)  BENGALI SIGN NUKTA
+09BE..09C4    ; output #  [7] (া..ৄ)  BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN VOCALIC RR
+09C7..09C8    ; output #  [2] (ে..ৈ)  BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+09CB..09CD    ; output #  [3] (ো..্)  BENGALI VOWEL SIGN O..BENGALI SIGN VIRAMA
+09D7          ; output #      (ৗ)  BENGALI AU LENGTH MARK
+09E0..09E3    ; output #  [4] (à§ ..à§£)  BENGALI LETTER VOCALIC RR..BENGALI VOWEL SIGN VOCALIC LL
+09E6..09F1    ; output # [12] (০..ৱ)  BENGALI DIGIT ZERO..BENGALI LETTER RA WITH LOWER DIAGONAL
+0A02          ; output #      (ਂ)  GURMUKHI SIGN BINDI
+0A05..0A0A    ; output #  [6] (ਅ..ਊ)  GURMUKHI LETTER A..GURMUKHI LETTER UU
+0A0F..0A10    ; output #  [2] (ਏ..ਐ)  GURMUKHI LETTER EE..GURMUKHI LETTER AI
+0A13..0A28    ; output # [22] (ਓ..ਨ)  GURMUKHI LETTER OO..GURMUKHI LETTER NA
+0A2A..0A30    ; output #  [7] (ਪ..ਰ)  GURMUKHI LETTER PA..GURMUKHI LETTER RA
+0A32          ; output #      (ਲ)  GURMUKHI LETTER LA
+0A35          ; output #      (ਵ)  GURMUKHI LETTER VA
+0A38..0A39    ; output #  [2] (ਸ..ਹ)  GURMUKHI LETTER SA..GURMUKHI LETTER HA
+0A3C          ; output #      (਼)  GURMUKHI SIGN NUKTA
+0A3E..0A42    ; output #  [5] (ਾ..ੂ)  GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN UU
+0A47..0A48    ; output #  [2] (ੇ..ੈ)  GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+0A4B..0A4D    ; output #  [3] (ੋ..੍)  GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+0A5C          ; output #      (ੜ)  GURMUKHI LETTER RRA
+0A66..0A74    ; output # [15] (੦..ੴ)  GURMUKHI DIGIT ZERO..GURMUKHI EK ONKAR
+0A81..0A83    ; output #  [3] (ઁ..ઃ)  GUJARATI SIGN CANDRABINDU..GUJARATI SIGN VISARGA
+0A85..0A8B    ; output #  [7] (અ..ઋ)  GUJARATI LETTER A..GUJARATI LETTER VOCALIC R
+0A8D          ; output #      (ઍ)  GUJARATI VOWEL CANDRA E
+0A8F..0A91    ; output #  [3] (એ..ઑ)  GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
+0A93..0AA8    ; output # [22] (ઓ..ન)  GUJARATI LETTER O..GUJARATI LETTER NA
+0AAA..0AB0    ; output #  [7] (પ..ર)  GUJARATI LETTER PA..GUJARATI LETTER RA
+0AB2..0AB3    ; output #  [2] (લ..ળ)  GUJARATI LETTER LA..GUJARATI LETTER LLA
+0AB5..0AB9    ; output #  [5] (વ..હ)  GUJARATI LETTER VA..GUJARATI LETTER HA
+0ABC..0AC5    ; output # [10] (઼..ૅ)  GUJARATI SIGN NUKTA..GUJARATI VOWEL SIGN CANDRA E
+0AC7..0AC9    ; output #  [3] (ે..ૉ)  GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN CANDRA O
+0ACB..0ACD    ; output #  [3] (ો..્)  GUJARATI VOWEL SIGN O..GUJARATI SIGN VIRAMA
+0AD0          ; output #      (ૐ)  GUJARATI OM
+0AE0          ; output #      (à« )  GUJARATI LETTER VOCALIC RR
+0AE6..0AEF    ; output # [10] (૦..૯)  GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
+0B01..0B03    ; output #  [3] (ଁ..ଃ)  ORIYA SIGN CANDRABINDU..ORIYA SIGN VISARGA
+0B05..0B0C    ; output #  [8] (ଅ..ଌ)  ORIYA LETTER A..ORIYA LETTER VOCALIC L
+0B0F..0B10    ; output #  [2] (ଏ..ଐ)  ORIYA LETTER E..ORIYA LETTER AI
+0B13..0B28    ; output # [22] (ଓ..ନ)  ORIYA LETTER O..ORIYA LETTER NA
+0B2A..0B30    ; output #  [7] (ପ..ର)  ORIYA LETTER PA..ORIYA LETTER RA
+0B32..0B33    ; output #  [2] (ଲ..ଳ)  ORIYA LETTER LA..ORIYA LETTER LLA
+0B36..0B39    ; output #  [4] (ଶ..ହ)  ORIYA LETTER SHA..ORIYA LETTER HA
+0B3C..0B43    ; output #  [8] (଼..ୃ)  ORIYA SIGN NUKTA..ORIYA VOWEL SIGN VOCALIC R
+0B47..0B48    ; output #  [2] (େ..ୈ)  ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+0B4B..0B4D    ; output #  [3] (ୋ..୍)  ORIYA VOWEL SIGN O..ORIYA SIGN VIRAMA
+0B56..0B57    ; output #  [2] (ୖ..ୗ)  ORIYA AI LENGTH MARK..ORIYA AU LENGTH MARK
+0B5F..0B61    ; output #  [3] (ୟ..ୡ)  ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
+0B66..0B6F    ; output # [10] (à­¦..à­¯)  ORIYA DIGIT ZERO..ORIYA DIGIT NINE
+0B82..0B83    ; output #  [2] (ஂ..ஃ)  TAMIL SIGN ANUSVARA..TAMIL SIGN VISARGA
+0B85..0B8A    ; output #  [6] (அ..ஊ)  TAMIL LETTER A..TAMIL LETTER UU
+0B8E..0B90    ; output #  [3] (எ..ஐ)  TAMIL LETTER E..TAMIL LETTER AI
+0B92..0B95    ; output #  [4] (ஒ..க)  TAMIL LETTER O..TAMIL LETTER KA
+0B99..0B9A    ; output #  [2] (ங..ச)  TAMIL LETTER NGA..TAMIL LETTER CA
+0B9C          ; output #      (ஜ)  TAMIL LETTER JA
+0B9E..0B9F    ; output #  [2] (ஞ..ட)  TAMIL LETTER NYA..TAMIL LETTER TTA
+0BA3..0BA4    ; output #  [2] (ண..த)  TAMIL LETTER NNA..TAMIL LETTER TA
+0BA8..0BAA    ; output #  [3] (ந..ப)  TAMIL LETTER NA..TAMIL LETTER PA
+0BAE..0BB5    ; output #  [8] (ம..வ)  TAMIL LETTER MA..TAMIL LETTER VA
+0BB7..0BB9    ; output #  [3] (ஷ..ஹ)  TAMIL LETTER SSA..TAMIL LETTER HA
+0BBE..0BC2    ; output #  [5] (ா..ூ)  TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN UU
+0BC6..0BC8    ; output #  [3] (ெ..ை)  TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+0BCA..0BCD    ; output #  [4] (ொ..்)  TAMIL VOWEL SIGN O..TAMIL SIGN VIRAMA
+0BD7          ; output #      (ௗ)  TAMIL AU LENGTH MARK
+0BE7..0BEF    ; output #  [9] (௧..௯)  TAMIL DIGIT ONE..TAMIL DIGIT NINE
+0C01..0C03    ; output #  [3] (ఁ..ః)  TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+0C05..0C0C    ; output #  [8] (అ..ఌ)  TELUGU LETTER A..TELUGU LETTER VOCALIC L
+0C0E..0C10    ; output #  [3] (ఎ..ఐ)  TELUGU LETTER E..TELUGU LETTER AI
+0C12..0C28    ; output # [23] (ఒ..న)  TELUGU LETTER O..TELUGU LETTER NA
+0C2A..0C33    ; output # [10] (à°ª..à°³)  TELUGU LETTER PA..TELUGU LETTER LLA
+0C35..0C39    ; output #  [5] (à°µ..à°¹)  TELUGU LETTER VA..TELUGU LETTER HA
+0C3E..0C44    ; output #  [7] (ా..ౄ)  TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN VOCALIC RR
+0C46..0C48    ; output #  [3] (ె..ై)  TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+0C4A..0C4D    ; output #  [4] (ొ..్)  TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+0C55..0C56    ; output #  [2] (ౕ..ౖ)  TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+0C60..0C61    ; output #  [2] (ౠ..ౡ)  TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
+0C66..0C6F    ; output # [10] (౦..౯)  TELUGU DIGIT ZERO..TELUGU DIGIT NINE
+0C82..0C83    ; output #  [2] (ಂ..ಃ)  KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+0C85..0C8C    ; output #  [8] (ಅ..ಌ)  KANNADA LETTER A..KANNADA LETTER VOCALIC L
+0C8E..0C90    ; output #  [3] (ಎ..ಐ)  KANNADA LETTER E..KANNADA LETTER AI
+0C92..0CA8    ; output # [23] (ಒ..ನ)  KANNADA LETTER O..KANNADA LETTER NA
+0CAA..0CB3    ; output # [10] (ಪ..ಳ)  KANNADA LETTER PA..KANNADA LETTER LLA
+0CB5..0CB9    ; output #  [5] (ವ..ಹ)  KANNADA LETTER VA..KANNADA LETTER HA
+0CBE..0CC4    ; output #  [7] (ಾ..ೄ)  KANNADA VOWEL SIGN AA..KANNADA VOWEL SIGN VOCALIC RR
+0CC6..0CC8    ; output #  [3] (ೆ..ೈ)  KANNADA VOWEL SIGN E..KANNADA VOWEL SIGN AI
+0CCA..0CCD    ; output #  [4] (ೊ..್)  KANNADA VOWEL SIGN O..KANNADA SIGN VIRAMA
+0CD5..0CD6    ; output #  [2] (ೕ..ೖ)  KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0CE0..0CE1    ; output #  [2] (ೠ..ೡ)  KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
+0CE6..0CEF    ; output # [10] (೦..೯)  KANNADA DIGIT ZERO..KANNADA DIGIT NINE
+0D02..0D03    ; output #  [2] (ം..ഃ)  MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+0D05..0D0C    ; output #  [8] (അ..ഌ)  MALAYALAM LETTER A..MALAYALAM LETTER VOCALIC L
+0D0E..0D10    ; output #  [3] (എ..ഐ)  MALAYALAM LETTER E..MALAYALAM LETTER AI
+0D12..0D28    ; output # [23] (ഒ..ന)  MALAYALAM LETTER O..MALAYALAM LETTER NA
+0D2A..0D39    ; output # [16] (à´ª..à´¹)  MALAYALAM LETTER PA..MALAYALAM LETTER HA
+0D3E..0D43    ; output #  [6] (ാ..ൃ)  MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN VOCALIC R
+0D46..0D48    ; output #  [3] (െ..ൈ)  MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+0D4A..0D4D    ; output #  [4] (ൊ..്)  MALAYALAM VOWEL SIGN O..MALAYALAM SIGN VIRAMA
+0D57          ; output #      (ൗ)  MALAYALAM AU LENGTH MARK
+0D60..0D61    ; output #  [2] (ൠ..ൡ)  MALAYALAM LETTER VOCALIC RR..MALAYALAM LETTER VOCALIC LL
+0D66..0D6F    ; output # [10] (൦..൯)  MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
+0D82..0D83    ; output #  [2] (ං..ඃ)  SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+0D85..0D96    ; output # [18] (අ..ඖ)  SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
+0D9A..0DB1    ; output # [24] (ක..න)  SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
+0DB3..0DBB    ; output #  [9] (à¶³..à¶»)  SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
+0DBD          ; output #      (à¶½)  SINHALA LETTER DANTAJA LAYANNA
+0DC0..0DC6    ; output #  [7] (ව..ෆ)  SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
+0DCA          ; output #      (්)  SINHALA SIGN AL-LAKUNA
+0DCF..0DD4    ; output #  [6] (ා..ු)  SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+0DD6          ; output #      (ූ)  SINHALA VOWEL SIGN DIGA PAA-PILLA
+0DD8..0DDF    ; output #  [8] (ෘ..ෟ)  SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+0DF2..0DF3    ; output #  [2] (à·²..à·³)  SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+0E01..0E32    ; output # [50] (ก..า)  THAI CHARACTER KO KAI..THAI CHARACTER SARA AA
+0E34..0E3A    ; output #  [7] (ิ..ฺ)  THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+0E40..0E4E    ; output # [15] (เ..๎)  THAI CHARACTER SARA E..THAI CHARACTER YAMAKKAN
+0E50..0E59    ; output # [10] (๐..๙)  THAI DIGIT ZERO..THAI DIGIT NINE
+0E81..0E82    ; output #  [2] (ກ..ຂ)  LAO LETTER KO..LAO LETTER KHO SUNG
+0E84          ; output #      (ຄ)  LAO LETTER KHO TAM
+0E87..0E88    ; output #  [2] (ງ..ຈ)  LAO LETTER NGO..LAO LETTER CO
+0E8A          ; output #      (ຊ)  LAO LETTER SO TAM
+0E8D          ; output #      (ຍ)  LAO LETTER NYO
+0E94..0E97    ; output #  [4] (ດ..ທ)  LAO LETTER DO..LAO LETTER THO TAM
+0E99..0E9F    ; output #  [7] (ນ..ຟ)  LAO LETTER NO..LAO LETTER FO SUNG
+0EA1..0EA3    ; output #  [3] (ມ..ຣ)  LAO LETTER MO..LAO LETTER LO LING
+0EA5          ; output #      (ລ)  LAO LETTER LO LOOT
+0EA7          ; output #      (ວ)  LAO LETTER WO
+0EAA..0EAB    ; output #  [2] (ສ..ຫ)  LAO LETTER SO SUNG..LAO LETTER HO SUNG
+0EAD..0EB2    ; output #  [6] (ອ..າ)  LAO LETTER O..LAO VOWEL SIGN AA
+0EB4..0EB9    ; output #  [6] (ິ..ູ)  LAO VOWEL SIGN I..LAO VOWEL SIGN UU
+0EBB..0EBD    ; output #  [3] (ົ..ຽ)  LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN NYO
+0EC0..0EC4    ; output #  [5] (ເ..ໄ)  LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+0EC6          ; output #      (ໆ)  LAO KO LA
+0EC8..0ECD    ; output #  [6] (່..ໍ)  LAO TONE MAI EK..LAO NIGGAHITA
+0ED0..0ED9    ; output # [10] (໐..໙)  LAO DIGIT ZERO..LAO DIGIT NINE
+0F00          ; output #      (ༀ)  TIBETAN SYLLABLE OM
+0F18..0F19    ; output #  [2] (༘..༙)  TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+0F20..0F29    ; output # [10] (༠..༩)  TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
+0F35          ; output #      (༵)  TIBETAN MARK NGAS BZUNG NYI ZLA
+0F37          ; output #      (༷)  TIBETAN MARK NGAS BZUNG SGOR RTAGS
+0F39          ; output #      (༹)  TIBETAN MARK TSA -PHRU
+0F3E..0F42    ; output #  [5] (༾..ག)  TIBETAN SIGN YAR TSHES..TIBETAN LETTER GA
+0F44..0F47    ; output #  [4] (ང..ཇ)  TIBETAN LETTER NGA..TIBETAN LETTER JA
+0F49..0F4C    ; output #  [4] (ཉ..ཌ)  TIBETAN LETTER NYA..TIBETAN LETTER DDA
+0F4E..0F51    ; output #  [4] (ཎ..ད)  TIBETAN LETTER NNA..TIBETAN LETTER DA
+0F53..0F56    ; output #  [4] (ན..བ)  TIBETAN LETTER NA..TIBETAN LETTER BA
+0F58..0F5B    ; output #  [4] (མ..ཛ)  TIBETAN LETTER MA..TIBETAN LETTER DZA
+0F5D..0F68    ; output # [12] (ཝ..ཨ)  TIBETAN LETTER WA..TIBETAN LETTER A
+0F6A          ; output #      (ཪ)  TIBETAN LETTER FIXED-FORM RA
+0F71..0F72    ; output #  [2] (ཱ..ི)  TIBETAN VOWEL SIGN AA..TIBETAN VOWEL SIGN I
+0F74          ; output #      (ུ)  TIBETAN VOWEL SIGN U
+0F7A..0F80    ; output #  [7] (ེ..ྀ)  TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN REVERSED I
+0F82..0F84    ; output #  [3] (ྂ..྄)  TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA
+0F86..0F8B    ; output #  [6] (྆..ྋ)  TIBETAN SIGN LCI RTAGS..TIBETAN SIGN GRU MED RGYINGS
+0F90..0F92    ; output #  [3] (ྐ..ྒ)  TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER GA
+0F94..0F97    ; output #  [4] (ྔ..ྗ)  TIBETAN SUBJOINED LETTER NGA..TIBETAN SUBJOINED LETTER JA
+0F99..0F9C    ; output #  [4] (ྙ..ྜ)  TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER DDA
+0F9E..0FA1    ; output #  [4] (ྞ..ྡ)  TIBETAN SUBJOINED LETTER NNA..TIBETAN SUBJOINED LETTER DA
+0FA3..0FA6    ; output #  [4] (ྣ..ྦ)  TIBETAN SUBJOINED LETTER NA..TIBETAN SUBJOINED LETTER BA
+0FA8..0FAB    ; output #  [4] (ྨ..ྫ)  TIBETAN SUBJOINED LETTER MA..TIBETAN SUBJOINED LETTER DZA
+0FAD..0FB8    ; output # [12] (ྭ..ྸ)  TIBETAN SUBJOINED LETTER WA..TIBETAN SUBJOINED LETTER A
+0FBA..0FBC    ; output #  [3] (ྺ..ྼ)  TIBETAN SUBJOINED LETTER FIXED-FORM WA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+0FC6          ; output #      (࿆)  TIBETAN SYMBOL PADMA GDAN
+1000..1021    ; output # [34] (က..အ)  MYANMAR LETTER KA..MYANMAR LETTER A
+1023..1027    ; output #  [5] (ဣ..ဧ)  MYANMAR LETTER I..MYANMAR LETTER E
+1029..102A    ; output #  [2] (ဩ..ဪ)  MYANMAR LETTER O..MYANMAR LETTER AU
+102C..1032    ; output #  [7] (ာ..ဲ)  MYANMAR VOWEL SIGN AA..MYANMAR VOWEL SIGN AI
+1036..1039    ; output #  [4] (ံ..္)  MYANMAR SIGN ANUSVARA..MYANMAR SIGN VIRAMA
+1040..1049    ; output # [10] (၀..၉)  MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
+1050..1059    ; output # [10] (ၐ..ၙ)  MYANMAR LETTER SHA..MYANMAR VOWEL SIGN VOCALIC LL
+10A0..10C5    ; output # [38] (Ⴀ..Ⴥ)  GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
+10D0..10F0    ; output # [33] (ა..ჰ)  GEORGIAN LETTER AN..GEORGIAN LETTER HAE
+10F7..10F8    ; output #  [2] (ჷ..ჸ)  GEORGIAN LETTER YN..GEORGIAN LETTER ELIFI
+1200..1206    ; output #  [7] (ሀ..ሆ)  ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE HO
+1208..1246    ; output # [63] (ለ..ቆ)  ETHIOPIC SYLLABLE LA..ETHIOPIC SYLLABLE QO
+1248          ; output #      (ቈ)  ETHIOPIC SYLLABLE QWA
+124A..124D    ; output #  [4] (ቊ..ቍ)  ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
+1250..1256    ; output #  [7] (ቐ..ቖ)  ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
+1258          ; output #      (ቘ)  ETHIOPIC SYLLABLE QHWA
+125A..125D    ; output #  [4] (ቚ..ቝ)  ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
+1260..1286    ; output # [39] (በ..ኆ)  ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XO
+1288          ; output #      (ኈ)  ETHIOPIC SYLLABLE XWA
+128A..128D    ; output #  [4] (ኊ..ኍ)  ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
+1290..12AE    ; output # [31] (ነ..ኮ)  ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KO
+12B0          ; output #      (ኰ)  ETHIOPIC SYLLABLE KWA
+12B2..12B5    ; output #  [4] (ኲ..ኵ)  ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
+12B8..12BE    ; output #  [7] (ኸ..ኾ)  ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
+12C0          ; output #      (ዀ)  ETHIOPIC SYLLABLE KXWA
+12C2..12C5    ; output #  [4] (ዂ..ዅ)  ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
+12C8..12CE    ; output #  [7] (ወ..ዎ)  ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE WO
+12D0..12D6    ; output #  [7] (ዐ..ዖ)  ETHIOPIC SYLLABLE PHARYNGEAL A..ETHIOPIC SYLLABLE PHARYNGEAL O
+12D8..12EE    ; output # [23] (ዘ..ዮ)  ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE YO
+12F0..130E    ; output # [31] (ደ..ጎ)  ETHIOPIC SYLLABLE DA..ETHIOPIC SYLLABLE GO
+1310          ; output #      (ጐ)  ETHIOPIC SYLLABLE GWA
+1312..1315    ; output #  [4] (ጒ..ጕ)  ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
+1318..131E    ; output #  [7] (ጘ..ጞ)  ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE GGO
+1320..1346    ; output # [39] (ጠ..ፆ)  ETHIOPIC SYLLABLE THA..ETHIOPIC SYLLABLE TZO
+1348..135A    ; output # [19] (ፈ..ፚ)  ETHIOPIC SYLLABLE FA..ETHIOPIC SYLLABLE FYA
+1369..1371    ; output #  [9] (፩..፱)  ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE
+13A0..13F4    ; output # [85] (Ꭰ..Ᏼ)  CHEROKEE LETTER A..CHEROKEE LETTER YV
+1401..166C    ; output # [620] (ᐁ..ᙬ)  CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
+166F..1676    ; output #  [8] (ᙯ..ᙶ)  CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS NNGAA
+1780..17A2    ; output # [35] (ក..អ)  KHMER LETTER KA..KHMER LETTER QA
+17A5..17A7    ; output #  [3] (ឥ..ឧ)  KHMER INDEPENDENT VOWEL QI..KHMER INDEPENDENT VOWEL QU
+17A9..17B3    ; output # [11] (ឩ..ឳ)  KHMER INDEPENDENT VOWEL QUU..KHMER INDEPENDENT VOWEL QAU
+17B6..17D0    ; output # [27] (ា..័)  KHMER VOWEL SIGN AA..KHMER SIGN SAMYOK SANNYA
+17D2          ; output #      (្)  KHMER SIGN COENG
+17D7          ; output #      (ៗ)  KHMER SIGN LEK TOO
+17DC          ; output #      (ៜ)  KHMER SIGN AVAKRAHASANYA
+17E0..17E9    ; output # [10] (០..៩)  KHMER DIGIT ZERO..KHMER DIGIT NINE
+1810..1819    ; output # [10] (᠐..᠙)  MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
+1820..1877    ; output # [88] (á  ..á¡·)  MONGOLIAN LETTER A..MONGOLIAN LETTER MANCHU ZHA
+1880..18A9    ; output # [42] (ᢀ..ᢩ)  MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI DAGALGA
+1E01          ; output #      (ḁ)  LATIN SMALL LETTER A WITH RING BELOW
+1E03          ; output #      (ḃ)  LATIN SMALL LETTER B WITH DOT ABOVE
+1E05          ; output #      (ḅ)  LATIN SMALL LETTER B WITH DOT BELOW
+1E07          ; output #      (ḇ)  LATIN SMALL LETTER B WITH LINE BELOW
+1E09          ; output #      (ḉ)  LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
+1E0B          ; output #      (ḋ)  LATIN SMALL LETTER D WITH DOT ABOVE
+1E0D          ; output #      (ḍ)  LATIN SMALL LETTER D WITH DOT BELOW
+1E0F          ; output #      (ḏ)  LATIN SMALL LETTER D WITH LINE BELOW
+1E11          ; output #      (ḑ)  LATIN SMALL LETTER D WITH CEDILLA
+1E13          ; output #      (ḓ)  LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
+1E15          ; output #      (ḕ)  LATIN SMALL LETTER E WITH MACRON AND GRAVE
+1E17          ; output #      (ḗ)  LATIN SMALL LETTER E WITH MACRON AND ACUTE
+1E19          ; output #      (ḙ)  LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
+1E1B          ; output #      (ḛ)  LATIN SMALL LETTER E WITH TILDE BELOW
+1E1D          ; output #      (ḝ)  LATIN SMALL LETTER E WITH CEDILLA AND BREVE
+1E1F          ; output #      (ḟ)  LATIN SMALL LETTER F WITH DOT ABOVE
+1E21          ; output #      (ḡ)  LATIN SMALL LETTER G WITH MACRON
+1E23          ; output #      (ḣ)  LATIN SMALL LETTER H WITH DOT ABOVE
+1E25          ; output #      (ḥ)  LATIN SMALL LETTER H WITH DOT BELOW
+1E27          ; output #      (ḧ)  LATIN SMALL LETTER H WITH DIAERESIS
+1E29          ; output #      (ḩ)  LATIN SMALL LETTER H WITH CEDILLA
+1E2B          ; output #      (ḫ)  LATIN SMALL LETTER H WITH BREVE BELOW
+1E2D          ; output #      (ḭ)  LATIN SMALL LETTER I WITH TILDE BELOW
+1E2F          ; output #      (ḯ)  LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
+1E31          ; output #      (ḱ)  LATIN SMALL LETTER K WITH ACUTE
+1E33          ; output #      (ḳ)  LATIN SMALL LETTER K WITH DOT BELOW
+1E35          ; output #      (ḵ)  LATIN SMALL LETTER K WITH LINE BELOW
+1E37          ; output #      (ḷ)  LATIN SMALL LETTER L WITH DOT BELOW
+1E39          ; output #      (ḹ)  LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
+1E3B          ; output #      (ḻ)  LATIN SMALL LETTER L WITH LINE BELOW
+1E3D          ; output #      (ḽ)  LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
+1E3F          ; output #      (ḿ)  LATIN SMALL LETTER M WITH ACUTE
+1E41          ; output #      (ṁ)  LATIN SMALL LETTER M WITH DOT ABOVE
+1E43          ; output #      (ṃ)  LATIN SMALL LETTER M WITH DOT BELOW
+1E45          ; output #      (ṅ)  LATIN SMALL LETTER N WITH DOT ABOVE
+1E47          ; output #      (ṇ)  LATIN SMALL LETTER N WITH DOT BELOW
+1E49          ; output #      (ṉ)  LATIN SMALL LETTER N WITH LINE BELOW
+1E4B          ; output #      (ṋ)  LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
+1E4D          ; output #      (ṍ)  LATIN SMALL LETTER O WITH TILDE AND ACUTE
+1E4F          ; output #      (ṏ)  LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
+1E51          ; output #      (ṑ)  LATIN SMALL LETTER O WITH MACRON AND GRAVE
+1E53          ; output #      (ṓ)  LATIN SMALL LETTER O WITH MACRON AND ACUTE
+1E55          ; output #      (ṕ)  LATIN SMALL LETTER P WITH ACUTE
+1E57          ; output #      (ṗ)  LATIN SMALL LETTER P WITH DOT ABOVE
+1E59          ; output #      (ṙ)  LATIN SMALL LETTER R WITH DOT ABOVE
+1E5B          ; output #      (ṛ)  LATIN SMALL LETTER R WITH DOT BELOW
+1E5D          ; output #      (ṝ)  LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
+1E5F          ; output #      (ṟ)  LATIN SMALL LETTER R WITH LINE BELOW
+1E61          ; output #      (ṡ)  LATIN SMALL LETTER S WITH DOT ABOVE
+1E63          ; output #      (á¹£)  LATIN SMALL LETTER S WITH DOT BELOW
+1E65          ; output #      (á¹¥)  LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
+1E67          ; output #      (á¹§)  LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
+1E69          ; output #      (ṩ)  LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
+1E6B          ; output #      (ṫ)  LATIN SMALL LETTER T WITH DOT ABOVE
+1E6D          ; output #      (á¹­)  LATIN SMALL LETTER T WITH DOT BELOW
+1E6F          ; output #      (ṯ)  LATIN SMALL LETTER T WITH LINE BELOW
+1E71          ; output #      (á¹±)  LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
+1E73          ; output #      (á¹³)  LATIN SMALL LETTER U WITH DIAERESIS BELOW
+1E75          ; output #      (á¹µ)  LATIN SMALL LETTER U WITH TILDE BELOW
+1E77          ; output #      (á¹·)  LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
+1E79          ; output #      (á¹¹)  LATIN SMALL LETTER U WITH TILDE AND ACUTE
+1E7B          ; output #      (á¹»)  LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
+1E7D          ; output #      (á¹½)  LATIN SMALL LETTER V WITH TILDE
+1E7F          ; output #      (ṿ)  LATIN SMALL LETTER V WITH DOT BELOW
+1E81          ; output #      (ẁ)  LATIN SMALL LETTER W WITH GRAVE
+1E83          ; output #      (ẃ)  LATIN SMALL LETTER W WITH ACUTE
+1E85          ; output #      (ẅ)  LATIN SMALL LETTER W WITH DIAERESIS
+1E87          ; output #      (ẇ)  LATIN SMALL LETTER W WITH DOT ABOVE
+1E89          ; output #      (ẉ)  LATIN SMALL LETTER W WITH DOT BELOW
+1E8B          ; output #      (ẋ)  LATIN SMALL LETTER X WITH DOT ABOVE
+1E8D          ; output #      (ẍ)  LATIN SMALL LETTER X WITH DIAERESIS
+1E8F          ; output #      (ẏ)  LATIN SMALL LETTER Y WITH DOT ABOVE
+1E91          ; output #      (ẑ)  LATIN SMALL LETTER Z WITH CIRCUMFLEX
+1E93          ; output #      (ẓ)  LATIN SMALL LETTER Z WITH DOT BELOW
+1E95..1E99    ; output #  [5] (ẕ..ẙ)  LATIN SMALL LETTER Z WITH LINE BELOW..LATIN SMALL LETTER Y WITH RING ABOVE
+1EA1          ; output #      (ạ)  LATIN SMALL LETTER A WITH DOT BELOW
+1EA3          ; output #      (ả)  LATIN SMALL LETTER A WITH HOOK ABOVE
+1EA5          ; output #      (ấ)  LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
+1EA7          ; output #      (ầ)  LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
+1EA9          ; output #      (ẩ)  LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+1EAB          ; output #      (ẫ)  LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
+1EAD          ; output #      (ậ)  LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+1EAF          ; output #      (ắ)  LATIN SMALL LETTER A WITH BREVE AND ACUTE
+1EB1          ; output #      (ằ)  LATIN SMALL LETTER A WITH BREVE AND GRAVE
+1EB3          ; output #      (ẳ)  LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
+1EB5          ; output #      (ẵ)  LATIN SMALL LETTER A WITH BREVE AND TILDE
+1EB7          ; output #      (ặ)  LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
+1EB9          ; output #      (ẹ)  LATIN SMALL LETTER E WITH DOT BELOW
+1EBB          ; output #      (ẻ)  LATIN SMALL LETTER E WITH HOOK ABOVE
+1EBD          ; output #      (ẽ)  LATIN SMALL LETTER E WITH TILDE
+1EBF          ; output #      (ế)  LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
+1EC1          ; output #      (ề)  LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
+1EC3          ; output #      (ể)  LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+1EC5          ; output #      (ễ)  LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
+1EC7          ; output #      (ệ)  LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+1EC9          ; output #      (ỉ)  LATIN SMALL LETTER I WITH HOOK ABOVE
+1ECB          ; output #      (ị)  LATIN SMALL LETTER I WITH DOT BELOW
+1ECD          ; output #      (ọ)  LATIN SMALL LETTER O WITH DOT BELOW
+1ECF          ; output #      (ỏ)  LATIN SMALL LETTER O WITH HOOK ABOVE
+1ED1          ; output #      (ố)  LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
+1ED3          ; output #      (ồ)  LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
+1ED5          ; output #      (ổ)  LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+1ED7          ; output #      (ỗ)  LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
+1ED9          ; output #      (ộ)  LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+1EDB          ; output #      (ớ)  LATIN SMALL LETTER O WITH HORN AND ACUTE
+1EDD          ; output #      (ờ)  LATIN SMALL LETTER O WITH HORN AND GRAVE
+1EDF          ; output #      (ở)  LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
+1EE1          ; output #      (ỡ)  LATIN SMALL LETTER O WITH HORN AND TILDE
+1EE3          ; output #      (ợ)  LATIN SMALL LETTER O WITH HORN AND DOT BELOW
+1EE5          ; output #      (ụ)  LATIN SMALL LETTER U WITH DOT BELOW
+1EE7          ; output #      (á»§)  LATIN SMALL LETTER U WITH HOOK ABOVE
+1EE9          ; output #      (ứ)  LATIN SMALL LETTER U WITH HORN AND ACUTE
+1EEB          ; output #      (ừ)  LATIN SMALL LETTER U WITH HORN AND GRAVE
+1EED          ; output #      (á»­)  LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
+1EEF          ; output #      (ữ)  LATIN SMALL LETTER U WITH HORN AND TILDE
+1EF1          ; output #      (á»±)  LATIN SMALL LETTER U WITH HORN AND DOT BELOW
+1EF3          ; output #      (ỳ)  LATIN SMALL LETTER Y WITH GRAVE
+1EF5          ; output #      (ỵ)  LATIN SMALL LETTER Y WITH DOT BELOW
+1EF7          ; output #      (á»·)  LATIN SMALL LETTER Y WITH HOOK ABOVE
+1EF9          ; output #      (ỹ)  LATIN SMALL LETTER Y WITH TILDE
+1F00..1F07    ; output #  [8] (ἀ..ἇ)  GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
+1F10..1F15    ; output #  [6] (ἐ..ἕ)  GREEK SMALL LETTER EPSILON WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+1F20..1F27    ; output #  [8] (á¼ ..á¼§)  GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
+1F30..1F37    ; output #  [8] (á¼°..á¼·)  GREEK SMALL LETTER IOTA WITH PSILI..GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
+1F40..1F45    ; output #  [6] (ὀ..ὅ)  GREEK SMALL LETTER OMICRON WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+1F50..1F57    ; output #  [8] (ὐ..ὗ)  GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F60..1F67    ; output #  [8] (á½ ..á½§)  GREEK SMALL LETTER OMEGA WITH PSILI..GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
+1F70          ; output #      (á½°)  GREEK SMALL LETTER ALPHA WITH VARIA
+1F72          ; output #      (á½²)  GREEK SMALL LETTER EPSILON WITH VARIA
+1F74          ; output #      (á½´)  GREEK SMALL LETTER ETA WITH VARIA
+1F76          ; output #      (á½¶)  GREEK SMALL LETTER IOTA WITH VARIA
+1F78          ; output #      (ὸ)  GREEK SMALL LETTER OMICRON WITH VARIA
+1F7A          ; output #      (ὺ)  GREEK SMALL LETTER UPSILON WITH VARIA
+1F7C          ; output #      (á½¼)  GREEK SMALL LETTER OMEGA WITH VARIA
+1FB0..1FB1    ; output #  [2] (á¾°..á¾±)  GREEK SMALL LETTER ALPHA WITH VRACHY..GREEK SMALL LETTER ALPHA WITH MACRON
+1FB6          ; output #      (á¾¶)  GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+1FC6          ; output #      (ῆ)  GREEK SMALL LETTER ETA WITH PERISPOMENI
+1FD0..1FD2    ; output #  [3] (ῐ..ῒ)  GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+1FD6..1FD7    ; output #  [2] (ῖ..ῗ)  GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+1FE0..1FE2    ; output #  [3] (á¿ ..á¿¢)  GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+1FE4..1FE7    ; output #  [4] (ῤ..ῧ)  GREEK SMALL LETTER RHO WITH PSILI..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+1FF6          ; output #      (á¿¶)  GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+2132          ; output #      (Ⅎ)  TURNED CAPITAL F
+3005..3007    ; output #  [3] (々..〇)  IDEOGRAPHIC ITERATION MARK..IDEOGRAPHIC NUMBER ZERO
+3041..3096    ; output # [86] (ぁ..ゖ)  HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
+3099..309A    ; output #  [2] (゙..゚)  COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+309D..309E    ; output #  [2] (ゝ..ゞ)  HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+30A1..30FE    ; output # [94] (ァ..ヾ)  KATAKANA LETTER SMALL A..KATAKANA VOICED ITERATION MARK
+3105..312C    ; output # [40] (ㄅ..ㄬ)  BOPOMOFO LETTER B..BOPOMOFO LETTER GN
+31A0..31B7    ; output # [24] (ㆠ..ㆷ)  BOPOMOFO LETTER BU..BOPOMOFO FINAL LETTER H
+31F0..31FF    ; output # [16] (ㇰ..ㇿ)  KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
+3447          ; output #      (㑇)  CJK UNIFIED IDEOGRAPH-3447
+3473          ; output #      (㑳)  CJK UNIFIED IDEOGRAPH-3473
+34E4          ; output #      (㓤)  CJK UNIFIED IDEOGRAPH-34E4
+3577          ; output #      (㕷)  CJK UNIFIED IDEOGRAPH-3577
+359E          ; output #      (㖞)  CJK UNIFIED IDEOGRAPH-359E
+35A1          ; output #      (㖡)  CJK UNIFIED IDEOGRAPH-35A1
+35AD          ; output #      (㖭)  CJK UNIFIED IDEOGRAPH-35AD
+35BF          ; output #      (㖿)  CJK UNIFIED IDEOGRAPH-35BF
+35CE          ; output #      (㗎)  CJK UNIFIED IDEOGRAPH-35CE
+35F3          ; output #      (㗳)  CJK UNIFIED IDEOGRAPH-35F3
+35FE          ; output #      (㗾)  CJK UNIFIED IDEOGRAPH-35FE
+360E          ; output #      (㘎)  CJK UNIFIED IDEOGRAPH-360E
+361A          ; output #      (㘚)  CJK UNIFIED IDEOGRAPH-361A
+3918          ; output #      (㤘)  CJK UNIFIED IDEOGRAPH-3918
+3960          ; output #      (㥠)  CJK UNIFIED IDEOGRAPH-3960
+396E          ; output #      (㥮)  CJK UNIFIED IDEOGRAPH-396E
+39CF..39D0    ; output #  [2] (㧏..㧐)  CJK UNIFIED IDEOGRAPH-39CF..CJK UNIFIED IDEOGRAPH-39D0
+39DF          ; output #      (㧟)  CJK UNIFIED IDEOGRAPH-39DF
+39F8          ; output #      (㧸)  CJK UNIFIED IDEOGRAPH-39F8
+39FE          ; output #      (ã§¾)  CJK UNIFIED IDEOGRAPH-39FE
+3A18          ; output #      (㨘)  CJK UNIFIED IDEOGRAPH-3A18
+3A52          ; output #      (㩒)  CJK UNIFIED IDEOGRAPH-3A52
+3A67          ; output #      (ã©§)  CJK UNIFIED IDEOGRAPH-3A67
+3A73          ; output #      (㩳)  CJK UNIFIED IDEOGRAPH-3A73
+3B39          ; output #      (㬹)  CJK UNIFIED IDEOGRAPH-3B39
+3B4E          ; output #      (㭎)  CJK UNIFIED IDEOGRAPH-3B4E
+3C6E          ; output #      (ã±®)  CJK UNIFIED IDEOGRAPH-3C6E
+3CE0          ; output #      (ã³ )  CJK UNIFIED IDEOGRAPH-3CE0
+3DE7          ; output #      (ã·§)  CJK UNIFIED IDEOGRAPH-3DE7
+3DEB          ; output #      (ã·«)  CJK UNIFIED IDEOGRAPH-3DEB
+3E74          ; output #      (ã¹´)  CJK UNIFIED IDEOGRAPH-3E74
+3ED0          ; output #      (㻐)  CJK UNIFIED IDEOGRAPH-3ED0
+4056          ; output #      (䁖)  CJK UNIFIED IDEOGRAPH-4056
+4065          ; output #      (䁥)  CJK UNIFIED IDEOGRAPH-4065
+406A          ; output #      (䁪)  CJK UNIFIED IDEOGRAPH-406A
+40BB          ; output #      (䂻)  CJK UNIFIED IDEOGRAPH-40BB
+40DF          ; output #      (䃟)  CJK UNIFIED IDEOGRAPH-40DF
+4137          ; output #      (䄷)  CJK UNIFIED IDEOGRAPH-4137
+415F          ; output #      (䅟)  CJK UNIFIED IDEOGRAPH-415F
+4337          ; output #      (䌷)  CJK UNIFIED IDEOGRAPH-4337
+43AC          ; output #      (䎬)  CJK UNIFIED IDEOGRAPH-43AC
+43B1          ; output #      (䎱)  CJK UNIFIED IDEOGRAPH-43B1
+43DD          ; output #      (䏝)  CJK UNIFIED IDEOGRAPH-43DD
+44D6          ; output #      (䓖)  CJK UNIFIED IDEOGRAPH-44D6
+44EA          ; output #      (䓪)  CJK UNIFIED IDEOGRAPH-44EA
+4606          ; output #      (䘆)  CJK UNIFIED IDEOGRAPH-4606
+464C          ; output #      (䙌)  CJK UNIFIED IDEOGRAPH-464C
+4661          ; output #      (䙡)  CJK UNIFIED IDEOGRAPH-4661
+4723          ; output #      (䜣)  CJK UNIFIED IDEOGRAPH-4723
+4729          ; output #      (䜩)  CJK UNIFIED IDEOGRAPH-4729
+477C          ; output #      (䝼)  CJK UNIFIED IDEOGRAPH-477C
+478D          ; output #      (䞍)  CJK UNIFIED IDEOGRAPH-478D
+47F4          ; output #      (䟴)  CJK UNIFIED IDEOGRAPH-47F4
+48B5          ; output #      (䢵)  CJK UNIFIED IDEOGRAPH-48B5
+48BC          ; output #      (䢼)  CJK UNIFIED IDEOGRAPH-48BC
+48C5          ; output #      (䣅)  CJK UNIFIED IDEOGRAPH-48C5
+48D3          ; output #      (䣓)  CJK UNIFIED IDEOGRAPH-48D3
+4947          ; output #      (䥇)  CJK UNIFIED IDEOGRAPH-4947
+497A          ; output #      (䥺)  CJK UNIFIED IDEOGRAPH-497A
+497D          ; output #      (䥽)  CJK UNIFIED IDEOGRAPH-497D
+4982..4983    ; output #  [2] (䦂..䦃)  CJK UNIFIED IDEOGRAPH-4982..CJK UNIFIED IDEOGRAPH-4983
+4985..4986    ; output #  [2] (䦅..䦆)  CJK UNIFIED IDEOGRAPH-4985..CJK UNIFIED IDEOGRAPH-4986
+499B          ; output #      (䦛)  CJK UNIFIED IDEOGRAPH-499B
+499F          ; output #      (䦟)  CJK UNIFIED IDEOGRAPH-499F
+49B6..49B7    ; output #  [2] (䦶..䦷)  CJK UNIFIED IDEOGRAPH-49B6..CJK UNIFIED IDEOGRAPH-49B7
+49D1          ; output #      (䧑)  CJK UNIFIED IDEOGRAPH-49D1
+4A12          ; output #      (䨒)  CJK UNIFIED IDEOGRAPH-4A12
+4AB8          ; output #      (䪸)  CJK UNIFIED IDEOGRAPH-4AB8
+4C77          ; output #      (ä±·)  CJK UNIFIED IDEOGRAPH-4C77
+4C7D          ; output #      (ä±½)  CJK UNIFIED IDEOGRAPH-4C7D
+4C81          ; output #      (䲁)  CJK UNIFIED IDEOGRAPH-4C81
+4C85          ; output #      (䲅)  CJK UNIFIED IDEOGRAPH-4C85
+4C9F..4CA3    ; output #  [5] (䲟..䲣)  CJK UNIFIED IDEOGRAPH-4C9F..CJK UNIFIED IDEOGRAPH-4CA3
+4CB3          ; output #      (ä²³)  CJK UNIFIED IDEOGRAPH-4CB3
+4D08          ; output #      (䴈)  CJK UNIFIED IDEOGRAPH-4D08
+4D13..4D19    ; output #  [7] (䴓..䴙)  CJK UNIFIED IDEOGRAPH-4D13..CJK UNIFIED IDEOGRAPH-4D19
+4DAE          ; output #      (ä¶®)  CJK UNIFIED IDEOGRAPH-4DAE
+4E00..9FA5    ; output # [20902] (一..龥)  CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FA5
+A000..A48C    ; output # [1165] (ꀀ..ꒌ)  YI SYLLABLE IT..YI SYLLABLE YYR
+AC00..D7A3    ; output # [11172] (가..힣)  HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
+FA0E..FA0F    ; output #  [2] (﨎..﨏)  CJK COMPATIBILITY IDEOGRAPH-FA0E..CJK COMPATIBILITY IDEOGRAPH-FA0F
+FA11          ; output #      (﨑)  CJK COMPATIBILITY IDEOGRAPH-FA11
+FA13..FA14    ; output #  [2] (﨓..﨔)  CJK COMPATIBILITY IDEOGRAPH-FA13..CJK COMPATIBILITY IDEOGRAPH-FA14
+FA1F          ; output #      (﨟)  CJK COMPATIBILITY IDEOGRAPH-FA1F
+FA21          ; output #      (﨡)  CJK COMPATIBILITY IDEOGRAPH-FA21
+FA23..FA24    ; output #  [2] (﨣..﨤)  CJK COMPATIBILITY IDEOGRAPH-FA23..CJK COMPATIBILITY IDEOGRAPH-FA24
+FA27..FA29    ; output #  [3] (﨧..﨩)  CJK COMPATIBILITY IDEOGRAPH-FA27..CJK COMPATIBILITY IDEOGRAPH-FA29
+2070E         ; output #      (𠜎)  CJK UNIFIED IDEOGRAPH-2070E
+20731         ; output #      (𠜱)  CJK UNIFIED IDEOGRAPH-20731
+20779         ; output #      (𠝹)  CJK UNIFIED IDEOGRAPH-20779
+20C53         ; output #      (𠱓)  CJK UNIFIED IDEOGRAPH-20C53
+20C78         ; output #      (𠱸)  CJK UNIFIED IDEOGRAPH-20C78
+20C96         ; output #      (𠲖)  CJK UNIFIED IDEOGRAPH-20C96
+20CCF         ; output #      (𠳏)  CJK UNIFIED IDEOGRAPH-20CCF
+20CD5         ; output #      (𠳕)  CJK UNIFIED IDEOGRAPH-20CD5
+20D15         ; output #      (𠴕)  CJK UNIFIED IDEOGRAPH-20D15
+20D7C         ; output #      (ð µ¼)  CJK UNIFIED IDEOGRAPH-20D7C
+20D7F         ; output #      (𠵿)  CJK UNIFIED IDEOGRAPH-20D7F
+20E0E..20E0F  ; output #  [2] (𠸎..𠸏)  CJK UNIFIED IDEOGRAPH-20E0E..CJK UNIFIED IDEOGRAPH-20E0F
+20E77         ; output #      (ð ¹·)  CJK UNIFIED IDEOGRAPH-20E77
+20E9D         ; output #      (𠺝)  CJK UNIFIED IDEOGRAPH-20E9D
+20EA2         ; output #      (𠺢)  CJK UNIFIED IDEOGRAPH-20EA2
+20ED7         ; output #      (𠻗)  CJK UNIFIED IDEOGRAPH-20ED7
+20EF9..20EFA  ; output #  [2] (𠻹..𠻺)  CJK UNIFIED IDEOGRAPH-20EF9..CJK UNIFIED IDEOGRAPH-20EFA
+20F2D..20F2E  ; output #  [2] (ð ¼­..ð ¼®)  CJK UNIFIED IDEOGRAPH-20F2D..CJK UNIFIED IDEOGRAPH-20F2E
+20F4C         ; output #      (𠽌)  CJK UNIFIED IDEOGRAPH-20F4C
+20FB4         ; output #      (ð ¾´)  CJK UNIFIED IDEOGRAPH-20FB4
+20FBC         ; output #      (ð ¾¼)  CJK UNIFIED IDEOGRAPH-20FBC
+20FEA         ; output #      (𠿪)  CJK UNIFIED IDEOGRAPH-20FEA
+2105C         ; output #      (𡁜)  CJK UNIFIED IDEOGRAPH-2105C
+2106F         ; output #      (𡁯)  CJK UNIFIED IDEOGRAPH-2106F
+21075..21076  ; output #  [2] (𡁵..𡁶)  CJK UNIFIED IDEOGRAPH-21075..CJK UNIFIED IDEOGRAPH-21076
+2107B         ; output #      (𡁻)  CJK UNIFIED IDEOGRAPH-2107B
+210C1         ; output #      (𡃁)  CJK UNIFIED IDEOGRAPH-210C1
+210C9         ; output #      (𡃉)  CJK UNIFIED IDEOGRAPH-210C9
+211D9         ; output #      (𡇙)  CJK UNIFIED IDEOGRAPH-211D9
+220C7         ; output #      (𢃇)  CJK UNIFIED IDEOGRAPH-220C7
+227B5         ; output #      (𢞵)  CJK UNIFIED IDEOGRAPH-227B5
+22AD5         ; output #      (𢫕)  CJK UNIFIED IDEOGRAPH-22AD5
+22B43         ; output #      (𢭃)  CJK UNIFIED IDEOGRAPH-22B43
+22BCA         ; output #      (𢯊)  CJK UNIFIED IDEOGRAPH-22BCA
+22C51         ; output #      (𢱑)  CJK UNIFIED IDEOGRAPH-22C51
+22C55         ; output #      (𢱕)  CJK UNIFIED IDEOGRAPH-22C55
+22CC2         ; output #      (𢳂)  CJK UNIFIED IDEOGRAPH-22CC2
+22D08         ; output #      (𢴈)  CJK UNIFIED IDEOGRAPH-22D08
+22D4C         ; output #      (𢵌)  CJK UNIFIED IDEOGRAPH-22D4C
+22D67         ; output #      (𢵧)  CJK UNIFIED IDEOGRAPH-22D67
+22EB3         ; output #      (𢺳)  CJK UNIFIED IDEOGRAPH-22EB3
+23CB7         ; output #      (𣲷)  CJK UNIFIED IDEOGRAPH-23CB7
+244D3         ; output #      (𤓓)  CJK UNIFIED IDEOGRAPH-244D3
+24DB8         ; output #      (𤶸)  CJK UNIFIED IDEOGRAPH-24DB8
+24DEA         ; output #      (𤷪)  CJK UNIFIED IDEOGRAPH-24DEA
+2512B         ; output #      (𥄫)  CJK UNIFIED IDEOGRAPH-2512B
+26258         ; output #      (𦉘)  CJK UNIFIED IDEOGRAPH-26258
+267CC         ; output #      (𦟌)  CJK UNIFIED IDEOGRAPH-267CC
+269F2         ; output #      (𦧲)  CJK UNIFIED IDEOGRAPH-269F2
+269FA         ; output #      (𦧺)  CJK UNIFIED IDEOGRAPH-269FA
+27A3E         ; output #      (𧨾)  CJK UNIFIED IDEOGRAPH-27A3E
+2815D         ; output #      (𨅝)  CJK UNIFIED IDEOGRAPH-2815D
+28207         ; output #      (𨈇)  CJK UNIFIED IDEOGRAPH-28207
+282E2         ; output #      (𨋢)  CJK UNIFIED IDEOGRAPH-282E2
+28CCA         ; output #      (𨳊)  CJK UNIFIED IDEOGRAPH-28CCA
+28CCD         ; output #      (𨳍)  CJK UNIFIED IDEOGRAPH-28CCD
+28CD2         ; output #      (𨳒)  CJK UNIFIED IDEOGRAPH-28CD2
+29D98         ; output #      (𩶘)  CJK UNIFIED IDEOGRAPH-29D98
+
+# Total code points: 37201
+
+# Not allowed at start of identifier
+
+0300..033F    ; nonstarting # [64] (̀..̿)  COMBINING GRAVE ACCENT..COMBINING DOUBLE OVERLINE
+0342          ; nonstarting #      (͂)  COMBINING GREEK PERISPOMENI
+0345..034E    ; nonstarting # [10] (ͅ..͎)  COMBINING GREEK YPOGEGRAMMENI..COMBINING UPWARDS ARROW BELOW
+0360..036F    ; nonstarting # [16] (͠..ͯ)  COMBINING DOUBLE TILDE..COMBINING LATIN SMALL LETTER X
+0591..05A1    ; nonstarting # [17] (֑..֡)  HEBREW ACCENT ETNAHTA..HEBREW ACCENT PAZER
+05A3..05B9    ; nonstarting # [23] (Ö£..Ö¹)  HEBREW ACCENT MUNAH..HEBREW POINT HOLAM
+05BB..05BD    ; nonstarting #  [3] (Ö»..Ö½)  HEBREW POINT QUBUTS..HEBREW POINT METEG
+05BF          ; nonstarting #      (Ö¿)  HEBREW POINT RAFE
+05C1..05C2    ; nonstarting #  [2] (ׁ..ׂ)  HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+05C4          ; nonstarting #      (ׄ)  HEBREW MARK UPPER DOT
+064B..0655    ; nonstarting # [11] (ً..ٕ)  ARABIC FATHATAN..ARABIC HAMZA BELOW
+0670          ; nonstarting #      (Ù°)  ARABIC LETTER SUPERSCRIPT ALEF
+06D6..06DC    ; nonstarting #  [7] (ۖ..ۜ)  ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+06DF..06E4    ; nonstarting #  [6] (۟..ۤ)  ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+06E7..06E8    ; nonstarting #  [2] (Û§..Û¨)  ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+06EA..06ED    ; nonstarting #  [4] (Ûª..Û­)  ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+0711          ; nonstarting #      (ܑ)  SYRIAC LETTER SUPERSCRIPT ALAPH
+0730..073F    ; nonstarting # [16] (ܰ..ܿ)  SYRIAC PTHAHA ABOVE..SYRIAC RWAHA
+07A6..07B0    ; nonstarting # [11] (Þ¦..Þ°)  THAANA ABAFILI..THAANA SUKUN
+0901..0903    ; nonstarting #  [3] (ँ..ः)  DEVANAGARI SIGN CANDRABINDU..DEVANAGARI SIGN VISARGA
+093C          ; nonstarting #      (़)  DEVANAGARI SIGN NUKTA
+093E..094D    ; nonstarting # [16] (ा..्)  DEVANAGARI VOWEL SIGN AA..DEVANAGARI SIGN VIRAMA
+0951..0954    ; nonstarting #  [4] (॑..॔)  DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT
+0962..0963    ; nonstarting #  [2] (ॢ..ॣ)  DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+0981..0983    ; nonstarting #  [3] (ঁ..ঃ)  BENGALI SIGN CANDRABINDU..BENGALI SIGN VISARGA
+09BC          ; nonstarting #      (়)  BENGALI SIGN NUKTA
+09BE..09C4    ; nonstarting #  [7] (া..ৄ)  BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN VOCALIC RR
+09C7..09C8    ; nonstarting #  [2] (ে..ৈ)  BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+09CB..09CD    ; nonstarting #  [3] (ো..্)  BENGALI VOWEL SIGN O..BENGALI SIGN VIRAMA
+09D7          ; nonstarting #      (ৗ)  BENGALI AU LENGTH MARK
+09E2..09E3    ; nonstarting #  [2] (à§¢..à§£)  BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+0A02          ; nonstarting #      (ਂ)  GURMUKHI SIGN BINDI
+0A3C          ; nonstarting #      (਼)  GURMUKHI SIGN NUKTA
+0A3E..0A42    ; nonstarting #  [5] (ਾ..ੂ)  GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN UU
+0A47..0A48    ; nonstarting #  [2] (ੇ..ੈ)  GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+0A4B..0A4D    ; nonstarting #  [3] (ੋ..੍)  GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+0A70..0A71    ; nonstarting #  [2] (ੰ..ੱ)  GURMUKHI TIPPI..GURMUKHI ADDAK
+0A81..0A83    ; nonstarting #  [3] (ઁ..ઃ)  GUJARATI SIGN CANDRABINDU..GUJARATI SIGN VISARGA
+0ABC          ; nonstarting #      (઼)  GUJARATI SIGN NUKTA
+0ABE..0AC5    ; nonstarting #  [8] (ા..ૅ)  GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN CANDRA E
+0AC7..0AC9    ; nonstarting #  [3] (ે..ૉ)  GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN CANDRA O
+0ACB..0ACD    ; nonstarting #  [3] (ો..્)  GUJARATI VOWEL SIGN O..GUJARATI SIGN VIRAMA
+0B01..0B03    ; nonstarting #  [3] (ଁ..ଃ)  ORIYA SIGN CANDRABINDU..ORIYA SIGN VISARGA
+0B3C          ; nonstarting #      (଼)  ORIYA SIGN NUKTA
+0B3E..0B43    ; nonstarting #  [6] (ା..ୃ)  ORIYA VOWEL SIGN AA..ORIYA VOWEL SIGN VOCALIC R
+0B47..0B48    ; nonstarting #  [2] (େ..ୈ)  ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+0B4B..0B4D    ; nonstarting #  [3] (ୋ..୍)  ORIYA VOWEL SIGN O..ORIYA SIGN VIRAMA
+0B56..0B57    ; nonstarting #  [2] (ୖ..ୗ)  ORIYA AI LENGTH MARK..ORIYA AU LENGTH MARK
+0B82          ; nonstarting #      (ஂ)  TAMIL SIGN ANUSVARA
+0BBE..0BC2    ; nonstarting #  [5] (ா..ூ)  TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN UU
+0BC6..0BC8    ; nonstarting #  [3] (ெ..ை)  TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+0BCA..0BCD    ; nonstarting #  [4] (ொ..்)  TAMIL VOWEL SIGN O..TAMIL SIGN VIRAMA
+0BD7          ; nonstarting #      (ௗ)  TAMIL AU LENGTH MARK
+0C01..0C03    ; nonstarting #  [3] (ఁ..ః)  TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+0C3E..0C44    ; nonstarting #  [7] (ా..ౄ)  TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN VOCALIC RR
+0C46..0C48    ; nonstarting #  [3] (ె..ై)  TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+0C4A..0C4D    ; nonstarting #  [4] (ొ..్)  TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+0C55..0C56    ; nonstarting #  [2] (ౕ..ౖ)  TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+0C82..0C83    ; nonstarting #  [2] (ಂ..ಃ)  KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+0CBE..0CC4    ; nonstarting #  [7] (ಾ..ೄ)  KANNADA VOWEL SIGN AA..KANNADA VOWEL SIGN VOCALIC RR
+0CC6..0CC8    ; nonstarting #  [3] (ೆ..ೈ)  KANNADA VOWEL SIGN E..KANNADA VOWEL SIGN AI
+0CCA..0CCD    ; nonstarting #  [4] (ೊ..್)  KANNADA VOWEL SIGN O..KANNADA SIGN VIRAMA
+0CD5..0CD6    ; nonstarting #  [2] (ೕ..ೖ)  KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+0D02..0D03    ; nonstarting #  [2] (ം..ഃ)  MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+0D3E..0D43    ; nonstarting #  [6] (ാ..ൃ)  MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN VOCALIC R
+0D46..0D48    ; nonstarting #  [3] (െ..ൈ)  MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+0D4A..0D4D    ; nonstarting #  [4] (ൊ..്)  MALAYALAM VOWEL SIGN O..MALAYALAM SIGN VIRAMA
+0D57          ; nonstarting #      (ൗ)  MALAYALAM AU LENGTH MARK
+0D82..0D83    ; nonstarting #  [2] (ං..ඃ)  SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+0DCA          ; nonstarting #      (්)  SINHALA SIGN AL-LAKUNA
+0DCF..0DD4    ; nonstarting #  [6] (ා..ු)  SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+0DD6          ; nonstarting #      (ූ)  SINHALA VOWEL SIGN DIGA PAA-PILLA
+0DD8..0DDF    ; nonstarting #  [8] (ෘ..ෟ)  SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+0DF2..0DF3    ; nonstarting #  [2] (à·²..à·³)  SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+0E31          ; nonstarting #      (ั)  THAI CHARACTER MAI HAN-AKAT
+0E34..0E3A    ; nonstarting #  [7] (ิ..ฺ)  THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+0E47..0E4E    ; nonstarting #  [8] (็..๎)  THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+0EB1          ; nonstarting #      (ັ)  LAO VOWEL SIGN MAI KAN
+0EB4..0EB9    ; nonstarting #  [6] (ິ..ູ)  LAO VOWEL SIGN I..LAO VOWEL SIGN UU
+0EBB..0EBC    ; nonstarting #  [2] (ົ..ຼ)  LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO
+0EC8..0ECD    ; nonstarting #  [6] (່..ໍ)  LAO TONE MAI EK..LAO NIGGAHITA
+0F18..0F19    ; nonstarting #  [2] (༘..༙)  TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+0F35          ; nonstarting #      (༵)  TIBETAN MARK NGAS BZUNG NYI ZLA
+0F37          ; nonstarting #      (༷)  TIBETAN MARK NGAS BZUNG SGOR RTAGS
+0F39          ; nonstarting #      (༹)  TIBETAN MARK TSA -PHRU
+0F3E..0F3F    ; nonstarting #  [2] (༾..༿)  TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+0F71..0F72    ; nonstarting #  [2] (ཱ..ི)  TIBETAN VOWEL SIGN AA..TIBETAN VOWEL SIGN I
+0F74          ; nonstarting #      (ུ)  TIBETAN VOWEL SIGN U
+0F76          ; nonstarting #      (ྲྀ)  TIBETAN VOWEL SIGN VOCALIC R
+0F78          ; nonstarting #      (ླྀ)  TIBETAN VOWEL SIGN VOCALIC L
+0F7A..0F80    ; nonstarting #  [7] (ེ..ྀ)  TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN REVERSED I
+0F82..0F84    ; nonstarting #  [3] (ྂ..྄)  TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA
+0F86..0F87    ; nonstarting #  [2] (྆..྇)  TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+0F90..0F97    ; nonstarting #  [8] (ྐ..ྗ)  TIBETAN SUBJOINED LETTER KA..TIBETAN SUBJOINED LETTER JA
+0F99..0FBC    ; nonstarting # [36] (ྙ..ྼ)  TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+0FC6          ; nonstarting #      (࿆)  TIBETAN SYMBOL PADMA GDAN
+102C..1032    ; nonstarting #  [7] (ာ..ဲ)  MYANMAR VOWEL SIGN AA..MYANMAR VOWEL SIGN AI
+1036..1039    ; nonstarting #  [4] (ံ..္)  MYANMAR SIGN ANUSVARA..MYANMAR SIGN VIRAMA
+1056..1059    ; nonstarting #  [4] (ၖ..ၙ)  MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC LL
+17B6..17D0    ; nonstarting # [27] (ា..័)  KHMER VOWEL SIGN AA..KHMER SIGN SAMYOK SANNYA
+17D2          ; nonstarting #      (្)  KHMER SIGN COENG
+18A9          ; nonstarting #      (ᢩ)  MONGOLIAN LETTER ALI GALI DAGALGA
+3099..309A    ; nonstarting #  [2] (゙..゚)  COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+
+# Total code points: 524
diff --git a/nxhtml/etc/viper-tut/0intro b/nxhtml/etc/viper-tut/0intro
new file mode 100644
index 0000000..da8d35a
--- /dev/null
+++ b/nxhtml/etc/viper-tut/0intro
@@ -0,0 +1,59 @@
+Viper tutorial #0: Introduction
+
+This Viper tutorial is based on the vi tutorial VILEARN.  Some things
+works differently in Emacs and corresponding parts of the tutorial has
+been changed for this.  There has also been added some basic
+information about Emacs that are useful to get started if you already
+are a vi user.
+
+This tutorial is a hands-on-tutorial for Viper.  If you want more
+information about Viper, please read the VIPER-MANUAL.
+
+Note that if you are using Viper you probably still want to know quite
+a bit about Emacs to use Emacs efficiently.  Therefore you can also
+run the Emacs tutorial from here - with special support for
+Viper. This is part 6 below. You should run this part also to get to
+know which Emacs standard key bindings are shadowed by Viper.
+
+The tutorial consists of these parts:
+
+    0 Introduction
+      (this file)
+
+    1 Basic Editing
+      Covers the handful of commands required to both navigate all
+      five tutorials and do basic editing.
+
+    2 Moving Efficiently
+      Covers all of the cursor positioning commands. These are the
+      commands used later as arguments to editing commands.
+
+    3 Cutting and Pasting
+      Introduces the first compound commands, numbering, and copy
+      buffers.
+
+    4 Inserting Techniques
+      Continues the discussion of compound commands, while completing
+      the list of insertion commands first discussed in tutorial one.
+
+    5 Tricks and Timesavers
+      This is less a tutorial than a description of common vi commands
+      which don't fit correctly into normal logic.
+
+    6 Emacs Tutorial for Viper Users
+      Even Viper users use a lot of keys from Emacs.  Therefore you can
+      run the Emacs tutorial here too.  It will show you which keys in
+      the tutorial that are changed because you are using Viper.  This
+      depends of which Viper state you are in, vi state or some insert
+      state.  If you switch Viper state the tutorial will immediately
+      show which keys are affected.
+
+
+BUGS
+Vilearn has the remark that it "Still doesn't cover variables, ex
+commands, or tags.  At least one more tutorial is necessary for a
+complete introduction to vi." - I do not think you have to learn those
+parts to use Viper. There are other ways to do these things in Emacs!
+
+For more information about vilearn see the the README-FILE.
+
diff --git a/nxhtml/etc/viper-tut/1basics b/nxhtml/etc/viper-tut/1basics
new file mode 100644
index 0000000..aea1fc5
--- /dev/null
+++ b/nxhtml/etc/viper-tut/1basics
@@ -0,0 +1,187 @@
+Viper tutorial #1: The Basics
+
+This lesson lasts 10-15 minutes and teaches simple editing.  Lines
+which begin with  >>>  mark exercises you should try.  When you
+want to exit this tutorial type  'Z''Z'  (type capital Z, twice).
+
+When you type commands in vi they do not appear on the screen.  If the
+letters you type unexpectedly appear on the screen, press the ESC key.
+
+
+BASIC CURSOR MOVEMENT
+---------------------
+To move through the tutorial use C-d (control d) and C-u (control u).
+
+        C-d     Move DOWN one half-screen
+                (depress the control key and type d)
+
+        C-u     Move UP one half-screen
+                (depress the control key and type u)
+
+* EMACS-NOTICE: C-u is normally used in Emacs for UNIVERSAL-ARGUMENT.
+  You can in most cases use DIGIT-ARGUMENT instead.
+
+>>> Now type C-d (control d) and C-u (control u) to move down and back up.
+
+When you are done reading a screen, you are expected to type C-d to move
+down to the next screen.  You must remember to type C-d throughout the
+tutorial.
+
+To move the cursor line by line, or character by character, use the
+four keys 'h', 'j', 'k', and 'l'.
+
+        'h'     Move left one character
+        'j'     Move down one line
+        'k'     Move up one line
+        'l'     Move right one character
+
+You will notice that these keys are in a straight line on the
+keyboard.  Study the diagram below showing the function of h, j, k, l.
+
+                                       UP
+                .......   .......   .......   .......
+                :     :   :     :   :     :   :     :
+          LEFT  :  h  :   :  j  :   :  k  :   :  l  :  RIGHT
+                :.....:   :.....:   :.....:   :.....:
+
+                           DOWN
+
+>>> Now type  'j'  or  'k'  a few times to bring the cursor to this line.
+
+>>> Try moving off the right end of a line using  'l' .  Notice that
+>>> vi will not allow you to move off the end of the line using  'l' .
+>>> Likewise, you cannot use  'h'  and  'l'  on a blank line.
+
+>>> Try moving past the bottom of the screen using  'j' . Notice how
+>>> how the screen scrolls downward.
+
+>>> Now practice using  'k'  to move up, and  'h'  to move left.
+
+
+DELETION
+--------
+To delete characters and lines, use 'x' and 'd''d'.
+
+        'x'       X-OUT one character
+        'd''d'      DELETE one line
+
+To undo your changes, use 'u'.
+
+        'u'       UNDO last change only
+
+>>> Delete this SCRAP line. Move to this line with  'j' or 'k' , now type  'd''d' .
+>>> Try undoing the deletion with  'u' .
+
+>>> Move to this line and x-out the Y's with  'x' : "whY ask whY?"
+
+>>> Try undoing the deletion with  'u' . Try typing  'u'  several times.
+>>> Notice that  'u'  only undoes the last change.
+
+* EMACS-NOTICE: In Viper you can use the repeat command '.' (just a dot)
+  to undo more changes.  This goes in both direction, ie undoing and
+  redoing. Typing just 'u' changes direction.
+
+Here are more lines on which to practice deleting and undoing (use: 'd''d' 'x' 'u' )
+
+        Emacs is a nice creation. Emacs is a nice creation.
+        Emacs is a nice creation. Emacs is a nice creation.
+        Emacs is a nice creation. Emacs is a nice creation.
+
+
+QUIT COMMANDS
+-------------
+(DO NOT QUIT the tutorial at this time.)
+
+To quit a file without saving any changes you have made (for instance,
+with the  'd''d'  or  'x'  commands) use  :q! . To quit and save your
+changes, use  'Z''Z' .  When you are editing your own files, you normally
+use  'Z''Z'  to quit.
+
+ :q!    QUIT without saving changes
+                (type a colon, then the letter q, then an
+                exclamation point, and press RETURN)
+
+        'Z''Z'      Exit and save any changes
+                (type capital Z, twice)
+
+
+
+INSERTION
+---------
+You enter insert mode with  'i'  or  'o' . Anything you type during insert
+mode appears on the screen.  When you are done inserting, press ESC
+to exit insert mode.  Type  C-[ (control [ ), if you do not have an ESC key.
+
+        'o'       OPEN a line for inserting text
+        'i'       INSERT starting at the cursor
+
+        ESC     ESCAPE from insert mode
+
+During insert mode, use your erase character (usually backspace or
+delete) to delete mistakes. The characters you delete will remain on
+the screen until you press ESC.
+
+>>> Insert your name and phone number below the next blank line. To do this:
+>>>     Open a line below using  'o' .
+>>>     Type your first and last name. Press RETURN.
+>>>     Then type your phone number and press ESC.
+>>>     Use  'x'  to erase part of your phone number.
+
+>>> Type the date below your phone number. To do this:
+>>>     Open another line using  'o' .
+>>>     Type the date and press ESC.
+
+>>> Type  'u'  to undo the insertion.
+
+>>> Insert a nickname between your first and last names, using 'i'. To do this:
+>>>     Move the cursor to the spot between your names using  'h', 'j', 'k', 'l'.
+>>>     Press  'i' .
+>>>     Type the nickname, use DELETE or BACKSPACE to erase any typos.
+>>>     Then press ESC.
+
+On some computers, a line may be longer than the width of the screen.
+This means that a very long line may appear to be two lines on the
+screen.  This happens when you keep typing without pressing RETURN at
+the edge of the screen. To avoid any confusion when you're inserting
+text, be sure to press RETURN before reaching the right edge of the
+screen.
+
+
+SUMMARY
+-------
+These are the vi commands you should know after tutorial #1:
+
+        C-d     Move DOWN one half-screen
+                (depress the control key and type d)
+
+        C-u     Move UP one half-screen
+                (depress the control key and type u)
+
+        'h'       Move left one character
+        'j'       Move down one line
+        'k'       Move up one line
+        'l'       Move right one character
+
+        'd''d'      DELETE one line
+        'x'       X-OUT one character
+
+        'u'       UNDO last change
+
+ :q!    QUIT without saving changes
+                (type a colon, then the letter q, then an
+                exclamation point, and press RETURN)
+
+        'Z''Z'      Exit and save any changes
+                (type capital Z, twice)
+
+        'o'       OPEN a line for inserting text
+        'i'       INSERT starting at the cursor
+
+        ESC     ESCAPE from insert mode
+
+
+You are now prepared to do simple editing on your own files.  Practice
+using vi for a few days.  Then take the second vi tutorial to learn
+more powerful and useful vi commands.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
diff --git a/nxhtml/etc/viper-tut/2moving b/nxhtml/etc/viper-tut/2moving
new file mode 100644
index 0000000..8e4148e
--- /dev/null
+++ b/nxhtml/etc/viper-tut/2moving
@@ -0,0 +1,269 @@
+Viper tutorial #2: Moving Through Files Efficiently
+
+This lesson lasts 15-20 minutes.  The material taught here is used in
+tutorial #3: Cutting and Pasting.  Lines which begin with  >>>  mark
+exercises you should try.  When you want to exit this tutorial type 'Z''Z'.
+
+
+WORDS
+-----
+There are many ways to move from one word to another. Consider these:
+
+        'w'       Move to the beginning of the next WORD
+        'e'       Move to the END of the next word
+        'b'       Move BACK to the beginning to the previous word
+
+For  'w', 'e', and 'b',  a word is delimited by any non-alphanumeric
+character. The capitalized versions,  'W', 'E', and 'B',  also move from word
+to word. The difference is that for  'W', 'E', and 'B',  a word is delimited
+by any blank space.
+
+>>>  Try out  'w', 'b', 'e',  on the lines provided below.
+>>>  Next practice using  'B', 'W', 'b', 'E'  on the lines provided below.
+
+    EX-PER-IMENT on these lines;test moving back &forth.
+    EX-PER-IMENT on these lines;test moving back &forth.
+
+
+ON THE LINE
+-----------
+You can move immediately to any point on the current line.
+
+        '$'       Move to the end of the line
+        '^'       Move to the first non-white character on the line
+
+        '0'       Move to the first column on the line (column zero)
+        #'|'      Move to an exact column on the line (column #) e.g.  5| 12|
+
+>>>  Experiment with  '$'  and  '^'  on the line provided below.  Notice
+>>>  that  '^'  moves to the first non-white character, not the beginning.
+
+    This is a PRACTICE LINE.  There is white space at the front.  END
+
+'0' (zero) will always take you to the far left edge of the screen.
+
+#'|' (number vertical-bar) is for moving to an explicit column on a line.
+Just type any number 1-80 and press  | . For example:  5|   20|   30|
+Note that you can't move beyond the last column on a line.
+
+
+FINDING CHARACTERS
+------------------
+Often you want to move to a specific letter or character on a line.
+
+    'f' char      FIND the next occurrence of char on the line
+    't' char      Move 'TIL the next occurrence of char on the line
+
+    'F' char      FIND the previous occurrence of char on the line
+    'T' char      Move 'TIL the previous occurrence of char on the line
+
+        ';'       Repeat the last  f, t, F, or T
+        ','       Reverse the last  f, t, F, or T
+
+'f' and 'F' land on the character.  't' and 'T' land next to the character.
+'f' and 't' move forward, while 'F' and 'T' move backward.
+
+If the specified character is not on the line, vi will beep.
+
+>>>  Move to the beginning of the line below, and try out these commands:
+>>>     'f'e  'f'E  ';'  ';'  ','  ','  't'@  'T'P  't'e  't'E  ','  ';'  ','  ';'
+
+    "PRACTICE line?" "Each and Every?" "Find thE char@cter and move to it.END
+
+
+MATCHING
+--------
+vi has a handy way to determine if (), {}, and [] pairs match up.
+
+        '%'       Move to matching () or {} or []
+
+>>>  On the practice lines below, move your cursor over a (,),{,},[, or ].
+>>>  Then type  '%'  .
+
+    [TRY THIS.  ((Whether) the pairs match up is the question.)  [One]
+    pair is incomplete].  Can you tell {which one? ]} END
+
+
+WINDOW POSITIONS
+----------------
+You can move the cursor to the top, middle, or bottom of the vi window.
+
+        'H'    Move to the HIGHEST position in the window
+        'M'    Move to the MIDDLE position in the window
+        'L'    Move to the LOWEST position in the window
+
+>>>  Try out these commands:  type  H  then  M  and  L  and then  M  again.
+
+
+MARKING LOCATIONS
+-----------------
+You can mark positions in the file and return to them.
+
+     'm' char     MARK this location and name it char
+     ''' char     (quote character) return to line named char
+     ''''''         (quote quote) return from last movement
+
+char can be any lower case letter, a-z.  A mark persists until you:
+     1) use the same char to mark another location
+  or 2) delete the marked line
+
+>>>  Move to this line and type  ma  to mark it  a
+>>>  Move to this line and type  mb  to mark it  b
+>>>  Move to this line and type  mz  to mark it  z
+>>>  Type  'a  to return to line  a
+>>>  Type  'b  to return to line  b
+>>>  Type  'z  to return to line  z
+
+Certain commands can move you large distances. These commands cause
+your last position to be remembered in the special mark named ' (quote).
+To move to this special mark, just type '' (quote quote).
+
+>>>  Try this:  'b  to return to line b, and then  ''  to return here.
+
+
+GO TO A LINE
+------------
+
+         'G'      GO to the last line in the file
+        #'G'      GO to line #.  (e.g., 3G , 5G , 124G )
+
+Read these directions carefully:
+>>>  Type  '1''G'  to go to the top of the file, and then  ''''''  (quote quote)
+>>>  to return here.
+>>>  Now try  'G'  to go to the end of the file, and then  ''''''  to return here.
+
+
+BLOCKS OF TEXT
+--------------
+It is often convenient to move through files jumping from one block of
+text to the next.  To do this use braces and parentheses:
+
+        '{'       (left brace) Move to the beginning of a paragraph
+        '}'       (right brace) Move to the end of a paragraph
+
+        '('       (left paren) Move to the beginning of a sentence
+        ')'       (right paren) Move to the beginning of the next sentence
+
+>>>  Experiment with  '}'  and  '{'  on the two paragraphs provided below.
+>>>  Note that paragraphs are separated by a blank line.
+
+        EXPERIMENT on this first paragraph.  The quick brown fox jumped
+    over the seven lazy dogs.  The fox must have been very large to
+    jump over seven dogs!
+
+        EXPERIMENT on this second paragraph.  The quick brown dog
+    jumped over the seven lazy foxes.  The dog didn't have to be nearly
+    as large, since foxes aren't too big.
+
+>>>  Try out  ')'  and  '('  on the two paragraphs provided above.
+>>>  Notice that sentences are separated by two blank spaces.
+
+C programmers find it useful to move by sections, since sections may be
+delimited by a left brace in the first column.  By placing the opening
+brace of a C subroutine in the first column, you can move to the top of
+the next subroutine, using '[''[' and  ']'']' .
+
+        '[''['      Move to the beginning of a section
+        ']'']'      Move to the end of a section
+
+Note that if vi does not find a left brace at the far left, it will
+move to the top or bottom of the file.
+
+>>>  Now try  ']'']'  then  ']'']'  and  '[''['  on the subroutines provided below:
+
+main()
+{
+    helloworld();
+}
+
+helloworld()
+{
+    printf( "Hello world\n" );
+}
+
+
+SEARCHING
+---------
+This enables you to jump to the next occurrence of a string in a file.
+To initially find the string use:
+
+    '/'string      Find string looking forward
+    '?'string      Find string looking backward
+
+To find additional occurrences of the string type:
+
+        'n'        Repeat last / or ? command
+        'N'        Reverse last / or ? command
+
+vi may search past the bottom of the file and then start again at the top.
+(Or, vi may search past the top and then start again at the bottom.)
+
+>>>  You are going to search for a string, find the next three
+>>>  occurrences.  Then flip directions and find the string until you
+>>>  return to this location.  To do this:
+>>>      Type   '/''t''h''e'   then press RETURN.
+>>>      Type  'n'  three times.
+>>>      Type  'N'  until you return to this location.
+
+* EMACS-NOTICE: Emacs has very powerful SEARCH-COMMANDS which you may
+  want to use in parallell to those above.  One of the first you want
+  to try is probably C-s (ISEARCH-FORWARD).
+
+
+SUMMARY
+-------
+
+        'w'       Move to the beginning of the next WORD
+        'e'       Move to the END of the next word
+        'b'       Move BACK to the beginning to the previous word
+
+        '$'       Move to the end of the line
+        '^'       Move to the first non-white character on the line
+
+        '0'       Move to the first column on the line (column zero)
+        #'|'      Move to an exact column on the line (column #) e.g.  5| 12|
+
+    'f' char      FIND the next occurrence of char on the line
+    't' char      Move 'TIL the next occurrence of char on the line
+
+    'F' char      FIND the previous occurrence of char on the line
+    'T' char      Move 'TIL the previous occurrence of char on the line
+
+        ';'       Repeat the last  f, t, F, or T
+        ','       Reverse the last  f, t, F, or T
+
+        '%'       Show matching () or {} or []
+
+        'H'       Move to the HIGHEST position in the window
+        'M'       Move to the MIDDLE position in the window
+        'L'       Move to the LOWEST position in the window
+
+    'm' char      MARK this location and name it char
+    ''' char      (quote character) return to line named char
+    ''''''          (quote quote) return from last movement
+
+         'G'      GO to the last line in the file
+        #'G'      GO to line #.  (e.g., 3G , 5G , 175G )
+
+        '{'       (left brace) Move to the beginning of a paragraph
+        '}'       (right brace) Move to the end of a paragraph
+
+        '('       (left paren) Move to the beginning of a sentence
+        ')'       (right paren) Move to the beginning of the next sentence
+
+        '[''['      Move to the beginning of a section
+        ']'']'      Move to the end of a section
+
+    '/'string      Find string looking forward
+    '?'string      Find string looking backward
+
+        'n'        Repeat last / or ? command
+        'N'        Reverse last / or ? command
+
+You should now be able to move around files very efficiently.  These
+commands are especially useful if you are using vi over a slow modem.
+Practice the material in this lesson for a few days and then take
+either the third vi tutorial to learn how to copy, cut, and paste, or
+the forth vi tutorial to learn additional insertion techniques.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
diff --git a/nxhtml/etc/viper-tut/3cutpaste b/nxhtml/etc/viper-tut/3cutpaste
new file mode 100644
index 0000000..6d531d9
--- /dev/null
+++ b/nxhtml/etc/viper-tut/3cutpaste
@@ -0,0 +1,318 @@
+Viper tutorial #3: Copying, Cutting, and Pasting
+
+This lesson lasts 15-20 minutes.  This tutorial assumes full knowledge
+of tutorial #1, and familiarity with tutorial #2.  Lines which begin
+with  >>>  mark exercises you should try.
+
+When you want to exit this tutorial type  'Z''Z'  to exit and save your
+changes.  Or type  :q!  to exit without saving changes.
+Remember that typing  u  will UNDO your last change.
+
+
+CUTTING TEXT
+------------
+The delete command can be combined with any of the movement commands
+taught throughout tutorial #2.  The resulting command is of the form:
+
+    'd'movement	DELETE to where the movement command specifies
+
+Consider the following examples:
+
+	'd''w'	DELETE to the beginning of the next WORD
+	'd''$'	DELETE to the end of the line
+	'd'')'	DELETE to the beginning of the next sentence
+	'd''t'e	DELETE 'TIL the next  e
+	'd''d'	DELETE a line (dd is a special case of the d command)
+
+>>>  Experiment with  'd''w'  'd''$'  'd'')'  'd''t'e  'd''d'  on the paragraph provided below:
+
+    PRACTICE here.  Now is the time for all good users to learn the
+    editor.  The quick brown fox jumped over the seven lazy fish.  Now
+    is the time for all good users to learn the editor.  The quick
+    brown computer jumped over the seven lazy users.  END PRACTICE
+
+* EMACS-NOTICE: In Viper you can also use 'r' and 'R' for Emacs region and
+  Viper line extended region. This is very convenient together with
+  CUA-MODE where the region is visible (it is usually called the
+  selected text or something similar in other applications).
+
+
+PASTING TEXT
+------------
+When text is deleted it is put into a buffer which contains the most
+recently deleted text.  To paste the contents of this buffer elsewhere
+in the file use the  p  or  P  command.
+
+	'P'	(upper p) PUT the contents of the buffer before the cursor
+	'p'	(lower p) PUT the contents of the buffer after the cursor
+
+>>>  Try this sequence of commands on the practice lines below:
+>>>  	'd''d'  	to delete one line
+>>>	'j'	to move down a line
+>>>	'p'	(lower p) to PUT the deleted text after the cursor
+>>>	'}'	to move to the end of the paragraph
+>>>	'P'	(upper p) to PUT the deleted text before the cursor
+
+	PRACTICE line.  Cut and Paste this line to the bottom of the
+	paragraph.  Here is some filler, feel free to cut and paste the
+	text in this practice region.  Remember that  u  undoes the last
+	action.  END OF PRACTICE
+
+>>>  Try this sequence of commands at the beginning of a word:
+>>>	'd''w'  'w'  'P'
+
+The fastest way to swap two letters is to type:  'x''p'
+
+>>>  Use  xp  to correct the misspelled words below:
+
+	PRACTICE.  Thier weird quiet recieved an inconvenient shriek.
+	Thier belief is that to recieve grief from nieghbors outwieghs
+	all else.  Biege skies lead to wierd science.  END.
+
+
+NUMBERING
+---------
+Consider cutting and pasting 3 words.  Based on previous exercises you
+would type  'd''w' , move to the new location, and type  'p' , and repeat
+this procedure twice more.  There is an easier way to do this:
+
+>>>  Using the practice lines below, try the following sequence of commands:
+>>>    Move to the beginning of the first sentence.
+>>>    Type  'd''3''w'  to DELETE 3 WORDS.
+>>>    Type  'w'  to move ahead one WORD.
+>>>    Type  'P'  (upper p) to PUT the three words before the cursor.
+
+    PRACTICE Numbering vi commands is easy to do.  Now is the time for
+    all good users to learn the editor.  The quick brown fox jumped
+    over the seven lazy dogs.  Numbering vi commands is easy to do.
+    Now is the time for all good users to learn the editor. END PRACTICE
+
+>>>  Type  'd''2''d'  to DELETE 2 lines, using the practice paragraph above.
+>>>  Move to the top of the paragraph.
+>>>  Type  'p'  (lower p) to PUT the two lines after of the cursor.
+
+Numbering also works for movement commands.
+
+>>>  Now try  '4''w'  to move ahead 4 WORDs, on the lines provided above.
+>>>  Then use  '3''b'  to move BACK 3 words.
+
+When you type  '4''w'  THINK "4 words", when you type  d4w  think "delete 4
+words".  In general, we can write
+
+    #movement	repeat movement # times
+    d#movement	DELETE to where the  #movement  command specifies
+
+
+COPYING TEXT
+------------
+The YANK command works just like the DELETE command, except  'y'  is used
+instead of  'd'  .
+
+    'y'movement	YANK to where the movement command specifies
+
+YANK and DELETE are identical except that YANK only copies the specified
+text into the buffer.
+
+>>>  Try this sequence of commands on the practice lines below:
+>>>  	'y''y'  	to YANK a line (yy is a special case of the y command)
+>>>	'3''j'	to move down 3 lines
+>>>	'p'	(lower p) to PUT the yanked text after the cursor
+
+	PRACTICE line.  Copy and Paste this line to the bottom of the
+	paragraph.  Here is some filler, feel free to copy and paste the
+	text in this practice region.  Remember that  u  undoes the last
+	action.  END OF PRACTICE
+
+Please note that copy, cutting, and pasting large blocks of text may
+significantly alter the tutorial file.  Remember that you can always get
+a new copy of the tutorial file and that  u  UNDOes your last change.
+
+Here are some examples which show the similarity between  y  and  d .
+
+	'y''w'	YANK to the beginning of the next WORD
+	'y''$'	YANK to the end of the line
+	'y'')'	YANK to the beginning of the next sentence
+	'y''t'e	YANK 'TIL the next  e
+	'y''y'	YANK a line
+
+Here are some more examples using commands from tutorial #2.
+
+	'y''L'	YANK from here to the lowest point of the window
+	'y''/'and	YANK from here to the word "and"
+	'y''2''}'	YANK 2 paragraphs
+	'y''''a	YANK from here to the marked line "a" (mark line first)
+
+>>>  Experiment with  'y''w'  'y''t'e  'y''4''w'  'y''2''}'  'y''3''y'  and  'y''$'  on the paragraph
+>>>  provided below.  Copy text AND use  'p'  or  'P'  to paste it.
+
+	PRACTICE line.  Copy and Paste this line to the bottom of the
+	paragraph.  Here is some filler, feel free to copy and paste
+	the text in this practice region.  Remember that  u  undoes the
+        last action.  END OF PRACTICE
+
+
+NUMBERED BUFFERS
+----------------
+In all of the previous pasting exercises you've used the "un-named"
+buffer.  The un-named buffer contains the text you most recently cut or
+copied.  When you make a new cut or copy, the old contents of the
+un-named buffer are moved to one of the "numbered" buffers.  The
+buffers are numbered 1-9.  Each time you cut or copy text,
+
+	vi saves your current cut or copy in a buffer #1
+	vi saves your 2nd to last cut or copy in a buffer #2
+	The cut or copy before that is saved in a buffer #3 ...
+	vi saves your 8th oldest cut or copy in a buffer #8
+	vi saves your 9th oldest cut or copy in a buffer #9
+
+Note that buffer #1 is the same as the un-named buffer.  Here's how to
+paste from the numbered buffers:
+
+	"#P	(upper p) PUT contents of buffer # before the cursor
+	"#p	(lower p) PUT contents of buffer # after the cursor
+
+For example:
+
+	"1p	PUT buffer 1 after the cursor
+	"7p	PUT buffer 7 after the cursor
+
+>>>  Delete this 1st line with  dd
+>>>  Delete this 2nd line with  dd
+>>>  Delete this 3rd block with  d2d
+>>>    (2nd half of block 3)
+>>>  Delete this 4th block with  dd
+>>>  Now type   "1p   "2p   "3p   "4p
+
+If you are using vi and have made accidental deletions, just PUT the
+contents of each numbered buffer to recover the deleted text.
+
+
+NAMED BUFFERS
+-------------
+vi maintains the un-named and numbered buffers automatically.  You can
+maintain your own buffers named a-z.  That is, you can cut or copy text
+into buffer x and later paste the text from buffer x.
+
+    '"'aDELETE	DELETE text into buffer a
+    "aYANK	YANK text into buffer a
+    "aPUT	PUT text from buffer a
+
+Note, don't actually type 'DELETE', 'YANK', or 'PUT'; type one of the
+DELETE commands, YANK commands, or PUT commands.  See the examples below:
+
+	"ad}		DELETE paragraph into buffer a
+	"by3y		YANK 3 lines into buffer b
+	"cy200G    	YANK to line 200 into buffer c
+	"dp		PUT buffer d  after the cursor
+	"zP		PUT buffer z  before the cursor
+
+The contents of a named buffer are lost if:
+     1) you store new text in a buffer with the same name
+  or 2) you quit vi (using  'Z''Z'  or  :q!  )
+
+>>>  Delete this START line into buffer a  by typing  "add
+>>>  Paste buffer a  by typing  "ap
+
+>>>  Delete this INTERMEDIATE line into buffer b  by typing  "bdd
+>>>  Paste buffer b  by typing  "bp
+
+To put new material into buffer a
+>>>  Delete this FINAL line into buffer a  by typing  "add
+>>>  Paste buffer a  by typing  "ap
+
+
+SAVING WITHOUT QUITTING
+-----------------------
+With ZZ you save changes and kill the current buffer.  (In vi you also
+exit with 'Z''Z'.) With :w you can save and not quit vi.  It is a safe
+practice to save changes to a file regularly.  This reduces re-typing
+in the event your computer crashes.
+
+    :w	WRITE contents of the file (without quitting)
+		(type a colon, type w , then press the RETURN key)
+
+>>>  Try  :w  now.  Note the message at the bottom of the screen.
+
+
+PASTING BETWEEN FILES
+---------------------
+
+* EMACS-NOTICE: In Emacs there are no problems editing several
+  files. You can however do it in the more complicated vi way below if
+  you really want to ;-)
+
+This is an extremely useful procedure in vi.  Only one new command is
+required for pasting between files, the EDIT command
+
+    :e filename    Begin EDITing the file called "filename"
+
+The EDIT command allows you to edit another file without quitting vi.
+This is useful since named buffers are lost when you quit vi.
+
+Let's say you want to copy 6 lines from the file called "3temp" into
+this file which is named "3cutpaste":
+(Note that "3temp" has already been created for you)
+
+    1) WRITE "3cutpaste".  vi will not allow	:w (press RETURN)
+    you to edit another file without first
+    saving any changes you've made.
+
+    2) EDIT "3temp" without quitting vi.	:e 3temp (press RETURN)
+
+    3) YANK 6 lines from "3temp".		"ay6y
+
+    4) Return to "3cutpaste".			:e 3cutpaste (press RETURN)
+
+    5) PUT from buffer a			"ap
+
+Note that the un-named and numbered buffers are lost when the EDIT
+command is used.  Only named buffers are preserved with EDIT.
+
+>>>  Follow the 5-step procedure outlined above.  Don't be concerned
+>>>  with remembering all 5 steps, the instructions are repeated in
+>>>  "3temp".  Paste the text from "3temp" near this line of this file,
+>>>  "3cutpaste".
+
+You can use this 5-step procedure on any two files, with any cutting or
+copying action (here, y6y is the example).
+
+
+SUMMARY
+-------
+
+    #movement	repeat movement # times
+                * EMACS-NOTICE: You may also use 'r' or 'R' in Viper.
+
+    'd'movement	DELETE to where "movement" command specifies
+    'd'#movement	DELETE to where the  #movement  command specifies
+		(e.g.  'd''w'  'd''3''w' )
+
+    'y'movement	YANK to where "movement" command specifies
+    'y'#movement	YANK to where the  #movement  command specifies
+		(e.g.  'y''w'  'y''3''w' )
+
+	'P'	(upper p) PUT the contents of the buffer before the cursor
+	'p'	(lower p) PUT the contents of the buffer after the cursor
+
+	'"'#P	(upper p) PUT contents of buffer # before the cursor
+	'"'#p	(lower p) PUT contents of buffer # after the cursor
+		(e.g.  '"''2''p'  '"''7''P' )
+
+    '"'aDELETE	DELETE text into buffer a
+    '"'aYANK	YANK text into buffer a
+    '"'aPUT	PUT text from named buffer a
+		(Note, don't actually type 'DELETE', 'YANK', or 'PUT';
+		type one of the DELETE commands, YANK commands, or PUT
+		commands, e.g.  '"''a''d''}'  '"''b''y''3''y'  '"''c''y''2''0''0''G'  '"''d''p'  '"''z''P'  )
+
+    :w	WRITE contents of the file (without quitting)
+		(type a colon, type w , then press the RETURN key)
+
+    :e filename    Begin EDITing the file called "filename"
+
+
+You are now prepared to handle all cutting, copying and pasting tasks
+which may arise.  If you practice what you've learned you'll find editing
+in vi to be fast and convenient.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
diff --git a/nxhtml/etc/viper-tut/4inserting b/nxhtml/etc/viper-tut/4inserting
new file mode 100644
index 0000000..ab2c6a5
--- /dev/null
+++ b/nxhtml/etc/viper-tut/4inserting
@@ -0,0 +1,180 @@
+Viper tutorial #4: Insertion Techniques
+
+This lesson lasts 5-10 minutes.  This tutorial assumes full knowledge
+of tutorial #1, and familiarity with tutorial #2.  Lines which begin
+with  >>>  mark exercises you should try.  When you want to exit this
+tutorial type  'Z''Z' .
+
+
+SIMPLE INSERTION
+----------------
+You spend most of your time in vi inserting text.  As you might expect,
+there are several commands to begin insertion.
+
+        'o'       OPEN a line below the cursor
+        'O'       OPEN a line above the cursor
+
+        'i'       INSERT starting before the cursor
+        'I'       INSERT at the beginning of the line
+
+        'a'       APPEND starting after the cursor
+        'A'       APPEND at the end of the line
+
+Remember to type ESC to leave insert mode.  If you don't have an ESC key
+type  C-[ (control [ ).
+
+        ESC     ESCAPE from insert mode
+
+>>>  Move the cursor to this line.  Type  'O'  , enter your name.  Press ESC.
+>>>  Next type  'o'  , enter the date.  Press ESC.
+
+Note that  'O'  opens the line above and puts you in insert mode,
+while  'o'  opens the line below and also puts you in insert mode.
+
+>>>  Type  'a'  on any line above, enter your name.  Press ESC.  Do the
+>>>  same for  'A'.
+
+>>>  Read the following.  Your goal is to take the sentence fragment below:
+
+        BROWN FOX  OVER THE SEVEN LAZY
+
+>>>  and convert it to
+
+        THE QUICK BROWN FOX JUMPED OVER THE SEVEN LAZY DOGS.
+
+>>>  To do this type:
+>>>     'I'  to insert  THE QUICK  (then press ESC)
+>>>     move the cursor to after the X in FOX
+>>>     'a'  to insert  JUMPED   (then press ESC)
+>>>     'A'  to insert  DOGS.  (then press ESC)
+>>>  Now move to the sentence fragment and make the changes outlined above.
+
+
+JOINING LINES
+-------------
+Often it is convenient to join two short lines into one line.  There
+are several ways to do this.  The easiest is the  J  command.  Other
+methods will be explored in tutorial #5.
+
+        'J'       JOIN two lines
+
+>>>  Go to the first line in the block below.  Type J.  Type J again.
+
+        Example: NOW IS THE TIME
+        the walrus said
+        TO THINK OF MANY THINGS
+
+In the event that joining lines creates a line which exceeds the width
+of the screen, you can break the line by typing  i  and pressing RETURN.
+
+
+SUBSTITUTING TEXT
+-----------------
+Substituting combines the delete command and the insert command into a
+single step.
+
+        #'s'      SUBSTITUTE for # characters
+        #'S'      SUBSTITUTE for # whole lines
+
+
+In order to substitute text you have to know how much text you want to
+delete.  Consider the following examples:
+
+        '3''s'      SUBSTITUTE the next 3 characters for what will be typed
+        '7''s'      SUBSTITUTE the next 7 characters for what will be typed
+
+>>>  Change the SAMPLE DEFINITION below.  To do this:
+>>>     move the cursor to the T in TWO
+>>>     type  '3's
+>>>     type  FOUR  then press ESC
+
+     SAMPLE DEFINITION:  A string quartet is defined to be
+                         a group of TWO musicians.
+
+
+REPLACING TEXT
+--------------
+The  'r'  and  'R'  commands allow you to directly type over existing text.
+
+        'r'       REPLACE character (NO need to press ESC)
+        'R'       enter over-type mode
+
+>>>  Correct each of the TYPOs on the sample line below.  To do this:
+>>>     move the cursor to the misspelled character
+>>>     type  'r'
+>>>     type  the correct character
+
+     SAMPLE: maintanence  conveniance  complience  applience  dilagent
+
+>>>  Use the over-type command,  'R'  ,  on the sample line above.
+>>>  Type  'R'  then type the name of a local restaurant.  Press ESC.
+
+
+CHANGING TEXT
+-------------
+The change command combines insertion, deletion, and the movement
+commands. (Recall that the movement commands were taught in tutorial
+#2.)  Change is probably more useful than replace or substitute.  The
+general form of the change command is:
+
+    'c'movement   CHANGE to where the movement command specifies
+
+Consider the following examples:
+
+        'c''w'      CHANGE to the beginning of the next WORD
+        'c''$'      CHANGE to the end of the line
+        'c'')'      CHANGE to the beginning of the next sentence
+        'c''t'e     CHANGE 'TIL the next  e
+        'c''3''w'     CHANGE the next 3 WORDS
+        'c''c'      CHANGE a line (cc is a special case of the c command)
+        'c''}'      CHANGE to the end of the paragraph
+
+>>>  Follow these steps:
+>>>     1.  move to the desired location in the practice paragraph below
+>>>     2.  type 'c''w'  (change to the beginning of the next WORD)
+>>>     3.  type your name
+>>>     4.  press ESC
+
+    PRACTICE here.  Now is the time for all good users to learn the
+    editor.  The quick red fox jumped over the seven lazy fish.  Now
+    is the time for all good users to learn the editor.  The quick
+    brown computer jumped over the seven lazy users.  END PRACTICE
+
+>>>  Experiment by using a variety of options for step #2.  Try
+>>>  out   'c''$'  'c'')'  'c''t'e  'c''3''w'  'c''c'  'c''}'   on the practice paragraph above.
+
+Note that the change command follows the same pattern as the delete
+and yank commands which were explored in tutorial #3.
+
+
+SUMMARY
+-------
+
+        'o'       OPEN a line below the cursor
+        'O'       OPEN a line above the cursor
+
+        'i'       INSERT starting before the cursor
+        'I'       INSERT at the beginning of the line
+
+        'a'       APPEND starting after the cursor
+        'A'       APPEND at the end of the line
+
+        ESC     ESCAPE from insert mode
+
+        'J'       JOIN two lines
+
+        #'s'      SUBSTITUTE for # characters
+        #'S'      SUBSTITUTE for # whole lines
+
+        'r'       REPLACE character (NO need to press ESC)
+        'R'       enter over-type mode
+
+    'c'movement   CHANGE to where the movement commands specifies
+                (e.g.  'c''3''w'  'c''$'  'c''c' )
+
+
+These commands should improve your ability to insert text efficiently.
+The next tutorials deal with advanced commands and tricks which can
+further speed up your editing.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
diff --git a/nxhtml/etc/viper-tut/5tricks b/nxhtml/etc/viper-tut/5tricks
new file mode 100644
index 0000000..c1e414e
--- /dev/null
+++ b/nxhtml/etc/viper-tut/5tricks
@@ -0,0 +1,229 @@
+Viper tutorial #5: Tricks and Timesavers
+
+This lesson lasts 10-15 minutes.  You should have a strong
+understanding of tutorials #1-3 before working through these timesaving
+techniques.  Lines which begin with  >>>  mark exercises you should
+try.  When you want to exit this tutorial type  'Z''Z' .
+
+
+CASE CONVERSION
+---------------
+When you want to change an upper-case character to a lower-case
+character (or lower-case to upper-case) there is a single command which
+does both:
+
+        '~'     (tilde) Convert case of current character
+
+>>>  Move the cursor to be OVER the first character in the example
+>>>  line below.  Press  '~'  until you have changed the case of the
+>>>  entire line.  (  '~'  will advance to the right automatically).
+
+        bOB WENT TO pARIS, fRANCE, TO SEE THE #1 CYCLING EVENT.  end.
+
+Note that  '~'  only affects alphabetic characters.
+
+
+UNDOING
+-------
+* EMACS-NOTICE: Uppercase U does the same thing as lowercase u in
+  Viper so this part of the tutorial which was about U has been
+  removed.
+
+
+REPEAT LAST COMMAND
+-------------------
+Often you want to make the same change at multiple locations in the
+file.  To help accomplish this, vi remembers your previous action.
+
+        '.'       (dot) repeat last change
+
+>>> Go through the example below changing "FISH" to "TOAD":
+>>>     Go to the "F" in the first instance of "FISH"
+>>>     To change the word:  type  'c''w'  then type  TOAD  then press ESC
+>>>     Move the cursor to "F" in the second occurence of "FISH"
+>>>     Type  '.'  (dot)
+>>>     Move the cursor to "F" in the final occurence of "FISH"
+>>>     Type  '.'  (dot)
+>>>     Now move the cursor to each occurence of "CROW";  Type  '.'  (dot)
+
+        EXAMPLE:  The FISH fed the cat.  The CROW fed the cat.  Example
+        text is FISH to make interesting.  The man fed the CROW.  The
+        worm fed the FISH.  Example text is hard to make CROW.  END.
+
+>>> Go through the example above deleting all occurences of "TOAD":
+>>>     Move to the beginning of the EXAMPLE paragraph above.
+>>>     Type  '/''T''O''A''D'  and press RETURN (recall tutorial #2)
+>>>     Delete the word by typing  'd''w'
+>>>     Type  'n'  to move to the next occurence of "TOAD"
+>>>     Type  '.'  (dot) to repeat the  dw  command
+>>>     Use  'n''.'  to delete the remaining "TOAD"s
+
+Note that  '.'  only repeats changes, not cursor movements.
+
+* EMACS-NOTICE: In Emacs  '.'  also repeat undo and redo.
+
+* EMACS-NOTICE: Emacs KEYBOARD-MACROS are very powerful for repeating
+  whole sequences of keyboard commands.
+
+
+WINDOW ACTIONS
+--------------
+You are already familiar with the  C-u  (depress the control key and
+type u) and C-d  commands from tutorial #1.
+
+        C-d     Move DOWN one half-screen
+        C-u     Move UP one half-screen
+
+There are several related commands:
+
+        C-f     Move FORWARD one full-screen
+        C-b     Move BACKWARD one full-screen
+
+        C-e     Move the window down one line without moving cursor
+        C-y     Move the window up one line without moving cursor
+
+The  C-e  and  C-y  commands may seem obscure; however, notice that on
+the keyboard,  e and  y  are close to  d  and  u  respectively.  This
+should help you remember that  C-e  moves DOWN, and  C-y  moves UP.
+
+Recall the  'H'  'M'  'L'  (HIGH MIDDLE LOW) window commands from Tutorial 2.
+Consider a scenario where you want to yank from the current line to a
+line near the top of the window.  You could use  C-e  and  C-y  to
+position the text in the window before you use the  yH  command.
+
+The  'z'  command also moves the window without moving your cursor:
+
+    'z'   Position the current line to top of window
+        'z''.'      Position the current line to middle of window
+        'z''-'      Position the current line to bottom of window
+
+>>>     Move to this line.  Type  'z'  and press RETURN.  Notice that
+>>>     this text and the cursor have moved to the top of the window.
+>>>     Try  'z''-'  and  'z''.'  also.
+
+
+FILE AND DISPLAY CONTROL
+------------------------
+
+* EMACS-NOTICE: In vi C-g shows the status of the current file, but
+  C-g in Emacs in most situation stops what Emacs is doing. To get
+  information about the current file you can use C-c C-g instead when
+  Viper is in vi state.
+
+* EMACS-NOTICE: In vi C-l refreshes the screen, but C-l in Emacs calls
+  the command recenter.
+
+
+SUSPENDING VI
+-------------
+* EMACS-NOTICE: In vi C-z suspends vi. However in Viper C-z is by
+  default the VIPER-TOGGLE-KEY. To suspend or iconify Emacs use C-x
+  C-z.
+
+
+BANG COMMAND
+------------
+* EMACS-NOTICE: Emacs has builtin commands to sort etc.
+
+The exclamation point,  '!'  (aka BANG), command allows you to feed text
+to any Unix command.  The output of the Unix command replaces the
+original text.  Here is a useful Unix command to use from within vi:
+
+        !}fmt   Format the paragraph, joining and filling lines to
+                produce output lines of up to 72 characters
+
+>>>  Move to the example paragraph below. Type  !}fmt  and press
+>>>  RETURN.  Notice the paragraph will be reformatted such that
+>>>  the lines are of approximately equal length.
+
+        EXAMPLE:
+        So we grow together,
+        Like to a double cherry, seeming parted,
+        But yet an union in partition;
+        Two lovely berries moulded on one stem;
+        So, with two seeming bodies, but one heart;
+        END.
+
+Another useful command is:
+
+       !}sort   Sort lines of a paragraph alphabetically
+
+>>>  Move to the example text below. Type  !}sort  and press RETURN.
+
+        OBERON          king of the fairies.
+        PUCK            or Robin Goodfellow.
+        HERMIA          daughter to Egeus, in love with Lysander.
+        HELENA          in love with Demetrius.
+        LYSANDER        in love with Hermia.
+        DEMETRIUS       in love with Hermia.
+
+Remember, any Unix command may be used this way.
+
+
+SHIFTING TEXT
+-------------
+It is possible to shift large blocks of text right and left with the '>'
+and  '<'  commands.
+
+   '>'movement    Shift right to where the movement command specifies
+   '<'movement    Shift left to where the movement command specifies
+
+These commands work like the  'd'  command.  For example:
+
+        '>''}'      Shift right to the end of the paragraph
+        '<''}'      Shift left to the end of the paragraph
+        '>''>'      Shift the current line right
+        '<''<'      Shift the current line left
+
+>>>  Move the cursor to the first line of the paragraph below.
+>>>  Type  '>''>'  and  '<''<'  to shift the line back and forth.  Next
+>>>  try  '>''}'  to shift the paragraph to the right, then  '<''}'  to shift
+>>>  it left, then type  '.'  until all four lines start at the left edge.
+
+        THIS IS THE FIRST LINE OF EXAMPLE TEXT
+            IS
+    EXAMPLE
+                TEXT END
+
+
+SUMMARY
+-------
+
+        '~'       (tilde) Convert case of current character
+
+        'U'       * EMACS-NOTICE: Same as lowercase u undo in Viper.
+
+        '.'       (dot) repeat last change
+
+        C-d      Move DOWN one half-screen
+                (depress the control key and type d)
+
+        C-u      Move UP one half-screen
+                (depress the control key and type u)
+
+        C-f     Move FORWARD one full-screen
+        C-b     Move BACKWARD one full-screen
+
+        C-e     Move the window down one line without moving cursor
+        C-y     Move the window up one line without moving cursor
+
+    'z'   Position the current line to top of window
+        'z''.'      Position the current line to middle of window
+        'z''-'      Position the current line to bottom of window
+
+    C-c C-g     Show status of current file
+        C-l     Recenter
+
+        '!'}fmt   Format the paragraph, joining and filling lines to
+                produce output lines of up to 72 characters
+
+       '!'}sort   Sort lines of a paragraph alphabetically
+
+   '>'movement    Shift right to where the movement command specifies
+   '<'movement    Shift left to where the movement command specifies
+
+
+These commands should significantly speed up your editing. Have a nice
+day.  Tutorial 6 contains even more nifty commands.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
diff --git a/nxhtml/etc/viper-tut/README b/nxhtml/etc/viper-tut/README
new file mode 100644
index 0000000..dd39176
--- /dev/null
+++ b/nxhtml/etc/viper-tut/README
@@ -0,0 +1,49 @@
+Viper Tutorial README
+=====================
+
+To install the Viper tutorial you must do two things:
+
+1) Put viper-tutorial.el in your Emacs load-path.
+
+2) Put the tutorial files (0intro, 1basics etc) in subdirectory to
+   where you put viper-tutorial.el with the name viper-tut.
+   Optionally you may put those file any where and customize the
+   option viper-tut-directory.
+
+The tutorial is started by
+
+  M-x viper-tutorial RET
+
+
+
+
+Viper tutorial is based on vilearn version 1.0 which was downloaded
+from http://vilearn.org.
+
+Below is the original readme from vilearn. Note that the only part
+that applies here is the copyright notice.
+
+---------------------------------------------------
+This is version 1.0 of vilearn, an interactive vi tutorial.
+
+Copyright (c) 1992 Jill Kliger and Wesley Craig.  All Rights Reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appears in all copies and that
+the copyright notice, this permission notice, and an explicit record of
+any local changes, appear in supporting documentation.  This software
+is supplied as is without expressed or implied warranties of any kind.
+
+To install, edit the Makefile and type
+
+	make install
+
+We have a mailing list, vilearn-admins@terminator.rs.itd.umich.edu. To
+be added to the list, send mail to vilearn-admins-request.  The list is
+intended to discuss the tutorials, coordinate projects relating to
+them, and provide help to those who may need it.
+
+Wesley Craig & Jill Kliger
+1317 Packard Street		vilearn@terminator.rs.itd.umich.edu
+Ann Arbor, MI 48104
diff --git a/nxhtml/etc/viper-tut/outline b/nxhtml/etc/viper-tut/outline
new file mode 100644
index 0000000..9eaa3e4
--- /dev/null
+++ b/nxhtml/etc/viper-tut/outline
@@ -0,0 +1,131 @@
+
+*
+* tutorial 1		FILENAME:  1basics
+*	basics
+*
+
+C-d	down
+C-u	up
+
+h	left
+j	down
+k	up
+l	right
+
+dd	delete line
+x	x-out character
+
+u	undo
+
+:q!	force quit
+ZZ	good bye
+
+o	open
+i	insert
+
+*
+* tutorial 2		FILENAME:  2moving
+*	objects, finds & marks
+*
+
+w W	word
+b B	back
+e E	end
+
+{ }	paragraph
+( )	sentence
+[ ]	sections
+
+$	end of line
+^	first non-white
+|	column
+0	beginning of line
+
+f F	find
+t T	to
+;	repeat fFtT
+,	reverse fFtT
+
+G	goto
+
+H	high
+M	middle
+L	low
+
+n N	next
+? /	regex
+
+%	match
+
+'	move to marked line
+m	mark
+
+
+*
+* tutorial 3		FILENAME:  3cutpaste & 3temp
+*
+*	cutting, pasting, buffers, and files
+*
+
+d D	deletes
+y Y	yank
+p P	put
+"	buffer
+:e	edit
+
+*
+* tutorial 4		FILENAME: 4inserting
+*	insertion
+*
+
+a A	append
+c C	change
+i I	insert
+o O	open
+r R	replace
+s S	substitute
+
+J	join
+
+*
+* tutorial 5		FILENAME: 5tricks
+*	tricks
+*
+
+~	case
+
+u U	undo
+
+.	do again
+
+C-b	back
+C-f	forward
+C-e	down line
+C-y	up line
+z	zero
+
+C-g	status
+C-l	refresh
+
+C-z	suspend
+
+C-t	pop tag		proposed
+C-]	follow tag	proposed
+
+!	command
+
+< >	shift
+
+*
+* tutorial 6		PROPOSED
+*	commands from hell
+*
+
+:	colon commands
+Q	quit
+C-r	redraw
+@	execute buffer as macro
+&	like :&
+
+C-t	shift (insert)
+C-d	unshift (insert)
diff --git a/nxhtml/nxhtml-base.el b/nxhtml/nxhtml-base.el
new file mode 100644
index 0000000..d768a5e
--- /dev/null
+++ b/nxhtml/nxhtml-base.el
@@ -0,0 +1,150 @@
+;;; nxhtml-base.el --- The very, very basic vars...
+;;
+;; Author: Lennart Borgman (lennart O borgman A gmail O com)
+;; Created: 2010-01-13 Wed
+;; Version:
+;; Last-Updated:
+;; URL:
+;; Keywords:
+;; Compatibility:
+;;
+;; Features that might be required by this library:
+;;
+;;   None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Things that always must be loaded and that are often necessary when
+;; byte compiling.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 3, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+;;(eval-when-compile (require 'web-vcs nil t))
+(eval-when-compile (require 'flymake-js nil t))
+(eval-when-compile (require 'flymake-css nil t))
+(eval-when-compile (require 'flymake-java-1 nil t))
+
+(defconst nxhtml-menu:version "2.08")
+(setq message-log-max t)
+(setq debug-on-error t)
+
+(defconst nxhtml-install-dir
+  (file-name-directory (or load-file-name
+                           (when (boundp 'bytecomp-filename) bytecomp-filename)
+                           buffer-file-name))
+  "Installation directory for nXhtml.")
+
+(define-minor-mode nxhtml-autoload-web
+  "If on download elisp files from web when they are needed.
+If t then during `require' nXhtml elisp files can be downloaded
+from the nXhtml repository on the web.  This will currently
+download the development sources, latest version.
+
+Other files that are used by a command may also be downloaded.
+
+Note that files are not updated automatically.  You have to use
+`nxhtml-update-existing-files' for that."
+  :global t
+  ;;:lighter (propertize " nX" 'face 'font-lock-comment-face)
+  :lighter " nX"
+  :group 'nxhtml)
+
+(defun nxhtml-autoload (fun src &optional docstring interactive type)
+  "Generalized `autoload'. May setup autoload from the web.
+If `nxhtml-autoload-web' is t then setup autoloading from the web.
+Otherwise setup for normal local autoloading."
+  (if nxhtml-autoload-web
+      (progn
+        ;; Do not require this until we really need it.
+        (require 'web-autoload)
+        (web-autoload fun src docstring interactive type))
+    (let ((file src))
+      (when (listp file)
+        (setq file (file-name-nondirectory (nth 2 file))))
+      (autoload fun file docstring interactive type))))
+
+;; Fix-me: web autoload defcustoms.
+;;
+;; I have no good idea how to fix this. It looks like I have to
+;; defadvice `custom-load-symbol'. I thought that should not be
+;; necessary since it does (require load) on line 605 but the web
+;; autoload does not start. Why? Hm, you never know since it is inside
+;; a (condition-case nil ...).
+;;
+;; Ah, found it. The require is only done if custom loads contains a
+;; symbol, not a string. So I changed this to a symbol instead in
+;; nxhtml-loaddefs.el. Maybe `load' instead of `require' should be
+;; advised?
+
+;; What a hell is this below? Have things been rewritten in custom or
+;; did I mix somethintg?
+(defun nxhtml-custom-autoload (symbol load &optional noset)
+  "Like `custom-autoload', but also run :set for defcustoms etc."
+  ;; Fix-me: is-boundp is currently always t because of the order in
+  ;; loaddefs. Hm, so this worked just by chance...
+  (let* ((is-boundp (prog1 (boundp symbol)
+                      (custom-autoload symbol load noset)))
+         (standard (get symbol 'standard-value))
+         (saved (get symbol 'saved-value))
+         ;; Fix-me: property custom-set etc are not available
+         (custom-set (get symbol 'custom-set))
+         (custom-initialize (get symbol 'custom-initialize))
+         (set (or custom-set 'custom-set-default))) ;; Fix-me: initialize
+    (setq custom-set t) ;; Not available here
+    (when (or custom-initialize
+              (and saved
+                   (not (equal (car saved) (symbol-value symbol)))
+                   custom-set))
+      (funcall set symbol (car saved))
+      (custom-load-symbol symbol))))
+
+(defun flymake-init-load-flymakemsg ()
+  (require 'flymakemsg))
+
+(define-minor-mode nxhtml-flymake-setup
+  "Let nXhtml add some addtions to flymake.
+This adds support for CSS and JavaScript files.
+
+It also adds showing of errors in minibuffer when point is on
+them.
+
+If you turn this off you must restart Emacs for it to take
+effect."
+  :group 'nxhtml
+  :group 'flymake
+  (when nxhtml-flymake-setup
+    (flymake-js-load)
+    (flymake-css-load)
+    (flymake-java-1-load)
+    (add-hook 'flymake-mode-hook 'flymake-init-load-flymakemsg)))
+
+
+(provide 'nxhtml-base)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; nxhtml-base.el ends here
diff --git a/nxhtml/nxhtml-loaddefs.el b/nxhtml/nxhtml-loaddefs.el
new file mode 100644
index 0000000..bfa98ee
--- /dev/null
+++ b/nxhtml/nxhtml-loaddefs.el
@@ -0,0 +1,4490 @@
+;; Autoloads for nXthml
+;;
+;; This file should be updated by `nxhtmlmaint-get-file-autoloads',
+;; `nxhtmlmaint-get-dir-autoloads' or `nxhtmlmaint-get-all-autoloads'.
+(eval-when-compile (require 'nxhtml-base))
+(eval-when-compile (require 'web-vcs))
+
+;;;### (autoloads (cancel-secondary-selection set-secondary-selection
+;;;;;;  anchored-transpose) "anchored-transpose" "util/anchored-transpose.el"
+;;;;;;  (19333 54924))
+;;; Generated autoloads from util/anchored-transpose.el
+(web-autoload-require 'anchored-transpose 'lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'anchored-transpose `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\
+Transpose portions of the region around an anchor phrase.
+
+`this phrase but not that word'    can be transposed into
+`that word but not this phrase'
+
+I want this phrase but not that word.
+       |----------------------------|. .This is the entire phrase.
+                  |-------|. . . . . . .This is the anchor phrase.
+
+First select the entire phrase and type \\[anchored-transpose].
+This set the secondary selection.
+
+Then select the anchor phrase and type \\[anchored-transpose]
+again.  Alternatively you can do the selections like this:
+
+I want this phrase but not that word.
+       |----------|       |---------|   Separate phrase selection.
+
+By default the anchor phrase will automatically include
+any surrounding whitespace even if you don't explicitly select
+it.  Also, it won't include certain trailing punctuation.  See
+`anchored-transpose-do-fuzzy' for details.  A prefix arg prior to
+either selection means `no fuzzy logic, use selections
+literally'.
+
+You can select the regions to be swapped separately in any
+order.
+
+After swapping both primary and secondary selection are still
+active.  They will be canceled after second next command if you
+do not swap regions again.  (Second because this allow you to
+adjust the regions and try again.)
+
+You can also swap text between different buffers this way.
+
+Typing \\[anchored-transpose] with nothing selected clears any
+prior selection, ie secondary selection.
+
+\(fn BEG1 END1 FLG1 &optional BEG2 END2 FLG2 WIN2)" t nil)
+
+(nxhtml-autoload 'set-secondary-selection `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\
+Set the secondary selection to the current region.
+This must be bound to a mouse drag event.
+
+\(fn BEG END)" t nil)
+
+(nxhtml-autoload 'cancel-secondary-selection `(lp '(nxhtml-download-root-url nil) "util/anchored-transpose" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (appmenu-mode appmenu-add appmenu) "appmenu" "util/appmenu.el"
+;;;;;;  (19275 63380))
+;;; Generated autoloads from util/appmenu.el
+(web-autoload-require 'appmenu 'lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'appmenu 'custom-loads))) (if (member '"appmenu" loads) nil (put 'appmenu 'custom-loads (cons '"appmenu" loads))))
+
+(nxhtml-autoload 'appmenu-add `(lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir) "\
+Add entry to `appmenu-alist'.
+Add an entry to this list with ID, PRIORITY, TEST, TITLE and
+DEFINITION as explained there.
+
+\(fn ID PRIORITY TEST TITLE DEFINITION)" nil nil)
+
+(defvar appmenu-mode nil "\
+Non-nil if Appmenu mode is enabled.
+See the command `appmenu-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `appmenu-mode'.")
+
+(nxhtml-custom-autoload 'appmenu-mode 'appmenu nil)
+
+(nxhtml-autoload 'appmenu-mode `(lp '(nxhtml-download-root-url nil) "util/appmenu" nxhtml-install-dir) "\
+Use a context sensitive popup menu.
+AppMenu (appmenu.el) is a framework for creating cooperative
+context sensitive popup menus with commands from different major
+and minor modes. Using this different modes may cooperate about
+the use of popup menus.
+
+There is also the command `appmenu-as-help' that shows the key
+bindings at current point in the help buffer.
+
+The popup menu and the help buffer version are on these keys:
+
+\\{appmenu-mode-map}
+
+The variable `appmenu-alist' is where the popup menu entries
+comes from.
+
+If there is a `keymap' property at point then relevant bindings
+from this is also shown in the popup menu.
+
+You can write functions that use whatever information you want in
+Emacs to construct these entries. Since this information is only
+collected when the popup menu is shown you do not have to care as
+much about computation time as for entries in the menu bar.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (as-external-mode as-external-for-wiki as-external-for-mail-mode
+;;;;;;  as-external-for-xhtml as-external) "as-external" "util/as-external.el"
+;;;;;;  (19292 49706))
+;;; Generated autoloads from util/as-external.el
+(web-autoload-require 'as-external 'lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'as-external 'custom-loads))) (if (member '"as-external" loads) nil (put 'as-external 'custom-loads (cons '"as-external" loads))))
+
+(nxhtml-autoload 'as-external-for-xhtml `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\
+Setup for Firefox addon It's All Text to edit XHTML.
+It's All Text is a Firefox add-on for editing textareas with an
+external editor.
+See URL `https://addons.mozilla.org/en-US/firefox/addon/4125'.
+
+In this case Emacs is used to edit textarea fields on a web page.
+The text will most often be part of a web page later, like on a
+blog.  Therefore turn on these:
+
+- `nxhtml-mode' since some XHTML tags may be allowed.
+- `nxhtml-validation-header-mode' since it is not a full page.
+- `wrap-to-fill-column-mode' to see what you are writing.
+- `html-write-mode' to see it even better.
+
+Also bypass the question for line end conversion when using
+emacsw32-eol.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'as-external-for-mail-mode `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\
+Setup for Firefox addon It's All Text to edit mail.
+Set normal mail comment markers in column 1 (ie >).
+
+Set `fill-column' to 90 and enable `wrap-to-fill-column-mode' so
+that it will look similar to how it will look in the sent plain
+text mail.
+
+See also `as-external-mode'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'as-external-for-wiki `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\
+Setup for Firefox addon It's All Text to edit MediaWikis.
+
+\(fn)" t nil)
+
+(defvar as-external-mode nil "\
+Non-nil if As-External mode is enabled.
+See the command `as-external-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `as-external-mode'.")
+
+(nxhtml-custom-autoload 'as-external-mode 'as-external nil)
+
+(nxhtml-autoload 'as-external-mode `(lp '(nxhtml-download-root-url nil) "util/as-external" nxhtml-install-dir) "\
+If non-nil check if Emacs is called as external editor.
+When Emacs is called as an external editor for example to edit
+text areas on a web page viewed with Firefox this library tries
+to help to setup the buffer in a useful way. It may for example
+set major and minor modes for the buffer.
+
+This can for example be useful when blogging or writing comments
+on blogs.
+
+See `as-external-alist' for more information.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (buffer-bg-set-color) "buffer-bg" "util/buffer-bg.el"
+;;;;;;  (19254 64104))
+;;; Generated autoloads from util/buffer-bg.el
+(web-autoload-require 'buffer-bg 'lp '(nxhtml-download-root-url nil) "util/buffer-bg" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'buffer-bg-set-color `(lp '(nxhtml-download-root-url nil) "util/buffer-bg" nxhtml-install-dir) "\
+Add an overlay with background color COLOR to buffer BUFFER.
+If COLOR is nil remove previously added overlay.
+
+\(fn COLOR BUFFER)" t nil)
+
+;;;***
+
+;;;### (autoloads (chartg-make-chart chartg-complete) "chartg" "util/chartg.el"
+;;;;;;  (19278 15746))
+;;; Generated autoloads from util/chartg.el
+(web-autoload-require 'chartg 'lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'chartg-complete `(lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'chartg-make-chart `(lp '(nxhtml-download-root-url nil) "util/chartg" nxhtml-install-dir) "\
+Try to make a new chart.
+If region is active then make a new chart from data in the
+selected region.
+
+Else if current buffer is in `chartg-mode' then do it from the
+chart specifications in this buffer.  Otherwise create a new
+buffer and initialize it with `chartg-mode'.
+
+If the chart specifications are complete enough to make a chart
+then do it and show the resulting chart image.  If not then tell
+user what is missing.
+
+NOTE: This is beta, no alpha code. It is not ready.
+
+Below are some examples.  To test them mark an example and do
+
+  M-x chartg-make-chart
+
+* Example, simple x-y chart:
+
+  Output-file: \"~/temp-chart.png\"
+  Size: 200 200
+  Data: 3 8 5 | 10 20 30
+  Type: line-chartg-xy
+
+* Example, pie:
+
+  Output-file: \"~/temp-depression.png\"
+  Size: 400 200
+  Data:
+  2,160,000
+  3,110,000
+  1,510,000
+  73,600
+  775,000
+  726,000
+  8,180,000
+  419,000
+  Type: pie-3-dimensional
+  Chartg-title: \"Depression hits on Google\"
+  Legends:
+  \"SSRI\"
+  | \"Psychotherapy\"
+  | \"CBT\"
+  | \"IPT\"
+  | \"Psychoanalysis\"
+  | \"Mindfulness\"
+  | \"Meditation\"
+  | \"Exercise\"
+
+
+* Example, pie:
+
+  Output-file: \"~/temp-panic.png\"
+  Size: 400 200
+  Data:
+  979,000
+  969,000
+  500,000
+  71,900
+  193,000
+  154,000
+  2,500,000
+  9,310,000
+  Type: pie-3-dimensional
+  Chartg-title: \"Depression hits on Google\"
+  Legends:
+  \"SSRI\"
+  | \"Psychotherapy\"
+  | \"CBT\"
+  | \"IPT\"
+  | \"Psychoanalysis\"
+  | \"Mindfulness\"
+  | \"Meditation\"
+  | \"Exercise\"
+
+
+* Example using raw:
+
+  Output-file: \"~/temp-chartg-slipsen-kostar.png\"
+  Size: 400 130
+  Data: 300 1000 30000
+  Type: bar-chartg-horizontal
+  Chartg-title: \"Vad killen i slips tjänar jämfört med dig och mig\"
+  Google-chartg-raw: \"&chds=0,30000&chco=00cd00|ff4500|483d8b&chxt=y,x&chxl=0:|Killen+i+slips|Partiledarna|Du+och+jag&chf=bg,s,ffd700\"
+
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (css-color-test css-color-global-mode css-color-mode
+;;;;;;  css-color) "css-color" "util/css-color.el" (19386 34254))
+;;; Generated autoloads from util/css-color.el
+(web-autoload-require 'css-color 'lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'css-color 'custom-loads))) (if (member '"css-color" loads) nil (put 'css-color 'custom-loads (cons '"css-color" loads))))
+
+(nxhtml-autoload 'css-color-mode `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\
+Show hex color literals with the given color as background.
+In this mode hexadecimal colour specifications like #6600ff are
+displayed with the specified colour as background.
+
+Certain keys are bound to special colour editing commands when
+point is at a hexadecimal colour:
+
+\\{css-color-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar css-color-global-mode nil "\
+Non-nil if Css-Color-Global mode is enabled.
+See the command `css-color-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `css-color-global-mode'.")
+
+(nxhtml-custom-autoload 'css-color-global-mode 'css-color nil)
+
+(nxhtml-autoload 'css-color-global-mode `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\
+Toggle Css-Color mode in every possible buffer.
+With prefix ARG, turn Css-Color-Global mode on if and only if
+ARG is positive.
+Css-Color mode is enabled in all buffers where
+`css-color-turn-on-in-buffer' would do it.
+See `css-color-mode' for more information on Css-Color mode.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'css-color-test `(lp '(nxhtml-download-root-url nil) "util/css-color" nxhtml-install-dir) "\
+Test colors interactively.
+The colors are displayed in the echo area. You can specify the
+colors as any viable css color.  Example:
+
+  red
+  #f00
+  #0C0
+  #b0ff00
+  hsla(100, 50%, 25%)
+  rgb(255,100,120)
+
+\(fn FG-COLOR BG-COLOR)" t nil)
+
+;;;***
+
+;;;### (autoloads (css-palette-global-mode css-palette css-palette-mode)
+;;;;;;  "css-palette" "util/css-palette.el" (19235 1650))
+;;; Generated autoloads from util/css-palette.el
+(web-autoload-require 'css-palette 'lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'css-palette-mode `(lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir) "\
+Minor mode for palettes in CSS.
+
+The mode `css-palette-mode' acts on the first COLORS declaration in your
+  file of the form:
+
+COLORS:
+\(
+c0 \"#6f5d25\"	;tainted sand
+c1 \"#000000\"	;Black
+c2 \"#cca42b\"	;goldenslumber
+c3 \"#6889cb\"	;far off sky
+c4 \"#fff\"	;strange aeons
+)
+
+Such declarations should appear inside a block comment, in order
+  to be parsed properly by the LISP reader.
+
+Type \\[css-palette-update-all], and any occurence of
+
+  color: #f55; /*[c3]*/
+
+will be updated with
+
+  color: #6899cb; /*[c3]*/
+
+The following commands are available to insert key-value pairs
+  and palette declarations:
+  \\{css-palette-mode-map}
+
+You can extend or redefine the types of palettes by defining a
+  new palette specification of the form (PATTERN REGEXP
+  REF-FOLLOWS-VALUE), named according to the naming scheme
+  css-palette:my-type, where
+
+PATTERN is a pattern containing two (%s) format directives which
+  will be filled in with the variable and its value,
+
+REGEXP is a regular expression to match a value - variable
+  pattern,
+
+and REF-FOLLOWS-VALUE defined whether or not the reference comes
+  after the value. This allows for more flexibility.
+
+Note that, although the w3c spec at URL
+  `http://www.w3.org/TR/CSS2/syndata.html#comments' says that
+  comments \" may occur anywhere between tokens, and their
+  contents have no influence on the rendering\", Internet
+  Explorer does not think so. Better keep all your comments after
+  a \"statement\", as per the default. This means `css-palette'
+  is ill-suited for use within shorthands.
+
+See variable `css-palette:colors' for an example of a palette
+  type.
+
+The extension mechanism means that palette types can be used to
+  contain arbitrary key-value mappings.
+
+Besides the colors palette, css-palette defines the palette
+  definition variables `css-palette:colors-outside' and
+  `css-palette:files', for colors with the reference outside and
+  for file url()'s respectively.
+
+You can fine-control which palette types css-palette should look
+  at via the variable `css-palette-types'.
+
+\(fn &optional ARG)" t nil)
+
+(let ((loads (get 'css-palette 'custom-loads))) (if (member '"css-palette" loads) nil (put 'css-palette 'custom-loads (cons '"css-palette" loads))))
+
+(defvar css-palette-global-mode nil "\
+Non-nil if Css-Palette-Global mode is enabled.
+See the command `css-palette-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `css-palette-global-mode'.")
+
+(nxhtml-custom-autoload 'css-palette-global-mode 'css-palette nil)
+
+(nxhtml-autoload 'css-palette-global-mode `(lp '(nxhtml-download-root-url nil) "util/css-palette" nxhtml-install-dir) "\
+Toggle Css-Palette mode in every possible buffer.
+With prefix ARG, turn Css-Palette-Global mode on if and only if
+ARG is positive.
+Css-Palette mode is enabled in all buffers where
+`css-palette-turn-on-in-buffer' would do it.
+See `css-palette-mode' for more information on Css-Palette mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (cusnu-export-my-skin-options customize-for-new-user)
+;;;;;;  "cus-new-user" "util/cus-new-user.el" (19173 56140))
+;;; Generated autoloads from util/cus-new-user.el
+(web-autoload-require 'cus-new-user 'lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'customize-for-new-user `(lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir) "\
+Show special customization page for new user.
+
+\(fn &optional NAME)" t nil)
+
+(nxhtml-autoload 'cusnu-export-my-skin-options `(lp '(nxhtml-download-root-url nil) "util/cus-new-user" nxhtml-install-dir) "\
+Export to file FILE custom options in `cusnu-my-skin-options'.
+The options is exported to elisp code that other users can run to
+set the options that you have added to `cusnu-my-skin-options'.
+
+For more information about this see `cusnu-export-cust-group'.
+
+\(fn FILE)" t nil)
+
+;;;***
+
+;;;### (autoloads (ediff-url) "ediff-url" "util/ediff-url.el" (19362
+;;;;;;  34258))
+;;; Generated autoloads from util/ediff-url.el
+(web-autoload-require 'ediff-url 'lp '(nxhtml-download-root-url nil) "util/ediff-url" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'ediff-url `(lp '(nxhtml-download-root-url nil) "util/ediff-url" nxhtml-install-dir) "\
+Compare current buffer to a web URL using `ediff-buffers'.
+Check URL using `ediff-url-redirects' before fetching the file.
+
+This is for checking downloaded file.  A the file may have a comment
+telling the download URL of thise form in the header:
+
+   ;; URL: http://the-server.net/the-path/the-file.el
+
+If not the user is asked for the URL.
+
+\(fn URL)" t nil)
+
+;;;***
+
+;;;### (autoloads (ffip-find-file-in-dirtree ffip-set-current-project)
+;;;;;;  "ffip" "util/ffip.el" (19257 25432))
+;;; Generated autoloads from util/ffip.el
+(web-autoload-require 'ffip 'lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'ffip-set-current-project `(lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir) "\
+Setup ffip project NAME with top directory ROOT of type TYPE.
+ROOT can either be just a directory or a list of directory where
+the first used just for prompting purposes and the files in the
+rest are read into the ffip project.
+
+Type is a type in `ffip-project-file-types'.
+
+\(fn NAME ROOT TYPE)" nil nil)
+
+(nxhtml-autoload 'ffip-find-file-in-dirtree `(lp '(nxhtml-download-root-url nil) "util/ffip" nxhtml-install-dir) "\
+Find files in directory tree ROOT.
+
+\(fn ROOT)" t nil)
+
+;;;***
+
+;;;### (autoloads (fold-dwim-turn-on-outline-and-hide-all fold-dwim-turn-on-hs-and-hide
+;;;;;;  fold-dwim-unhide-hs-and-outline fold-dwim-mode fold-dwim-toggle
+;;;;;;  fold-dwim) "fold-dwim" "util/fold-dwim.el" (19218 42180))
+;;; Generated autoloads from util/fold-dwim.el
+(web-autoload-require 'fold-dwim 'lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'fold-dwim 'custom-loads))) (if (member '"fold-dwim" loads) nil (put 'fold-dwim 'custom-loads (cons '"fold-dwim" loads))))
+
+(nxhtml-autoload 'fold-dwim-toggle `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\
+Toggle visibility or some other visual things.
+Try toggling different visual things in this order:
+
+- Images shown at point with `inlimg-mode'
+- Text at point prettified by `html-write-mode'.
+
+For the rest it unhides if possible, otherwise hides in this
+order:
+
+- `org-mode' header or something else using that outlines.
+- Maybe `fold-dwim-toggle-selective-display'.
+- `Tex-fold-mode' things.
+- In html if `outline-minor-mode' and after heading hide content.
+- `hs-minor-mode' things.
+- `outline-minor-mode' things. (Turns maybe on this.)
+
+It uses `fold-dwim-show' to show any hidden text at point; if no
+hidden fold is found, try `fold-dwim-hide' to hide the
+construction at the cursor.
+
+Note: Also first turn on `fold-dwim-mode' to get the keybinding
+for this function from it.
+
+\(fn)" t nil)
+
+(defvar fold-dwim-mode nil "\
+Non-nil if Fold-Dwim mode is enabled.
+See the command `fold-dwim-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `fold-dwim-mode'.")
+
+(nxhtml-custom-autoload 'fold-dwim-mode 'fold-dwim nil)
+
+(nxhtml-autoload 'fold-dwim-mode `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\
+Key binding for `fold-dwim-toggle'.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'fold-dwim-unhide-hs-and-outline `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\
+Unhide everything hidden by Hide/Show and Outline.
+Ie everything hidden by `hs-minor-mode' and
+`outline-minor-mode'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'fold-dwim-turn-on-hs-and-hide `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\
+Turn on minor mode `hs-minor-mode' and hide.
+If major mode is derived from `nxml-mode' call `hs-hide-block'
+else call `hs-hide-all'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'fold-dwim-turn-on-outline-and-hide-all `(lp '(nxhtml-download-root-url nil) "util/fold-dwim" nxhtml-install-dir) "\
+Turn on `outline-minor-mode' and call `hide-body'.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (foldit-global-mode foldit-mode foldit) "foldit"
+;;;;;;  "util/foldit.el" (19275 63380))
+;;; Generated autoloads from util/foldit.el
+(web-autoload-require 'foldit 'lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'foldit 'custom-loads))) (if (member '"foldit" loads) nil (put 'foldit 'custom-loads (cons '"foldit" loads))))
+
+(nxhtml-autoload 'foldit-mode `(lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir) "\
+Minor mode providing visual aids for folding.
+Shows some hints about what you have hidden and how to reveal it.
+
+Supports `hs-minor-mode', `outline-minor-mode' and major modes
+derived from `outline-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar foldit-global-mode nil "\
+Non-nil if Foldit-Global mode is enabled.
+See the command `foldit-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `foldit-global-mode'.")
+
+(nxhtml-custom-autoload 'foldit-global-mode 'foldit nil)
+
+(nxhtml-autoload 'foldit-global-mode `(lp '(nxhtml-download-root-url nil) "util/foldit" nxhtml-install-dir) "\
+Toggle Foldit mode in every possible buffer.
+With prefix ARG, turn Foldit-Global mode on if and only if
+ARG is positive.
+Foldit mode is enabled in all buffers where
+`(lambda nil (foldit-mode 1))' would do it.
+See `foldit-mode' for more information on Foldit mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (gimpedit-can-edit gimpedit-edit-buffer gimpedit-edit-file
+;;;;;;  gimpedit) "gimpedit" "util/gimpedit.el" (19275 63380))
+;;; Generated autoloads from util/gimpedit.el
+(web-autoload-require 'gimpedit 'lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'gimpedit 'custom-loads))) (if (member '"gimpedit" loads) nil (put 'gimpedit 'custom-loads (cons '"gimpedit" loads))))
+
+(nxhtml-autoload 'gimpedit-edit-file `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\
+Edit IMAGE-FILE with GIMP.
+See also `gimpedit-edit-file'.
+
+\(fn IMAGE-FILE &optional EXTRA-ARGS)" t nil)
+
+(nxhtml-autoload 'gimpedit-edit-buffer `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\
+Edit image file in current buffer with GIMP.
+See also `gimpedit-edit-file'.
+
+You may also be interested in gimpedit-mode with which you can edit
+gimp files from within Emacs using GIMP's scripting
+possibilities. See
+
+  URL `http://www.emacswiki.org/emacs/GimpMode'
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'gimpedit-can-edit `(lp '(nxhtml-download-root-url nil) "util/gimpedit" nxhtml-install-dir) "\
+Not documented
+
+\(fn FILE-NAME)" nil nil)
+
+;;;***
+
+;;;### (autoloads (gpl-mode) "gpl" "util/gpl.el" (18795 27308))
+;;; Generated autoloads from util/gpl.el
+(web-autoload-require 'gpl 'lp '(nxhtml-download-root-url nil) "util/gpl" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'gpl-mode `(lp '(nxhtml-download-root-url nil) "util/gpl" nxhtml-install-dir) "\
+Mode for font-locking and editing color palettes of the GPL format.
+
+Such palettes are used and produced by free software applications
+such as the GIMP, Inkscape, Scribus, Agave and on-line tools such
+as http://colourlovers.com.
+
+You can also use
+URL `http://niels.kicks-ass.org/public/elisp/css-palette.el' to import
+such palette into a css-file as hexadecimal color palette.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (hfyview-frame hfyview-window hfyview-region hfyview-buffer
+;;;;;;  hfyview-quick-print-in-files-menu) "hfyview" "util/hfyview.el"
+;;;;;;  (19400 17335))
+;;; Generated autoloads from util/hfyview.el
+(web-autoload-require 'hfyview 'lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(defvar hfyview-quick-print-in-files-menu nil "\
+Add Quick print entries to File menu if non-nil.
+If you set this to nil you have to restart Emacs to get rid of
+the Quick Print entry.")
+
+(nxhtml-custom-autoload 'hfyview-quick-print-in-files-menu 'hfyview nil)
+
+(nxhtml-autoload 'hfyview-buffer `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\
+Convert buffer to html preserving faces and show in web browser.
+With command prefix ARG also show html source in other window.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'hfyview-region `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\
+Convert region to html preserving faces and show in web browser.
+With command prefix ARG also show html source in other window.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'hfyview-window `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\
+Convert window to html preserving faces and show in web browser.
+With command prefix ARG also show html source in other window.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'hfyview-frame `(lp '(nxhtml-download-root-url nil) "util/hfyview" nxhtml-install-dir) "\
+Convert frame to html preserving faces and show in web browser.
+Make an XHTML view of the current Emacs frame. Put it in a buffer
+named *hfyview-frame* and show that buffer in a web browser.
+
+If WHOLE-BUFFERS is non-nil then the whole content of the buffers
+is shown in the XHTML page, otherwise just the part that is
+visible currently on the frame.
+
+If you turn on the minor mode `hfyview-frame-mode' you can also
+get the minibuffer/echo area in the output. See this mode for
+details.
+
+With command prefix also show html source in other window.
+
+\(fn WHOLE-BUFFERS)" t nil)
+
+;;;***
+
+;;;### (autoloads (hl-needed-mode hl-needed) "hl-needed" "util/hl-needed.el"
+;;;;;;  (19394 16942))
+;;; Generated autoloads from util/hl-needed.el
+(web-autoload-require 'hl-needed 'lp '(nxhtml-download-root-url nil) "util/hl-needed" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'hl-needed 'custom-loads))) (if (member '"hl-needed" loads) nil (put 'hl-needed 'custom-loads (cons '"hl-needed" loads))))
+
+(defvar hl-needed-mode nil "\
+Non-nil if Hl-Needed mode is enabled.
+See the command `hl-needed-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `hl-needed-mode'.")
+
+(nxhtml-custom-autoload 'hl-needed-mode 'hl-needed nil)
+
+(nxhtml-autoload 'hl-needed-mode `(lp '(nxhtml-download-root-url nil) "util/hl-needed" nxhtml-install-dir) "\
+Try to highlight current line and column when needed.
+This is a global minor mode.  It can operate in some different
+ways:
+
+- Highlighting can be on always, see `hl-needed-always'.
+
+Or, it can be turned on depending on some conditions.  In this
+case highlighting is turned off after each command and turned on
+again in the current window when either:
+
+- A new window was selected, see `hl-needed-on-new-window'.
+- A new buffer was selected, see `hl-needed-on-new-buffer'.
+- Window configuration was changed, see `hl-needed-on-config-change'.
+- Buffer was scrolled see `hl-needed-on-scrolling'.
+- A window was clicked with the mouse, see `hl-needed-on-mouse'.
+
+After this highlighting may be turned off again, normally after a
+short delay, see `hl-needed-flash'.
+
+If either highlighting was not turned on or was turned off again
+it will be turned on when
+
+- Emacs has been idle for `hl-needed-idle-time' seconds.
+
+See also `hl-needed-not-in-modes' and `hl-needed-currently-fun'.
+
+Note 1: For columns to be highlighted vline.el must be available.
+
+Note 2: This mode depends on `hl-line-mode' and `vline-mode' and
+tries to cooperate with them. If you turn on either of these that
+overrides the variables for turning on the respective
+highlighting here.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (html-write-mode html-write) "html-write" "util/html-write.el"
+;;;;;;  (19275 63380))
+;;; Generated autoloads from util/html-write.el
+(web-autoload-require 'html-write 'lp '(nxhtml-download-root-url nil) "util/html-write" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-write 'custom-loads))) (if (member '"html-write" loads) nil (put 'html-write 'custom-loads (cons '"html-write" loads))))
+
+(nxhtml-autoload 'html-write-mode `(lp '(nxhtml-download-root-url nil) "util/html-write" nxhtml-install-dir) "\
+Minor mode for convenient display of some HTML tags.
+When this mode is on a tag in `html-write-tag-list' is displayed as
+the inner text of the tag with a face corresponding to the tag.
+By default for example ... is displayed as italic and
+... is displayed as an underlined clickable link.
+
+Only non-nested tags are hidden.  The idea is just that it should
+be easier to read and write, not that it should look as html
+rendered text.
+
+See the customization group `html-write' for more information about
+faces.
+
+The following keys are defined when you are on a tag handled by
+this minor mode:
+
+\\{html-write-keymap}
+
+IMPORTANT: Most commands you use works also on the text that is
+hidden.  The movement commands is an exception, but as soon as
+you edit the buffer you may also change the hidden parts.
+
+Hint: Together with `wrap-to-fill-column-mode' this can make it
+easier to see what text you are actually writing in html parts of
+a web file.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (inlimg-toggle-slicing inlimg-toggle-display inlimg-global-mode
+;;;;;;  inlimg-mode inlimg) "inlimg" "util/inlimg.el" (19269 33008))
+;;; Generated autoloads from util/inlimg.el
+(web-autoload-require 'inlimg 'lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'inlimg 'custom-loads))) (if (member '"inlimg" loads) nil (put 'inlimg 'custom-loads (cons '"inlimg" loads))))
+
+(nxhtml-autoload 'inlimg-mode `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\
+Display images inline.
+Search buffer for image tags.  Display found images.
+
+Image tags are setup per major mode in `inlimg-mode-specs'.
+
+Images are displayed on a line below the tag referencing them.
+The whole image or a slice of it may be displayed, see
+`inlimg-slice'.  Margins relative text are specified in
+`inlimg-margins'.
+
+See also the commands `inlimg-toggle-display' and
+`inlimg-toggle-slicing'.
+
+Note: This minor mode uses `font-lock-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar inlimg-global-mode nil "\
+Non-nil if Inlimg-Global mode is enabled.
+See the command `inlimg-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `inlimg-global-mode'.")
+
+(nxhtml-custom-autoload 'inlimg-global-mode 'inlimg nil)
+
+(nxhtml-autoload 'inlimg-global-mode `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\
+Toggle Inlimg mode in every possible buffer.
+With prefix ARG, turn Inlimg-Global mode on if and only if
+ARG is positive.
+Inlimg mode is enabled in all buffers where
+`inlimg--global-turn-on' would do it.
+See `inlimg-mode' for more information on Inlimg mode.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'inlimg-toggle-display `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\
+Toggle display of image at point POINT.
+See also the command `inlimg-mode'.
+
+\(fn POINT)" t nil)
+
+(nxhtml-autoload 'inlimg-toggle-slicing `(lp '(nxhtml-download-root-url nil) "util/inlimg" nxhtml-install-dir) "\
+Toggle slicing of image at point POINT.
+See also the command `inlimg-mode'.
+
+\(fn POINT)" t nil)
+
+;;;***
+
+;;;### (autoloads (majmodpri majmodpri-apply-priorities majmodpri-apply
+;;;;;;  majmodpri-sort-lists) "majmodpri" "util/majmodpri.el" (19407
+;;;;;;  18407))
+;;; Generated autoloads from util/majmodpri.el
+(web-autoload-require 'majmodpri 'lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'majmodpri-sort-lists `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\
+Sort the list used when selecting major mode.
+Only sort those lists choosen in `majmodpri-lists-to-sort'.
+Sort according to priorities in `majmodpri-mode-priorities'.
+Keep the old order in the list otherwise.
+
+The lists can be sorted when loading elisp libraries, see
+`majmodpri-sort-after-load'.
+
+See also `majmodpri-apply-priorities'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'majmodpri-apply `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\
+Sort major mode lists and apply to existing buffers.
+Note: This function is suitable to add to
+`desktop-after-read-hook'. It will restore the multi major modes
+in buffers.
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'majmodpri-apply-priorities `(lp '(nxhtml-download-root-url nil) "util/majmodpri" nxhtml-install-dir) "\
+Apply major mode priorities.
+First run `majmodpri-sort-lists' and then if CHANGE-MODES is
+non-nil apply to existing file buffers.  If interactive ask
+before applying.
+
+\(fn CHANGE-MODES)" t nil)
+
+(let ((loads (get 'majmodpri 'custom-loads))) (if (member '"majmodpri" loads) nil (put 'majmodpri 'custom-loads (cons '"majmodpri" loads))))
+
+;;;***
+
+;;;### (autoloads (markchars-global-mode markchars-mode markchars)
+;;;;;;  "markchars" "util/markchars.el" (19372 5886))
+;;; Generated autoloads from util/markchars.el
+(web-autoload-require 'markchars 'lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'markchars 'custom-loads))) (if (member '"markchars" loads) nil (put 'markchars 'custom-loads (cons '"markchars" loads))))
+
+(nxhtml-autoload 'markchars-mode `(lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir) "\
+Mark special characters.
+Which characters to mark are defined by `markchars-keywords'.
+
+The default is to mark non-IDN, non-ascii chars with a magenta
+underline.
+
+For information about IDN chars see `idn-is-recommended'.
+
+If you change anything in the customization group `markchars' you
+must restart this minor mode for the changes to take effect.
+
+\(fn &optional ARG)" t nil)
+
+(defvar markchars-global-mode nil "\
+Non-nil if Markchars-Global mode is enabled.
+See the command `markchars-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `markchars-global-mode'.")
+
+(nxhtml-custom-autoload 'markchars-global-mode 'markchars nil)
+
+(nxhtml-autoload 'markchars-global-mode `(lp '(nxhtml-download-root-url nil) "util/markchars" nxhtml-install-dir) "\
+Toggle Markchars mode in every possible buffer.
+With prefix ARG, turn Markchars-Global mode on if and only if
+ARG is positive.
+Markchars mode is enabled in all buffers where
+`(lambda nil (markchars-mode 1))' would do it.
+See `markchars-mode' for more information on Markchars mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (mlinks-global-mode mlinks-mode mlinks) "mlinks"
+;;;;;;  "util/mlinks.el" (19364 56214))
+;;; Generated autoloads from util/mlinks.el
+(web-autoload-require 'mlinks 'lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'mlinks 'custom-loads))) (if (member '"mlinks" loads) nil (put 'mlinks 'custom-loads (cons '"mlinks" loads))))
+
+(nxhtml-autoload 'mlinks-mode `(lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir) "\
+Recognizes certain parts of a buffer as hyperlinks.
+The hyperlinks are created in different ways for different major
+modes with the help of the functions in the list
+`mlinks-mode-functions'.
+
+The hyperlinks can be hilighted when point is over them.  Use
+`mlinks-toggle-hilight' to toggle this feature for the current
+buffer.
+
+All keybindings in this mode are by default done under the prefi§x
+key
+
+  C-c RET
+
+which is supposed to be a kind of mnemonic for link (alluding to
+the RET key commonly used in web browser to follow a link).
+\(Unfortunately this breaks the rules in info node `Key Binding
+Conventions'.) Below are the key bindings defined by this mode:
+
+\\{mlinks-mode-map}
+
+For some major modes `mlinks-backward-link' and
+`mlinks-forward-link' will take you to the previous/next link.
+By default the link moved to will be active, see
+`mlinks-active-links'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar mlinks-global-mode nil "\
+Non-nil if Mlinks-Global mode is enabled.
+See the command `mlinks-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `mlinks-global-mode'.")
+
+(nxhtml-custom-autoload 'mlinks-global-mode 'mlinks nil)
+
+(nxhtml-autoload 'mlinks-global-mode `(lp '(nxhtml-download-root-url nil) "util/mlinks" nxhtml-install-dir) "\
+Toggle Mlinks mode in every possible buffer.
+With prefix ARG, turn Mlinks-Global mode on if and only if
+ARG is positive.
+Mlinks mode is enabled in all buffers where
+`mlinks-turn-on-in-buffer' would do it.
+See `mlinks-mode' for more information on Mlinks mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (mumamo-multi-major-modep mumamo-list-defined-multi-major-modes
+;;;;;;  mumamo-mark-for-refontification mumamo-hi-lock-faces mumamo
+;;;;;;  mumamo-add-to-defined-multi-major-modes define-mumamo-multi-major-mode)
+;;;;;;  "mumamo" "util/mumamo.el" (19412 26290))
+;;; Generated autoloads from util/mumamo.el
+(web-autoload-require 'mumamo 'lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'define-mumamo-multi-major-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\
+Define a function that turn on support for multiple major modes.
+Define a function FUN-SYM that set up to divide the current
+buffer into chunks with different major modes.
+
+The documentation string for FUN-SYM should contain the special
+documentation in the string SPEC-DOC, general documentation for
+functions of this type and information about chunks.
+
+The new function will use the definitions in CHUNKS (which is
+called a \"chunk family\") to make the dividing of the buffer.
+
+The function FUN-SYM can be used to setup a buffer instead of a
+major mode function:
+
+- The function FUN-SYM can be called instead of calling a major
+  mode function when you want to use multiple major modes in a
+  buffer.
+
+- The defined function can be used instead of a major mode
+  function in for example `auto-mode-alist'.
+
+- As the very last thing FUN-SYM will run the hook FUN-SYM-hook,
+  just as major modes do.
+
+- There is also a general hook, `mumamo-turn-on-hook', which is
+  run when turning on mumamo with any of these functions.  This
+  is run right before the hook specific to any of the functions
+  above that turns on the multiple major mode support.
+
+- The multi major mode FUN-SYM has a keymap named FUN-SYM-map.
+  This overrides the major modes' keymaps since it is handled as
+  a minor mode keymap.
+
+- There is also a special mumamo keymap, `mumamo-map' that is
+  active in every buffer with a multi major mode.  This is also
+  handled as a minor mode keymap and therefor overrides the major
+  modes' keymaps.
+
+- However when this support for multiple major mode is on the
+  buffer is divided into chunks, each with its own major mode.
+
+- The chunks are fontified according the major mode assigned to
+  them for that.
+
+- Indenting is also done according to the major mode assigned to
+  them for that.
+
+- The actual major mode used in the buffer is changed to the one
+  in the chunk when moving point between these chunks.
+
+- When major mode is changed the hooks for the new major mode,
+  `after-change-major-mode-hook' and `change-major-mode-hook' are
+  run.
+
+- There will be an alias for FUN-SYM called mumamo-alias-FUN-SYM.
+  This can be used to check whic multi major modes have been
+  defined.
+
+** A little bit more technical description:
+
+The dividing of a buffer into chunks is done during fontification
+by `mumamo-get-chunk-at'.
+
+The name of the function is saved in in the buffer local variable
+`mumamo-multi-major-mode' when the function is called.
+
+All functions defined by this macro is added to the list
+`mumamo-defined-multi-major-modes'.
+
+Basically Mumamo handles only major modes that uses jit-lock.
+However as a special effort also `nxml-mode' and derivatives
+thereof are handled.  Since it seems impossible to me to restrict
+those major modes fontification to only a chunk without changing
+`nxml-mode' the fontification is instead done by
+`html-mode'/`sgml-mode' for chunks using `nxml-mode' and its
+derivates.
+
+CHUNKS is a list where each entry have the format
+
+  (CHUNK-DEF-NAME MAIN-MAJOR-MODE SUBMODE-CHUNK-FUNCTIONS)
+
+CHUNK-DEF-NAME is the key name by which the entry is recognized.
+MAIN-MAJOR-MODE is the major mode used when there is no chunks.
+If this is nil then `major-mode' before turning on this mode will
+be used.
+
+SUBMODE-CHUNK-FUNCTIONS is a list of the functions that does the
+chunk division of the buffer.  They are tried in the order they
+appear here during the chunk division process.
+
+If you want to write new functions for chunk divisions then
+please see `mumamo-find-possible-chunk'.  You can perhaps also
+use `mumamo-quick-static-chunk' which is more easy-to-use
+alternative.  See also the file mumamo-fun.el where there are
+many routines for chunk division.
+
+When you write those new functions you may want to use some of
+the functions for testing chunks:
+
+ `mumamo-test-create-chunk-at'  `mumamo-test-create-chunks-at-all'
+ `mumamo-test-easy-make'        `mumamo-test-fontify-region'
+
+These are in the file mumamo-test.el.
+
+\(fn FUN-SYM SPEC-DOC CHUNKS)" nil (quote macro))
+
+(nxhtml-autoload 'mumamo-add-to-defined-multi-major-modes `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\
+Not documented
+
+\(fn ENTRY)" nil nil)
+
+(let ((loads (get 'mumamo 'custom-loads))) (if (member '"mumamo" loads) nil (put 'mumamo 'custom-loads (cons '"mumamo" loads))))
+
+(let ((loads (get 'mumamo-hi-lock-faces 'custom-loads))) (if (member '"mumamo" loads) nil (put 'mumamo-hi-lock-faces 'custom-loads (cons '"mumamo" loads))))
+
+(nxhtml-autoload 'mumamo-mark-for-refontification `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\
+Mark region between MIN and MAX for refontification.
+
+\(fn MIN MAX)" nil nil)
+
+(nxhtml-autoload 'mumamo-list-defined-multi-major-modes `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\
+List currently defined multi major modes.
+If SHOW-DOC is non-nil show the doc strings added when defining
+them. (This is not the full doc string. To show the full doc
+string you can click on the multi major mode in the list.)
+
+If SHOW-CHUNKS is non-nil show the names of the chunk dividing
+functions each multi major mode uses.
+
+If MATCH then show only multi major modes whos names matches.
+
+\(fn SHOW-DOC SHOW-CHUNKS MATCH)" t nil)
+
+(nxhtml-autoload 'mumamo-multi-major-modep `(lp '(nxhtml-download-root-url nil) "util/mumamo" nxhtml-install-dir) "\
+Return t if VALUE is a multi major mode function.
+
+\(fn VALUE)" nil nil)
+
+;;;***
+
+;;;### (autoloads (python-rst-mumamo-mode latex-haskell-mumamo-mode
+;;;;;;  latex-clojure-mumamo-mode markdown-html-mumamo-mode xsl-sgml-mumamo-mode
+;;;;;;  xsl-nxml-mumamo-mode mako-html-mumamo-mode org-mumamo-mode
+;;;;;;  asp-html-mumamo-mode noweb2-mumamo-mode mumamo-noweb2 csound-sgml-mumamo-mode
+;;;;;;  laszlo-nxml-mumamo-mode metapost-mumamo-mode ruby-heredoc-mumamo-mode
+;;;;;;  python-heredoc-mumamo-mode cperl-heredoc-mumamo-mode perl-heredoc-mumamo-mode
+;;;;;;  php-heredoc-mumamo-mode sh-heredoc-mumamo-mode eruby-javascript-mumamo-mode
+;;;;;;  eruby-html-mumamo-mode eruby-mumamo-mode jsp-html-mumamo-mode
+;;;;;;  gsp-html-mumamo-mode ssjs-html-mumamo-mode smarty-html-mumamo-mode
+;;;;;;  mjt-html-mumamo-mode genshi-html-mumamo-mode django-html-mumamo-mode
+;;;;;;  embperl-html-mumamo-mode mason-html-mumamo-mode nxml-mumamo-mode
+;;;;;;  html-mumamo-mode mumamo-define-html-file-wide-keys) "mumamo-fun"
+;;;;;;  "util/mumamo-fun.el" (19410 22971))
+;;; Generated autoloads from util/mumamo-fun.el
+(web-autoload-require 'mumamo-fun 'lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'mumamo-define-html-file-wide-keys `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Define keys in multi major mode keymap for html files.
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for (X)HTML with main mode `html-mode'.
+This covers inlined style and javascript and PHP." t)
+
+(nxhtml-autoload 'nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for (X)HTML with main mode `nxml-mode'.
+This covers inlined style and javascript and PHP.
+
+See also `mumamo-alt-php-tags-mode'." t)
+
+(nxhtml-autoload 'mason-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Mason using main mode `html-mode'.
+This covers inlined style and javascript." t)
+
+(nxhtml-autoload 'embperl-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Embperl files with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'django-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Django with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'genshi-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Genshi with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'mjt-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for MJT with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'smarty-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Smarty with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'ssjs-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for SSJS with main mode `html-mode'.
+This covers inlined style and javascript." t)
+
+(nxhtml-autoload 'gsp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for GSP with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'jsp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for JSP with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'eruby-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major mode for eRuby with unspecified main mode.
+Current major-mode will be used as the main major mode." t)
+
+(nxhtml-autoload 'eruby-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for eRuby with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'eruby-javascript-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for eRuby with main mode `javascript-mode'." t)
+
+(nxhtml-autoload 'sh-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for sh heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'php-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for PHP heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'perl-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Perl heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'cperl-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Perl heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'python-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Perl heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'ruby-heredoc-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Ruby heredoc document.
+See `mumamo-heredoc-modes' for how to specify heredoc major modes." t)
+
+(nxhtml-autoload 'metapost-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for MetaPost." t)
+
+(nxhtml-autoload 'laszlo-nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for OpenLaszlo." t)
+
+(nxhtml-autoload 'csound-sgml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on mutiple major modes for CSound orc/sco Modes." t)
+
+(let ((loads (get 'mumamo-noweb2 'custom-loads))) (if (member '"mumamo-fun" loads) nil (put 'mumamo-noweb2 'custom-loads (cons '"mumamo-fun" loads))))
+
+(nxhtml-autoload 'noweb2-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Multi major mode for noweb files." t)
+
+(nxhtml-autoload 'asp-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for ASP with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'org-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for `org-mode' files with main mode `org-mode'.
+** Note about HTML subchunks:
+Unfortunately this only allows `html-mode' (not `nxhtml-mode') in
+sub chunks." t)
+
+(nxhtml-autoload 'mako-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Mako with main mode `html-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'xsl-nxml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multi major mode for XSL with main mode `nxml-mode'.
+This covers inlined style and javascript." t)
+
+(nxhtml-autoload 'xsl-sgml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multi major mode for XSL with main mode `sgml-mode'.
+This covers inlined style and javascript." t)
+
+(nxhtml-autoload 'markdown-html-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multi major markdown mode in buffer.
+Main major mode will be `markdown-mode'.
+Inlined html will be in `html-mode'.
+
+You need `markdown-mode' which you can download from URL
+`http://jblevins.org/projects/markdown-mode/'." t)
+
+(nxhtml-autoload 'latex-clojure-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multi major mode latex+clojure.
+Main major mode will be `latex-mode'.
+Subchunks will be in `clojure-mode'.
+
+You will need `clojure-mode' which you can download from URL
+`http://github.com/jochu/clojure-mode/tree'." t)
+
+(nxhtml-autoload 'latex-haskell-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multi major mode latex+haskell.
+Main major mode will be `latex-mode'.
+Subchunks will be in `haskell-mode'.
+
+You will need `haskell-mode' which you can download from URL
+`http://projects.haskell.org/haskellmode-emacs/'." t)
+
+(nxhtml-autoload 'python-rst-mumamo-mode `(lp '(nxhtml-download-root-url nil) "util/mumamo-fun" nxhtml-install-dir) "\
+Turn on multiple major modes for Python with RestructuredText docstrings." t)
+
+;;;***
+
+;;;### (autoloads (mumamo-add-region-from-string mumamo-add-region)
+;;;;;;  "mumamo-regions" "util/mumamo-regions.el" (19275 63380))
+;;; Generated autoloads from util/mumamo-regions.el
+(web-autoload-require 'mumamo-regions 'lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'mumamo-add-region `(lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir) "\
+Add a mumamo region from selection.
+Mumamo regions are like another layer of chunks above the normal chunks.
+They does not affect the normal chunks, but they overrides them.
+
+To create a mumamo region first select a visible region and then
+call this function.
+
+If the buffer is not in a multi major mode a temporary multi
+major mode will be created applied to the buffer first.
+To get out of this and get back to a single major mode just use
+
+  M-x normal-mode
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'mumamo-add-region-from-string `(lp '(nxhtml-download-root-url nil) "util/mumamo-regions" nxhtml-install-dir) "\
+Add a mumamo region from string at point.
+Works as `mumamo-add-region' but for string or comment at point.
+
+Buffer must be fontified.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (n-back-game n-back) "n-back" "util/n-back.el"
+;;;;;;  (19278 15746))
+;;; Generated autoloads from util/n-back.el
+(web-autoload-require 'n-back 'lp '(nxhtml-download-root-url nil) "util/n-back" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'n-back 'custom-loads))) (if (member '"n-back" loads) nil (put 'n-back 'custom-loads (cons '"n-back" loads))))
+
+(nxhtml-autoload 'n-back-game `(lp '(nxhtml-download-root-url nil) "util/n-back" nxhtml-install-dir) "\
+Emacs n-Back game.
+This game is supposed to increase your working memory and fluid
+intelligence.
+
+In this game something is shown for half a second on the screen
+and maybe a sound is played.  You should then answer if parts of
+it is the same as you have seen or heard before.  This is
+repeated for about 20 trials.
+
+You answer with the keys shown in the bottom window.
+
+In the easiest version of the game you should answer if you have
+just seen or heard what is shown now.  By default the game gets
+harder as you play it with success.  Then first the number of
+items presented in a trial grows.  After that it gets harder by
+that you have to somehow remember not the last item, but the item
+before that (or even earlier). That is what \"n-Back\" stands
+for.
+
+Note that remember does not really mean remember clearly.  The
+game is for training your brain getting used to keep those things
+in the working memory, maybe as a cross-modal unit.  You are
+supposed to just nearly be able to do what you do in the game.
+And you are supposed to have fun, that is what your brain like.
+
+You should probably not overdue this. Half an hour a day playing
+might be an optimal time according to some people.
+
+The game is shamelessly modeled after Brain Workshop, see URL
+`http://brainworkshop.sourceforge.net/' just for the fun of
+getting it into Emacs.  The game resembles but it not the same as
+that used in the report by Jaeggi mentioned at the above URL.
+
+Not all features in Brain Workshop are implemented here, but some
+new are maybe ... - and you have it available here in Emacs.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (nxhtmltest-run nxhtmltest-run-indent) "nxhtmltest-suites"
+;;;;;;  "tests/nxhtmltest-suites.el" (19360 6294))
+;;; Generated autoloads from tests/nxhtmltest-suites.el
+(web-autoload-require 'nxhtmltest-suites 'lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtmltest-run-indent `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir) "\
+Run indentation tests.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'nxhtmltest-run `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-suites" nxhtml-install-dir) "\
+Run all tests defined for nXhtml.
+Currently there are only tests using ert.el defined.
+
+Note that it is currently expected that the following tests will
+fail (they corresponds to known errors in nXhtml/Emacs):
+
+  `nxhtml-ert-nxhtml-changes-jump-back-10549'
+  `nxhtml-ert-nxhtml-changes-jump-back-7014'
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (nxhtmltest-run-Q) "nxhtmltest-Q" "tests/nxhtmltest-Q.el"
+;;;;;;  (19264 36684))
+;;; Generated autoloads from tests/nxhtmltest-Q.el
+(web-autoload-require 'nxhtmltest-Q 'lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-Q" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtmltest-run-Q `(lp '(nxhtml-download-root-url nil) "tests/nxhtmltest-Q" nxhtml-install-dir) "\
+Run all tests defined for nXhtml in fresh Emacs.
+See `nxhtmltest-run' for more information about the tests.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (ert-run-tests-interactively ert-deftest) "ert"
+;;;;;;  "tests/ert.el" (19173 56140))
+;;; Generated autoloads from tests/ert.el
+(web-autoload-require 'ert 'lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'ert-deftest `(lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir) "\
+Define NAME (a symbol) as a test.
+
+\(fn NAME () [:documentation DOCSTRING] [:expected-result TYPE] BODY...)" nil (quote macro))
+
+(nxhtml-autoload 'ert-run-tests-interactively `(lp '(nxhtml-download-root-url nil) "tests/ert" nxhtml-install-dir) "\
+Run the tests specified by SELECTOR and display the results in a buffer.
+
+\(fn SELECTOR &optional OUTPUT-BUFFER-NAME MESSAGE-FN)" t nil)
+
+;;;***
+
+;;;### (autoloads (ocr-user-mode) "ocr-user" "util/ocr-user.el" (19290
+;;;;;;  21626))
+;;; Generated autoloads from util/ocr-user.el
+(web-autoload-require 'ocr-user 'lp '(nxhtml-download-root-url nil) "util/ocr-user" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'ocr-user-mode `(lp '(nxhtml-download-root-url nil) "util/ocr-user" nxhtml-install-dir) "\
+Color up digits three by three.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (ourcomments-warning ourcomments-M-x-menu-mode
+;;;;;;  ourcomments-paste-with-convert-mode use-custom-style info-open-file
+;;;;;;  replace-read-files rdir-query-replace ldir-query-replace
+;;;;;;  grep-query-replace emacs-Q-nxhtml emacs-Q emacs--no-desktop
+;;;;;;  emacs--debug-init emacs-buffer-file emacs emacs-restart ourcomments-ido-ctrl-tab
+;;;;;;  ourcomments-ido-buffer-raise-frame ourcomments-ido-buffer-other-frame
+;;;;;;  ourcomments-ido-buffer-other-window describe-symbol describe-defstruct
+;;;;;;  describe-custom-group narrow-to-comment buffer-narrowed-p
+;;;;;;  describe-command ourcomments-ediff-files find-emacs-other-file
+;;;;;;  ourcomments-insert-date-and-time describe-timers ourcomments-copy+paste-set-point
+;;;;;;  better-fringes-mode describe-key-and-map-briefly ourcomments-move-end-of-line
+;;;;;;  ourcomments-move-beginning-of-line ourcomments-mark-whole-buffer-or-field
+;;;;;;  fill-dwim unfill-individual-paragraphs unfill-region unfill-paragraph
+;;;;;;  define-toggle-old define-toggle popup-menu-at-point ourcomments-indirect-fun)
+;;;;;;  "ourcomments-util" "util/ourcomments-util.el" (19411 29548))
+;;; Generated autoloads from util/ourcomments-util.el
+(web-autoload-require 'ourcomments-util 'lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'ourcomments-indirect-fun `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Get the alias symbol for function FUN if any.
+
+\(fn FUN)" nil nil)
+
+(nxhtml-autoload 'popup-menu-at-point `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Popup the given menu at point.
+This is similar to `popup-menu' and MENU and PREFIX has the same
+meaning as there.  The position for the popup is however where
+the window point is.
+
+\(fn MENU &optional PREFIX)" nil nil)
+
+(nxhtml-autoload 'define-toggle `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Declare SYMBOL as a customizable variable with a toggle function.
+The purpose of this macro is to define a defcustom and a toggle
+function suitable for use in a menu.
+
+The arguments have the same meaning as for `defcustom' with these
+restrictions:
+
+- The :type keyword cannot be used.  Type is always 'boolean.
+- VALUE must be t or nil.
+
+DOC and ARGS are just passed to `defcustom'.
+
+A `defcustom' named SYMBOL with doc-string DOC and a function
+named SYMBOL-toggle is defined.  The function toggles the value
+of SYMBOL.  It takes no parameters.
+
+To create a menu item something similar to this can be used:
+
+    (define-key map [SYMBOL]
+      (list 'menu-item \"Toggle nice SYMBOL\"
+            'SYMBOL-toggle
+            :button '(:toggle . SYMBOL)))
+
+\(fn SYMBOL VALUE DOC &rest ARGS)" nil (quote macro))
+
+(nxhtml-autoload 'define-toggle-old `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Not documented
+
+\(fn SYMBOL VALUE DOC &rest ARGS)" nil (quote macro))
+
+(nxhtml-autoload 'unfill-paragraph `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Unfill the current paragraph.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'unfill-region `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Unfill the current region.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'unfill-individual-paragraphs `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Unfill individual paragraphs in the current region.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'fill-dwim `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Fill or unfill paragraph or region.
+With prefix ARG fill only current line.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'ourcomments-mark-whole-buffer-or-field `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Mark whole buffer or editable field at point.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'ourcomments-move-beginning-of-line `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Move point to beginning of line or indentation.
+See `beginning-of-line' for ARG.
+
+If `line-move-visual' is non-nil then the visual line beginning
+is first tried.
+
+If in a widget field stay in that.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'ourcomments-move-end-of-line `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Move point to end of line or after last non blank char.
+See `end-of-line' for ARG.
+
+Similar to `ourcomments-move-beginning-of-line' but for end of
+line.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'describe-key-and-map-briefly `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Try to print names of keymap from which KEY fetch its definition.
+Look in current active keymaps and find keymap variables with the
+same value as the keymap where KEY is bound.  Print a message
+with those keymap variable names.  Return a list with the keymap
+variable symbols.
+
+When called interactively prompt for KEY.
+
+INSERT and UNTRANSLATED should normall be nil (and I am not sure
+what they will do ;-).
+
+\(fn &optional KEY INSERT UNTRANSLATED)" t nil)
+
+(defvar better-fringes-mode nil "\
+Non-nil if Better-Fringes mode is enabled.
+See the command `better-fringes-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `better-fringes-mode'.")
+
+(nxhtml-custom-autoload 'better-fringes-mode 'ourcomments-util nil)
+
+(nxhtml-autoload 'better-fringes-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Choose another fringe bitmap color and bottom angle.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'ourcomments-copy+paste-set-point `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Set point for copy+paste here.
+Enable temporary minor mode `ourcomments-copy+paste-mode'.
+However if point for copy+paste already is set then cancel it and
+disable the minor mode.
+
+The purpose of this command is to make it easy to grab a piece of
+text and paste it at current position.  After this command you
+should select a piece of text to copy and then call the command
+`ourcomments-copy+paste'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'describe-timers `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Show timers with readable time format.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'ourcomments-insert-date-and-time `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Insert date and time.
+See option `ourcomments-insert-date-and-time' for how to
+customize it.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'find-emacs-other-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Find corresponding file to source or installed elisp file.
+If you have checked out and compiled Emacs yourself you may have
+Emacs lisp files in two places, the checked out source tree and
+the installed Emacs tree.  If buffer contains an Emacs elisp file
+in one of these places then find the corresponding elisp file in
+the other place. Return the file name of this file.
+
+Rename current buffer using your `uniquify-buffer-name-style' if
+it is set.
+
+When DISPLAY-FILE is non-nil display this file in other window
+and go to the same line number as in the current buffer.
+
+\(fn DISPLAY-FILE)" t nil)
+
+(nxhtml-autoload 'ourcomments-ediff-files `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+In directory DEF-DIR run `ediff-files' on files FILE-A and FILE-B.
+The purpose of this function is to make it eaiser to start
+`ediff-files' from a shell through Emacs Client.
+
+This is used in EmacsW32 in the file ediff.cmd where Emacs Client
+is called like this:
+
+  @%emacs_client% -e \"(setq default-directory \\\"%emacs_cd%\\\")\"
+  @%emacs_client% -n  -e \"(ediff-files \\\"%f1%\\\" \\\"%f2%\\\")\"
+
+It can of course be done in a similar way with other shells.
+
+\(fn DEF-DIR FILE-A FILE-B)" nil nil)
+
+(nxhtml-autoload 'describe-command `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Like `describe-function', but prompts only for interactive commands.
+
+\(fn COMMAND)" t nil)
+
+(nxhtml-autoload 'buffer-narrowed-p `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Return non-nil if the current buffer is narrowed.
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'narrow-to-comment `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'describe-custom-group `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Describe customization group SYMBOL.
+
+\(fn SYMBOL)" t nil)
+
+(nxhtml-autoload 'describe-defstruct `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Not documented
+
+\(fn SYMBOL)" t nil)
+
+(nxhtml-autoload 'describe-symbol `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Show information about SYMBOL.
+Show SYMBOL plist and whether is is a variable or/and a
+function.
+
+\(fn SYMBOL)" t nil)
+
+(nxhtml-autoload 'ourcomments-ido-buffer-other-window `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Show buffer in other window.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'ourcomments-ido-buffer-other-frame `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Show buffer in other frame.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'ourcomments-ido-buffer-raise-frame `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Raise frame showing buffer.
+
+\(fn)" t nil)
+
+(defvar ourcomments-ido-ctrl-tab nil "\
+Non-nil if Ourcomments-Ido-Ctrl-Tab mode is enabled.
+See the command `ourcomments-ido-ctrl-tab' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ourcomments-ido-ctrl-tab'.")
+
+(nxhtml-custom-autoload 'ourcomments-ido-ctrl-tab 'ourcomments-util nil)
+
+(nxhtml-autoload 'ourcomments-ido-ctrl-tab `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Enable buffer switching using C-Tab with function `ido-mode'.
+This changes buffer switching with function `ido-mode' the
+following way:
+
+- You can use C-Tab.
+
+- You can show the selected buffer in three ways independent of
+  how you entered function `ido-mode' buffer switching:
+
+  * S-return: other window
+  * C-return: other frame
+  * M-return: raise frame
+
+Those keys are selected to at least be a little bit reminiscent
+of those in for example common web browsers.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'emacs-restart `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Restart Emacs and start `server-mode' if on before.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'emacs `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start a new Emacs with default parameters.
+Additional ARGS are passed to the new Emacs.
+
+See also `ourcomments-started-emacs-use-output-buffer'.
+
+\(fn &rest ARGS)" t nil)
+
+(nxhtml-autoload 'emacs-buffer-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start a new Emacs showing current buffer file.
+Go to the current line and column in that file.
+If there is no buffer file then instead start with `dired'.
+
+This calls the function `emacs' with argument --no-desktop and
+the file or a call to dired.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'emacs--debug-init `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start a new Emacs with --debug-init parameter.
+This calls the function `emacs' with added arguments ARGS.
+
+\(fn &rest ARGS)" t nil)
+
+(nxhtml-autoload 'emacs--no-desktop `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start a new Emacs with --no-desktop parameter.
+This calls the function `emacs' with added arguments ARGS.
+
+\(fn &rest ARGS)" t nil)
+
+(nxhtml-autoload 'emacs-Q `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start a new Emacs with -Q parameter.
+Start new Emacs without any customization whatsoever.
+This calls the function `emacs' with added arguments ARGS.
+
+\(fn &rest ARGS)" t nil)
+
+(nxhtml-autoload 'emacs-Q-nxhtml `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Start new Emacs with -Q and load nXhtml.
+This calls the function `emacs' with added arguments ARGS.
+
+\(fn &rest ARGS)" t nil)
+
+(nxhtml-autoload 'grep-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Do `query-replace-regexp' of FROM with TO, on all files in *grep*.
+Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
+If you exit (\\[keyboard-quit], RET or q), you can resume the query replace
+with the command \\[tags-loop-continue].
+
+\(fn FROM TO &optional DELIMITED)" t nil)
+
+(nxhtml-autoload 'ldir-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Replace FROM with TO in FILES in directory DIR.
+This runs `query-replace-regexp' in files matching FILES in
+directory DIR.
+
+See `tags-query-replace' for DELIMETED and more information.
+
+\(fn FROM TO FILES DIR &optional DELIMITED)" t nil)
+
+(nxhtml-autoload 'rdir-query-replace `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Replace FROM with TO in FILES in directory tree ROOT.
+This runs `query-replace-regexp' in files matching FILES in
+directory tree ROOT.
+
+See `tags-query-replace' for DELIMETED and more information.
+
+\(fn FROM TO FILE-REGEXP ROOT &optional DELIMITED)" t nil)
+
+(nxhtml-autoload 'replace-read-files `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Read files arg for replace.
+
+\(fn REGEXP &optional REPLACE)" nil nil)
+
+(nxhtml-autoload 'info-open-file `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Open an info file in `Info-mode'.
+
+\(fn INFO-FILE)" t nil)
+
+(nxhtml-autoload 'use-custom-style `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Setup like in `Custom-mode', but without things specific to Custom.
+
+\(fn)" nil nil)
+
+(defvar ourcomments-paste-with-convert-mode nil "\
+Non-nil if Ourcomments-Paste-With-Convert mode is enabled.
+See the command `ourcomments-paste-with-convert-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ourcomments-paste-with-convert-mode'.")
+
+(nxhtml-custom-autoload 'ourcomments-paste-with-convert-mode 'ourcomments-util nil)
+
+(nxhtml-autoload 'ourcomments-paste-with-convert-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Pasted text may be automatically converted in this mode.
+The functions in `ourcomments-paste-with-convert-hook' are run
+after commands in `ourcomments-paste-with-convert-commands' if any
+of the functions returns non-nil that text is inserted instead of
+the original text.
+
+For exampel when this mode is on and you paste an html link in an
+`org-mode' buffer it will be directly converted to an org style
+link. (This is the default behaviour.)
+
+Tip: The Firefox plugin Copy as HTML Link is handy, see URL
+     `https://addons.mozilla.org/en-US/firefox/addon/2617'.
+
+Note: This minor mode will defadvice the paste commands.
+
+\(fn &optional ARG)" t nil)
+
+(defvar ourcomments-M-x-menu-mode nil "\
+Non-nil if Ourcomments-M-X-Menu mode is enabled.
+See the command `ourcomments-M-x-menu-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ourcomments-M-x-menu-mode'.")
+
+(nxhtml-custom-autoload 'ourcomments-M-x-menu-mode 'ourcomments-util nil)
+
+(nxhtml-autoload 'ourcomments-M-x-menu-mode `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Add commands started from Emacs menus to M-x history.
+The purpose of this is to make it easier to redo them and easier
+to learn how to do them from the command line (which is often
+faster if you know how to do it).
+
+Only commands that are not already in M-x history are added.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'ourcomments-warning `(lp '(nxhtml-download-root-url nil) "util/ourcomments-util" nxhtml-install-dir) "\
+Not documented
+
+\(fn FORMAT-STRING &rest ARGS)" nil nil)
+
+;;;***
+
+;;;### (autoloads (major-modep major-or-multi-majorp) "ourcomments-widgets"
+;;;;;;  "util/ourcomments-widgets.el" (19275 63380))
+;;; Generated autoloads from util/ourcomments-widgets.el
+(web-autoload-require 'ourcomments-widgets 'lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+ (nxhtml-autoload 'command "ourcomments-widgets")
+
+(nxhtml-autoload 'major-or-multi-majorp `(lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir) "\
+Return t if VALUE is a major or multi major mode function.
+
+\(fn VALUE)" nil nil)
+
+(nxhtml-autoload 'major-modep `(lp '(nxhtml-download-root-url nil) "util/ourcomments-widgets" nxhtml-install-dir) "\
+Return t if VALUE is a major mode function.
+
+\(fn VALUE)" nil nil)
+ (nxhtml-autoload 'major-mode-function "ourcomments-widgets")
+
+;;;***
+
+;;;### (autoloads (pause-start-in-new-emacs pause-mode pause) "pause"
+;;;;;;  "util/pause.el" (19335 58922))
+;;; Generated autoloads from util/pause.el
+(web-autoload-require 'pause 'lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'pause 'custom-loads))) (if (member '"pause" loads) nil (put 'pause 'custom-loads (cons '"pause" loads))))
+
+(defvar pause-mode nil "\
+Non-nil if Pause mode is enabled.
+See the command `pause-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `pause-mode'.")
+
+(nxhtml-custom-autoload 'pause-mode 'pause nil)
+
+(nxhtml-autoload 'pause-mode `(lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir) "\
+This minor mode tries to make you take a break.
+It will jump up and temporary stop your work - even if you are
+not in Emacs.  If you are in Emacs it will however try to be
+gentle and wait until you have been idle with the keyboard for a
+short while. (If you are not in Emacs it can't be gentle. How
+could it?)
+
+Then it will show you a special screen with a link to a yoga
+exercise you can do when you pause.
+
+After the pause you continue your work where you were
+interrupted.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'pause-start-in-new-emacs `(lp '(nxhtml-download-root-url nil) "util/pause" nxhtml-install-dir) "\
+Start pause with interval AFTER-MINUTES in a new Emacs instance.
+The new Emacs instance will be started with -Q.  However if
+`custom-file' is non-nil it will be loaded so you can still
+customize pause.
+
+One way of using this function may be to put in your .emacs
+something like
+
+  ;; for just one Emacs running pause
+  (when server-mode (pause-start-in-new-emacs 15))
+
+See `pause-start' for more info.
+
+\(fn AFTER-MINUTES)" t nil)
+
+;;;***
+
+;;;### (autoloads (global-pointback-mode pointback-mode) "pointback"
+;;;;;;  "util/pointback.el" (19023 47096))
+;;; Generated autoloads from util/pointback.el
+(web-autoload-require 'pointback 'lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'pointback-mode `(lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir) "\
+Restore previous window point when switching back to a buffer.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-pointback-mode nil "\
+Non-nil if Global-Pointback mode is enabled.
+See the command `global-pointback-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-pointback-mode'.")
+
+(nxhtml-custom-autoload 'global-pointback-mode 'pointback nil)
+
+(nxhtml-autoload 'global-pointback-mode `(lp '(nxhtml-download-root-url nil) "util/pointback" nxhtml-install-dir) "\
+Toggle Pointback mode in every possible buffer.
+With prefix ARG, turn Global-Pointback mode on if and only if
+ARG is positive.
+Pointback mode is enabled in all buffers where
+`pointback-on' would do it.
+See `pointback-mode' for more information on Pointback mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (popcmp-completing-read popcmp-completion-style
+;;;;;;  popcmp) "popcmp" "util/popcmp.el" (19365 33760))
+;;; Generated autoloads from util/popcmp.el
+(web-autoload-require 'popcmp 'lp '(nxhtml-download-root-url nil) "util/popcmp" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'popcmp 'custom-loads))) (if (member '"popcmp" loads) nil (put 'popcmp 'custom-loads (cons '"popcmp" loads))))
+
+(defvar popcmp-completion-style (cond (t 'popcmp-popup)) "\
+Completion style.
+The currently available completion styles are:
+
+- popcmp-popup: Use OS popup menus (default).
+- emacs-default: Emacs default completion.
+- Company Mode completion.
+- anything: The Anything elisp lib completion style.
+
+The style of completion set here is not implemented for all
+completions.  The scope varies however with which completion
+style you have choosen.
+
+For information about Company Mode and how to use it see URL
+`http://www.emacswiki.org/emacs/CompanyMode'.
+
+For information about Anything and how to use it see URL
+`http://www.emacswiki.org/emacs/Anything'.
+
+See also the options `popcmp-short-help-beside-alts' and
+`popcmp-group-alternatives' which are also availabe when popup
+completion is available.")
+
+(nxhtml-custom-autoload 'popcmp-completion-style 'popcmp nil)
+
+(nxhtml-autoload 'popcmp-completing-read `(lp '(nxhtml-download-root-url nil) "util/popcmp" nxhtml-install-dir) "\
+Read a string in the minubuffer with completion, or popup a menu.
+This function can be used instead `completing-read'. The main
+purpose is to provide a popup style menu for completion when
+completion is tighed to text at point in a buffer. If a popup
+menu is used it will be shown at window point. Whether a popup
+menu or minibuffer completion is used is governed by
+`popcmp-completion-style'.
+
+The variables PROMPT, TABLE, PREDICATE, REQUIRE-MATCH,
+INITIAL-INPUT, POP-HIST, DEF and INHERIT-INPUT-METHOD all have the
+same meaning is for `completing-read'.
+
+ALT-HELP should be nil or a hash variable or an association list
+with the completion alternative as key and a short help text as
+value.  You do not need to supply help text for all alternatives.
+The use of ALT-HELP is set by `popcmp-short-help-beside-alts'.
+
+ALT-SETS should be nil or an association list that has as keys
+groups and as second element an alternative that should go into
+this group.
+
+\(fn PROMPT TABLE &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT POP-HIST DEF INHERIT-INPUT-METHOD ALT-HELP ALT-SETS)" nil nil)
+
+;;;***
+
+;;;### (autoloads (rebind-keys-mode rebind) "rebind" "util/rebind.el"
+;;;;;;  (19292 11678))
+;;; Generated autoloads from util/rebind.el
+(web-autoload-require 'rebind 'lp '(nxhtml-download-root-url nil) "util/rebind" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'rebind 'custom-loads))) (if (member '"rebind" loads) nil (put 'rebind 'custom-loads (cons '"rebind" loads))))
+
+(defvar rebind-keys-mode nil "\
+Non-nil if Rebind-Keys mode is enabled.
+See the command `rebind-keys-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `rebind-keys-mode'.")
+
+(nxhtml-custom-autoload 'rebind-keys-mode 'rebind nil)
+
+(nxhtml-autoload 'rebind-keys-mode `(lp '(nxhtml-download-root-url nil) "util/rebind" nxhtml-install-dir) "\
+Rebind keys as defined in `rebind-keys'.
+The key bindings will override almost all other key bindings
+since it is put on emulation level, like for example ``cua-mode'
+and `viper-mode'.
+
+This is for using for example C-a to mark the whole buffer (or a
+field). There are some predifined keybindings for this.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (rnc-mode) "rnc-mode" "util/rnc-mode.el" (18775
+;;;;;;  60004))
+;;; Generated autoloads from util/rnc-mode.el
+(web-autoload-require 'rnc-mode 'lp '(nxhtml-download-root-url nil) "util/rnc-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'rnc-mode `(lp '(nxhtml-download-root-url nil) "util/rnc-mode" nxhtml-install-dir) "\
+Major mode for editing RELAX NG Compact Syntax schemas.
+\\{rnc-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (search-form) "search-form" "util/search-form.el"
+;;;;;;  (19275 63380))
+;;; Generated autoloads from util/search-form.el
+(web-autoload-require 'search-form 'lp '(nxhtml-download-root-url nil) "util/search-form" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'search-form `(lp '(nxhtml-download-root-url nil) "util/search-form" nxhtml-install-dir) "\
+Display a form for search and replace.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (sex-mode sex) "sex-mode" "util/sex-mode.el" (19218
+;;;;;;  42182))
+;;; Generated autoloads from util/sex-mode.el
+(web-autoload-require 'sex-mode 'lp '(nxhtml-download-root-url nil) "util/sex-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'sex 'custom-loads))) (if (member '"sex-mode" loads) nil (put 'sex 'custom-loads (cons '"sex-mode" loads))))
+
+(defvar sex-mode nil "\
+Non-nil if Sex mode is enabled.
+See the command `sex-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `sex-mode'.")
+
+(nxhtml-custom-autoload 'sex-mode 'sex-mode nil)
+
+(nxhtml-autoload 'sex-mode `(lp '(nxhtml-download-root-url nil) "util/sex-mode" nxhtml-install-dir) "\
+Open certain files in external programs.
+See `sex-get-file-open-cmd' for how to determine which files to
+open by external applications.  Note that this selection is
+nearly the same as in `org-mode'.  The main difference is that
+the fallback always is to open a file in Emacs. (This is
+necessary to avoid to disturb many of Emacs operations.)
+
+This affects all functions that opens files, like `find-file',
+`find-file-noselect' etc.
+
+However it does not affect files opened through Emacs client.
+
+Urls can also be handled, see `sex-handle-urls'.
+
+When opening a file with the shell a (temporary) dummy buffer is
+created in Emacs with major mode `sex-file-mode' and an external
+program is called to handle the file.  How this dummy buffer is
+handled is governed by `sex-keep-dummy-buffer'.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (sml-modeline-mode sml-modeline) "sml-modeline"
+;;;;;;  "util/sml-modeline.el" (19362 49086))
+;;; Generated autoloads from util/sml-modeline.el
+(web-autoload-require 'sml-modeline 'lp '(nxhtml-download-root-url nil) "util/sml-modeline" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'sml-modeline 'custom-loads))) (if (member '"sml-modeline" loads) nil (put 'sml-modeline 'custom-loads (cons '"sml-modeline" loads))))
+
+(defvar sml-modeline-mode nil "\
+Non-nil if Sml-Modeline mode is enabled.
+See the command `sml-modeline-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `sml-modeline-mode'.")
+
+(nxhtml-custom-autoload 'sml-modeline-mode 'sml-modeline nil)
+
+(nxhtml-autoload 'sml-modeline-mode `(lp '(nxhtml-download-root-url nil) "util/sml-modeline" nxhtml-install-dir) "\
+Show buffer size and position like scrollbar in mode line.
+You can customize this minor mode, see option `sml-modeline-mode'.
+
+Note: If you turn this mode on then you probably want to turn off
+option `scroll-bar-mode'.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (tabkey2-emma-without-tabkey2 tabkey2-mode tabkey2)
+;;;;;;  "tabkey2" "util/tabkey2.el" (19277 65356))
+;;; Generated autoloads from util/tabkey2.el
+(web-autoload-require 'tabkey2 'lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'tabkey2 'custom-loads))) (if (member '"tabkey2" loads) nil (put 'tabkey2 'custom-loads (cons '"tabkey2" loads))))
+
+(defvar tabkey2-mode nil "\
+Non-nil if Tabkey2 mode is enabled.
+See the command `tabkey2-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `tabkey2-mode'.")
+
+(nxhtml-custom-autoload 'tabkey2-mode 'tabkey2 nil)
+
+(nxhtml-autoload 'tabkey2-mode `(lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir) "\
+More fun with Tab key number two (completion etc).
+This global minor mode by default binds Tab in a way that let you
+do completion with Tab in all buffers (where it is possible).
+
+The Tab key is easy to type on your keyboard.  Then why not use
+it for completion, something that is very useful?  Shells usually
+use Tab for completion so many are used to it.  This was the idea
+of Smart Tabs and this is a generalization of that idea.
+
+However in Emacs the Tab key is usually used for indentation.
+The idea here is that if Tab has been pressed once for
+indentation, then as long as point stays further Tab keys might
+as well do completion.
+
+So you kind of do Tab-Tab for first completion (and then just
+Tab for further completions as long as point is not moved).
+
+And there is even kind of Tab-Tab-Tab completion: If completion
+fails the next completion function will be the one you try with
+next Tab. (You get some notification of this, of course.)
+
+See `tabkey2-first' for more information about usage.
+
+Note: If you do not want the Tab-Tab behaviour above, but still
+want an easy way to reach the available completion functions,
+then you can instead of turning on tabkey2-mode enter this in
+your .emacs:
+
+ (global-set-key [f8] 'tabkey2-cycle-completion-functions)
+
+After hitting f8 you will then be in the same state as after the
+first in tabkey2-mode.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'tabkey2-emma-without-tabkey2 `(lp '(nxhtml-download-root-url nil) "util/tabkey2" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (tyda-mode) "tyda" "util/tyda.el" (19275 63380))
+;;; Generated autoloads from util/tyda.el
+(web-autoload-require 'tyda 'lp '(nxhtml-download-root-url nil) "util/tyda" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(defvar tyda-mode nil "\
+Non-nil if Tyda mode is enabled.
+See the command `tyda-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `tyda-mode'.")
+
+(nxhtml-custom-autoload 'tyda-mode 'tyda nil)
+
+(nxhtml-autoload 'tyda-mode `(lp '(nxhtml-download-root-url nil) "util/tyda" nxhtml-install-dir) "\
+Minor mode for key bindings for `tyda-lookup-word'.
+It binds Alt-Mouse-1 just as the Tyda add-on does in Firefox.
+Here are all key bindings
+
+\\{tyda-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (udev-call-first-step) "udev" "util/udev.el" (19412
+;;;;;;  25976))
+;;; Generated autoloads from util/udev.el
+(web-autoload-require 'udev 'lp '(nxhtml-download-root-url nil) "util/udev" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'udev-call-first-step `(lp '(nxhtml-download-root-url nil) "util/udev" nxhtml-install-dir) "\
+Set up and call first step.
+Set up buffer LOG-BUFFER to be used for log messages and
+controling of the execution of the functions in list STEPS which
+are executed one after another.
+
+Write HEADER at the end of LOG-BUFFER.
+
+Call first step.
+
+If FINISH-FUN non-nil it should be a function. This is called
+after last step with LOG-BUFFER as parameter.
+
+\(fn LOG-BUFFER STEPS HEADER FINISH-FUN)" nil nil)
+
+;;;***
+
+;;;### (autoloads (udev-ecb-customize-startup udev-ecb-update) "udev-ecb"
+;;;;;;  "util/udev-ecb.el" (19256 5410))
+;;; Generated autoloads from util/udev-ecb.el
+(web-autoload-require 'udev-ecb 'lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'udev-ecb-update `(lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir) "\
+Fetch and install ECB from the devel sources.
+To determine where to store the sources see `udev-ecb-dir'.
+For how to start ECB see `udev-ecb-load-ecb'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'udev-ecb-customize-startup `(lp '(nxhtml-download-root-url nil) "util/udev-ecb" nxhtml-install-dir) "\
+Customize ECB dev nXhtml startup group.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (udev-rinari-update) "udev-rinari" "util/udev-rinari.el"
+;;;;;;  (19256 5410))
+;;; Generated autoloads from util/udev-rinari.el
+(web-autoload-require 'udev-rinari 'lp '(nxhtml-download-root-url nil) "util/udev-rinari" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'udev-rinari-update `(lp '(nxhtml-download-root-url nil) "util/udev-rinari" nxhtml-install-dir) "\
+Fetch and install Rinari from the devel sources.
+To determine where to store the sources and how to start rinari
+see `udev-rinari-dir' and `udev-rinari-load-rinari'.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (viper-tutorial) "viper-tut" "util/viper-tut.el"
+;;;;;;  (19388 44990))
+;;; Generated autoloads from util/viper-tut.el
+(web-autoload-require 'viper-tut 'lp '(nxhtml-download-root-url nil) "util/viper-tut" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'viper-tutorial `(lp '(nxhtml-download-root-url nil) "util/viper-tut" nxhtml-install-dir) "\
+Run a tutorial for Viper.
+
+A simple classic tutorial in 5 parts that have been used by many
+people starting to learn vi keys.  You may learn enough to start
+using `viper-mode' in Emacs.
+
+Some people find that vi keys helps against repetetive strain
+injury, see URL
+
+  `http://www.emacswiki.org/emacs/RepeatedStrainInjury'.
+
+Note: There might be a few clashes between vi key binding and
+Emacs standard key bindings.  You will be notified about those in
+the tutorial.  Even more, if your own key bindings comes in
+between you will be notified about that too.
+
+\(fn PART &optional DONT-ASK-FOR-REVERT)" t nil)
+
+;;;***
+
+;;;### (autoloads (vline-global-mode vline-mode) "vline" "util/vline.el"
+;;;;;;  (19157 2168))
+;;; Generated autoloads from util/vline.el
+(web-autoload-require 'vline 'lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'vline-mode `(lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir) "\
+Display vertical line mode.
+
+\(fn &optional ARG)" t nil)
+
+(defvar vline-global-mode nil "\
+Non-nil if Vline-Global mode is enabled.
+See the command `vline-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `vline-global-mode'.")
+
+(nxhtml-custom-autoload 'vline-global-mode 'vline nil)
+
+(nxhtml-autoload 'vline-global-mode `(lp '(nxhtml-download-root-url nil) "util/vline" nxhtml-install-dir) "\
+Display vertical line mode as globally.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (whelp) "whelp" "util/whelp.el" (19277 65356))
+;;; Generated autoloads from util/whelp.el
+(web-autoload-require 'whelp 'lp '(nxhtml-download-root-url nil) "util/whelp" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'whelp 'custom-loads))) (if (member '"whelp" loads) nil (put 'whelp 'custom-loads (cons '"whelp" loads))))
+
+;;;***
+
+;;;### (autoloads (wikipedia-draft-buffer wikipedia-draft-page wikipedia-draft
+;;;;;;  wikipedia-mode) "wikipedia-mode" "related/wikipedia-mode.el"
+;;;;;;  (19277 65356))
+;;; Generated autoloads from related/wikipedia-mode.el
+(web-autoload-require 'wikipedia-mode 'lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'wikipedia-mode `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\
+Major mode for editing wikimedia style wikis.
+Major mode for editing articles written in the markup language
+used by Wikipedia, the free on-line
+encyclopedia (see URL `http://www.wikipedia.org').
+
+There are several ways to use wikipedia-mode:
+
+- You can simply cut and paste articles between Emacs and your
+  web browser's text box.
+- If you are using Firefox you can use the It's All Text add-on
+  for Firefox.
+- You can use MozEx, a Mozilla/Firefox web browser extension that
+  allows you to call Emacs from a text
+  box (see URL `http://mozex.mozdev.org/').
+- Another way is to use the PERL script ee-helper, which allows
+  you to up and download wiki texts.
+
+Wikipedia articles are usually unfilled: newline characters are not
+used for breaking paragraphs into lines. Unfortunately, Emacs does not
+handle word wrapping yet. As a workaround, wikipedia-mode turns on
+longlines-mode automatically. In case something goes wrong, the
+following commands may come in handy:
+
+\\[wikipedia-fill-article] fills the buffer.
+\\[wikipedia-unfill-article] unfills the buffer.
+Be warned that function can be dead  slow, better use wikipedia-unfill-paragraph-or-region.
+\\[wikipedia-unfill-paragraph-or-region] unfills the paragraph
+\\[wikipedia-unfill-paragraph-simple] doehe same but simpler.
+
+
+
+The following commands put in markup structures.
+
+\\[wikipedia-insert-bold-italic] bold+italic
+\\[wikipedia-insert-bold] bold text
+\\[wikipedia-insert-italics] italics
+\\[wikipedia-insert-nowiki] no wiki markup
+\\[wikipedia-insert-link-wiki] inserts a link
+
+The following commands are also defined:
+\\[wikipedia-insert-user] inserts user name
+\\[wikipedia-insert-signature] inserts ~~~~
+\\[wikipedia-insert-enumerate] inserts enumerate type structures
+\\[wikipedia-insert-itemize] inserts itemize type structures
+\\[wikipedia-insert-hline] inserts a hline
+
+The draft functionality
+\\[wikipedia-draft]
+\\[wikipedia-draft-region]
+\\[wikipedia-draft-view-draft]
+\\[wikipedia-draft-page]
+\\[wikipedia-draft-buffer]
+
+Replying and sending functionality
+\\[wikipedia-reply-at-point-simple]
+\\[wikipedia-draft-reply]
+
+
+The register functionality
+\\[wikipedia-copy-page-to-register]
+\\[defun wikipedia-insert-page-to-register]
+
+
+Some simple editing commands.
+\\[wikipedia-enhance-indent]
+\\[wikipedia-yank-prefix]
+\\[wikipedia-unfill-paragraph-or-region]
+
+
+
+\\[wikipedia-terminate-paragraph]     starts a new list item or paragraph in a context-aware manner.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'wikipedia-draft `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\
+Open a temporary buffer in wikipedia mode for editing an
+ wikipedia draft, which an arbitrary piece of data. After
+ finishing the editing either use \\[wikipedia-draft-buffer] to
+ send the data into the wikipedia-draft-data-file, or send the
+ buffer using `wikipedia-draft-send-to-mozex' and insert it later
+ into a wikipedia article.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'wikipedia-draft-page `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'wikipedia-draft-buffer `(lp '(nxhtml-download-root-url nil) "related/wikipedia-mode" nxhtml-install-dir) "\
+Wikipedia-draft-buffer sends the contents of the current (temporary)
+buffer to the wikipedia-draft-buffer, see the variable
+wikipedia-draft-data-file.
+
+\(fn)" t nil)
+
+(defvar wikipedia-draft-send-archive t "\
+*Archive the reply.")
+
+;;;***
+
+;;;### (autoloads (visual-basic-mode) "visual-basic-mode" "related/visual-basic-mode.el"
+;;;;;;  (19235 1650))
+;;; Generated autoloads from related/visual-basic-mode.el
+(web-autoload-require 'visual-basic-mode 'lp '(nxhtml-download-root-url nil) "related/visual-basic-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'visual-basic-mode `(lp '(nxhtml-download-root-url nil) "related/visual-basic-mode" nxhtml-install-dir) "\
+A mode for editing Microsoft Visual Basic programs.
+Features automatic indentation, font locking, keyword capitalization,
+and some minor convenience functions.
+Commands:
+\\{visual-basic-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (tt-mode) "tt-mode" "related/tt-mode.el" (18603
+;;;;;;  15792))
+;;; Generated autoloads from related/tt-mode.el
+(web-autoload-require 'tt-mode 'lp '(nxhtml-download-root-url nil) "related/tt-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'tt-mode `(lp '(nxhtml-download-root-url nil) "related/tt-mode" nxhtml-install-dir) "\
+Major mode for editing Template Toolkit files.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (smarty-mode smarty) "smarty-mode" "related/smarty-mode.el"
+;;;;;;  (19235 1650))
+;;; Generated autoloads from related/smarty-mode.el
+(web-autoload-require 'smarty-mode 'lp '(nxhtml-download-root-url nil) "related/smarty-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'smarty 'custom-loads))) (if (member '"smarty-mode" loads) nil (put 'smarty 'custom-loads (cons '"smarty-mode" loads))))
+
+(nxhtml-autoload 'smarty-mode `(lp '(nxhtml-download-root-url nil) "related/smarty-mode" nxhtml-install-dir) "\
+Smarty Mode
+***********
+
+Smarty Mode is a GNU XEmacs major mode for editing Smarty templates.
+
+1 Introduction
+**************
+
+Smarty-Mode is a mode allowing easy edit of Smarty templates:
+highlight, templates, navigation into source files...
+
+
+
+Features (new features in bold) :
+
+   * Completion
+
+   * Customizable
+
+   * Highlight
+
+   * Menu
+
+   * Stuttering
+
+   * Templates
+        - Built-in Functions
+
+        - User Functions
+
+        - Variable Modifiers
+
+        - Plugin (Functions)
+             * BlockRepeatPlugin
+
+             * ClipCache
+
+             * Smarty Formtool
+
+             * Smarty Paginate
+
+             * Smarty Validate
+
+        - Plugin (Variable Modifiers)
+             * AlternativeDateModifierPlugin
+
+             * B2Smilies
+
+             * BBCodePlugin
+
+        - Fonctions Non-Smarty
+
+
+
+This manual describes Smarty Mode version 0.0.5.
+
+2 Installation
+**************
+
+2.1 Requirements
+================
+
+Smarty Mode is a XEmacs major mode that needs the following
+software/packages:
+
+   * XEmacs (http://www.xemacs.org/).
+
+   * `font-lock' mode generaly installed with XEmacs.
+
+   * `assoc' mode generaly installed with XEmacs.
+
+   * `easymenu' mode generaly installed with XEmacs.
+
+   * `hippie-exp' mode generaly installed with XEmacs.
+
+Before continuing, you must be sure to have all this packages
+installed.
+
+2.2 Download
+============
+
+Two internet address to download Smarty Mode :
+
+   * Principal: Smarty-Mode 0.0.5
+     (http://deboutv.free.fr/lisp/smarty/download/smarty-0.0.5.tar.gz)
+     (http://deboutv.free.fr/lisp/smarty/)
+
+   * Secondary: Smarty-Mode 0.0.5
+     (http://www.morinie.fr/lisp/smarty/download/smarty-0.0.5.tar.gz)
+     (http://www.morinie.fr/lisp/smarty/)
+
+   * Old releases: Smarty-Mode
+     (http://deboutv.free.fr/lisp/smarty/download.php)
+     (http://deboutv.free.fr/lisp/smarty/)
+
+2.3 Installation
+================
+
+2.3.1 Installation
+------------------
+
+To install Smarty Mode you need to choose an installation directory
+\(for example `/usr/local/share/lisp' or `c:lisp'). The administrator
+must have the write rights on this directory.
+
+With your favorite unzip software, unzip the archive in the
+installation directory.
+
+Example:
+     cd /usr/local/share/lisp
+     tar zxvf smarty-0.0.5.tar.gz
+Now you have a `smarty' directory in the installation directory. This
+directory contains 2 files `smarty-mode.el' and `smarty-mode.elc' and
+another directory `docs' containing the documentation.
+
+You need to configure XEmacs. open you initialization file `init.el'
+\(open the file or start XEmacs then choose the Options menu and Edit
+Init File). Add the following lines (the installation directory in
+this example is `/usr/local/share/lisp') :
+
+     (setq load-path
+           (append (list \"/usr/local/share/lisp/\") load-path))
+     (nxhtml-autoload 'smarty-mode \"smarty-mode\" \"Smarty Mode\" t)
+
+2.3.2 Update
+------------
+
+The update is easy. You need to unzip the archive in the installation
+directory to remove the old release.
+
+Example:
+     cd /usr/local/share/lisp
+     rm -rf smarty
+     tar zxvf smarty-0.0.5.tar.gz
+
+2.4 Invoke Smarty-Mode
+======================
+
+You have two possibilities to invoke the Smarty Mode.
+
+   - Manually: At each file opening you need to launch Smarty Mode
+     with the following command:
+
+     `M-x smarty-mode'
+
+   - Automatically: Add the following linesin your initialization
+     file `init.el' :
+
+          (setq auto-mode-alist
+                (append
+                 '((\"\\.tpl$\" . smarty-mode))
+          	 auto-mode-alist))
+
+
+3 Customization
+***************
+
+This chapter describes the differents parameters and functions that
+you can change to customize Smarty Mode.  To do that, open a Smarty
+file, click on the Smarty menu and choose Options then Browse
+Options....
+
+3.1 Parameters
+==============
+
+3.1.1 Mode
+----------
+
+Smarty Mode has 2 modes allowing to simplify the writing of Smarty
+templates. You can enable/disable each mode individually.
+
+`smarty-electric-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable automatic generation of template.
+     If `nil'; template generators can still be invoked through key
+     bindings and menu. Is indicated in the modeline by \"/e\" after
+     the mode name and can be toggled by `smarty-electric-mode'.
+
+`smarty-stutter-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable the stuttering. Is indicated in the
+     modeline by \"/s\" after the mode name and can be toggled by
+     `smarty-stutter-mode'.
+
+3.1.2 Menu
+----------
+
+Smarty Mode has also 1 menu that you can enable/disable. The menu
+Sources is specific to each Smarty files opened.
+
+`smarty-source-file-menu'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the Sources menu is enabled. This menu
+     contains the list of Smarty file located in the current
+     directory. The Sources menu scans the directory when a file is
+     opened.
+
+3.1.3 Menu
+----------
+
+`smarty-highlight-plugin-functions'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the functions described in the smarty
+     plugins are highlighted.
+
+3.1.4 Templates
+---------------
+
+3.1.4.1 Header
+..............
+
+`smarty-file-header'
+     Type: string
+     Default value: `\"\"'
+     Description: String or file to insert as file header. If the
+     string specifies an existing file name the contents of the file
+     is inserted; otherwise the string itself is inserted as file
+     header.
+     Type `C-j' for newlines.
+     The follonwing keywords are supported:
+     : replaced by the file name.
+     : replaced by the user name and email address.
+     : replaced by `user-login-name'.
+     : replaced by `smarty-company-name' content.
+     : replaced by the current date.
+     : replaced by the current year.
+     : replaced by `smarty-copyright-string' content.
+     : final cursor position.
+
+`smarty-file-footer'
+     Type: string
+     Default value: `\"\"'
+     Description: String or file to insert as file footer.  See
+     `smarty-file-header'
+
+`smarty-company-name'
+     Type: string
+     Default value: `\"\"'
+     Description: Name of the company to insert in file header.
+
+`smarty-copyright-string'
+     Type: string
+     Default value: `\"\"'
+     Description: Coryright string to insert in file header.
+
+`smarty-date-format'
+     Type: string
+     Default value: `\"%Y-%m-%d\"'
+     Description: Date format.
+
+`smarty-modify-date-prefix-string'
+     Type: string
+     Default value: `\"\"'
+     Description: Prefix string of modification date in Smarty file
+     header.
+
+`smarty-modify-date-on-saving'
+     Type: bool
+     Default value: `nil'
+     Description: If `t'; update the modification date when the
+     buffer is saved.
+
+3.1.5 Miscellaneous
+-------------------
+
+`smarty-left-delimiter'
+     Type: string
+     Default value: `\"\"'
+     Description: Left escaping delimiter for Smarty templates.
+
+`smarty-right-delimiter'
+     Type: string
+     Default value: `\"\"'
+     Description: Right escaping delimiter for Smarty templates.
+
+`smarty-intelligent-tab'
+     Type: bool
+     Default value: `t'
+     Description: If `t'; TAB does indentation; completion and insert
+     tabulations. If `nil'; TAB does only indentation.
+
+`smarty-word-completion-in-minibuffer'
+     Type: bool
+     Default value: `t'
+     Description: If `t'; enable completion in the minibuffer.
+
+`smarty-word-completion-case-sensitive'
+     Type: bool
+     Default value: `nil'
+     Description: If `t'; completion is case sensitive.
+
+3.2 Functions
+=============
+
+3.2.1 Mode
+----------
+
+`smarty-electric-mode'
+     Menu: Smarty -> Options -> Mode -> Electric Mode
+     Keybinding: `C-c C-m C-e'
+     Description: This functions is used to enable/disable the
+     electric mode.
+
+`smarty-stutter-mode'
+     Menu: Smarty -> Options -> Mode -> Stutter Mode
+     Keybinding: `C-c C-m C-s'
+     Description: This function is used to enable/disable the stutter
+     mode.
+
+4 Menus
+*******
+
+There are 2 menus: Smarty and Sources. All theses menus can be
+accessed from the menubar or from the right click. This chapter
+describes each menus.
+
+4.1 Smarty
+==========
+
+This is the main menu of Smarty Mode. It allows an easy access to the
+main features of the Smarty Mode: Templates (see *Note Templates::)
+and Options (see *Note Customization::).
+
+This menu contains also 3 functions that are discussed in the next
+part.
+
+4.1.1 Functions
+---------------
+
+`smarty-show-messages'
+     Menu: Smarty -> Show Messages
+     Keybinding: `C-c M-m'
+     Description: This function opens the *Messages* buffer to
+     display previous error messages.
+
+`smarty-doc-mode'
+     Menu: Smarty -> Smarty Mode Documentation
+     Keybinding: `C-c C-h'
+     Description: This function opens the *Help* buffer and prints in
+     it the Smarty Mode documentation.
+
+`smarty-version'
+     Menu: Smarty -> Version
+     Keybinding: `C-c C-v'
+     Description: This function displays in the minibuffer the
+     current Smarty Mode version with the timestamp.
+
+4.2 Sources
+===========
+
+The Sources menu shows the Smarty files in the current directory. If
+you add or delete a file in the current directory, you need to
+refresh the menu.
+
+4.2.1 Customization
+-------------------
+
+`smarty-source-file-menu'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; the Sources menu is enabled. This menu
+     contains the list of Smarty file located in the current
+     directory. The Sources menu scans the directory when a file is
+     opened.
+
+4.2.2 Functions
+---------------
+
+`smarty-add-source-files-menu'
+     Menu: Sources -> *Rescan*
+     Keybinding: `C-c C-s C-u'
+     Description: This function is used to refresh the Sources menu.
+
+5 Stuttering
+************
+
+The stutter mode is a mode that affects a function to a key. For
+example, when you use the `ENTER' key, the associated function will
+create a new line and indent it.
+
+5.1 Customization
+=================
+
+`smarty-stutter-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable the stuttering. Is indicated in the
+     modeline by \"/s\" after the mode name and can be toggled by
+     `smarty-stutter-mode'.
+
+5.2 Functions
+=============
+
+`SPACE'
+     If in comment, indent the comment and add new line if necessary.
+     In other case, add a space.
+
+`('
+     If the previous character is a `(', the `((' will be replaced by
+     `['.
+     If the previous character is a `[', the `[(' will be replaced by
+     `{'.
+     In other case, insert a `('.
+
+`)'
+     If the previous character is a `)', the `))' will be replaced by
+     `]'.
+     If the previous character is a `]', the `])' will be replaced by
+     `}'.
+     In other case, insert a `)'.
+
+6 Templates
+***********
+
+In the Smarty Mode, the Smarty functions (like if, while, for, fopen,
+fclose) are predefined in functions called \"Templates\".
+
+Each template can be invoked by the function name or by using the
+ key after the Smarty function name in the buffer (Note, using
+`M-' disable the template).
+
+A template can be aborted by using the `C-g' or by lefting empty the
+tempate prompt (in the minibuffer).
+
+6.1 Customization
+=================
+
+`smarty-electric-mode'
+     Type: boolean
+     Default value: `t'
+     Description: If `t'; enable automatic generation of template.
+     If `nil'; template generators can still be invoked through key
+     bindings and menu. Is indicated in the modeline by \"/e\" after
+     the mode name and can be toggled by `smarty-electric-mode'.
+
+For a complete description of the template customizable variables,
+see *Note Cu01-Pa01-Template::
+
+6.2 Functions
+=============
+
+6.2.1 Smarty Functions
+----------------------
+
+For Smarty functions, see PDF or HTML documentation.
+
+6.2.2 Non-Smarty Functions
+--------------------------
+
+`smarty-template-header'
+     Menu: Smarty -> Templates -> Insert Header
+     Keybinding: `C-c C-t C-h'
+     Description: This function is used to insert a header in the
+     current buffer.
+
+`smarty-template-footer'
+     Menu: Smarty -> Templates -> Insert Footer
+     Keybinding: `C-c C-t C-f'
+     Description: This function is used to insert a footer in the
+     current buffer.
+
+`smarty-template-insert-date'
+     Menu: Smarty -> Templates -> Insert Date
+     Keybinding: `C-c C-t C-d i'
+     Description: This function is used to insert the date in the
+     current buffer.
+
+`smarty-template-modify'
+     Menu: Smarty -> Templates -> Modify Date
+     Keybinding: `C-c C-t C-d m'
+     Description: This function is used to modify the last
+     modification date in the current buffer.
+
+7 Bugs, Help
+************
+
+   * To report bugs: Bugtracker
+     (http://bugtracker.morinie.fr/lisp/set_project.php?project_id=2)
+
+   * To obtain help you can post on the dedicated forum: Forum
+     (http://forum.morinie.fr/lisp/)
+
+8 Key bindings
+**************
+
+\\{smarty-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (php-mode php-file-patterns php) "php-mode" "related/php-mode.el"
+;;;;;;  (19218 42180))
+;;; Generated autoloads from related/php-mode.el
+(web-autoload-require 'php-mode 'lp '(nxhtml-download-root-url nil) "related/php-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'php 'custom-loads))) (if (member '"php-mode" loads) nil (put 'php 'custom-loads (cons '"php-mode" loads))))
+
+(defvar php-file-patterns '("\\.php[s34]?\\'" "\\.phtml\\'" "\\.inc\\'") "\
+List of file patterns for which to automatically invoke `php-mode'.")
+
+(nxhtml-custom-autoload 'php-file-patterns 'php-mode nil)
+
+(nxhtml-autoload 'php-mode `(lp '(nxhtml-download-root-url nil) "related/php-mode" nxhtml-install-dir) "\
+Major mode for editing PHP code.
+
+\\{php-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (global-mozadd-mirror-mode mozadd-mirror-mode global-mozadd-refresh-edited-on-save-mode
+;;;;;;  mozadd-refresh-edited-on-save-mode) "mozadd" "related/mozadd.el"
+;;;;;;  (19235 1650))
+;;; Generated autoloads from related/mozadd.el
+(web-autoload-require 'mozadd 'lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'mozadd-refresh-edited-on-save-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\
+Refresh mozadd edited file in Firefox when saving file.
+The mozadd edited file is the file in the last buffer visited in
+`mozadd-mirror-mode'.
+
+You can use this for example when you edit CSS files.
+
+The mozadd edited file must be shown in Firefox and visible.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-mozadd-refresh-edited-on-save-mode nil "\
+Non-nil if Global-Mozadd-Refresh-Edited-On-Save mode is enabled.
+See the command `global-mozadd-refresh-edited-on-save-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-mozadd-refresh-edited-on-save-mode'.")
+
+(nxhtml-custom-autoload 'global-mozadd-refresh-edited-on-save-mode 'mozadd nil)
+
+(nxhtml-autoload 'global-mozadd-refresh-edited-on-save-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\
+Toggle Mozadd-Refresh-Edited-On-Save mode in every possible buffer.
+With prefix ARG, turn Global-Mozadd-Refresh-Edited-On-Save mode on if and only if
+ARG is positive.
+Mozadd-Refresh-Edited-On-Save mode is enabled in all buffers where
+`(lambda nil (when (or (derived-mode-p (quote css-mode)) (mozadd-html-buffer-file-p)) (mozadd-refresh-edited-on-save-mode 1)))' would do it.
+See `mozadd-refresh-edited-on-save-mode' for more information on Mozadd-Refresh-Edited-On-Save mode.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'mozadd-mirror-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\
+Mirror content of current file buffer immediately in Firefox.
+When you turn on this mode the file will be opened in Firefox.
+Every change you make in the buffer will trigger a redraw in
+Firefox - regardless of if you save the file or not.
+
+For the mirroring to work the edited file must be shown in
+Firefox and visible.
+
+If `nxml-where-mode' is on the marks will also be shown in
+Firefox as CSS outline style.  You can customize the style
+through the option `mozadd-xml-path-outline-style'.
+
+See also `mozadd-refresh-edited-on-save-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-mozadd-mirror-mode nil "\
+Non-nil if Global-Mozadd-Mirror mode is enabled.
+See the command `global-mozadd-mirror-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-mozadd-mirror-mode'.")
+
+(nxhtml-custom-autoload 'global-mozadd-mirror-mode 'mozadd nil)
+
+(nxhtml-autoload 'global-mozadd-mirror-mode `(lp '(nxhtml-download-root-url nil) "related/mozadd" nxhtml-install-dir) "\
+Toggle Mozadd-Mirror mode in every possible buffer.
+With prefix ARG, turn Global-Mozadd-Mirror mode on if and only if
+ARG is positive.
+Mozadd-Mirror mode is enabled in all buffers where
+`(lambda nil (when (mozadd-html-buffer-file-p) (mozadd-mirror-mode 1)))' would do it.
+See `mozadd-mirror-mode' for more information on Mozadd-Mirror mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (inferior-moz-mode moz-minor-mode) "moz" "related/moz.el"
+;;;;;;  (19048 2102))
+;;; Generated autoloads from related/moz.el
+(web-autoload-require 'moz 'lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'moz-minor-mode `(lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir) "\
+MozRepl minor mode for interaction with Firefox.
+With no argument, this command toggles the mode.
+Non-null prefix argument turns on the mode.
+Null prefix argument turns off the mode.
+
+When this minor mode is enabled, some commands become available
+to send current code area (as understood by c-mark-function) or
+region or buffer to an inferior MozRepl process (which will be
+started as needed).
+
+The following keys are bound in this minor mode:
+
+\\{moz-minor-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'inferior-moz-mode `(lp '(nxhtml-download-root-url nil) "related/moz" nxhtml-install-dir) "\
+Major mode for interacting with Firefox via MozRepl.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (iss-mumamo-mode) "iss-mumamo" "related/iss-mumamo.el"
+;;;;;;  (19294 54042))
+;;; Generated autoloads from related/iss-mumamo.el
+(web-autoload-require 'iss-mumamo 'lp '(nxhtml-download-root-url nil) "related/iss-mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'iss-mumamo-mode `(lp '(nxhtml-download-root-url nil) "related/iss-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes Inno Setup .iss files.
+The main major mode will be `iss-mode'.
+The [code] section, if any, will be in `pascal-mode'." t)
+
+;;;***
+
+;;;### (autoloads (iss-mode) "iss-mode" "related/iss-mode.el" (19294
+;;;;;;  54042))
+;;; Generated autoloads from related/iss-mode.el
+(web-autoload-require 'iss-mode 'lp '(nxhtml-download-root-url nil) "related/iss-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'iss-mode `(lp '(nxhtml-download-root-url nil) "related/iss-mode" nxhtml-install-dir) "\
+Major mode for editing InnoSetup script files. Upon startup iss-mode-hook is run.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (flymake-js-load flymake-js) "flymake-js" "related/flymake-js.el"
+;;;;;;  (19218 42180))
+;;; Generated autoloads from related/flymake-js.el
+(web-autoload-require 'flymake-js 'lp '(nxhtml-download-root-url nil) "related/flymake-js" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'flymake-js 'custom-loads))) (if (member '"flymake-js" loads) nil (put 'flymake-js 'custom-loads (cons '"flymake-js" loads))))
+
+(nxhtml-autoload 'flymake-js-load `(lp '(nxhtml-download-root-url nil) "related/flymake-js" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (flymake-java-1-load) "flymake-java-1" "related/flymake-java-1.el"
+;;;;;;  (19264 27004))
+;;; Generated autoloads from related/flymake-java-1.el
+(web-autoload-require 'flymake-java-1 'lp '(nxhtml-download-root-url nil) "related/flymake-java-1" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'flymake-java-1-load `(lp '(nxhtml-download-root-url nil) "related/flymake-java-1" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (flymake-css-load) "flymake-css" "related/flymake-css.el"
+;;;;;;  (19292 11678))
+;;; Generated autoloads from related/flymake-css.el
+(web-autoload-require 'flymake-css 'lp '(nxhtml-download-root-url nil) "related/flymake-css" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'flymake-css-load `(lp '(nxhtml-download-root-url nil) "related/flymake-css" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (django-mode) "django" "related/django.el" (19411
+;;;;;;  8520))
+;;; Generated autoloads from related/django.el
+(web-autoload-require 'django 'lp '(nxhtml-download-root-url nil) "related/django" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'django-mode `(lp '(nxhtml-download-root-url nil) "related/django" nxhtml-install-dir) "\
+Simple Django mode for use with mumamo.
+This mode only provides syntax highlighting.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (csharp-mode csharp-mode-hook) "csharp-mode" "related/csharp-mode.el"
+;;;;;;  (19410 9973))
+;;; Generated autoloads from related/csharp-mode.el
+(web-autoload-require 'csharp-mode 'lp '(nxhtml-download-root-url nil) "related/csharp-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode))
+
+(defvar csharp-mode-hook nil "\
+*Hook called by `csharp-mode'.")
+
+(nxhtml-custom-autoload 'csharp-mode-hook 'csharp-mode t)
+
+(nxhtml-autoload 'csharp-mode `(lp '(nxhtml-download-root-url nil) "related/csharp-mode" nxhtml-install-dir) "\
+Major mode for editing C# code. This mode is derived from CC Mode to
+support C#.
+
+The hook `c-mode-common-hook' is run with no args at mode
+initialization, then `csharp-mode-hook'.
+
+This mode will automatically add a regexp for Csc.exe error and warning
+messages to the `compilation-error-regexp-alist'.
+
+Key bindings:
+\\{csharp-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (winring-rename-configuration winring-delete-configuration
+;;;;;;  winring-jump-to-configuration winring-prev-configuration
+;;;;;;  winring-next-configuration winring-duplicate-configuration
+;;;;;;  winring-new-configuration) "winring" "util/winring.el" (19392
+;;;;;;  30980))
+;;; Generated autoloads from util/winring.el
+(web-autoload-require 'winring 'lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'winring-new-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Save the current window configuration and create an empty new one.
+The buffer shown in the new empty configuration is defined by
+`winring-new-config-buffer-name'.
+
+With \\[universal-argument] prompt for the new configuration's name.
+Otherwise, the function in `winring-name-generator' will be called to
+get the new configuration's name.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'winring-duplicate-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Push the current window configuration on the ring, and duplicate it.
+
+With \\[universal-argument] prompt for the new configuration's name.
+Otherwise, the function in `winring-name-generator' will be called to
+get the new configuration's name.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'winring-next-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Switch to the next window configuration for this frame.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winring-prev-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Switch to the previous window configuration for this frame.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winring-jump-to-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Go to the named window configuration.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winring-delete-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Delete the current configuration and switch to the next one.
+With \\[universal-argument] prompt for named configuration to delete.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'winring-rename-configuration `(lp '(nxhtml-download-root-url nil) "util/winring" nxhtml-install-dir) "\
+Rename the current configuration to NAME.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (winsav-switch-config winsav-save-full-config winsav-save-mode
+;;;;;;  winsav winsav-put-window-tree) "winsav" "util/winsav.el"
+;;;;;;  (19295 38082))
+;;; Generated autoloads from util/winsav.el
+(web-autoload-require 'winsav 'lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'winsav-put-window-tree `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\
+Put window structure SAVED-TREE into WINDOW.
+Restore a structure SAVED-TREE returned from
+`winsav-get-window-tree' into window WINDOW.
+
+If COPY-WIN-OVL is non-nil then overlays having a 'window
+property pointing to one of the windows in SAVED-TREE where this
+window still is shown will be copied to a new overlay with
+'window property pointing to the corresponding new window.
+
+If WIN-OVL-ALL-BUFS is non-nil then all buffers will be searched
+for overlays with a 'window property of the kind above.
+
+At the very end of this function the hook `winsav-after-put' is
+run.
+
+\(fn SAVED-TREE WINDOW &optional COPY-WIN-OVL WIN-OVL-ALL-BUFS)" nil nil)
+
+(let ((loads (get 'winsav 'custom-loads))) (if (member '"winsav" loads) nil (put 'winsav 'custom-loads (cons '"winsav" loads))))
+
+(defvar winsav-save-mode nil "\
+Non-nil if Winsav-Save mode is enabled.
+See the command `winsav-save-mode' for a description of this minor mode.")
+
+(nxhtml-custom-autoload 'winsav-save-mode 'winsav nil)
+
+(nxhtml-autoload 'winsav-save-mode `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\
+Toggle winsav configuration saving mode.
+With numeric ARG, turn winsav saving on if ARG is positive, off
+otherwise.
+
+When this mode is turned on, winsav configurations are saved from
+one session to another.  A winsav configuration consists of
+frames, windows and visible buffers configurations plus
+optionally buffers and files managed by the functions used by
+option `desktop-save-mode'
+
+By default this is integrated with `desktop-save-mode'.  If
+`desktop-save-mode' is on and `winsav-handle-also-desktop' is
+non-nil then save and restore also desktop.
+
+See the command `winsav-switch-config' for more information and
+other possibilities.
+
+Note: If you want to avoid saving when you exit just turn off
+this minor mode.
+
+For information about what is saved and restored and how to save
+and restore additional information see the function
+`winsav-save-configuration'.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'winsav-save-full-config `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\
+Saved current winsav configuration in directory DIRNAME.
+Then change to this configuration.
+
+See also `winsav-switch-config'.
+
+\(fn DIRNAME)" nil nil)
+
+(nxhtml-autoload 'winsav-switch-config `(lp '(nxhtml-download-root-url nil) "util/winsav" nxhtml-install-dir) "\
+Change to winsav configuration in directory DIRNAME.
+If DIRNAME is the current winsav configuration directory then
+offer to save it or restore it from saved values.
+
+Otherwise, before switching offer to save the current winsav
+configuration.  Then finally switch to the new winsav
+configuration, creating it if it does not exist.
+
+If option `desktop-save-mode' is on then buffers and files are also
+restored and saved the same way.
+
+See also option `winsav-save-mode' and command
+`winsav-tell-configuration'.
+
+\(fn DIRNAME)" t nil)
+
+;;;***
+
+;;;### (autoloads (winsav-rotate winsize-set-mode-line-colors winsize-save-window-configuration
+;;;;;;  winsize-balance-siblings resize-windows) "winsize" "util/winsize.el"
+;;;;;;  (19292 49706))
+;;; Generated autoloads from util/winsize.el
+(web-autoload-require 'winsize 'lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'resize-windows `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\
+Start window resizing.
+During resizing a window is selected.  You can move its
+borders. In the default configuration the arrow keys moves the
+right or bottom border if they are there. To move the opposite
+border use S-arrowkeys.
+
+You can also do other window operations, like splitting, deleting
+and balancing the sizes.  The keybindings below describes the key
+bindings during resizing:\\
+
+  `balance-windows'                      \\[balance-windows]
+  `winsize-balance-siblings'             \\[winsize-balance-siblings]
+  `fit-window-to-buffer'                 \\[fit-window-to-buffer]
+  `shrink-window-if-larger-than-buffer'  \\[shrink-window-if-larger-than-buffer]
+
+  `winsav-rotate'                        \\[winsav-rotate]
+
+  `winsize-move-border-up'      \\[winsize-move-border-up]
+  `winsize-move-border-down'    \\[winsize-move-border-down]
+  `winsize-move-border-left'    \\[winsize-move-border-left]
+  `winsize-move-border-right'   \\[winsize-move-border-right]
+
+  `winsize-to-border-or-window-left'    \\[winsize-to-border-or-window-left]
+  `winsize-to-border-or-window-up'      \\[winsize-to-border-or-window-up]
+  `winsize-to-border-or-window-right'   \\[winsize-to-border-or-window-right]
+  `winsize-to-border-or-window-down'    \\[winsize-to-border-or-window-down]
+
+   Note that you can also use your normal keys for
+   `forward-char', `backward-char', `next-line', `previous-line'
+   and what you have on HOME and END to move in the windows. That
+   might sometimes be necessary to directly select a
+   window. (You may however also use `other-window' or click
+   with the mouse, see below.)
+
+  `delete-window'                \\[delete-window]
+  `delete-other-windows'         \\[delete-other-windows]
+  `split-window-vertically'      \\[split-window-vertically]
+  `split-window-horizontally'    \\[split-window-horizontally]
+  `other-window'                 \\[other-window]
+
+  `winsize-save-window-configuration'       \\[winsize-save-window-configuration]
+  `winsize-next-window-configuration'       \\[winsize-next-window-configuration]
+  `winsize-previous-window-configuration'   \\[winsize-previous-window-configuration]
+
+  `mouse-set-point'   \\[mouse-set-point]
+
+  `winsize-quit'               \\[winsize-quit]
+  `winsize-stop-go-back'       \\[winsize-stop-go-back]
+  `winsize-stop'               \\[winsize-stop]
+  `winsize-stop-and-execute'   \\[winsize-stop-and-execute]
+
+  `winsize-help'          \\[winsize-help]
+  `describe-key'          \\[describe-key]
+  `describe-key-briefly'  \\[describe-key-briefly]
+  (All the normal help keys work, and at least those above will
+  play well with resizing.)
+
+Nearly all other keys exits window resizing and they are also
+executed.  However, the key sequences in `winsize-let-me-use' and
+dito for commands there are also executed without exiting
+resizing.
+
+The colors of the modelines are changed to those given in
+`winsize-mode-line-colors' to indicate that you are resizing
+windows.  To make this indication more prominent the text in the
+selected window is marked with the face hold in the variable
+`winsize-selected-window-face'.
+
+The option `winsize-juris-way' decides how the borders to move
+are selected. If this option is non-nil then the right or bottom
+border are the ones that are moved with the arrow keys and the
+opposite border with shift arrow keys.
+
+If `winsize-juris-way' is nil then the following apply:
+
+As you select other borders or move to new a window the mouse
+pointer is moved inside the selected window to show which borders
+are beeing moved. The mouse jumps a little bit to make its
+position more visible. You can turn this off by customizing
+`winsize-make-mouse-prominent'.
+
+Which borders initially are choosen are controlled by the
+variable `winsize-autoselect-borders'.
+
+** Example: Border selection, movements and windows.
+
+  Suppose you have a frame divided into windows like in the
+  figure below.  If window B is selected when you start resizing
+  then (with default settings) the borders marked with 'v' and
+  'h' will be the ones that the arrow keys moves. To indicate
+  this the mouse pointer is placed in the right lower corner of
+  the selected window B.
+
+    +----------+-----------+--------+
+    |          |           v        |
+    |          |           v        |
+    |    A     |    _B_    v        |
+    |          |           v        |
+    |          |           v        |
+    |          |         x v        |
+    +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    +----------+---------+----------+
+
+  Now if you press M- then the picture below shows what has
+  happened. Note that the selected vertical border is now the one
+  between A and B. The mouse pointer has moved to the
+  corresponding corner in the window B, which is still selected.
+
+    +----------+-----------+--------+
+    |          v           |        |
+    |          v           |        |
+    |    A     v    _B_    |        |
+    |          v           |        |
+    |          v           |        |
+    |          v x         |        |
+    +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    +----------+---------+----------+
+
+  Press M- once again. This gives this picture:
+
+    +----------+-----------+--------+
+    |          v           |        |
+    |          v           |        |
+    |   _A_    v     B     |        |
+    |          v           |        |
+    |          v           |        |
+    |        x v           |        |
+    +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    +----------+---------+----------+
+
+  Note that the window A is now selected. However there is no
+  border that could be moved to the left of this window (which
+  would otherwise be chosen now) so the border between A and B is
+  still the one that  and  moves. The mouse has
+  moved to A.
+
+  If we now delete window A the new situation will look like
+  this:
+
+    +----------+-----------+--------+
+    |                      |        |
+    |                      |        |
+    |         _B_          |        |
+    |                      |        |
+    |                      |        |
+    |                    x |        |
+    +hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh+
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    |                    |          |
+    +----------+---------+----------+
+
+
+
+>>>> testing stuff >>>>
+`help-mode-hook'
+`temp-buffer-show-function'
+`view-exit-action'
+<<<<<<<<<<<<<<<<<<<<<<<
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winsize-balance-siblings `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\
+Make current window siblings the same height or width.
+It works the same way as `balance-windows', but only for the
+current window and its siblings.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winsize-save-window-configuration `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'winsize-set-mode-line-colors `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\
+Turn mode line colors on if ON is non-nil, otherwise off.
+
+\(fn ON)" nil nil)
+
+(nxhtml-autoload 'winsav-rotate `(lp '(nxhtml-download-root-url nil) "util/winsize" nxhtml-install-dir) "\
+Rotate window configuration on selected frame.
+MIRROR should be either 'mirror-left-right, 'mirror-top-bottom or
+nil.  In the first case the window configuration is mirrored
+vertically and in the second case horizontally.  If MIRROR is nil
+the configuration is not mirrored.
+
+If TRANSPOSE is non-nil then the window structure is transposed
+along the diagonal from top left to bottom right (in analogy with
+matrix transosition).
+
+If called interactively MIRROR will is 'mirror-left-right by
+default, but 'mirror-top-bottom if called with prefix.  TRANSPOSE
+is t. This mean that the window configuration will be turned one
+quarter clockwise (or counter clockwise with prefix).
+
+\(fn MIRROR TRANSPOSE)" t nil)
+
+;;;***
+
+;;;### (autoloads (wrap-to-fill-column-mode wrap-to-fill-left-marg-modes
+;;;;;;  wrap-to-fill-left-marg wrap-to-fill) "wrap-to-fill" "util/wrap-to-fill.el"
+;;;;;;  (19306 50510))
+;;; Generated autoloads from util/wrap-to-fill.el
+(web-autoload-require 'wrap-to-fill 'lp '(nxhtml-download-root-url nil) "util/wrap-to-fill" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'wrap-to-fill 'custom-loads))) (if (member '"wrap-to-fill" loads) nil (put 'wrap-to-fill 'custom-loads (cons '"wrap-to-fill" loads))))
+
+(defvar wrap-to-fill-left-marg nil "\
+Left margin handling for `wrap-to-fill-column-mode'.
+Used by `wrap-to-fill-column-mode'. If nil then center the
+display columns. Otherwise it should be a number which will be
+the left margin.")
+
+(nxhtml-custom-autoload 'wrap-to-fill-left-marg 'wrap-to-fill t)
+
+(defvar wrap-to-fill-left-marg-modes '(text-mode fundamental-mode) "\
+Major modes where `wrap-to-fill-left-margin' may be nil.")
+
+(nxhtml-custom-autoload 'wrap-to-fill-left-marg-modes 'wrap-to-fill t)
+
+(nxhtml-autoload 'wrap-to-fill-column-mode `(lp '(nxhtml-download-root-url nil) "util/wrap-to-fill" nxhtml-install-dir) "\
+Use `fill-column' display columns in buffer windows.
+By default the display columns are centered, but see the option
+`wrap-to-fill-left-marg'.
+
+Fix-me:
+Note 1: When turning this on `visual-line-mode' is also turned on. This
+is not reset when turning off this mode.
+
+Note 2: The text properties 'wrap-prefix and 'wrap-to-fill-prefix
+is set by this mode to indent continuation lines.
+
+Key bindings added by this minor mode:
+
+\\{wrap-to-fill-column-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (xhtml-help xhtml-help-show-tag-ref xhtml-help-tag-at-point
+;;;;;;  xhtml-help-show-css-ref) "xhtml-help" "nxhtml/xhtml-help.el"
+;;;;;;  (19364 56214))
+;;; Generated autoloads from nxhtml/xhtml-help.el
+(web-autoload-require 'xhtml-help 'lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'xhtml-help-show-css-ref `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\
+Show CSS reference for CSS property name at point.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'xhtml-help-tag-at-point `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\
+Get xhtml tag name at or before point.
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'xhtml-help-show-tag-ref `(lp '(nxhtml-download-root-url nil) "nxhtml/xhtml-help" nxhtml-install-dir) "\
+Show xhtml reference for tag name at or before point.
+
+\(fn)" t nil)
+
+(let ((loads (get 'xhtml-help 'custom-loads))) (if (member '"xhtml-help" loads) nil (put 'xhtml-help 'custom-loads (cons '"xhtml-help" loads))))
+
+;;;***
+
+;;;### (autoloads (tidy-build-menu tidy) "tidy-xhtml" "nxhtml/tidy-xhtml.el"
+;;;;;;  (19364 56214))
+;;; Generated autoloads from nxhtml/tidy-xhtml.el
+(web-autoload-require 'tidy-xhtml 'lp '(nxhtml-download-root-url nil) "nxhtml/tidy-xhtml" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'tidy 'custom-loads))) (if (member '"tidy-xhtml" loads) nil (put 'tidy 'custom-loads (cons '"tidy-xhtml" loads))))
+
+(nxhtml-autoload 'tidy-build-menu `(lp '(nxhtml-download-root-url nil) "nxhtml/tidy-xhtml" nxhtml-install-dir) "\
+Set up the tidy menu in MAP.
+Used to set up a Tidy menu in your favourite mode.
+
+\(fn &optional MAP)" t nil)
+
+;;;***
+
+;;;### (autoloads (rngalt-set-validation-header) "rngalt" "nxhtml/rngalt.el"
+;;;;;;  (19365 33760))
+;;; Generated autoloads from nxhtml/rngalt.el
+(web-autoload-require 'rngalt 'lp '(nxhtml-download-root-url nil) "nxhtml/rngalt" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'rngalt-set-validation-header `(lp '(nxhtml-download-root-url nil) "nxhtml/rngalt" nxhtml-install-dir) "\
+Not documented
+
+\(fn START-OF-DOC)" nil nil)
+
+;;;***
+
+;;;### (autoloads (nxml-where-global-mode nxml-where-mode nxml-where)
+;;;;;;  "nxml-where" "nxhtml/nxml-where.el" (19365 33760))
+;;; Generated autoloads from nxhtml/nxml-where.el
+(web-autoload-require 'nxml-where 'lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'nxml-where 'custom-loads))) (if (member '"nxml-where" loads) nil (put 'nxml-where 'custom-loads (cons '"nxml-where" loads))))
+
+(nxhtml-autoload 'nxml-where-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir) "\
+Shows path in mode line.
+
+\(fn &optional ARG)" t nil)
+
+(defvar nxml-where-global-mode nil "\
+Non-nil if Nxml-Where-Global mode is enabled.
+See the command `nxml-where-global-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `nxml-where-global-mode'.")
+
+(nxhtml-custom-autoload 'nxml-where-global-mode 'nxml-where nil)
+
+(nxhtml-autoload 'nxml-where-global-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxml-where" nxhtml-install-dir) "\
+Toggle Nxml-Where mode in every possible buffer.
+With prefix ARG, turn Nxml-Where-Global mode on if and only if
+ARG is positive.
+Nxml-Where mode is enabled in all buffers where
+`nxml-where-turn-on-in-nxml-child' would do it.
+See `nxml-where-mode' for more information on Nxml-Where mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (nxhtml-features-check nxhtml-customize nxhtml)
+;;;;;;  "nxhtml" "nxhtml/nxhtml.el" (19412 25954))
+;;; Generated autoloads from nxhtml/nxhtml.el
+(web-autoload-require 'nxhtml 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'nxhtml 'custom-loads))) (if (member '"nxhtml" loads) nil (put 'nxhtml 'custom-loads (cons '"nxhtml" loads))))
+
+(nxhtml-autoload 'nxhtml-customize `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir) "\
+Customize nXhtml.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'nxhtml-features-check `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml" nxhtml-install-dir) "\
+Check if external modules used by nXhtml are found.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (mako-nxhtml-mumamo-mode asp-nxhtml-mumamo-mode
+;;;;;;  eruby-nxhtml-mumamo-mode jsp-nxhtml-mumamo-mode gsp-nxhtml-mumamo-mode
+;;;;;;  smarty-nxhtml-mumamo-mode mjt-nxhtml-mumamo-mode genshi-nxhtml-mumamo-mode
+;;;;;;  mason-nxhtml-mumamo-mode django-nxhtml-mumamo-mode embperl-nxhtml-mumamo-mode
+;;;;;;  nxhtml-mumamo-mode) "nxhtml-mumamo" "nxhtml/nxhtml-mumamo.el"
+;;;;;;  (19389 57826))
+;;; Generated autoloads from nxhtml/nxhtml-mumamo.el
+(web-autoload-require 'nxhtml-mumamo 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for (X)HTML with main mode `nxhtml-mode'.
+This covers inlined style and javascript and PHP.
+
+See also `mumamo-alt-php-tags-mode'." t)
+
+(nxhtml-autoload 'embperl-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Embperl files with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'django-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Django with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'mason-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Mason using main mode `nxhtml-mode'.
+This covers inlined style and javascript." t)
+
+(nxhtml-autoload 'genshi-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Genshi with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'mjt-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for MJT with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'smarty-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Smarty with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'gsp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for GSP with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'jsp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for JSP with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'eruby-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for eRuby with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'asp-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for ASP with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+(nxhtml-autoload 'mako-nxhtml-mumamo-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mumamo" nxhtml-install-dir) "\
+Turn on multiple major modes for Mako with main mode `nxhtml-mode'.
+This also covers inlined style and javascript." t)
+
+;;;***
+
+;;;### (autoloads (nxhtml-validation-header-mode nxhtml-short-tag-help
+;;;;;;  nxhtml-mode) "nxhtml-mode" "nxhtml/nxhtml-mode.el" (19412
+;;;;;;  25947))
+;;; Generated autoloads from nxhtml/nxhtml-mode.el
+(web-autoload-require 'nxhtml-mode 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(when (fboundp 'nxml-mode)
+(nxhtml-autoload 'nxhtml-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\
+Major mode for editing XHTML documents.
+It is based on `nxml-mode' and adds some features that are useful
+when editing XHTML files.\\
+
+To see an overview in html format do \\[nxhtml-overview].
+
+* Note: Please observe that when loading nXhtml some file
+  associations are done, see `nxhtml-setup-file-assoc'.
+
+The nXhtml menu is added by this mode (or actually the minor
+mode `nxhtml-menu-mode') and gives quick access and an overview
+of some other important features. These includes:
+
+- multiple major modes, see `define-mumamo-multi-major-mode'
+- easy uploading and viewing of files, see for example
+  `html-upl-upload-file'
+- validation in XHTML part for php etc, see
+  `nxhtml-validation-header-mode' (you probably also want to know about
+  `nxhtml-toggle-visible-warnings' for this!)
+- converting of html to xhtml, see `tidy-buffer'
+
+The XML menu contains functionality added by `nxml-mode' (on
+which this major mode is based).  There is also a popup menu
+added to the [apps] key.
+
+The most important features are probably completion and
+validation, which is inherited from `nxml-mode' with some small
+addtions.  In very many situation you can use completion. To
+access it type \\[nxml-complete]. Completion has been enhanced in
+the following way:
+
+- If region is active and visible then completion will surround the
+  region with the chosen tag's start and end tag.  However only the
+  starting point is checked for validity. If something is wrong after
+  insertion you will however immediately see it if you have validation
+  on.
+- It can in some cases give assistance with attribute values.
+- Completion can be customized, see the menus XHTML - Completion:
+  * You can use a menu popup style completion.
+  * You can have alternatives grouped.
+  * You can get a short help text shown for each alternative.
+- There does not have to be a '<' before point for tag name
+  completion. (`nxml-mode' requires a '<' before point for tag name
+  completion.)
+- Completes xml version and encoding.
+- Completes in an empty buffer, ie inserts a skeleton.
+
+Some smaller, useful, but easy-to-miss features:
+
+* Following links. The href and src attribute names are
+  underlined and a special keymap is bound to
+  them:\\
+
+    \\[mlinks-backward-link], \\[mlinks-forward-link] Move
+        between underlined href/src attributes
+
+    \\[mlinks-goto], Mouse-1 Follow link inside Emacs
+        (if possible)
+
+  It is even a little bit quicker when the links are in an active
+  state (marked with the face `isearch'):\\
+
+    \\[mlinks-backward-link], \\[mlinks-forward-link] Move
+        between underlined href/src attributes
+    \\[mlinks-goto], Mouse-1  Follow link inside Emacs (if possible)
+
+  If the link is not into a file that you can edit (a mailto link
+  for example) you will be prompted for an alternative action.
+
+* Creating links. To make it easier to create links to id/name
+  attribute in different files there are two special
+  functions:\\
+
+    \\[nxhtml-save-link-to-here] copy link to id/name (you must
+        be in the tag to get the link)
+    \\[nxhtml-paste-link-as-a-tag] paste this as an a-tag.
+
+Here are all key bindings in nxhtml-mode itself:
+
+\\{nxhtml-mode-map}
+
+The minor mode `nxhtml-menu-mode' adds some bindings:
+
+\\{nxhtml-menu-mode-map}
+
+Notice that other minor mode key bindings may also be active, as
+well as emulation modes. Do \\[describe-bindings] to get a list
+of all active key bindings. Also, *VERY IMPORTANT*, if mumamo is
+used in the buffer each mumamo chunk has a different major mode
+with different key bindings. You can however still see all
+bindings with \\[describe-bindings], but you have to do that with
+point in the mumamo chunk you want to know the key bindings in.
+
+---------
+* Note: Some of the features supported by this mode are optional
+  and available only if other Emacs modules are found.  Use
+  \\[nxhtml-features-check] to get a list of these optional
+  features and modules needed. You should however have no problem
+  with this if you have followed the installation instructions
+  for nXhtml.
+
+\(fn)" t nil))
+
+(nxhtml-autoload 'nxhtml-short-tag-help `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\
+Display description of tag TAG.  If TAG is omitted, try tag at point.
+
+\(fn TAG)" t nil)
+
+(when (fboundp 'nxml-mode)
+(nxhtml-autoload 'nxhtml-validation-header-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-mode" nxhtml-install-dir) "\
+If on use a Fictive XHTML Validation Header for the buffer.
+See `nxhtml-set-validation-header' for information about Fictive XHTML Validation Headers.
+
+This mode may be turned on automatically in two ways:
+- If you try to do completion of a XHTML tag or attribute then
+  `nxthml-mode' may ask you if you want to turn this mode on if
+  needed.
+- You can also choose to have it turned on automatically whenever
+  a mumamo multi major mode is used, see
+  `nxhtml-validation-header-if-mumamo' for further information.
+
+\(fn &optional ARG)" t nil))
+
+;;;***
+
+;;;### (autoloads (nxhtml-overview nxhtml-menu-mode nxhtml-browse-region
+;;;;;;  nxhtml-browse-file nxhtml-edit-with-gimp) "nxhtml-menu" "nxhtml/nxhtml-menu.el"
+;;;;;;  (19412 26360))
+;;; Generated autoloads from nxhtml/nxhtml-menu.el
+(web-autoload-require 'nxhtml-menu 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtml-edit-with-gimp `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\
+Edit with GIMP buffer or file at point.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'nxhtml-browse-file `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\
+View file in web browser.
+
+\(fn FILE)" t nil)
+
+(nxhtml-autoload 'nxhtml-browse-region `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\
+View region in web browser.
+
+\(fn)" t nil)
+
+(defvar nxhtml-menu-mode nil "\
+Non-nil if Nxhtml-Menu mode is enabled.
+See the command `nxhtml-menu-mode' for a description of this minor mode.")
+
+(nxhtml-custom-autoload 'nxhtml-menu-mode 'nxhtml-menu nil)
+
+(nxhtml-autoload 'nxhtml-menu-mode `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\
+Minor mode to turn on some key and menu bindings.
+See `nxhtml-mode' for more information.
+
+\(fn &optional ARG)" t nil)
+
+(nxhtml-autoload 'nxhtml-overview `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-menu" nxhtml-install-dir) "\
+Show a HTML page with an overview of nXhtml.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (nxhtml-report-bug) "nxhtml-bug" "nxhtml/nxhtml-bug.el"
+;;;;;;  (19277 65354))
+;;; Generated autoloads from nxhtml/nxhtml-bug.el
+(web-autoload-require 'nxhtml-bug 'lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-bug" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtml-report-bug `(lp '(nxhtml-download-root-url nil) "nxhtml/nxhtml-bug" nxhtml-install-dir) "\
+Report a bug in nXhtml.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (html-wtoc) "html-wtoc" "nxhtml/html-wtoc.el" (19364
+;;;;;;  56214))
+;;; Generated autoloads from nxhtml/html-wtoc.el
+(web-autoload-require 'html-wtoc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-wtoc" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-wtoc 'custom-loads))) (if (member '"html-wtoc" loads) nil (put 'html-wtoc 'custom-loads (cons '"html-wtoc" loads))))
+
+;;;***
+
+;;;### (autoloads (html-upl-ediff-file html-upl-edit-remote-file-with-toc
+;;;;;;  html-upl-edit-remote-file html-upl-upload-file html-upl-remote-dired
+;;;;;;  html-upl-upload-site html-upl-upload-site-with-toc html-upl)
+;;;;;;  "html-upl" "nxhtml/html-upl.el" (19364 56214))
+;;; Generated autoloads from nxhtml/html-upl.el
+(web-autoload-require 'html-upl 'lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-upl 'custom-loads))) (if (member '"html-upl" loads) nil (put 'html-upl 'custom-loads (cons '"html-upl" loads))))
+
+(nxhtml-autoload 'html-upl-upload-site-with-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-upl-upload-site `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-upl-remote-dired `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Start dired for remote directory or its parent/ancestor.
+
+\(fn DIRNAME)" t nil)
+
+(nxhtml-autoload 'html-upl-upload-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Upload a single file in a site.
+For the definition of a site see `html-site-current'.
+
+\(fn FILENAME)" t nil)
+
+(nxhtml-autoload 'html-upl-edit-remote-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-upl-edit-remote-file-with-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Not documented
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-upl-ediff-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-upl" nxhtml-install-dir) "\
+Run ediff on local and remote file.
+FILENAME could be either the remote or the local file.
+
+\(fn FILENAME)" t nil)
+
+;;;***
+
+;;;### (autoloads (html-toc) "html-toc" "nxhtml/html-toc.el" (19364
+;;;;;;  56214))
+;;; Generated autoloads from nxhtml/html-toc.el
+(web-autoload-require 'html-toc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-toc" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-toc 'custom-loads))) (if (member '"html-toc" loads) nil (put 'html-toc 'custom-loads (cons '"html-toc" loads))))
+
+(defconst html-toc-menu-map (let ((map (make-sparse-keymap))) (define-key map [html-toc-browse-frames-file] (list 'menu-item "Browse Frames File" 'html-toc-browse-frames-file)) (define-key map [html-toc-write-frames-file] (list 'menu-item "Write Frames File" 'html-toc-write-frames-file)) (define-key map [html-toc-write-toc-file] (list 'menu-item "Write TOC File for Frames" 'html-toc-write-toc-file)) (define-key map [html-toc-sep1] (list 'menu-item "--")) (define-key map [html-toc-edit-pages-file] (list 'menu-item "Edit List of Pages for TOC" 'html-site-edit-pages-file)) (define-key map [html-toc-create-pages-file] (list 'menu-item "Write List of Pages for TOC" 'html-toc-create-pages-file)) map))
+
+;;;***
+
+;;;### (autoloads (html-site-query-replace html-site-rgrep html-site-find-file
+;;;;;;  html-site-dired-current html-site-set-site html-site-buffer-or-dired-file-name
+;;;;;;  html-site) "html-site" "nxhtml/html-site.el" (19364 56214))
+;;; Generated autoloads from nxhtml/html-site.el
+(web-autoload-require 'html-site 'lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-site 'custom-loads))) (if (member '"html-site" loads) nil (put 'html-site 'custom-loads (cons '"html-site" loads))))
+
+(nxhtml-autoload 'html-site-buffer-or-dired-file-name `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Return buffer file name or file pointed to in dired.
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'html-site-set-site `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Not documented
+
+\(fn NAME)" t nil)
+
+(nxhtml-autoload 'html-site-dired-current `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Open `dired' in current site top directory.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-site-find-file `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Find file in current site.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'html-site-rgrep `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Search current site's files with `rgrep'.
+See `rgrep' for the arguments REGEXP and FILES.
+
+\(fn REGEXP FILES)" t nil)
+
+(nxhtml-autoload 'html-site-query-replace `(lp '(nxhtml-download-root-url nil) "nxhtml/html-site" nxhtml-install-dir) "\
+Query replace in current site's files.
+
+\(fn FROM TO FILE-REGEXP DELIMITED)" t nil)
+
+;;;***
+
+;;;### (autoloads (html-pagetoc-rebuild-toc html-pagetoc-insert-toc
+;;;;;;  html-pagetoc) "html-pagetoc" "nxhtml/html-pagetoc.el" (19364
+;;;;;;  56214))
+;;; Generated autoloads from nxhtml/html-pagetoc.el
+(web-autoload-require 'html-pagetoc 'lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-pagetoc 'custom-loads))) (if (member '"html-pagetoc" loads) nil (put 'html-pagetoc 'custom-loads (cons '"html-pagetoc" loads))))
+
+(nxhtml-autoload 'html-pagetoc-insert-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir) "\
+Inserts a table of contents for the current html file.
+The html header tags h1-h6 found in the file are inserted into
+this table.  MIN-LEVEL and MAX-LEVEL specifies the minimum and
+maximum level of h1-h6 to include.  They should be integers.
+
+\(fn &optional MIN-LEVEL MAX-LEVEL)" t nil)
+
+(nxhtml-autoload 'html-pagetoc-rebuild-toc `(lp '(nxhtml-download-root-url nil) "nxhtml/html-pagetoc" nxhtml-install-dir) "\
+Update the table of contents inserted by `html-pagetoc-insert-toc'.
+
+\(fn)" t nil)
+
+(defconst html-pagetoc-menu-map (let ((map (make-sparse-keymap))) (define-key map [html-pagetoc-rebuild-toc] (list 'menu-item "Update Page TOC" 'html-pagetoc-rebuild-toc)) (define-key map [html-pagetoc-insert-style-guide] (list 'menu-item "Insert CSS Style for Page TOC" 'html-pagetoc-insert-style-guide)) (define-key map [html-pagetoc-insert-toc] (list 'menu-item "Insert Page TOC" 'html-pagetoc-insert-toc)) map))
+
+;;;***
+
+;;;### (autoloads (html-chklnk) "html-chklnk" "nxhtml/html-chklnk.el"
+;;;;;;  (19364 56214))
+;;; Generated autoloads from nxhtml/html-chklnk.el
+(web-autoload-require 'html-chklnk 'lp '(nxhtml-download-root-url nil) "nxhtml/html-chklnk" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'html-chklnk 'custom-loads))) (if (member '"html-chklnk" loads) nil (put 'html-chklnk 'custom-loads (cons '"html-chklnk" loads))))
+
+;;;***
+
+;;;### (autoloads (web-vcs-investigate-elisp-file web-vcs-byte-compile-file
+;;;;;;  web-vcs-message-with-face web-vcs-get-files-from-root web-vcs-log-edit
+;;;;;;  web-vcs-default-download-directory) "web-vcs" "web-vcs.el"
+;;;;;;  (19412 16397))
+;;; Generated autoloads from web-vcs.el
+(web-autoload-require 'web-vcs 'lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'web-vcs-default-download-directory `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Try to find a suitable place.
+Considers site-start.el, site-
+
+\(fn)" nil nil)
+
+(nxhtml-autoload 'web-vcs-log-edit `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Open log file.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'web-vcs-get-files-from-root `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Download a file tree from VCS system using the web interface.
+Use WEB-VCS entry in variable `web-vcs-links-regexp' to download
+files via http from URL to directory DL-DIR.
+
+Show URL first and offer to visit the page.  That page will give
+you information about version control system (VCS) system used
+etc.
+
+\(fn WEB-VCS URL DL-DIR)" nil nil)
+
+(nxhtml-autoload 'web-vcs-message-with-face `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Display a colored message at the bottom of the string.
+FACE is the face to use for the message.
+FORMAT-STRING and ARGS are the same as for `message'.
+
+Also put FACE on the message in *Messages* buffer.
+
+\(fn FACE FORMAT-STRING &rest ARGS)" nil nil)
+
+(nxhtml-autoload 'web-vcs-byte-compile-file `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Byte compile FILE in a new Emacs sub process.
+EXTRA-LOAD-PATH is added to the front of `load-path' during
+compilation.
+
+FILE is set to `buffer-file-name' when called interactively.
+If LOAD
+
+\(fn FILE &optional LOAD EXTRA-LOAD-PATH COMP-DIR)" t nil)
+
+(nxhtml-autoload 'web-vcs-investigate-elisp-file `(lp '(nxhtml-download-root-url nil) "web-vcs" nxhtml-install-dir) "\
+Not documented
+
+\(fn FILE-OR-BUFFER)" t nil)
+
+;;;***
+
+;;;### (autoloads (nxhtmlmaint-byte-uncompile-all nxhtmlmaint-byte-recompile
+;;;;;;  nxhtmlmaint-start-byte-compilation) "nxhtmlmaint" "nxhtmlmaint.el"
+;;;;;;  (19378 31293))
+;;; Generated autoloads from nxhtmlmaint.el
+(web-autoload-require 'nxhtmlmaint 'lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(nxhtml-autoload 'nxhtmlmaint-start-byte-compilation `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\
+Start byte compilation of nXhtml in new Emacs instance.
+Byte compiling in general makes elisp code run 5-10 times faster
+which is quite noticeable when you use nXhtml.
+
+This will also update the file nxhtml-loaddefs.el.
+
+You must restart Emacs to use the byte compiled files.
+
+If for some reason the byte compiled files does not work you can
+remove then with `nxhtmlmaint-byte-uncompile-all'.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'nxhtmlmaint-byte-recompile `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\
+Recompile or compile all nXhtml files in current Emacs.
+
+\(fn)" t nil)
+
+(nxhtml-autoload 'nxhtmlmaint-byte-uncompile-all `(lp '(nxhtml-download-root-url nil) "nxhtmlmaint" nxhtml-install-dir) "\
+Delete byte compiled files in nXhtml.
+This will also update the file nxhtml-loaddefs.el.
+
+See `nxhtmlmaint-start-byte-compilation' for byte compiling.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads (zencoding-preview zencoding-expand-yas zencoding-mode
+;;;;;;  zencoding-expand-line zencoding) "zencoding-mode" "util/zencoding-mode.el"
+;;;;;;  (19275 63380))
+;;; Generated autoloads from util/zencoding-mode.el
+(web-autoload-require 'zencoding-mode 'lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir 'nxhtml-byte-compile-file)
+
+
+(let ((loads (get 'zencoding 'custom-loads))) (if (member '"zencoding-mode" loads) nil (put 'zencoding 'custom-loads (cons '"zencoding-mode" loads))))
+
+(nxhtml-autoload 'zencoding-expand-line `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\
+Replace the current line's zencode expression with the corresponding expansion.
+If prefix ARG is given or region is visible call `zencoding-preview' to start an
+interactive preview.
+
+Otherwise expand line directly.
+
+For more information see `zencoding-mode'.
+
+\(fn ARG)" t nil)
+
+(nxhtml-autoload 'zencoding-mode `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\
+Minor mode for writing HTML and CSS markup.
+With zen coding for HTML and CSS you can write a line like
+
+  ul#name>li.item*2
+
+and have it expanded to
+
+  
    +
  • +
  • +
+ +This minor mode defines keys for quick access: + +\\{zencoding-mode-keymap} + +Home page URL `http://www.emacswiki.org/emacs/ZenCoding'. + +See also `zencoding-expand-line'. + +\(fn &optional ARG)" t nil) + +(nxhtml-autoload 'zencoding-expand-yas `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Not documented + +\(fn)" t nil) + +(nxhtml-autoload 'zencoding-preview `(lp '(nxhtml-download-root-url nil) "util/zencoding-mode" nxhtml-install-dir) "\ +Expand zencode between BEG and END interactively. +This will show a preview of the expanded zen code and you can +accept it or skip it. + +\(fn BEG END)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("autostart.el" "autostart22.el" "etc/schema/schema-path-patch.el" +;;;;;; "nxhtml-base.el" "nxhtml/html-imenu.el" "nxhtml/html-move.el" +;;;;;; "nxhtml/html-quote.el" "nxhtml/nxhtml-autoload.el" "nxhtml/nxhtml-strval.el" +;;;;;; "nxhtml/nxhtmljs.el" "nxhtml/outline-magic.el" "nxhtml/wtest.el" +;;;;;; "related/flymake-helpers.el" "related/flymakemsg.el" "related/flymu.el" +;;;;;; "related/php-imenu.el" "tests/angus77-setup-jde.el" "tests/emacstest-suites.el" +;;;;;; "tests/ert2.el" "tests/hfy-test.el" "tests/inemacs/bug1013.el" +;;;;;; "tests/mumamo-test.el" "tests/nxhtmltest-helpers.el" "tests/temp-test.el" +;;;;;; "util/appmenu-fold.el" "util/css-simple-completion.el" "util/custsets.el" +;;;;;; "util/ecb-batch-compile.el" "util/fupd.el" "util/idn.el" +;;;;;; "util/key-cat.el" "util/mumamo-aspnet.el" "util/mumamo-trace.el" +;;;;;; "util/new-key-seq-widget.el" "util/nxml-mode-os-additions.el" +;;;;;; "util/org-panel.el" "util/rxi.el" "util/useful-commands.el" +;;;;;; "web-autoload.el") (19412 26385 593000)) + +;;;*** + +;;;### (autoloads (nxhtml-byte-recompile-file nxhtml-byte-compile-file +;;;;;; nxhtml-get-missing-files nxhtml-update-existing-files nxhtml-setup-download-all +;;;;;; nxhtml-setup-auto-download nxhtml-setup-install) "nxhtml-web-vcs" +;;;;;; "nxhtml-web-vcs.el" (19412 16464)) +;;; Generated autoloads from nxhtml-web-vcs.el +(web-autoload-require 'nxhtml-web-vcs 'lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir 'nxhtml-byte-compile-file) + + +(nxhtml-autoload 'nxhtml-setup-install `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Setup and start nXhtml installation. + +This is for installation and updating directly from the nXhtml +development sources. + +There are two different ways to install: + + (1) Download all at once: `nxhtml-setup-download-all' + (2) Automatically download part by part: `nxhtml-setup-auto-download' + +You can convert between those ways by calling this function again. +You can also do this by setting the option `nxhtml-autoload-web' yourself. + +When you have nXhtml installed you can update it: + + (3) Update new files in nXhtml: `nxhtml-update-existing-files' + +To learn more about nXhtml visit its home page at URL +`http://www.emacswiki.com/NxhtmlMode/'. + +If you want to test auto download (but not use it further) there +is a special function for that, you answer T here: + + (T) Test automatic download part by part: `nxhtml-setup-test-auto-download' + +====== +*Note* +If you want to download a zip file with latest released version instead then +please see URL `http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html'. + +\(fn WAY)" t nil) + +(nxhtml-autoload 'nxhtml-setup-auto-download `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Set up to autoload nXhtml files from the web. + +This function will download some initial files and then setup to +download the rest when you need them. + +Files will be downloaded under the directory root you specify in +DL-DIR. + +Note that files will not be upgraded automatically. The auto +downloading is just for files you are missing. (This may change a +bit in the future.) If you want to upgrade those files that you +have downloaded you can just call `nxhtml-update-existing-files'. + +You can easily switch between this mode of downloading or +downloading the whole of nXhtml by once. To switch just call the +command `nxhtml-setup-install'. + +See also the command `nxhtml-setup-download-all'. + +Note: If your nXhtml is to old you can't use this function + directly. You have to upgrade first, se the function + above. Version 2.07 or above is good for this. + +\(fn DL-DIR)" t nil) + +(nxhtml-autoload 'nxhtml-setup-download-all `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Download or update all of nXhtml. + +You can download all if nXhtml with this command. + +To update existing files use `nxhtml-update-existing-files'. + +If you want to download only those files you are actually using +then call `nxhtml-setup-auto-download' instead. + +See the command `nxhtml-setup-install' for a convenient way to +call these commands. + +For more information about auto download of nXhtml files see +`nxhtml-setup-auto-download'. + +\(fn DL-DIR)" t nil) + +(nxhtml-autoload 'nxhtml-update-existing-files `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Update existing nXhtml files from the development sources. +Only files you already have will be updated. + +Note that this works both if you have setup nXhtml to auto +download files as you need them or if you have downloaded all of +nXhtml at once. + +For more information about installing and updating nXhtml see the +command `nxhtml-setup-install'. + +\(fn)" t nil) + +(nxhtml-autoload 'nxhtml-get-missing-files `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Not documented + +\(fn SUB-DIR FILE-NAME-LIST)" nil nil) + +(nxhtml-autoload 'nxhtml-byte-compile-file `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Not documented + +\(fn FILE &optional LOAD)" nil nil) + +(nxhtml-autoload 'nxhtml-byte-recompile-file `(lp '(nxhtml-download-root-url nil) "nxhtml-web-vcs" nxhtml-install-dir) "\ +Byte recompile FILE file if necessary. +For more information see `nxhtml-byte-compile-file'. +Loading is done if recompiled and LOAD is t. + +\(fn FILE &optional LOAD)" t nil) + +;;;*** diff --git a/nxhtml/nxhtml-web-vcs.el b/nxhtml/nxhtml-web-vcs.el new file mode 100644 index 0000000..fb0fb09 --- /dev/null +++ b/nxhtml/nxhtml-web-vcs.el @@ -0,0 +1,689 @@ +;;; nxhtml-web-vcs.el --- nXhtml things for web-vcs.el +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2010-01-13 Wed +;; Version: +;; Last-Updated: +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'cl)) +(eval-when-compile (require 'nxhtml-base nil t)) +;;(eval-when-compile (require 'nxhtmlmaint nil t)) +(eval-when-compile (require 'web-vcs nil t)) + +(defvar nxhtml-web-vcs-file (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name) + "This file.") + +(defun nxhtml-require-base () + (require 'nxhtml-base nil t) + (unless (featurep 'nxhtml-base) + ;; At startup, need to load it by hand. + (let ((load-path load-path)) + (add-to-list 'load-path (file-name-directory nxhtml-web-vcs-file)) + (require 'nxhtml-base)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Repository URL + + +;;(nxhtml-default-download-directory) +(defun nxhtml-default-download-directory () + (let* ((ur (expand-file-name "" "~")) + (ur-len (length ur)) + (full (if (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + nxhtml-install-dir + (file-name-as-directory + (expand-file-name "" + (web-vcs-default-download-directory))))) + (full-len (length full))) + (if (and (> full-len ur-len) + (string= ur (substring full 0 ur-len))) + (concat "~" (substring full ur-len)) + full))) + + +(defun nxhtml-web-vcs-read-dl-dir (prompt) + "Return current nXhtml install dir or read dir." + (or (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (let* ((pr (concat + "A directory named 'nxhtml' will be created below the root you give." + "\n" + prompt)) + (root (read-directory-name pr (nxhtml-default-download-directory)))) + (when root + (expand-file-name "nxhtml" root))))) + +;;(call-interactively 'nxhtml-setup-install) +;; (read-key "Prompt: ") +;; (y-or-n-p "Prompt") +;;;###autoload +(defun nxhtml-setup-install (way) + "Setup and start nXhtml installation. + +This is for installation and updating directly from the nXhtml +development sources. + +There are two different ways to install: + + (1) Download all at once: `nxhtml-setup-download-all' + (2) Automatically download part by part: `nxhtml-setup-auto-download' + +You can convert between those ways by calling this function again. +You can also do this by setting the option `nxhtml-autoload-web' yourself. + +When you have nXhtml installed you can update it: + + (3) Update new files in nXhtml: `nxhtml-update-existing-files' + +To learn more about nXhtml visit its home page at URL +`http://www.emacswiki.com/NxhtmlMode/'. + +If you want to test auto download \(but not use it further) there +is a special function for that, you answer T here: + + (T) Test automatic download part by part: `nxhtml-setup-test-auto-download' + +====== +*Note* +If you want to download a zip file with latest released version instead then +please see URL `http://ourcomments.org/Emacs/nXhtml/doc/nxhtml.html'." + (interactive (let ((curr-cfg (current-window-configuration))) + (describe-function 'nxhtml-setup-install) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + (list + (let* ((key nil) + (has-nxhtml (and (boundp 'nxhtml-install-dir) nxhtml-install-dir)) + (current-way (if has-nxhtml + (if (and (boundp 'nxhtml-autoload-web) + nxhtml-autoload-web) + "Your current setup is to download part by part from the web." + "Your current setup it to download all of nXhtml at once.") + "(You have not currently installed nXhtml.)")) + (prompt (concat "Setup nXhtml install." + "\n" current-way + "\n" + "\n(1) Download whole at once, or (2) part by part as needed" + (if has-nxhtml "\n(3) Update your existing nXhtml" "") + "\n(T) For temporary testing downloading part by part" + "\n" + "\n(? for help, q to quit): ")) + (allowed-keys (if has-nxhtml + '(?1 ?2 ?3 ?T ?q 7) + '(?1 ?2 ?T ?q 7))) + (please nil)) + (while (not (member key allowed-keys)) + (if (not (member key '(??))) + (when key + (unless please + (setq prompt (concat "Please answer with one of the alternatives.\n\n" + prompt)) + (setq please t))) + (describe-function 'nxhtml-setup-install) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows)) + (setq key (web-vcs-read-key prompt)) + ;;(message "key = %S" key) (sit-for 1) + ) + (case key + (7 (set-window-configuration curr-cfg) + nil) + (?1 'whole) + (?2 'part-by-part) + (?3 'update-existing) + (?T 'test-part-by-part) + ))))) + (message "") + (case way + (whole (call-interactively 'nxhtml-setup-download-all)) + (part-by-part (call-interactively 'nxhtml-setup-auto-download)) + (update-existing (call-interactively 'nxhtml-update-existing-files)) + (test-part-by-part (call-interactively 'nxhtml-setup-test-auto-download)) + ((eq nil way) nil) + (t (error "Unknown way = %S" way)))) + +(defvar nxhtml-basic-files '( + "nxhtml-base.el" + "nxhtml-loaddefs.el" + "web-autoload.el" + "etc/schema/schema-path-patch.el" + "nxhtml/nxhtml-autoload.el" + "autostart.el" + )) + +;;;###autoload +(defun nxhtml-setup-auto-download (dl-dir) + "Set up to autoload nXhtml files from the web. + +This function will download some initial files and then setup to +download the rest when you need them. + +Files will be downloaded under the directory root you specify in +DL-DIR. + +Note that files will not be upgraded automatically. The auto +downloading is just for files you are missing. (This may change a +bit in the future.) If you want to upgrade those files that you +have downloaded you can just call `nxhtml-update-existing-files'. + +You can easily switch between this mode of downloading or +downloading the whole of nXhtml by once. To switch just call the +command `nxhtml-setup-install'. + +See also the command `nxhtml-setup-download-all'. + +Note: If your nXhtml is to old you can't use this function + directly. You have to upgrade first, se the function + above. Version 2.07 or above is good for this." + (interactive (progn + (describe-function 'nxhtml-setup-auto-download) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + (nxhtml-check-convert-to-part-by-part) + (list + (progn + (when (and (boundp 'nxhtml-autoload-web) + (not nxhtml-autoload-web)) + (unless (yes-or-no-p "Convert to updating nXhtml part by part? ") + (throw 'command-level nil))) + (nxhtml-web-vcs-read-dl-dir "Download nXhtml part by part to directory: "))))) + (catch 'command-level + (if (not dl-dir) + (unless (with-no-warnings (called-interactively-p)) + (error "dl-dir should be a directory")) + (nxhtml-check-convert-to-part-by-part) + (when (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (unless (string= (file-truename dl-dir) + (file-truename nxhtml-install-dir)) + (error "Download dir must be same as nxhtml-install-dir=%S" nxhtml-install-dir))) + (let* (;; Need some files: + (web-vcs-el-src (concat (file-name-sans-extension web-vcs-el-this) ".el")) + (web-vcs-el (expand-file-name (file-name-nondirectory web-vcs-el-src) + dl-dir)) + (vcs 'lp) + (base-url (nxhtml-download-root-url nil)) + (byte-comp (if (boundp 'web-autoload-autocompile) + web-autoload-autocompile + t)) + (has-nxhtml (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir)) + (web-vcs-folder-cache nil)) + (setq nxhtml-install-dir dl-dir) + (let ((root (file-name-directory dl-dir))) + (unless (file-exists-p root) + (unless (yes-or-no-p (format "Directory %S does not exist, create it? " root)) + (error "Aborted by user")))) + (make-directory dl-dir t) + (setq message-log-max t) + (view-echo-area-messages) + (message "") + (message "") + (web-vcs-message-with-face 'web-vcs-green "==== Starting nXhtml part by part state ====") + (message "has-nxhtml=%s" has-nxhtml) + ;; Fix-me: First copy this file and web-vcs.el to its destination: + (unless (string= (file-truename dl-dir) + (file-truename (file-name-directory nxhtml-web-vcs-file))) + (dolist (f (list web-vcs-el-src nxhtml-web-vcs-file)) + (copy-file f (expand-file-name (file-name-nondirectory f) dl-dir) + 'ok-overwrite))) + (when byte-comp (web-vcs-byte-compile-newer-file web-vcs-el t)) + ;; Get basic file list: + (catch 'web-autoload-comp-restart + ;;(let ((file-mask (regexp-opt nxhtml-basic-files))) + ;; (web-vcs-get-missing-matching-files vcs base-url dl-dir file-mask)) + (dolist (f nxhtml-basic-files) + (web-vcs-get-missing-matching-files vcs base-url dl-dir f)) + ;; Autostart.el has not run yet, add download dir to load-path. + (let ((load-path (cons (file-name-directory web-vcs-el) load-path))) + (when byte-comp + (dolist (file nxhtml-basic-files) + (let ((el-file (expand-file-name file dl-dir))) + (web-vcs-byte-compile-newer-file el-file nil))))) + (let ((autostart-file (expand-file-name "autostart" dl-dir))) + ;;(ad-deactivate 'require) + (web-vcs-set&save-option 'nxhtml-autoload-web t) + (web-vcs-log nil nil "* nXhtml: Download Part by Part as Needed\n") + (load autostart-file) + (unless (ad-is-active 'require) (ad-activate 'require)) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-green "==== Basic files for nXhtml part by part are now installed ====") + (web-vcs-display-messages t) + (unless has-nxhtml (nxhtml-add-loading-to-custom-file autostart-file t)))))))) + +;;(call-interactively 'nxhtml-download) +;;;###autoload +(defun nxhtml-setup-download-all (dl-dir) + "Download or update all of nXhtml. + +You can download all if nXhtml with this command. + +To update existing files use `nxhtml-update-existing-files'. + +If you want to download only those files you are actually using +then call `nxhtml-setup-auto-download' instead. + +See the command `nxhtml-setup-install' for a convenient way to +call these commands. + +For more information about auto download of nXhtml files see +`nxhtml-setup-auto-download'." + (interactive (progn + (describe-function 'nxhtml-setup-auto-download) + (select-window (get-buffer-window (help-buffer))) + (delete-other-windows) + ;;(nxhtml-check-convert-to-part-by-part) + (list + (nxhtml-web-vcs-read-dl-dir "Download whole nXhtml to directory: ")))) + + (let ((root (file-name-directory dl-dir))) + (unless (file-exists-p root) + (unless (yes-or-no-p (format "Directory %S does not exist, create it? " root)) + (error "Aborted by user")))) + (make-directory dl-dir t) + (let ((msg (concat "Downloading nXhtml through Launchpad web interface will take rather long\n" + "time (5-15 minutes) so you may want to do it in a separate Emacs session.\n\n" + "Do you want to download using this Emacs session? " + ))) + (if (not (y-or-n-p msg)) + (message "Aborted") + (setq message-log-max t) + (let ((do-byte (y-or-n-p "Do you want to byte compile the files after downloading? "))) + (nxhtml-download-1 dl-dir nil do-byte))))) + + +(defun nxhtml-download-1 (dl-dir revision do-byte) + "Download nXhtml to directory DL-DIR. +If REVISION is nil download latest revision, otherwise the +specified one. + +If DO-BYTE is non-nil byte compile nXhtml after download." + (let* ((has-nxhtml (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir)) + (base-url nxhtml-web-vcs-base-url) + (files-url (concat base-url "files/")) + ;;(revs-url (concat base-url "changes/")) + (rev-part (if revision (number-to-string revision) "head%3A/")) + (full-root-url (concat files-url rev-part)) + (web-vcs-folder-cache nil) + (web-autoload-paranoid nil)) + ;;(nxhtml-require-base) + (when (web-vcs-get-files-from-root 'lp full-root-url dl-dir) + (web-vcs-display-messages t) + (web-vcs-log nil nil "* nXhtml: Download All\n") + (web-vcs-set&save-option 'nxhtml-autoload-web nil) + (message "") + (web-vcs-message-with-face 'web-vcs-green "==== Starting downloading whole nXhtml ====") + (let ((autostart-file (expand-file-name "autostart" dl-dir))) + (load autostart-file) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-green "==== All files for nXhtml are now installed ====") + (nxhtmlmaint-byte-recompile) + (unless has-nxhtml (nxhtml-add-loading-to-custom-file autostart-file nil)))))) + +(defun nxhtml-check-convert-to-part-by-part () + (when (and (boundp 'nxhtml-install-dir) + nxhtml-install-dir) + (unless (and (boundp 'nxhtml-autoload-web) + nxhtml-autoload-web) + (if (not (boundp 'nxhtml-menu:version)) + (error "nxhtml-install-dir set but no version found") + (unless (string-match "[\.0-9]+" nxhtml-menu:version) + (error "Can't find current version nxhtml-menu:version=%S" nxhtml-menu:version)) + (let* ((ver-str (match-string 0 nxhtml-menu:version)) + (ver-num (string-to-number ver-str))) + (when (< ver-num 2.07) + (web-vcs-message-with-face 'web-vcs-red "Too old nXhtml for download part by part.") + (throw 'command-level nil))))))) + + +;;(directory-files default-directory nil "\\el$") +;;(directory-files default-directory nil "[^#~]$") +;;;###autoload +(defun nxhtml-update-existing-files () + "Update existing nXhtml files from the development sources. +Only files you already have will be updated. + +Note that this works both if you have setup nXhtml to auto +download files as you need them or if you have downloaded all of +nXhtml at once. + +For more information about installing and updating nXhtml see the +command `nxhtml-setup-install'." + ;; Fix-me: download new files too if you are not auto downloading. + (interactive) + (when (y-or-n-p "Do you want to update your nXhtml files? ") + (message "") + (web-vcs-display-messages t) + (web-vcs-message-with-face 'web-vcs-yellow "*\nStarting updating your nXhtml files.\n*\n") + (message nil) + (web-vcs-clear-folder-cache) + (let ((vcs 'lp) + (base-url (nxhtml-download-root-url nil)) + (dl-dir nxhtml-install-dir) + web-vcs-folder-cache) + (setq dl-dir (file-name-as-directory dl-dir)) + (web-vcs-update-existing-files vcs base-url dl-dir dl-dir) + (web-vcs-clear-folder-cache)) + (display-buffer (get-buffer-create "*Compile-Log*")) + (nxhtmlmaint-byte-recompile) + (web-vcs-log-save) + (web-vcs-message-with-face 'web-vcs-yellow "*\nFinished updating your nXhtml files.\n*\n") + (message nil))) + + +;;(nxhtml-maybe-download-files (expand-file-name "nxhtml/doc/img/" nxhtml-install-dir) nil) +;;;###autoload +(defun nxhtml-get-missing-files (sub-dir file-name-list) + (let (file-mask + (root-url (nxhtml-download-root-url nil)) + files-regexp + (full-dir (expand-file-name sub-dir nxhtml-install-dir)) + miss-names) + (if file-name-list + (progn + (dolist (f file-name-list) + (let ((full-f (expand-file-name f full-dir))) + (unless (file-exists-p full-f) + (setq miss-names (cons f miss-names))))) + (setq files-regexp (regexp-opt miss-names))) + (setq files-regexp ".*")) + ;;(unless (file-exists-p full-dir) (make-directory full-dir t)) + (setq file-mask + (concat (file-relative-name (file-name-as-directory full-dir) + nxhtml-install-dir) + files-regexp)) + (let ((web-vcs-folder-cache nil)) + (web-vcs-get-missing-matching-files 'lp root-url nxhtml-install-dir + file-mask)))) + +;; Fix-me: Does not work, Emacs Bug +;; Maybe use wget? http://gnuwin32.sourceforge.net/packages/wget.htm +;; http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=5103 +;; (nxhtml-get-release-revision) +(defun nxhtml-get-release-revision () + "Get revision number for last release." + (let* ((all-rev-url "http://code.launchpad.net/%7Enxhtml/nxhtml/main") + (url-buf (url-retrieve-synchronously all-rev-url)) + (vcs-rec (or (assq 'lp web-vcs-links-regexp) + (error "Does not know web-vcs 'lp"))) + (rel-ver-regexp (nth 6 vcs-rec)) + ) + (message "%S" url-buf) + (with-current-buffer url-buf + (when (re-search-forward rel-ver-regexp nil t) + (match-string 1))))) + +;;;###autoload +(defun nxhtml-byte-compile-file (file &optional load) + (let ((extra-load-path (when nxhtml-install-dir + (mapcar (lambda (p) + (file-name-as-directory + (expand-file-name p nxhtml-install-dir))) + '("tests" "related" "nxhtml" "util" "."))))) + ;; (message "nxhtml-byte-compile-file:extra-load-path=%s" extra-load-path) + (web-vcs-byte-compile-file file load extra-load-path))) + +;; fix-me: change web-vcs-byte-compile-file instead +;;;###autoload +(defun nxhtml-byte-recompile-file (file &optional load) + "Byte recompile FILE file if necessary. +For more information see `nxhtml-byte-compile-file'. +Loading is done if recompiled and LOAD is t." + (interactive (list (buffer-file-name) + t)) + (let ((elc-file (byte-compile-dest-file file))) + (if (file-newer-than-file-p file elc-file) + (nxhtml-byte-compile-file file load) + (message "Byte compilation of this file is up to date.")))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Add to custom file + + +(defvar nxhtml-handheld-wincfg nil) +(defun nxhtml-handheld-restore-wincg () + (when nxhtml-handheld-wincfg + (set-window-configuration nxhtml-handheld-wincfg) + (setq nxhtml-handheld-wincfg nil))) + +;;(nxhtml-handheld-add-loading-to-custom-file "TEST-ME") +(defun nxhtml-handheld-add-loading-to-custom-file (file-to-load) + (setq nxhtml-handheld-wincfg (current-window-configuration)) + (delete-other-windows) + (let ((info-buf (get-buffer-create "Information about how to add nXhtml to (custom-file)")) + (load-str (format "(load %S)" file-to-load))) + (with-current-buffer info-buf + (add-hook 'kill-buffer-hook 'nxhtml-handheld-restore-wincg nil t) + (insert "Insert the following line to (custom-file), ie the file in the other window:\n\n") + (let ((here (point))) + (insert " " + (propertize load-str 'face 'secondary-selection) + "\n") + (copy-region-as-kill here (point)) + (insert "\nThe line above is in the clipboard so you can just paste it where you want it.\n") + (insert "When ready kill this buffer.") + (goto-char here)) + (setq buffer-read-only t) + (set-buffer-modified-p nil)) + (set-window-buffer (selected-window) info-buf) + (find-file-other-window (custom-file)))) + +;; (nxhtml-add-loading-to-custom-file "test-file") +(defun nxhtml-add-loading-to-custom-file (file-to-load part-by-part) + (message "") + (require 'cus-edit) + (if (not (condition-case nil (custom-file) (error nil))) + (progn + (message "\n\n") + (web-vcs-message-with-face + 'web-vcs-red + (concat "Since you have started this Emacs session without running your init files" + "\nthey are unknown and the installation can not add the statement below." + "\nTo finish the setup of nXhtml you must add" + "\n\n (load %S)" + "\n\nto your custom-file if you have not done it yet." + "\nYou must also customize the variable `nxhtml-autoload-web' to tell that" + (if part-by-part + "\nyou want to download nXhml files as you need them." + "\nyou do not want to allow automatic downloading of nXhtml files." + ) + "\n") + file-to-load) + (message "") + (web-vcs-display-messages t)) + (let ((prompt (concat "Basic setup of nXhtml is done, but it must be loaded from (custom-file)." + "\nShould I add loading of nXhtml to (custom-file) for you? "))) + (if (yes-or-no-p prompt) + (nxhtml-add-loading-to-custom-file-auto file-to-load) + (if (yes-or-no-p "Should I guide you through how to do it? ") + (nxhtml-handheld-add-loading-to-custom-file file-to-load) + (web-vcs-message-with-face 'web-vcs-green + "OK. You need to add (load %S) to your init file" file-to-load)))))) + +;; Fix-me: really do this? Is it safe enough? +(defun nxhtml-add-loading-to-custom-file-auto (file-to-load) + (unless (file-name-absolute-p file-to-load) + (error "nxhtml-add-loading-to-custom-file: Not abs file name: %S" file-to-load)) + (let ((old-buf (find-buffer-visiting (custom-file))) + (full-to-load (expand-file-name file-to-load))) + (with-current-buffer (or old-buf (find-file-noselect (custom-file))) + (save-restriction + (widen) + (catch 'done + (while (progn + (while (progn (skip-chars-forward " \t\n\^l") + (looking-at ";")) + (forward-line 1)) + (not (eobp))) + (let ((start (point)) + (form (read (current-buffer)))) + (when (eq (nth 0 form) 'load) + (let* ((form-file (nth 1 form)) + (full-form-file (expand-file-name form-file))) + (when (string= full-form-file full-to-load) + (throw 'done nil)) + (when (and (string= (file-name-nondirectory full-form-file) + (file-name-nondirectory full-to-load)) + (not (string= full-form-file full-to-load))) + (if (yes-or-no-p "Replace current nXhtml loading in (custom-file)? ") + (progn + (goto-char start) ;; at form start now + (forward-char (length "(load ")) + (skip-chars-forward " \t\n\^l") ;; at start of string + (setq start (point)) + (setq form (read (current-buffer))) + (delete-region start (point)) + (insert (format "%S" full-to-load)) + (basic-save-buffer)) + (web-vcs-message-with-face 'web-vcs-red "Can't continue then") + (web-vcs-display-messages t) + (throw 'command-level nil))))))) + ;; At end of file + (insert (format "\n(load %S)\n" file-to-load)) + (basic-save-buffer)) + (unless old-buf (kill-buffer old-buf)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;; Start Testing function +(defun emacs-Q-no-nxhtml (&rest args) + (let* ((old-env-load-path (getenv "EMACSLOADPATH")) + sub-env-load-path + (elp-list (or (when old-env-load-path + ;;(split-string old-env-load-path ";")) + (split-string old-env-load-path path-separator)) + load-path)) + (sub-elp-list nil) + ret + (this-emacs-exe (locate-file invocation-name + (list invocation-directory) + exec-suffixes))) + (dolist (p elp-list) + (when (file-exists-p p) + (unless (string= nxhtml-install-dir p) + (let* ((dir (file-name-directory p)) + (last (file-name-nondirectory p)) + (last-dir (file-name-nondirectory + (directory-file-name dir)))) + (unless (and (string= "nxhtml" last-dir) + (member last '("util" "test" "nxhtml" "related" "alt"))) + (setq sub-elp-list (cons p sub-elp-list))))))) + ;;(setq sub-env-load-path (mapconcat 'identity (reverse sub-elp-list) ";")) + (setq sub-env-load-path (mapconcat 'identity (reverse sub-elp-list) path-separator)) + (setenv "EMACSLOADPATH" sub-env-load-path) + (setq ret (apply 'call-process this-emacs-exe nil 0 nil "-Q" args)) + (setenv "EMACSLOADPATH" old-env-load-path) + ret)) + +;; (call-interactively-p 'nxhtml-setup-test-auto-download) +;; (nxhtml-setup-test-auto-download "c:/test2/") +(defun nxhtml-setup-test-auto-download (test-dir) + "Test autoload in a new emacs, started with 'emacs -Q'. +You can choose where to download the files and just delete them +when you have tested enough." + (interactive (list (read-directory-name "Directory for test of auto download of nXhtml: "))) + (let ((this-dir (file-name-directory web-vcs-el-this)) + (this-name (file-name-nondirectory web-vcs-el-this)) + that-file) + (when (and (file-exists-p test-dir) + (not (y-or-n-p (format "Directory %S exists, really test there? " test-dir)))) + (error "Aborted")) + (unless (file-exists-p test-dir) (make-directory test-dir)) + (setq that-file (expand-file-name this-name test-dir)) + (when (file-exists-p that-file) (delete-file that-file)) + (copy-file web-vcs-el-this that-file) + (emacs-Q-no-nxhtml "-l" that-file "-f" "nxhtml-setup-test-auto-download-do-it-here"))) + +(defun nxhtml-setup-test-auto-download-do-it-here () + "Helper for `nxhtml-setup-test-auto-down-load'." + (let ((this-dir (file-name-directory web-vcs-el-this))) + (nxhtml-setup-auto-download this-dir))) + +(defun web-vcs-check-if-modified () + (let ( + (t1 (format-time-string "%Y-%m-%dT%T%z" (date-to-time "2010-01-01 18:20"))) + (t2 (format-time-string "%Y-%m-%dT%T%z" (date-to-time "Mon, 28 Dec 2009 08:57:44 GMT"))) + (url-request-extra-headers + (list + (cons "If-Modified-Since" + (format-time-string + ;;"%Y-%m-%dT%T%z" + "%a, %e %b %Y %H:%M:%S GMT" + (nth 5 (file-attributes "c:/test/temp.el" ))) + ))) + xb) + (setq xb (url-retrieve-synchronously "http://www.emacswiki.org/emacs/download/anything.el")) + (switch-to-buffer xb) + )) +;; (emacs-Q-no-nxhtml "web-vcs.el" "-l" "c:/test/d27/web-autostart.el") +;; (emacs-Q-no-nxhtml "web-vcs.el" "-l" "c:/test/d27/autostart.el") +;; (emacs-Q-no-nxhtml "web-vcs.el" "-f" "eval-buffer" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "-l" "c:/test/d27/web-vcs" "-l" "c:/test/d27/nxhtml-web-vcs" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "-l" "c:/test/d27/nxhtml-web-vcs" "-f" "nxhtml-temp-setup-auto-download") +;; (emacs-Q-no-nxhtml "--geometry=200x50+100+100" "-l" "c:/test/d27/web-vcs" "-f" "web-vcs-nxhtml") +(defun nxhtml-temp-setup-auto-download () + ;;(when (fboundp 'w32-send-sys-command) (w32-send-sys-command #xf030) (sit-for 2)) + (set-frame-size (selected-frame) + (/ 1024 (frame-char-width)) + (/ 512 (frame-char-height)) + ) + (tool-bar-mode -1) + (set-frame-position (selected-frame) 100 50) + (when (y-or-n-p "Do nXhtml? ") + (view-echo-area-messages) + (setq truncate-lines t) + (split-window-horizontally) + (let ((load-path (cons default-directory load-path))) + (require 'web-vcs)) + ;(nxhtml-setup-auto-download "c:/test/d27") + (call-interactively 'nxhtml-setup-auto-download) + )) +;;;;;; End Testing function +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(provide 'nxhtml-web-vcs) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; nxhtml-web-vcs.el ends here diff --git a/nxhtml/nxhtml/ChangeLog b/nxhtml/nxhtml/ChangeLog new file mode 100644 index 0000000..9a6dad9 --- /dev/null +++ b/nxhtml/nxhtml/ChangeLog @@ -0,0 +1,17 @@ +2006-04-26 + + * nxhtml.el (nxhtml-insert-skeleton-if-empty) + (nxhtml-insert-frame-skeleton): New functions. + +2006-04-25 + + * nxhtml.el (nxhtml-coding-systems-complete) + (nxhtml-script-url-predicate, nxhtml-script-completion-pattern) + (nxhtml-image-url-predicate, nxhtml-image-completion-pattern) + (nxhtml-mailto-predicate, nxhtml-predicate-error) + (nxhtml-in-xml-attribute-value-regex) + (nxhtml-read-mail-url-history, nxhtml-read-web-url-history) + (nxhtml-read-url-history, nxhtml-read-url-type) + (nxhtml-read-url-type-help, nxhtml-read-url) + (rng-complete-attribute-value): New entries for completion. + diff --git a/nxhtml/nxhtml/doc/demo.html b/nxhtml/nxhtml/doc/demo.html new file mode 100644 index 0000000..8696032 --- /dev/null +++ b/nxhtml/nxhtml/doc/demo.html @@ -0,0 +1,71 @@ + + + + + nXhtml Short Tour + + + + + + + + + +
+ +
+

Popup completion

+

nXhtml can use popup style completion too (for XHTML)

+ + Popup completion + Popup completion (thumbnail) +
+

+ more about popup +

+

+ more about popup +

+
+
+ +
+

Emacs style completion

+

Emacs default style for completion uses the minibuffer and an Emacs window

+ + Emacs style completion + Emacs style completion (thumbnail) +
du
+
+
+ +
+ desc div +
+ + diff --git a/nxhtml/nxhtml/doc/html2xhtml.html b/nxhtml/nxhtml/doc/html2xhtml.html new file mode 100644 index 0000000..2228c80 --- /dev/null +++ b/nxhtml/nxhtml/doc/html2xhtml.html @@ -0,0 +1,39 @@ + + + + + + How to Convert to XHTML + + + + +

+ How to Convert to XHTML +

+

+ With nxhtml-mode you can edit XHTML documents, but not HTML + dito. So what do you do with your old HTML documents? The + answer is simple: You convert them to XHTML! There is today + not many reasons not to convert them to XHTML. You may say + "but what about old browsers?". Most users just do not have + old browsers today. Old browsers are too dangerous to use on the + Internet. +

+

+ You can convert the documents easily from within nxhtml-mode + with Tidy. However + Tidy does not come with nxhtml, you have to install it yourself. +

+

+ When Tidy is called from Emacs you can do a whole directory tree + at once. When a buffer is in nxhtml-mode (and tidy.el is found) + there is an entry on the menus called Tidy from which you + can access tidy and set the options for it. Note especially the + Quick Options Settings where you can set options for + converting to XHTML easily. +

+ + + diff --git a/nxhtml/nxhtml/doc/htmlfontify-example.html b/nxhtml/nxhtml/doc/htmlfontify-example.html new file mode 100644 index 0000000..0eafb8d --- /dev/null +++ b/nxhtml/nxhtml/doc/htmlfontify-example.html @@ -0,0 +1,424 @@ + + + + + + + + + + +

Example of htmlfontify.el output

+ +

+ The following is an example of the output you can get with htmlfontify.el. + The version used here is shipped with nXhtml. + (A new version from the original author is on its way.) +

+ + + + + + + + + + + +
Emacs Icon (patched)  Emacs - Frame Dump
+ + + + + + + + + + + + + + + +
+ + + +
+ +
;; This buffer is for notes you don't want to save, and for Lisp evaluation.
+;; If you want to create a file, visit that file with C-x C-f,
+;; then enter the text in that file's own buffer.
+
+
+ +
+
-- (Unix)-- *scratch* (Lisp Interaction Abbrev hs) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
cadr is a compiled Lisp function in `subr.el'.
+(cadr x)
+
+Return the car of the cdr of x.
+
+[back]
+
+ +
+
-- (Unix)%% *Help* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ + + +
+ + + + +
comint-highlight-prompt                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-column-number                     abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-error                             abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-info                              abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-line-number                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+compilation-warning                           abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+completion-dynamic-face                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+completion-tooltip-face                       abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+
+ + +
Truncated to line 11 - 19!
+
+
-- (Unix)%% *Faces* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
snow                   snow                                                                                                                        #fffafa
+ghost white            GhostWhite                                                                                                                  #f8f8ff
+white smoke            WhiteSmoke                                                                                                                  #f5f5f5
+gainsboro              gainsboro                                                                                                                   #dcdcdc
+floral white           FloralWhite                                                                                                                 #fffaf0
+old lace               OldLace                                                                                                                     #fdf5e6
+linen                  linen                                                                                                                       #faf0e6
+antique white          AntiqueWhite                                                                                                                #faebd7
+
+ + +
Truncated to line 1 - 9!
+
+
-- (Unix)%% *Colors* (Help View Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ + + + +
________________________
+Program and Value Search
+
+When you use Emacs on MS Windows you sometimes want to fetch values
+and program locations from MS Windows.  Many of these values are
+stored in the MS Windows Registry.  Since Emacs is written to be used
+on many platforms (with the emphasis on GPL platforms) the effort to
+let Emacs read the Registry directly has not been made.  Below you can
+
+ + +
Truncated to line 29 - 37!
+
+
-- (Unix)** *Customize EmacsW32* (Custom Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
  Add quick printing to File menu (htmlize-view-print-visible): t
+  Keep default print entries in File menu (w32-print-menu-show-print): nil
+  Keep default ps print entries in File menu (w32-print-menu-show-ps-print): nil
+  Use keyboard Window keys as Emacs META (w32-meta-style): w32-lr
+  Underlined accelerators in menu bar (menuacc-active): t
+  Inferior shell + path for unix style programs (w32shell-shell): cmd
+
+   Set all to w32 style!   Reset all to default!   Customize EmacsW32 ... 
+
+ + +
Truncated to line 13 - 21!
+
+
-- (Unix)** *Customize EmacsW32* (Custom Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + +
+ + + + +
-*- mode: grep; default-directory: "c:/emacs/p/070604/EmacsW32/nxml/util/" -*-
+Grep started at Fri Dec 28 22:54:06
+
+grep -i -nH -e "hfy-tmpfont-stack" *.el
+htmlfontify.el:596:(defvar hfy-tmpfont-stack nil
+htmlfontify.el:999:           (entry (assoc key hfy-tmpfont-stack))
+htmlfontify.el:1003:        (setq tag               (format "%04d" (length hfy-tmpfont-stack))
+htmlfontify.el:1005:              hfy-tmpfont-stack (cons entry hfy-tmpfont-stack)))
+
+ + +
Truncated to line 1 - 9!
+
+
-- (Unix)%% *grep* (Grep Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ + + + +
5 matches for "hfy-tmpfont-stack" in buffer: htmlfontify.el
+    596:(defvar hfy-tmpfont-stack nil
+    999:           (entry (assoc key hfy-tmpfont-stack))
+   1003:        (setq tag               (format "%04d" (length hfy-tmpfont-stack))
+   1005:              hfy-tmpfont-stack (cons entry hfy-tmpfont-stack)))
+   1228:        ;;(hfy-tmpfont-stack nil)
+
+ +
+
-- (Unix)%% *Occur* (Occur Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+ M-x  hfyview-frame
+ + diff --git a/nxhtml/nxhtml/doc/img/Las_Medulas.jpg b/nxhtml/nxhtml/doc/img/Las_Medulas.jpg new file mode 100644 index 0000000..694a2c5 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/Las_Medulas.jpg differ diff --git a/nxhtml/nxhtml/doc/img/Toco_toucan.jpg b/nxhtml/nxhtml/doc/img/Toco_toucan.jpg new file mode 100644 index 0000000..269886c Binary files /dev/null and b/nxhtml/nxhtml/doc/img/Toco_toucan.jpg differ diff --git a/nxhtml/nxhtml/doc/img/bacchante2.jpg b/nxhtml/nxhtml/doc/img/bacchante2.jpg new file mode 100644 index 0000000..a736099 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/bacchante2.jpg differ diff --git a/nxhtml/nxhtml/doc/img/butterflies.jpg b/nxhtml/nxhtml/doc/img/butterflies.jpg new file mode 100644 index 0000000..a7352a6 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/butterflies.jpg differ diff --git a/nxhtml/nxhtml/doc/img/butterflies.png b/nxhtml/nxhtml/doc/img/butterflies.png new file mode 100644 index 0000000..8d60637 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/butterflies.png differ diff --git a/nxhtml/nxhtml/doc/img/butterflies.xcf b/nxhtml/nxhtml/doc/img/butterflies.xcf new file mode 100644 index 0000000..9260725 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/butterflies.xcf differ diff --git a/nxhtml/nxhtml/doc/img/continue-play.jpg b/nxhtml/nxhtml/doc/img/continue-play.jpg new file mode 100644 index 0000000..587113e Binary files /dev/null and b/nxhtml/nxhtml/doc/img/continue-play.jpg differ diff --git a/nxhtml/nxhtml/doc/img/divine2.jpg b/nxhtml/nxhtml/doc/img/divine2.jpg new file mode 100644 index 0000000..6a8ea51 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/divine2.jpg differ diff --git a/nxhtml/nxhtml/doc/img/edit-part.png b/nxhtml/nxhtml/doc/img/edit-part.png new file mode 100644 index 0000000..7c6ab2a Binary files /dev/null and b/nxhtml/nxhtml/doc/img/edit-part.png differ diff --git a/nxhtml/nxhtml/doc/img/editing-web-files.png b/nxhtml/nxhtml/doc/img/editing-web-files.png new file mode 100644 index 0000000..ce30bdf Binary files /dev/null and b/nxhtml/nxhtml/doc/img/editing-web-files.png differ diff --git a/nxhtml/nxhtml/doc/img/editing-web-files.xcf b/nxhtml/nxhtml/doc/img/editing-web-files.xcf new file mode 100644 index 0000000..6703882 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/editing-web-files.xcf differ diff --git a/nxhtml/nxhtml/doc/img/emacs-style-completion.png b/nxhtml/nxhtml/doc/img/emacs-style-completion.png new file mode 100644 index 0000000..0a404fb Binary files /dev/null and b/nxhtml/nxhtml/doc/img/emacs-style-completion.png differ diff --git a/nxhtml/nxhtml/doc/img/emacsP.png b/nxhtml/nxhtml/doc/img/emacsP.png new file mode 100644 index 0000000..e0a5ecb Binary files /dev/null and b/nxhtml/nxhtml/doc/img/emacsP.png differ diff --git a/nxhtml/nxhtml/doc/img/emacsP16.png b/nxhtml/nxhtml/doc/img/emacsP16.png new file mode 100644 index 0000000..54b597b Binary files /dev/null and b/nxhtml/nxhtml/doc/img/emacsP16.png differ diff --git a/nxhtml/nxhtml/doc/img/embedded-css.png b/nxhtml/nxhtml/doc/img/embedded-css.png new file mode 100644 index 0000000..25c11d4 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/embedded-css.png differ diff --git a/nxhtml/nxhtml/doc/img/embedded-xhtml.png b/nxhtml/nxhtml/doc/img/embedded-xhtml.png new file mode 100644 index 0000000..85b98f3 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/embedded-xhtml.png differ diff --git a/nxhtml/nxhtml/doc/img/foldit-closed.png b/nxhtml/nxhtml/doc/img/foldit-closed.png new file mode 100644 index 0000000..fc1b49c Binary files /dev/null and b/nxhtml/nxhtml/doc/img/foldit-closed.png differ diff --git a/nxhtml/nxhtml/doc/img/foldit-temp-opened.png b/nxhtml/nxhtml/doc/img/foldit-temp-opened.png new file mode 100644 index 0000000..5e02725 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/foldit-temp-opened.png differ diff --git a/nxhtml/nxhtml/doc/img/fun-brain-2.png b/nxhtml/nxhtml/doc/img/fun-brain-2.png new file mode 100644 index 0000000..a24f0f4 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/fun-brain-2.png differ diff --git a/nxhtml/nxhtml/doc/img/getitbuttons-1.png b/nxhtml/nxhtml/doc/img/getitbuttons-1.png new file mode 100644 index 0000000..5f3c757 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/getitbuttons-1.png differ diff --git a/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf b/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf new file mode 100644 index 0000000..8ec9aaa Binary files /dev/null and b/nxhtml/nxhtml/doc/img/getitbuttons-1.xcf differ diff --git a/nxhtml/nxhtml/doc/img/getitbuttons-2.png b/nxhtml/nxhtml/doc/img/getitbuttons-2.png new file mode 100644 index 0000000..c3615f3 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/getitbuttons-2.png differ diff --git a/nxhtml/nxhtml/doc/img/getitbuttons.png b/nxhtml/nxhtml/doc/img/getitbuttons.png new file mode 100644 index 0000000..b9b0c43 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/getitbuttons.png differ diff --git a/nxhtml/nxhtml/doc/img/getitbuttons.xcf b/nxhtml/nxhtml/doc/img/getitbuttons.xcf new file mode 100644 index 0000000..ce416ce Binary files /dev/null and b/nxhtml/nxhtml/doc/img/getitbuttons.xcf differ diff --git a/nxhtml/nxhtml/doc/img/giraffe.jpg b/nxhtml/nxhtml/doc/img/giraffe.jpg new file mode 100644 index 0000000..6bf9b57 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/giraffe.jpg differ diff --git a/nxhtml/nxhtml/doc/img/healthy_feet2.jpg b/nxhtml/nxhtml/doc/img/healthy_feet2.jpg new file mode 100644 index 0000000..ed3ab6f Binary files /dev/null and b/nxhtml/nxhtml/doc/img/healthy_feet2.jpg differ diff --git a/nxhtml/nxhtml/doc/img/itsalltext-pref.png b/nxhtml/nxhtml/doc/img/itsalltext-pref.png new file mode 100644 index 0000000..3b3d9f1 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/itsalltext-pref.png differ diff --git a/nxhtml/nxhtml/doc/img/links-appmenu.png b/nxhtml/nxhtml/doc/img/links-appmenu.png new file mode 100644 index 0000000..a03ba4a Binary files /dev/null and b/nxhtml/nxhtml/doc/img/links-appmenu.png differ diff --git a/nxhtml/nxhtml/doc/img/nxml-where.png b/nxhtml/nxhtml/doc/img/nxml-where.png new file mode 100644 index 0000000..102d084 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/nxml-where.png differ diff --git a/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png b/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png new file mode 100644 index 0000000..c204f4d Binary files /dev/null and b/nxhtml/nxhtml/doc/img/php-in-nxhtml-2.png differ diff --git a/nxhtml/nxhtml/doc/img/php-in-nxhtml.png b/nxhtml/nxhtml/doc/img/php-in-nxhtml.png new file mode 100644 index 0000000..cda754a Binary files /dev/null and b/nxhtml/nxhtml/doc/img/php-in-nxhtml.png differ diff --git a/nxhtml/nxhtml/doc/img/php-in-php.png b/nxhtml/nxhtml/doc/img/php-in-php.png new file mode 100644 index 0000000..c7664da Binary files /dev/null and b/nxhtml/nxhtml/doc/img/php-in-php.png differ diff --git a/nxhtml/nxhtml/doc/img/php-in-xhtml.png b/nxhtml/nxhtml/doc/img/php-in-xhtml.png new file mode 100644 index 0000000..310d07f Binary files /dev/null and b/nxhtml/nxhtml/doc/img/php-in-xhtml.png differ diff --git a/nxhtml/nxhtml/doc/img/popup-compl.png b/nxhtml/nxhtml/doc/img/popup-compl.png new file mode 100644 index 0000000..a40bd49 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/popup-compl.png differ diff --git a/nxhtml/nxhtml/doc/img/raindrops2.jpg b/nxhtml/nxhtml/doc/img/raindrops2.jpg new file mode 100644 index 0000000..04d0610 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/raindrops2.jpg differ diff --git a/nxhtml/nxhtml/doc/img/region-selected-after.png b/nxhtml/nxhtml/doc/img/region-selected-after.png new file mode 100644 index 0000000..c7ea553 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/region-selected-after.png differ diff --git a/nxhtml/nxhtml/doc/img/region-selected-completion.png b/nxhtml/nxhtml/doc/img/region-selected-completion.png new file mode 100644 index 0000000..b971b9d Binary files /dev/null and b/nxhtml/nxhtml/doc/img/region-selected-completion.png differ diff --git a/nxhtml/nxhtml/doc/img/region-selected.png b/nxhtml/nxhtml/doc/img/region-selected.png new file mode 100644 index 0000000..0a2358b Binary files /dev/null and b/nxhtml/nxhtml/doc/img/region-selected.png differ diff --git a/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg b/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg new file mode 100644 index 0000000..2689598 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/rembrandt-self-portrait.jpg differ diff --git a/nxhtml/nxhtml/doc/img/style-in-nxhtml.png b/nxhtml/nxhtml/doc/img/style-in-nxhtml.png new file mode 100644 index 0000000..151681d Binary files /dev/null and b/nxhtml/nxhtml/doc/img/style-in-nxhtml.png differ diff --git a/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png b/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png new file mode 100644 index 0000000..4ae2ff8 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/use-nXhtml-trans.png differ diff --git a/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png b/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png new file mode 100644 index 0000000..c348c92 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/use-nXhtml-trans2.png differ diff --git a/nxhtml/nxhtml/doc/img/use-nXhtml.png b/nxhtml/nxhtml/doc/img/use-nXhtml.png new file mode 100644 index 0000000..408980f Binary files /dev/null and b/nxhtml/nxhtml/doc/img/use-nXhtml.png differ diff --git a/nxhtml/nxhtml/doc/img/use-nXhtml.xcf b/nxhtml/nxhtml/doc/img/use-nXhtml.xcf new file mode 100644 index 0000000..d42da0b Binary files /dev/null and b/nxhtml/nxhtml/doc/img/use-nXhtml.xcf differ diff --git a/nxhtml/nxhtml/doc/img/validation-error.png b/nxhtml/nxhtml/doc/img/validation-error.png new file mode 100644 index 0000000..7682642 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/validation-error.png differ diff --git a/nxhtml/nxhtml/doc/img/volga.jpg b/nxhtml/nxhtml/doc/img/volga.jpg new file mode 100644 index 0000000..c11e93c Binary files /dev/null and b/nxhtml/nxhtml/doc/img/volga.jpg differ diff --git a/nxhtml/nxhtml/doc/img/xml-validation-header.png b/nxhtml/nxhtml/doc/img/xml-validation-header.png new file mode 100644 index 0000000..2093781 Binary files /dev/null and b/nxhtml/nxhtml/doc/img/xml-validation-header.png differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif new file mode 100644 index 0000000..316dea7 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow1.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif new file mode 100644 index 0000000..24a6be1 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/carrow2.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif new file mode 100644 index 0000000..218233d Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png new file mode 100644 index 0000000..61e8660 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche1.png differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif new file mode 100644 index 0000000..dc91f06 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png new file mode 100644 index 0000000..bbf66a1 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/fleche2.png differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif new file mode 100644 index 0000000..99368d6 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/loading-bar-black.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif new file mode 100644 index 0000000..d145e66 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.gif differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png new file mode 100644 index 0000000..aebf498 Binary files /dev/null and b/nxhtml/nxhtml/doc/js/smoothgallery/css/img/open.png differ diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css b/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css new file mode 100644 index 0000000..b0d87ec --- /dev/null +++ b/nxhtml/nxhtml/doc/js/smoothgallery/css/jd.gallery.css @@ -0,0 +1,238 @@ +#myGallery +{ + width: 460px; + height: 345px; + z-index:5; + display: none; + border: 1px solid #000; +} + +.jdGallery +{ + overflow: hidden; + position: relative; +} + +.jdGallery img +{ + border: 0; + margin: 0; +} + +.jdGallery .slideElement +{ + width: 100%; + height: 100%; + background-color: #000; + background-repeat: no-repeat; +} + +.jdGallery .loadingElement +{ + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background-color: #000; + background-repeat: no-repeat; + background-position: center center; + background-image: url('img/loading-bar-black.gif'); +} + +.jdGallery .slideInfoZone +{ + position: absolute; + z-index: 10; + width: 100%; + margin: 0px; + left: 0; + bottom: 0; + height: 40px; + background: #333; + color: #fff; + text-indent: 0; + overflow: hidden; +} + +* html .jdGallery .slideInfoZone +{ + bottom: -1px; +} + +.jdGallery .slideInfoZone h2 +{ + padding: 0; + font-size: 80%; + margin: 0; + margin: 2px 5px; + font-weight: bold; + color: inherit; +} + +.jdGallery .slideInfoZone p +{ + padding: 0; + font-size: 80%; + margin: 2px 5px; + color: #eee; +} + +.jdGallery div.carouselContainer +{ + position: absolute; + height: 135px; + width: 100%; + z-index: 10; + margin: 0px; + left: 0; + top: 0; +} + +.jdGallery a.carouselBtn +{ + position: absolute; + bottom: 0; + right: 30px; + height: 20px; + /*width: 100px; background: url('img/carousel_btn.gif') no-repeat;*/ + text-align: center; + padding: 0 10px; + font-size: 13px; + background: #333; + color: #fff; + cursor: pointer; +} + +.jdGallery .carousel +{ + position: absolute; + width: 100%; + margin: 0px; + left: 0; + top: 0; + height: 115px; + background: #333; + color: #fff; + text-indent: 0; + overflow: hidden; +} + +.jdGallery .carousel .carouselWrapper +{ + position: absolute; + width: 100%; + height: 78px; + top: 10px; + left: 0; + overflow: hidden; +} + +.jdGallery .carousel .carouselInner +{ + position: relative; +} + +.jdGallery .carousel .carouselInner .thumbnail +{ + cursor: pointer; + background: #000; + background-position: center center; + float: left; + border: solid 1px #fff; +} + +.jdGallery .carousel .label +{ + font-size: 13px; + position: absolute; + bottom: 5px; + left: 10px; + padding: 0; + margin: 0; +} + +.jdGallery .carousel .label .number +{ + color: #b5b5b5; +} + +.jdGallery a +{ + font-size: 100%; + text-decoration: none; + color: inherit; +} + +.jdGallery a.right, .jdGallery a.left +{ + position: absolute; + height: 99%; + width: 25%; + cursor: pointer; + z-index:10; + filter:alpha(opacity=20); + -moz-opacity:0.2; + -khtml-opacity: 0.2; + opacity: 0.2; +} + +* html .jdGallery a.right, * html .jdGallery a.left +{ + filter:alpha(opacity=50); +} + +.jdGallery a.right:hover, .jdGallery a.left:hover +{ + filter:alpha(opacity=80); + -moz-opacity:0.8; + -khtml-opacity: 0.8; + opacity: 0.8; +} + +.jdGallery a.left +{ + left: 0; + top: 0; + background: url('img/fleche1.png') no-repeat center left; +} + +* html .jdGallery a.left { background: url('img/fleche1.gif') no-repeat center left; } + +.jdGallery a.right +{ + right: 0; + top: 0; + background: url('img/fleche2.png') no-repeat center right; +} + +* html .jdGallery a.right { background: url('img/fleche2.gif') no-repeat center right; } + +.jdGallery a.open +{ + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.withArrows a.open +{ + position: absolute; + top: 0; + left: 25%; + height: 99%; + width: 50%; + cursor: pointer; + z-index: 10; + background: none; + -moz-opacity:0.8; + -khtml-opacity: 0.8; + opacity: 0.8; +} + +.withArrows a.open:hover { background: url('img/open.png') no-repeat center center; } + +* html .withArrows a.open:hover { background: url('img/open.gif') no-repeat center center; + filter:alpha(opacity=80); } + diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css b/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css new file mode 100644 index 0000000..9c807b6 --- /dev/null +++ b/nxhtml/nxhtml/doc/js/smoothgallery/css/layout.css @@ -0,0 +1,91 @@ +body { + color: #ccc; + font-family: "Trebuchet MS", "Lucida Grande", Arial, Helvetica, sans-serif; + margin: 0 auto; + padding: 0; + font-size: 1.0em; + background: #111 url('../images/bg/gradient1.gif') top left repeat-x; +} + +h1 +{ + color: #fff; + font-size: 47px; + font-weight: bolder; + margin: 0 40px; + padding: 0.08em 0; +} + +h1 sup +{ + color: #ddd; +} + +h1 a +{ + color: #fff; + text-decoration: none; +} + +h1 .company, h1 a .company +{ + color: #d01a71; +} + +h2 +{ + color: #ddd; + font-size: 2.5em; +} + +h3 +{ + color: #fff; + font-size: 1.5em; +} + +h4 +{ + font-size: 1.3em; +} + +.content +{ + margin: 0 20px; +} + +.content a +{ + color: #fff; +} + + +.content p.linkage +{ + margin-top: 2em; + text-align: right; + font-size: 1.7em; + color: #ddd; +} + +.content p.linkage a { color: #fff; } + +/*.content p.linkage a +{ + color: #fff; + background: url('../images/bg/biglink_off.gif') center right no-repeat; + padding: 10px 20px; + text-decoration: none; +} + +.content p.linkage a:hover +{ + background: url('../images/bg/biglink_on.gif') center right no-repeat; + font-style: italic; +}*/ + +#myGallery +{ + text-align: left; + margin: 0 auto; +} diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js b/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js new file mode 100644 index 0000000..d9181d0 --- /dev/null +++ b/nxhtml/nxhtml/doc/js/smoothgallery/scripts/jd.gallery.js @@ -0,0 +1,449 @@ +/* + This file is part of JonDesign's SmoothGallery v1.0.1. + + JonDesign's SmoothGallery is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + JonDesign's SmoothGallery is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JonDesign's SmoothGallery; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/) + Contributed code by: + - Christian Ehret (bugfix) + - Nitrix (bugfix) + - Valerio from Mad4Milk for his great help with the carousel scrolling and many other things. + - Archie Cowan for helping me find a bugfix on carousel inner width problem. + Many thanks to: + - The mootools team for the great mootools lib, and it's help and support throughout the project. +*/ + + +var $removeEvents = function (object, type) +{ + if (!object.events) return object; + if (type){ + if (!object.events[type]) return object; + for (var fn in object.events[type]) object.removeEvent(type, fn); + object.events[type] = null; + } else { + for (var evType in object.events) object.removeEvents(evType); + object.events = null; + } + return object; +}; + + +// declaring the class +var gallery = new Class({ + initialize: function(element, options) { + this.setOptions({ + showArrows: true, + showCarousel: true, + showInfopane: true, + showDescription: false, + thumbHeight: 75, + thumbWidth: 100, + thumbSpacing: 10, + embedLinks: true, + fadeDuration: 500, + timed: false, + delay: 9000, + preloader: true, + manualData: [], + populateData: true, + elementSelector: "div.imageElement", + titleSelector: "h3", + subtitleSelector: "p", + descriptionSelector: "div", + linkSelector: "a.open", + imageSelector: "img.full", + thumbnailSelector: "img.thumbnail", + slideInfoZoneOpacity: 0.7, + carouselMinimizedOpacity: 0.4, + carouselMinimizedHeight: 20, + carouselMaximizedOpacity: 0.7, + destroyAfterPopulate: true, + baseClass: 'jdGallery', + withArrowsClass: 'withArrows', + textShowCarousel: 'Pictures', + useThumbGenerator: false, + thumbGenerator: 'resizer.php' + }, options); + this.fireEvent('onInit'); + this.currentIter = 0; + this.lastIter = 0; + this.maxIter = 0; + this.galleryElement = element; + this.galleryData = this.options.manualData; + this.galleryInit = 1; + this.galleryElements = Array(); + this.thumbnailElements = Array(); + this.galleryElement.addClass(this.options.baseClass); + if (this.options.populateData) + this.populateData(); + element.style.display="block"; + + if (this.options.embedLinks) + { + this.currentLink = new Element('a').addClass('open').setProperties({ + href: '#', + title: '' + }).injectInside(element); + if ((!this.options.showArrows) && (!this.options.showCarousel)) + this.galleryElement = element = this.currentLink; + else + this.currentLink.setStyle('display', 'none'); + } + + this.constructElements(); + if ((data.length>1)&&(this.options.showArrows)) + { + var leftArrow = new Element('a').addClass('left').addEvent( + 'click', + this.prevItem.bind(this) + ).injectInside(element); + var rightArrow = new Element('a').addClass('right').addEvent( + 'click', + this.nextItem.bind(this) + ).injectInside(element); + this.galleryElement.addClass(this.options.withArrowsClass); + } + this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element); + if (this.options.showInfopane) this.initInfoSlideshow(); + if (this.options.showCarousel) this.initCarousel(); + this.doSlideShow(1); + }, + populateData: function() { + currentArrayPlace = this.galleryData.length; + options = this.options; + data = this.galleryData; + this.galleryElement.getElements(options.elementSelector).each(function(el) { + elementDict = { + image: el.getElement(options.imageSelector).getProperty('src'), + number: currentArrayPlace + }; + if ((options.showInfopane) | (options.showCarousel)) + Object.extend(elementDict, { + title: el.getElement(options.titleSelector).innerHTML, + description: el.getElement(options.subtitleSelector).innerHTML + }); + if ((options.showDescription)) + Object.extend(elementDict, { + outsideDescription: el.getElement(options.descriptionSelector).innerHTML + }); + if (options.embedLinks) + Object.extend(elementDict, { + link: el.getElement(options.linkSelector).href||false, + linkTitle: el.getElement(options.linkSelector).title||false + }); + if ((!options.useThumbGenerator) && (options.showCarousel)) + Object.extend(elementDict, { + thumbnail: el.getElement(options.thumbnailSelector).src + }); + else if (options.useThumbGenerator) + Object.extend(elementDict, { + thumbnail: 'resizer.php?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight + }); + + data[currentArrayPlace] = elementDict; + currentArrayPlace++; + if (this.options.destroyAfterPopulate) + el.remove(); + }); + this.galleryData = data; + this.fireEvent('onPopulated'); + }, + constructElements: function() { + el = this.galleryElement; + this.maxIter = this.galleryData.length; + var currentImg; + for(i=0;i= this.maxIter) + this.nextIter = 0; + this.galleryInit = 0; + this.goTo(this.nextIter); + }, + prevItem: function() { + this.fireEvent('onPreviousCalled'); + this.nextIter = this.currentIter-1; + if (this.nextIter <= -1) + this.nextIter = this.maxIter - 1; + this.galleryInit = 0; + this.goTo(this.nextIter); + }, + goTo: function(num) { + this.clearTimer(); + if (this.options.embedLinks) + this.clearLink(); + if (this.options.showInfopane) + { + this.slideInfoZone.clearChain(); + this.hideInfoSlideShow().chain(this.changeItem.pass(num, this)); + } else + this.changeItem.delay(500, this, num); + if (this.options.embedLinks) + this.makeLink(num); + if (this.options.showDescription) + this.showDescription(num); + this.prepareTimer(); + /*if (this.options.showCarousel) + this.clearThumbnailsHighlights();*/ + }, + changeItem: function(num) { + this.fireEvent('onStartChanging'); + this.galleryInit = 0; + if (this.currentIter != num) + { + for(i=0;i this.currentIter) this.galleryElements[num].custom(1); + else + { + this.galleryElements[num].set(1); + this.galleryElements[this.currentIter].custom(0); + } + this.currentIter = num; + } + this.doSlideShow.bind(this)(); + this.fireEvent('onChanged'); + }, + clearTimer: function() { + if (this.options.timed) + $clear(this.timer); + }, + prepareTimer: function() { + if (this.options.timed) + this.timer = this.nextItem.delay(this.options.delay, this); + }, + doSlideShow: function(position) { + if (this.galleryInit == 1) + { + imgPreloader = new Image(); + imgPreloader.onload=function(){ + this.startSlideShow.delay(10, this); + }.bind(this); + imgPreloader.src = this.galleryData[0].image; + } else { + if (this.options.showInfopane) + { + if (this.options.showInfopane) + { + this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this); + } else + if (this.options.showCarousel) + this.centerCarouselOn(position); + } + } + }, + initCarousel: function () { + var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement); + this.carouselContainer = new Fx.Styles(carouselContainerElement, {transition: Fx.Transitions.expoOut}); + this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight; + this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)}); + + this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({ + title: this.options.textShowCarousel + }).setHTML(this.options.textShowCarousel).injectInside(carouselContainerElement); + + this.carouselBtn.addEvent( + 'click', + function () { + this.carouselContainer.clearTimer(); + this.toggleCarousel(); + }.bind(this) + ); + this.carouselActive = false; + + var carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement); + this.carousel = new Fx.Styles(carouselElement); + + this.carouselLabel = new Element('p').addClass('label').injectInside(this.carousel.element); + this.carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(this.carousel.element); + this.carouselInner = new Element('div').addClass('carouselInner').injectInside(this.carouselWrapper); + + this.carouselWrapper.scroller = new Scroller(this.carouselWrapper, { + area: 100, + velocity: 0.2 + }) + + this.carouselWrapper.elementScroller = new Fx.Scroll(this.carouselWrapper, { + duration: 400, + onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller), + onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller) + }); + + this.constructThumbnails(); + + this.carouselInner.style.width = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing)) - this.options.thumbSpacing + this.options.thumbWidth) + "px"; + }, + toggleCarousel: function() { + if (this.carouselActive) + this.hideCarousel(); + else + this.showCarousel(); + }, + showCarousel: function () { + this.fireEvent('onShowCarousel'); + this.carouselContainer.custom({ + 'opacity': this.options.carouselMaximizedOpacity, + 'top': 0 + }).addEvent('onComplete', function() { this.carouselActive = true; this.carouselWrapper.scroller.start(); }.bind(this)); + }, + hideCarousel: function () { + this.fireEvent('onHideCarousel'); + this.carouselContainer.custom({ + 'opacity': this.options.carouselMinimizedOpacity, + 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight) + }).addEvent('onComplete', function() { this.carouselActive = false; this.carouselWrapper.scroller.stop(); }.bind(this)); + }, + constructThumbnails: function () { + element = this.carouselInner; + for(i=0;i' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ": " + myself.relatedImage.title); + }.pass(currentImg, this), + 'mouseout': function (myself) { + myself.clearTimer(); + myself.custom(0.2); + }.pass(currentImg, this), + 'click': function (myself) { + this.goTo(myself.relatedImage.number); + }.pass(currentImg, this) + }); + + currentImg.relatedImage = this.galleryData[i]; + this.thumbnailElements[parseInt(i)] = currentImg; + } + }, + clearThumbnailsHighlights: function() + { + for(i=0;i, MIT Style License. +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('k 11=f(1S){k 4s=f(){j(9.1e&&Y[0]!=\'7h\')h 9.1e.2m(9,Y);Q h 9};I(k n W 9)4s[n]=9[n];4s.U=1S;h 4s};11.1G=f(){};11.U={N:f(1S){k 4r=M 9(\'7h\');k 7g=f(2s,2f){j(!2s.2m||!2f.2m)h T;h f(){9.1t=2s;h 2f.2m(9,Y)}};I(k n W 1S){k 2s=4r[n];k 2f=1S[n];j(2s&&2s!=2f)2f=7g(2s,2f)||2f;4r[n]=2f}h M 11(4r)},1T:f(1S){I(k n W 1S)9.U[n]=1S[n]}};1H.N=f(){k R=Y;R=(R[1])?[R[0],R[1]]:[9,R[0]];I(k n W R[1])R[0][n]=R[1][n];h R[0]};1H.5p=f(){I(k i=0;i\'));$1o(9.96,f(4e){j(4e.24!=\'24\')l.4d(4e.24,4e.K)});j(9.26)9.6G(l);h l}6F:9.6E(n,K)}h 9},95:f(1L){I(k n W 1L)9.4d(n,1L[n]);h 9},94:f(6D){9.93=6D;h 9},92:f(n){h(n==\'6C\')?9.1d:9.6k(n)},3C:f(){h 9.41.3G()},2O:f(){k l=9,4c=0,4b=0;91{4c+=l.4c||0;4b+=l.4b||0;l=l.90}34(l);h{\'x\':4c,\'y\':4b}},2a:f(x,y){9.3U=x;9.3V=y},3P:f(){h{\'1V\':{\'x\':9.3U,\'y\':9.3V},\'2A\':{\'x\':9.2x,\'y\':9.2v},\'3O\':{\'x\':9.68,\'y\':9.69}}},4D:f(){h 9.2O().y},4F:f(){h 9.2O().x},8Z:f(){k 5i=9.2O();k u={\'3j\':9.2x,\'3i\':9.2v,\'2i\':5i.x,\'2w\':5i.y};u.5a=u.2i+u.3j;u.6B=u.2w+u.3i;h u},2F:f(){2c(9.3C()){1c\'2U\':j(9.6A!=-1)h 9.m[9.6A].K;1P;1c\'8Y\':j(!(9.8X&&[\'8W\',\'8V\'].15(9.q))&&![\'3S\',\'33\',\'8U\'].15(9.q))1P;1c\'8T\':h 9.K}h T}});k 8S=12;12.1a=L.1a=1b.U.1a;12.1E=L.1E=1b.U.1E;k 31={1w:[],6z:f(r){31.1w.18(r)},5g:f(){12.1E(\'6y\',31.5g);31.1w.1o(f(l){l.5h();I(k p W 1b.U)2I[p]=12[p]=L[p]=l[p]=1K;l.N=1K})}};12.1a(\'6y\',31.5g);k 3F=M 11({1e:f(o){9.o=o||12.o;9.q=9.o.q;9.3H=9.o.3H||9.o.8R;j(9.3H.6x==3)9.3H=9.3H.26;9.8Q=9.o.8P;9.8O=9.o.8N;9.8M=9.o.8L;9.8K=9.o.8J;j([\'5f\',\'2M\'].15(9.q)){9.3f=9.o.6w?(9.o.6w/ (12.51 ? -6v : 6v)) : -(9.o.8I || 0) /3}Q j(9.q.15(\'1O\')){9.5d=9.o.6r||9.o.8H;I(k 24 W 3F.1u){j(3F.1u[24]==9.5d)k 6u=24}9.1O=6u||5e.8G(9.5d).3G()}Q j(9.q.15(\'2l\')||9.q==\'8F\'){9.1y={\'x\':9.o.5c||9.o.6t+L.2r.3U,\'y\':9.o.5b||9.o.6s+L.2r.3V};9.5y={\'x\':9.o.5c?9.o.5c-12.66:9.o.6t,\'y\':9.o.5b?9.o.5b-12.67:9.o.6s};9.8E=(9.o.6r==3)||(9.o.8D==2);2c(9.q){1c\'8C\':9.4a=9.o.4a||9.o.8B;1P;1c\'8A\':9.4a=9.o.4a||9.o.5L}}},1s:f(){9.49();9.48();h 9},49:f(){j(9.o.49)9.o.49();Q 9.o.8z=1g;h 9},48:f(){j(9.o.48)9.o.48();Q 9.o.8y=T;h 9}});3F.1u={\'8x\':13,\'8w\':38,\'8v\':40,\'2i\':37,\'5a\':39,\'8u\':27,\'8t\':32,\'8s\':8,\'8r\':46};59.N({2y:f(J,R){h 9.2e({\'J\':J,\'Y\':R,\'o\':3F})}});k 5S=M 11({8q:f(O){9.2H=9.2H||[];9.2H.18(O);h 9},5Z:f(){j(9.2H&&9.2H.14)9.2H.47(0,1)[0].2d(10,9)},8p:f(){9.2H=[]}});k 3c=M 11({1a:f(q,O){j(O!=11.1G){9.V=9.V||{};9.V[q]=9.V[q]||[];j(!9.V[q].15(O))9.V[q].18(O)}h 9},1x:f(q,R,2d){j(9.V&&9.V[q]){9.V[q].1o(f(O){O.2e({\'J\':9,\'2d\':2d,\'Y\':R})()},9)}h 9},1E:f(q,O){j(9.V&&9.V[q])9.V[q].3Z(O);h 9}});k 3b=M 11({2N:f(6q,m){9.m=1H.N(6q,m);j(9.1a){I(k 3E W 9.m){j(($q(9.m[3E])==\'f\')&&3E.15(\'^58[A-Z]\'))9.1a(3E,9.m[3E])}}h 9}});f $E(1v,3D){h($(3D)||L).42(1v)};f $8o(1v,3D){h($(3D)||L).2G(1v)};1b.N({3B:f(1v){k 1Q=[];1v.45().4Y(\' \').1o(f(43,i){k 1q=43.28(\'^(\\\\w*|\\\\*)(?:#([\\\\6p-]+)|\\\\.([\\\\6p-]+))?(?:\\\\[["\\\']?(\\\\w+)["\\\']?(?:([\\\\*\\\\^\\\\$]?=)["\\\']?(\\\\w*)["\\\']?)?\\\\])?$\');j(!1q)h;1q[1]=1q[1]||\'*\';j(i==0){j(1q[2]){k l=9.44(1q[2]);j(!l||((1q[1]!=\'*\')&&(1b.U.3C.1i(l)!=1q[1])))h;1Q=[l]}Q{1Q=$A(9.56(1q[1]))}}Q{1Q=1N.U.6m.1i(1Q,1q[1]);j(1q[2])1Q=1N.U.6o.1i(1Q,1q[2])}j(1q[3])1Q=1N.U.6n.1i(1Q,1q[3]);j(1q[4])1Q=1N.U.6l.1i(1Q,1q[4],1q[6],1q[5])},9);h $$(1Q)},44:f(2Z){k l=L.44(2Z);j(!l)h T;I(k 1t=l.26;1t!=9;1t=1t.26){j(!1t)h T}h l},42:f(1v){h 9.2G(1v)[0]},2G:f(1v){k 57=[];1v.4Y(\',\').1o(f(43){57.N(9.3B(43))},9);h $$(57)}});L.N=1H.N;L.N({8n:f(1d){h L.3B(\'.\'+1d)},42:1b.U.42,3B:1b.U.3B,2G:1b.U.2G});1N.N({6o:f(2Z,8m){k 1p=[];9.1o(f(l){j(l.2Z==2Z)1p.18(l)});h 1p},6n:f(1d){k 1p=[];9.1o(f(l){j(1b.U.3A.1i(l,1d))1p.18(l)});h 1p},6m:f(41){k 1p=[];9.1o(f(l){1p.N(l.56(41))});h 1p},6l:f(24,K,55){k 1p=[];9.1o(f(l){k 30=l.6k(24);j(!30)h 1p;j(!55)h 1p.18(l);2c(55){1c\'*=\':j(30.15(K))1p.18(l);1P;1c\'=\':j(30==K)1p.18(l);1P;1c\'^=\':j(30.15(\'^\'+K))1p.18(l);1P;1c\'$=\':j(30.15(K+\'$\'))1p.18(l)}h 1p});h 1p}});k 6j=M 11({14:0,1e:f(u){9.u={};I(k n W u){9.u[n]=u[n];9.14++}},8l:f(1O){h 9.u[1O]},1U:f(1O,K){j(K==1K)h T;j(9.u[1O]==3z)9.14++;9.u[1O]=K;h 9},3Z:f(1O){j(9.u[1O]==3z)h T;k u={};9.14--;I(k n W 9.u){j(n!=1O)u[n]=9.u[n]}9.u=u;h 9},1o:f(O,J){I(k n W 9.u)O.1i(J||9,n,9.u[n])},N:f(u){9.1e(1H.N(9.u,u));h 9},1G:f(){h(9.14==0)},1u:f(){k 1u=[];I(k n W 9.u)1u.18(n);h 1u},1z:f(){k 1z=[];I(k n W 9.u)1z.18(9.u[n]);h 1z}});f $H(u){h M 6j(u)};k 2q=M 11({1e:f(1A){j(1A.6i&&1A.6h)h 1A;k 1l=(1A.18)?1A:1A.3s(1g);h 1H.N(1l,2q.U)},6i:f(){k 3y=$A(Y);k 3x=50;j($q(3y[3y.14-1])==\'5N\')3x=3y.8k();k 1l=9.54();3y.1o(f(1A){1A=M 2q(1A);I(k i=0;i<3;i++)1l[i]=G.3e((1l[i]/ 3g * (3g - 3x)) + (1A[i] /3g*3x))});h M 2q(1l)},6h:f(){k 1l=[];I(k i=0;i<3;i++)1l.18(8j-9[i]);h M 2q(1l)}});f $C(1A){h M 2q(1A)};12.N=1H.N;12.N({8i:f(){j(9.53)6g{L.8h("8g",T,1g)}6f(e){}},1a:f(q,O){j(q==\'3u\'){j(9.3Y)O();Q j(!9.V||!9.V.3u){k 3v=f(){j(9.3Y)h;9.3Y=1g;j(9.1f)9.1f=$3Q(9.1f);1b.U.1x.1i(9,\'3u\');9.V.3u=1K}.J(9);j(L.3X&&9.3W){9.1f=f(){j([\'3Y\',\'6d\'].15(L.3X))3v()}.2k(50)}Q j(L.3X&&9.3w){L.8f("<52 2Z=6e 8e 8d=8c:8b(0)><\\/52>");$(\'6e\').8a=f(){j(9.3X==\'6d\')3v()}}Q{9.1a("89",3v);L.1a("88",3v)}}}1b.U.1a.1i(9,q,O);h 9},87:f(6c){h 9.1a(\'3u\',6c)}});12.N({63:f(){j(9.3W||9.51)h 9.86;Q h L.2r.6b||L.4N.6b},62:f(){j(9.3W||9.51)h 9.85;h L.2r.6a||L.4N.6a},60:f(){h L.2r.69},61:f(){h L.2r.68},64:f(){h 9.67||L.2r.3V},65:f(){h 9.66||L.2r.3U},3P:f(){h{\'1V\':{\'x\':9.65(),\'y\':9.64()},\'2A\':{\'x\':9.63(),\'y\':9.62()},\'3O\':{\'x\':9.61(),\'y\':9.60()}}},2O:f(){h{\'x\':0,\'y\':0}}});k X={};X.1C=M 11({2j:f(){h{2K:11.1G,2g:11.1G,5T:11.1G,5Y:X.2Q.4U,4Z:84,1J:\'4I\',2T:1g,5U:50}},1e:f(m){9.r=9.r||1K;9.2N(9.2j(),m);j(9.m.1e)9.m.1e.1i(9)},19:f(){k 2Y=M 5W().5V();j(2Y<9.2Y+9.m.4Z){9.5X=2Y-9.2Y;9.2E();9.2o()}Q{9.1s(1g);9.P=9.B;9.2o();9.1x(\'2g\',9.r,10);9.5Z()}},1U:f(B){9.P=B;9.2o();h 9},2E:f(){9.P=9.2D(9.F,9.B)},2D:f(F,B){h 9.m.5Y(9.5X,F,(B-F),9.m.4Z)},1m:f(F,B){j(!9.m.2T)9.1s();Q j(9.1f)h 9;9.F=F;9.B=B;9.2Y=M 5W().5V();9.1f=9.19.2k(G.3e(83/9.m.5U),9);9.1x(\'2K\',9.r);h 9},1s:f(2h){j(!9.1f)h 9;9.1f=$3Q(9.1f);j(!2h)9.1x(\'5T\',9.r);h 9},82:f(F,B){h 9.1m(F,B)},81:f(2h){h 9.1s(2h)}});X.1C.1T(M 5S);X.1C.1T(M 3c);X.1C.1T(M 3b);X.2Q={5F:f(t,b,c,d){h c*t/d+b},4U:f(t,b,c,d){h-c/2*(G.4T(G.1X*t/d)-1)+b}};X.23={2U:f(n,B){j(n.15(\'1A\',\'i\'))h 9.2q;j(B.15&&B.15(\' \'))h 9.3T;h 9.5R},1M:f(l,n,2X){j(!2X.18)2X=[2X];k F=2X[0],B=2X[1];j(!B&&B!=0){B=F;F=l.1W(n)}k 17=9.2U(n,B);h{F:17.1M(F),B:17.1M(B),17:17}}};X.23.5R={1M:f(K){h 3t(K)},2V:f(F,B,2W){h 2W.2D(F,B)},2F:f(K,1J){h K+1J}};X.23.3T={1M:f(K){h K.18?K:K.4Y(\' \').4X(f(v){h 3t(v)})},2V:f(F,B,2W){k P=[];I(k i=0;i9.m.3N){L.1E(\'2P\',9.1I.3l);L.1a(\'2P\',9.1I.29);9.29(o);9.1x(\'5B\',9.r)}o.1s()},29:f(o){9.4O=T;9.2l.P=o.1y;I(k z W 9.m.2u){9.K.P[z]=o.1y[z]-9.2l.1D[z];j(9.1j[z]){j($2B(9.1j[z][1])&&(9.K.P[z]>9.1j[z][1])){9.K.P[z]=9.1j[z][1];9.4O=1g}Q j($2B(9.1j[z][0])&&(9.K.P[z]<9.1j[z][0])){9.K.P[z]=9.1j[z][0];9.4O=1g}}9.r.1F(9.m.2u[z],9.K.P[z]+9.m.1J)}9.1x(\'4A\',9.r);o.1s()},7k:f(){9.3k.1E(\'4H\',9.1I.1m)},1s:f(){L.1E(\'2P\',9.1I.29);L.1E(\'5A\',9.1I.1s);9.1x(\'2g\',9.r)}});2L.1C.1T(M 3c);2L.1C.1T(M 3b);1b.N({7j:f(m){h M 2L.1C(9,1H.N(m||{},{2u:{x:\'3j\',y:\'3i\'}}))}});k 4J=M 11({2j:f(){h{3h:20,4K:1,3K:f(x,y){9.r.2a(x,y)}}},1e:f(r,m){9.2N(9.2j(),m);9.r=$(r);9.4M=([12,L].15(r))?$(L.4N):9.r},1m:f(){9.4L=9.5z.2y(9);9.4M.1a(\'2P\',9.4L)},1s:f(){9.4M.1E(\'2P\',9.4L);9.1f=$3Q(9.1f)},5z:f(o){9.1y=(9.r==12)?o.5y:o.1y;j(!9.1f)9.1f=9.1V.2k(50,9)},1V:f(){k l=9.r.3P();k 1D=9.r.2O();k 2z={\'x\':0,\'y\':0};I(k z W 9.1y){j(9.1y[z]<(9.m.3h+1D[z])&&l.1V[z]!=0)2z[z]=(9.1y[z]-9.m.3h-1D[z])*9.m.4K;Q j(9.1y[z]+9.m.3h>(l.2A[z]+1D[z])&&l.1V[z]+l.2A[z]!=l.3O[z])2z[z]=(9.1y[z]-l.2A[z]+9.m.3h-1D[z])*9.m.4K}j(2z.y||2z.x)9.1x(\'3K\',[l.1V.x+2z.x,l.1V.y+2z.y])}});4J.1T(M 3c);4J.1T(M 3b);k 4t=M 11({2j:f(){h{3K:11.1G,2g:11.1G,4x:f(1D){9.21.1F(9.p,1D+\'4I\')},3d:3g,1k:\'4G\',3f:T}},1e:f(l,21,m){9.r=$(l);9.21=$(21);9.2N(9.2j(),m);9.4w=-1;9.4v=-1;9.19=-1;9.r.1a(\'4H\',9.5w.2y(9));j(9.m.3f)9.r.1a(\'2M\',9.5x.2y(9));j(9.m.1k==\'4G\'){9.z=\'x\';9.p=\'2i\';9.1B=9.r.2x-9.21.2x;9.4y=9.21.2x/2;9.4z=9.r.4F.J(9.r)}Q j(9.m.1k==\'4E\'){9.z=\'y\';9.p=\'2w\';9.1B=9.r.2v-9.21.2v;9.4y=9.21.2v/2;9.4z=9.r.4D.J(9.r)}9.21.1F(\'1Z\',\'7i\').1F(9.p,0);k 4B={},4C={};4C[9.z]=[0,9.1B];4B[9.z]=9.p;9.29=M 2L.1C(9.21,{1j:4C,3N:0,2u:4B,2K:f(){9.3M()}.J(9),4A:f(){9.3M()}.J(9),2g:f(){9.3M();9.2h()}.J(9)});j(9.m.1e)9.m.1e.1i(9)},1U:f(19){j(19>9.m.3d)19=9.m.3d;Q j(19<0)19=0;9.19=19;9.3L();9.2h();9.1x(\'4x\',9.5v(9.19)+\'\');h 9},5x:f(o){j(o.3f<0)9.1U(9.19+1);Q j(o.3f>0)9.1U(9.19-1);o.1s()},5w:f(o){k 1Z=o.1y[9.z]-9.4z()-9.4y;j(1Z>9.1B)1Z=9.1B;Q j(1Z<0)1Z=0;9.19=9.4u(1Z);9.3L();9.2h();9.1x(\'4x\',1Z+\'\')},3M:f(){9.19=9.4u(9.29.K.P[9.z]);9.3L()},3L:f(){j(9.4w!=9.19){9.4w=9.19;9.1x(\'3K\',9.19)}},2h:f(){j(9.4v!==9.19){9.4v=9.19;9.1x(\'2g\',9.19+\'\')}},4u:f(1Z){h G.3e(1Z/9.1B*9.m.3d)},5v:f(19){h(9.1B)*19/9.m.3d}});4t.1T(M 3c);4t.1T(M 3b);',62,619,'|||||||||this||||||function||return||if|var|el|options|property|event||type|element|||obj|||||||to||||from|Math||for|bind|value|document|new|extend|fn|now|else|args||false|prototype|events|in|Fx|arguments|||Class|window||length|test||css|push|step|addEvent|Element|case|className|initialize|timer|true|style|call|limit|mode|rgb|start|parsed|each|found|param|Array|stop|parent|keys|selector|elements|fireEvent|page|values|color|max|Base|pos|removeEvent|setStyle|empty|Object|bound|unit|null|source|parse|Elements|key|break|filters|array|properties|implement|set|scroll|getStyle|PI|opacity|position||knob|pow|CSS|name||parentNode||match|drag|scrollTo|iCss|switch|delay|create|current|onComplete|end|left|getOptions|periodical|mouse|apply|margin|increase|iTo|Color|documentElement|previous|returns|modifiers|offsetHeight|top|offsetWidth|bindWithEvent|change|size|chk|toInt|compute|setNow|getValue|getElementsBySelector|chains|HTMLElement|hex|onStart|Drag|mousewheel|setOptions|getOffsets|mousemove|Transitions|wrapper|offset|wait|select|getNow|fx|fromTo|time|id|att|Garbage||text|while|replace|newArray||||item|Options|Events|steps|round|wheel|100|area|height|width|handle|checkAndDrag|sqrt|sin|min|iNow|iFrom|join|hexToRgb|parseFloat|domready|domReady|ie|alpha|colors|undefined|hasClass|getElements|getTag|filter|option|Event|toLowerCase|target|rgbToHex|items|onChange|checkStep|draggedKnob|snap|scrollSize|getSize|clear|5625|hidden|Multi|scrollLeft|scrollTop|khtml|readyState|loaded|remove||tagName|getElement|sel|getElementById|clean||splice|preventDefault|stopPropagation|relatedTarget|offsetTop|offsetLeft|setProperty|attribute|whitespace|indexOf|currentStyle|visibility|string|appendChild|inject|instanceof|ms|attempt|bit|forEach|pr0t0typ3|klass|Slider|toStep|previousEnd|previousChange|onTick|half|getPos|onDrag|modSlide|limSlide|getTop|vertical|getLeft|horizontal|mousedown|px|Scroller|velocity|coord|mousemover|body|out|bounceOut|70158|asin|abs|cos|sineInOut|layout|iProps|map|split|duration||opera|script|ie6|copy|operator|getElementsByTagName|els|on|Function|right|pageY|pageX|code|String|DOMMouseScroll|trash|removeEvents|offs|getBrother|getNext|what|gecko|camelCase|object|Native|result|typeof|parseInt|charAt|results|toPosition|clickedElement|scrolledElement|client|getCoords|mouseup|onSnap|distance|bounceIn|525|linear|slideOut|slideIn|hide|adopt|injectAfter|toElement|full|number|iParsed|Styles|Style|Single|Chain|onCancel|fps|getTime|Date|cTime|transition|callChain|getScrollHeight|getScrollWidth|getHeight|getWidth|getScrollTop|getScrollLeft|pageXOffset|pageYOffset|scrollWidth|scrollHeight|clientHeight|clientWidth|init|complete|ie_ready|catch|try|invert|mix|Hash|getAttribute|filterByAttribute|filterByTagName|filterByClassName|filterById|w_|defaults|which|clientY|clientX|special|120|wheelDelta|nodeType|unload|collect|selectedIndex|bottom|class|html|setAttribute|default|replaceWith|createElement|setStyles|childNodes|Sibling|evType|removeEventListener|addEventListener|hyphenate|defaultView|visible|setOpacity|cssText|addClass|removeClass|contents|inside|after|before|insertBefore|where|_elements_extended_|_element_extended_|err|toFloat||Number|trim|toUpperCase|params|regex|iterable|some|every|random|picked|parentize|noinit|relative|makeResizable|detach|bounceInOut|984375|625|9375|backInOut|backOut|backIn|elasticInOut|elasticOut|elasticIn|circInOut|circOut|circIn|expoInOut|expoOut|expoIn|sineOut|sineIn|quintInOut|quintOut|quintIn|quartInOut|quartOut|quartIn|cubicInOut|cubicOut|cubicIn|quadInOut|quadOut|quadIn|toggle|show|overflow|div|Slide|toRight|toLeft|toBottom|toTop|Scroll|effects|effect|clearTimer|custom|1000|500|innerHeight|innerWidth|onDomReady|DOMContentLoaded|load|onreadystatechange|void|javascript|src|defer|write|BackgroundImageCache|execCommand|disableImageCache|255|pop|get|tag|getElementsByClassName|ES|clearChain|chain|delete|backspace|space|esc|down|up|enter|returnValue|cancelBubble|mouseout|fromElement|mouseover|button|rightClick|click|fromCharCode|keyCode|detail|metaKey|meta|altKey|alt|ctrlKey|control|shiftKey|shift|srcElement|Window|textarea|password|radio|checkbox|checked|input|getPosition|offsetParent|do|getProperty|innerHTML|setHTML|setProperties|attributes|getChildren|getParent|previousSibling|lastChild|getLast|nextSibling|firstChild|getFirst|next|getPrevious|detachEvent|addEvents|attachEvent|getPropertyValue|getComputedStyle|padding|zoom|hasLayout|toggleClass|createTextNode|styleSheet|appendText|replaceChild|cloneNode|clone|removeChild|injectInside|injectBefore|embed|bindAsEventListener|pass|finally|setInterval|setTimeout|concat|toString|transparent|capitalize|RegExp|associate|getBoxObjectFor|taintEnabled|navigator|all|ie7|XMLHttpRequest|ActiveXObject|clearInterval|clearTimeout|floor|pick|textnode|nodeValue|nodeName'.split('|'),0,{})) diff --git a/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js b/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js new file mode 100644 index 0000000..d0ef7e8 --- /dev/null +++ b/nxhtml/nxhtml/doc/js/smoothgallery/scripts/mootools.uncompressed.js @@ -0,0 +1,4078 @@ +/* +Script: Moo.js + My Object Oriented javascript. + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Class is slightly based on Base.js (c) 2006 Dean Edwards, License + - Some functions are based on those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license + - Documentation by Aaron Newton (aaron.newton [at] cnet [dot] com) and Valerio Proietti. +*/ + +/* +Class: Class + The base class object of the framework. + +Arguments: + properties - the collection of properties that apply to the class. Creates a new class, its initialize method will fire upon class instantiation. + +Example: + (start code) + var Cat = new Class({ + initialize: function(name){ + this.name = name; + } + }); + var myCat = new Cat('Micia'); + alert myCat.name; //alerts 'Micia' + (end) +*/ + +var Class = function(properties){ + var klass = function(){ + if (this.initialize && arguments[0] != 'noinit') return this.initialize.apply(this, arguments); + else return this; + }; + for (var property in this) klass[property] = this[property]; + klass.prototype = properties; + return klass; +}; + +/* +Property: empty + Returns an empty function +*/ + +Class.empty = function(){}; + +Class.prototype = { + + /* + Property: extend + Returns the copy of the Class extended with the passed in properties. + + Arguments: + properties - the properties to add to the base class in this new Class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + var Cat = Animal.extend({ + initialize: function(name, age){ + this.parent(age); //will call the previous initialize; + this.name = name; + } + }); + var myCat = new Cat('Micia', 20); + alert myCat.name; //alerts 'Micia' + alert myCat.age; //alerts 20 + (end) + */ + + extend: function(properties){ + var pr0t0typ3 = new this('noinit'); + + var parentize = function(previous, current){ + if (!previous.apply || !current.apply) return false; + return function(){ + this.parent = previous; + return current.apply(this, arguments); + }; + }; + + for (var property in properties){ + var previous = pr0t0typ3[property]; + var current = properties[property]; + if (previous && previous != current) current = parentize(previous, current) || current; + pr0t0typ3[property] = current; + } + return new Class(pr0t0typ3); + }, + + /* + Property: implement + Implements the passed in properties to the base Class prototypes, altering the base class, unlike . + + Arguments: + properties - the properties to add to the base class. + + Example: + (start code) + var Animal = new Class({ + initialize: function(age){ + this.age = age; + } + }); + Animal.implement({ + setName: function(name){ + this.name = name + } + }); + var myAnimal = new Animal(20); + myAnimal.setName('Micia'); + alert(myAnimal.name); //alerts 'Micia' + (end) + */ + + implement: function(properties){ + for (var property in properties) this.prototype[property] = properties[property]; + } + +}; + +/* Section: Object related Functions */ + +/* +Function: Object.extend + Copies all the properties from the second passed object to the first passed Object. + If you do myWhatever.extend = Object.extend the first parameter will become myWhatever, and your extend function will only need one parameter. + +Example: + (start code) + var firstOb = { + 'name': 'John', + 'lastName': 'Doe' + }; + var secondOb = { + 'age': '20', + 'sex': 'male', + 'lastName': 'Dorian' + }; + Object.extend(firstOb, secondOb); + //firstOb will become: + { + 'name': 'John', + 'lastName': 'Dorian', + 'age': '20', + 'sex': 'male' + }; + (end) + +Returns: + The first object, extended. +*/ + +Object.extend = function(){ + var args = arguments; + args = (args[1]) ? [args[0], args[1]] : [this, args[0]]; + for (var property in args[1]) args[0][property] = args[1][property]; + return args[0]; +}; + +/* +Function: Object.Native + Will add a .extend method to the objects passed as a parameter, equivalent to + +Arguments: + a number of classes/native javascript objects + +*/ + +Object.Native = function(){ + for (var i = 0; i < arguments.length; i++) arguments[i].extend = Class.prototype.implement; +}; + +new Object.Native(Function, Array, String, Number, Class); + +/* +Script: Utility.js + Contains Utility functions + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +//htmlelement mapping + +if (typeof HTMLElement == 'undefined'){ + var HTMLElement = Class.empty; + HTMLElement.prototype = {}; +} + +/* +Function: $type + Returns the type of object that matches the element passed in. + +Arguments: + obj - the object to inspect. + +Example: + >var myString = 'hello'; + >$type(myString); //returns "string" + +Returns: + 'element' - if obj is a DOM element node + 'textnode' - if obj is a DOM text node + 'whitespace' - if obj is a DOM whitespace node + 'array' - if obj is an array + 'object' - if obj is an object + 'string' - if obj is a string + 'number' - if obj is a number + 'boolean' - if obj is a boolean + 'function' - if obj is a function + false - (boolean) if the object is not defined or none of the above. +*/ + +function $type(obj){ + if (obj === null || obj === undefined) return false; + var type = typeof obj; + if (type == 'object'){ + if (obj instanceof HTMLElement) return 'element'; + if (obj instanceof Array) return 'array'; + if (obj.nodeName){ + switch (obj.nodeType){ + case 1: return 'element'; + case 3: return obj.nodeValue.test('\\S') ? 'textnode' : 'whitespace'; + } + } + } + return type; +}; + +/* +Function: $chk + Returns true if the passed in value/object exists or is 0, otherwise returns false. + Useful to accept zeroes. +*/ + +function $chk(obj){ + return !!(obj || obj === 0); +}; + +/* +Function: $pick + Returns the first object if defined, otherwise returns the second. +*/ + +function $pick(obj, picked){ + return ($type(obj)) ? obj : picked; +}; + +/* +Function: $random + Returns a random integer number between the two passed in values. + +Arguments: + min - integer, the minimum value (inclusive). + max - integer, the maximum value (inclusive). + +Returns: + a random integer between min and max. +*/ + +function $random(min, max){ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +/* +Function: $clear + clears a timeout or an Interval. + +Returns: + null + +Arguments: + timer - the setInterval or setTimeout to clear. + +Example: + >var myTimer = myFunction.delay(5000); //wait 5 seconds and execute my function. + >myTimer = $clear(myTimer); //nevermind + +See also: + , +*/ + +function $clear(timer){ + clearTimeout(timer); + clearInterval(timer); + return null; +}; + +/* Section: Browser Detection */ + +/* +Properties: + window.ie - will be set to true if the current browser is internet explorer (any). + window.ie6 - will be set to true if the current browser is internet explorer 6. + window.ie7 - will be set to true if the current browser is internet explorer 7. + window.khtml - will be set to true if the current browser is Safari/Konqueror. + window.gecko - will be set to true if the current browser is Mozilla/Gecko. +*/ + +if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true; +else if (document.childNodes && !document.all && !navigator.taintEnabled) window.khtml = true; +else if (document.getBoxObjectFor != null) window.gecko = true; + +/* +Script: Array.js + Contains Array prototypes and the function <$A>; + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: Array + A collection of The Array Object prototype methods. +*/ + +//emulated methods + +/* +Property: forEach + Iterates through an array; This method is only available for browsers without native *forEach* support. + For more info see +*/ + +Array.prototype.forEach = Array.prototype.forEach || function(fn, bind){ + for (var i = 0; i < this.length; i++) fn.call(bind, this[i], i, this); +}; + +/* +Property: map + This method is provided only for browsers without native *map* support. + For more info see +*/ + +Array.prototype.map = Array.prototype.map || function(fn, bind){ + var results = []; + for (var i = 0; i < this.length; i++) results[i] = fn.call(bind, this[i], i, this); + return results; +}; + +/* +Property: every + This method is provided only for browsers without native *every* support. + For more info see +*/ + +Array.prototype.every = Array.prototype.every || function(fn, bind){ + for (var i = 0; i < this.length; i++){ + if (!fn.call(bind, this[i], i, this)) return false; + } + return true; +}; + +/* +Property: some + This method is provided only for browsers without native *some* support. + For more info see +*/ + +Array.prototype.some = Array.prototype.some || function(fn, bind){ + for (var i = 0; i < this.length; i++){ + if (fn.call(bind, this[i], i, this)) return true; + } + return false; +}; + +/* +Property: indexOf + This method is provided only for browsers without native *indexOf* support. + For more info see +*/ + +Array.prototype.indexOf = Array.prototype.indexOf || function(item, from){ + from = from || 0; + if (from < 0) from = Math.max(0, this.length + from); + while (from < this.length){ + if(this[from] === item) return from; + from++; + } + return -1; +}; + +//custom methods + +Array.extend({ + + /* + Property: each + Same as . + + Arguments: + fn - the function to execute with each item in the array + bind - optional, the object that the "this" of the function will refer to. + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.forEach(function(animal){ + > document.write(animal) + >}); + */ + + each: Array.prototype.forEach, + + /* + Property: copy + Copy the array and returns it. + + Returns: + an Array + + Example: + >var letters = ["a","b","c"]; + >var copy = ["a","b","c"].copy(); + */ + + copy: function(){ + var newArray = []; + for (var i = 0; i < this.length; i++) newArray[i] = this[i]; + return newArray; + }, + + /* + Property: remove + Removes all occurrences of an item from the array. + + Arguments: + item - the item to remove + + Returns: + the Array with all occurrences of the item removed. + + Example: + >["1","2","3","2"].remove("2") // ["1","3"]; + */ + + remove: function(item){ + var i = 0; + while (i < this.length){ + if (this[i] == item) this.splice(i, 1); + else i++; + } + return this; + }, + + /* + Property: test + Tests an array for the presence of an item. + + Arguments: + item - the item to search for in the array. + from - optional, the index at which to begin the search, default is 0. If negative, it is taken as the offset from the end of the array. + + Returns: + true - the item was found + false - it wasn't + + Example: + >["a","b","c"].test("a"); // true + >["a","b","c"].test("d"); // false + */ + + test: function(item, from){ + return this.indexOf(item, from) != -1; + }, + + /* + Property: extend + Extends an array with another + + Arguments: + newArray - the array to extend ours with + + Example: + >var Animals = ['Cat', 'Dog', 'Coala']; + >Animals.extend(['Lizard']); + >//Animals is now: ['Cat', 'Dog', 'Coala', 'Lizard']; + */ + + extend: function(newArray){ + for (var i = 0; i < newArray.length; i++) this.push(newArray[i]); + return this; + }, + + /* + Property: associate + Creates an object with key-value pairs based on the array of keywords passed in + and the current content of the array. + + Arguments: + keys - the array of keywords. + + Example: + (start code) + var Animals = ['Cat', 'Dog', 'Coala', 'Lizard']; + var Speech = ['Miao', 'Bau', 'Fruuu', 'Mute']; + var Speeches = Animals.associate(speech); + //Speeches['Miao'] is now Cat. + //Speeches['Bau'] is now Dog. + //... + (end) + */ + + associate: function(keys){ + var obj = {}, length = Math.min(this.length, keys.length); + for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; + return obj; + } + +}); + +/* Section: Utility Functions */ + +/* +Function: $A() + Same as , but as function. + Useful to apply Array prototypes to iterable objects, as a collection of DOM elements or the arguments object. + +Example: + (start code) + function myFunction(){ + $A(arguments).each(argument, function(){ + alert(argument); + }); + }; + //the above will alert all the arguments passed to the function myFunction. + (end) +*/ + +function $A(array){ + return Array.prototype.copy.call(array); +}; + +/* +Function: $each + use to iterate through iterables that are not regular arrays, such as builtin getElementsByTagName calls, or arguments of a function. + +Arguments: + iterable - an iterable element. + function - function to apply to the iterable. + bind - optional, the 'this' of the function will refer to this object. +*/ + +function $each(iterable, fn, bind){ + return Array.prototype.forEach.call(iterable, fn, bind); +}; + +/* +Script: String.js + Contains String prototypes and Number prototypes. + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: String + A collection of The String Object prototype methods. +*/ + +String.extend({ + + /* + Property: test + Tests a string with a regular expression. + + Arguments: + regex - the regular expression you want to match the string with + params - optional, any parameters you want to pass to the regex ('g' has no effect) + + Returns: + true if a match for the regular expression is found in the string, false if not. + See + + Example: + >"I like cookies".test("cookie"); // returns true + >"I like cookies".test("COOKIE", "i") // ignore case, returns true + >"I like cookies".test("cake"); // returns false + */ + + test: function(regex, params){ + return new RegExp(regex, params).test(this); + }, + + /* + Property: toInt + parses a string to an integer. + + Returns: + either an int or "NaN" if the string is not a number. + + Example: + >var value = "10px".toInt(); // value is 10 + */ + + toInt: function(){ + return parseInt(this); + }, + + toFloat: function(){ + return parseFloat(this); + }, + + /* + Property: camelCase + Converts a hiphenated string to a camelcase string. + + Example: + >"I-like-cookies".camelCase(); //"ILikeCookies" + + Returns: + the camel cased string + */ + + camelCase: function(){ + return this.replace(/-\D/g, function(match){ + return match.charAt(1).toUpperCase(); + }); + }, + + /* + Property: hyphenate + Converts a camelCased string to a hyphen-ated string. + + Example: + >"ILikeCookies".hyphenate(); //"I-like-cookies" + */ + + hyphenate: function(){ + return this.replace(/\w[A-Z]/g, function(match){ + return (match.charAt(0)+'-'+match.charAt(1).toLowerCase()); + }); + }, + + /* + Property: capitalize + Converts the first letter in each word of a string to Uppercase. + + Example: + >"i like cookies".capitalize(); //"I Like Cookies" + + Returns: + the capitalized string + */ + + capitalize: function(){ + return this.toLowerCase().replace(/\b[a-z]/g, function(match){ + return match.toUpperCase(); + }); + }, + + /* + Property: trim + Trims the leading and trailing spaces off a string. + + Example: + >" i like cookies ".trim() //"i like cookies" + + Returns: + the trimmed string + */ + + trim: function(){ + return this.replace(/^\s+|\s+$/g, ''); + }, + + /* + Property: clean + trims () a string AND removes all the double spaces in a string. + + Returns: + the cleaned string + + Example: + >" i like cookies \n\n".clean() //"i like cookies" + */ + + clean: function(){ + return this.replace(/\s{2,}/g, ' ').trim(); + }, + + /* + Property: rgbToHex + Converts an RGB value to hexidecimal. The string must be in the format of "rgb(255, 255, 255)" or "rgba(255, 255, 255, 1)"; + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['FF', '33', '00'] as output instead of #FF3300 + + Returns: + hex string or array. returns transparent if the fourth value of rgba in input string is 0, + + Example: + >"rgb(17,34,51)".rgbToHex(); //"#112233" + >"rgba(17,34,51,0)".rgbToHex(); //"transparent" + >"rgb(17,34,51)".rgbToHex(true); //[11,22,33] + */ + + rgbToHex: function(array){ + var rgb = this.match(/\d{1,3}/g); + return (rgb) ? rgb.rgbToHex(array) : false; + }, + + /* + Property: hexToRgb + Converts a hexidecimal color value to RGB. Input string must be the hex color value (with or without the hash). Also accepts triplets ('333'); + + Arguments: + array - boolean value, defaults to false. Use true if you want the array ['255', '255', '255'] as output instead of "rgb(255,255,255)"; + + Returns: + rgb string or array. + + Example: + >"#112233".hexToRgb(); //"rgb(17,34,51)" + >"#112233".hexToRgb(true); //[17,34,51] + */ + + hexToRgb: function(array){ + var hex = this.match('^#?(\\w{1,2})(\\w{1,2})(\\w{1,2})$'); + return (hex) ? hex.hexToRgb(array) : false; + } + +}); + +Array.extend({ + + rgbToHex: function(array){ + if (this.length < 3) return false; + if (this[3] && this[3] == 0) return 'transparent'; + var hex = []; + for (var i = 0; i < 3; i++){ + var bit = (this[i]-0).toString(16); + hex.push(bit.length == 1 ? '0'+bit : bit); + } + return array ? hex : '#'+hex.join(''); + }, + + hexToRgb: function(array){ + if (this.length != 4) return false; + var rgb = []; + for (var i = 1; i < 4; i++){ + if (this[i].length == 1) this[i] += this[i]; + rgb.push(parseInt(this[i], 16)); + } + return array ? rgb : 'rgb('+rgb.join(',')+')'; + } + +}); + +/* +Class: Number + contains the internal method toInt. +*/ + +Number.extend({ + + /* + Property: toInt + Returns this number; useful because toInt must work on both Strings and Numbers. + */ + + toInt: function(){ + return parseInt(this); + }, + + toFloat: function(){ + return parseFloat(this); + } + +}); + +/* +Script: Function.js + Contains Function prototypes and utility functions . + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Function + A collection of The Function Object prototype methods. +*/ + +Function.extend({ + + create: function(options){ + var fn = this; + options = Object.extend({ + 'bind': fn, + 'event': false, + 'arguments': null, + 'delay': false, + 'periodical': false, + 'attempt': false + }, options || {}); + if (options.arguments != null && typeof options.arguments != 'undefined' && !(options.arguments instanceof Array)) + options.arguments = [options.arguments]; + return function(event){ + var args = options.arguments || arguments; + if (options.event){ + event = (options.event === true) ? event || window.event : new options.event(event); + args = [event].concat(args); + } + var returns = function(){ + return fn.apply(options.bind, args); + }; + if (options.delay) return setTimeout(returns, options.delay); + if (options.periodical) return setInterval(returns, options.periodical); + if (options.attempt){ + try { + var result = returns(); + } catch(err){ + result = err; + } finally { + return result; + } + } else return returns(); + }; + }, + + /* + Property: pass + Shortcut to create closures with arguments and bind. + + Returns: + a function. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.pass([arg1, arg2], myElement); + */ + + pass: function(args, bind){ + return this.create({'arguments': args, 'bind': bind}); + }, + + /* + Property: attempt + Tries to execute the function, returns either the function results or the error. + + Arguments: + args - the arguments passed. must be an array if arguments > 1 + bind - optional, the object that the "this" of the function will refer to. + + Example: + >myFunction.attempt([arg1, arg2], myElement); + */ + + attempt: function(args, bind){ + return this.create({'arguments': args, 'bind': bind, 'attempt': true})(); + }, + + /* + Property: bind + method to easily create closures with "this" altered. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function. + + Example: + >function myFunction(){ + > this.setStyle('color', 'red'); + > // note that 'this' here refers to myFunction, not an element + > // we'll need to bind this function to the element we want to alter + >}; + >var myBoundFunction = myFunction.bind(myElement); + >myBoundFunction(); // this will make the element myElement red. + */ + + bind: function(bind, args){ + return this.create({'bind': bind, 'arguments': args}); + }, + + /* + Property: bindAsEventListener + cross browser method to pass event firer + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindAsEventListener(myElement); + */ + + bindAsEventListener: function(bind, args){ + return this.create({'bind': bind, 'event': true, 'arguments': args}); + }, + + /* + Property: delay + Delays the execution of a function by a specified duration. + + Arguments: + ms - the duration to wait in milliseconds + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + + Example: + >myFunction.delay(50, myElement) //wait 50 milliseconds, then call myFunction and bind myElement to it + >(function(){alert('one second later...')}).delay(1000); //wait a second and alert + */ + + delay: function(ms, bind, args){ + return this.create({'delay': ms, 'bind': bind, 'arguments': args})(); + }, + + /* + Property: periodical + Executes a function in the specified intervals of time + + Arguments: + ms - the duration of the intervals between executions. + bind - optional, the object that the "this" of the function will refer to. + args - optional, the arguments passed. must be an array if arguments > 1 + */ + + periodical: function(ms, bind, args){ + return this.create({'periodical': ms, 'bind': bind, 'arguments': args})(); + } + +}); + +/* +Script: Element.js + Contains useful Element prototypes, to be used with the dollar function <$>. + +Author: + Valerio Proietti, + +License: + MIT-style license. + +Credits: + - Some functions are inspired by those found in prototype.js (c) 2005 Sam Stephenson sam [at] conio [dot] net, MIT-style license +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +var Element = new Class({ + + /* + Property: initialize + Creates a new element of the type passed in. + + Arguments: + el - the tag name for the element you wish to create. + + Example: + >var div = new Element('div'); + */ + + initialize: function(el){ + if ($type(el) == 'string') el = document.createElement(el); + return $(el); + } + +}); + +/* +Function: $() + returns the element passed in with all the Element prototypes applied. + +Arguments: + el - a reference to an actual element or a string representing the id of an element + +Example: + >$('myElement') // gets a DOM element by id with all the Element prototypes applied. + >var div = document.getElementById('myElement'); + >$(div) //returns an Element also with all the mootools extentions applied. + + You'll use this when you aren't sure if a variable is an actual element or an id, as + well as just shorthand for document.getElementById(). + +Returns: + a DOM element or false (if no id was found). + +Note: + you need to call $ on an element only once to get all the prototypes. + But its no harm to call it multiple times, as it will detect if it has been already extended. +*/ + +function $(el){ + if (!el) return false; + if (el._element_extended_ || [window, document].test(el)) return el; + if ($type(el) == 'string') el = document.getElementById(el); + if ($type(el) != 'element') return false; + if (['object', 'embed'].test(el.tagName.toLowerCase()) || el.extend) return el; + el._element_extended_ = true; + Garbage.collect(el); + el.extend = Object.extend; + if (!(el instanceof HTMLElement)) el.extend(Element.prototype); + return el; +}; + +//elements class + +var Elements = new Class({}); + +new Object.Native(Elements); + +document.getElementsBySelector = document.getElementsByTagName; + +/* +Function: $$() + Selects, and extends DOM elements. + +Arguments: + HTMLCollection(document.getElementsByTagName, element.childNodes), an array of elements, a string. + +Note: + if you loaded , $$ will also accept CSS Selectors. + +Example: + >$$('a') //an array of all anchor tags on the page + >$$('a', 'b') //an array of all anchor and bold tags on the page + >$$('#myElement') //array containing only the element with id = myElement. (only with ) + >$$('#myElement a.myClass') //an array of all anchor tags with the class "myClass" within the DOM element with id "myElement" (only with ) + +Returns: + array - array of all the dom elements matched +*/ + +function $$(){ + if (!arguments) return false; + if (arguments.length == 1){ + if (!arguments[0]) return false; + if (arguments[0]._elements_extended_) return arguments[0]; + } + var elements = []; + $each(arguments, function(selector){ + switch ($type(selector)){ + case 'element': elements.push($(selector)); break; + case 'string': selector = document.getElementsBySelector(selector); + default: + if (selector.length){ + $each(selector, function(el){ + if ($(el)) elements.push(el); + }); + } + } + }); + elements._elements_extended_ = true; + return Object.extend(elements, new Elements); +}; + +Elements.Multi = function(property){ + return function(){ + var args = arguments; + var items = []; + var elements = true; + $each(this, function(el){ + var returns = el[property].apply(el, args); + if ($type(returns) != 'element') elements = false; + items.push(returns); + }); + if (elements) items = $$(items); + return items; + }; +}; + +Element.extend = function(properties){ + for (var property in properties){ + HTMLElement.prototype[property] = properties[property]; + Element.prototype[property] = properties[property]; + Elements.prototype[property] = Elements.Multi(property); + } +}; + +Element.extend({ + + inject: function(el, where){ + el = $(el) || new Element(el); + switch (where){ + case "before": $(el.parentNode).insertBefore(this, el); break; + case "after": + if (!el.getNext()) $(el.parentNode).appendChild(this); + else $(el.parentNode).insertBefore(this, el.getNext()); + break; + case "inside": el.appendChild(this); + } + return this; + }, + + /* + Property: injectBefore + Inserts the Element before the passed element. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Example: + >html: + >
+ >
+ >js: + >$('mySecondElement').injectBefore('myElement'); + >resulting html: + >
+ >
+ + */ + + injectBefore: function(el){ + return this.inject(el, 'before'); + }, + + /* + Property: injectAfter + Same as , but inserts the element after. + */ + + injectAfter: function(el){ + return this.inject(el, 'after'); + }, + + /* + Property: injectInside + Same as , but inserts the element inside. + */ + + injectInside: function(el){ + return this.inject(el, 'inside'); + }, + + /* + Property: adopt + Inserts the passed element inside the Element. Works as but in reverse. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + */ + + adopt: function(el){ + this.appendChild($(el) || new Element(el)); + return this; + }, + + /* + Property: remove + Removes the Element from the DOM. + + Example: + >$('myElement').remove() //bye bye + */ + + remove: function(){ + this.parentNode.removeChild(this); + return this; + }, + + /* + Property: clone + Clones the Element and returns the cloned one. + + Returns: + the cloned element + + Example: + >var clone = $('myElement').clone().injectAfter('myElement'); + >//clones the Element and append the clone after the Element. + */ + + clone: function(contents){ + var el = this.cloneNode(contents !== false); + return $(el); + }, + + /* + Property: replaceWith + Replaces the Element with an element passed. + + Parameteres: + el - a string representing the element to be injected in (myElementId, or div), or an element reference. + If you pass div or another tag, the element will be created. + + Returns: + the passed in element + + Example: + >$('myOldElement').replaceWith($('myNewElement')); //$('myOldElement') is gone, and $('myNewElement') is in its place. + */ + + replaceWith: function(el){ + el = $(el) || new Element(el); + this.parentNode.replaceChild(el, this); + return el; + }, + + /* + Property: appendText + Appends text node to a DOM element. + + Arguments: + text - the text to append. + + Example: + >
hey
+ >$('myElement').appendText(' howdy'); //myElement innerHTML is now "hey howdy" + */ + + appendText: function(text){ + if (window.ie){ + switch(this.getTag()){ + case 'style': this.styleSheet.cssText = text; return this; + case 'script': this.setProperty('text', text); return this; + } + } + this.appendChild(document.createTextNode(text)); + return this; + }, + + /* + Property: hasClass + Tests the Element to see if it has the passed in className. + + Returns: + true - the Element has the class + false - it doesn't + + Arguments: + className - the class name to test. + + Example: + >
+ >$('myElement').hasClass('testClass'); //returns true + */ + + hasClass: function(className){ + return this.className.test('(?:^|\\s+)' + className + '(?:\\s+|$)'); + }, + + /* + Property: addClass + Adds the passed in class to the Element, if the element doesnt already have it. + + Arguments: + className - the class name to add + + Example: + >
+ >$('myElement').addClass('newClass'); //
+ */ + + addClass: function(className){ + if (!this.hasClass(className)) this.className = (this.className+' '+className).clean(); + return this; + }, + + /* + Property: removeClass + works like , but removes the class from the element. + */ + + removeClass: function(className){ + if (this.hasClass(className)) this.className = this.className.replace(className, '').clean(); + return this; + }, + + /* + Property: toggleClass + Adds or removes the passed in class name to the element, depending on if it's present or not. + + Arguments: + className - the class to add or remove + + Example: + >
+ >$('myElement').toggleClass('myClass'); + >
+ >$('myElement').toggleClass('myClass'); + >
+ */ + + toggleClass: function(className){ + return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); + }, + + /* + Property: setStyle + Sets a css property to the Element. + + Arguments: + property - the property to set + value - the value to which to set it + + Example: + >$('myElement').setStyle('width', '300px'); //the width is now 300px + */ + + setStyle: function(property, value){ + if (property == 'opacity') this.setOpacity(parseFloat(value)); + else this.style[property.camelCase()] = (value.push) ? value.rgbToHex() : value; + return this; + }, + + /* + Property: setStyles + Applies a collection of styles to the Element. + + Arguments: + source - an object or string containing all the styles to apply + + Examples: + >$('myElement').setStyles({ + > border: '1px solid #000', + > width: '300px', + > height: '400px' + >}); + + OR + + >$('myElement').setStyle('border: 1px solid #000; width: 300px; height: 400px;'); + */ + + setStyles: function(source){ + switch ($type(source)){ + case 'object': + for (var property in source) this.setStyle(property, source[property]); + break; + case 'string': + if (window.ie) this.cssText = source; + else this.setAttribute('style', source); + } + return this; + }, + + /* + Property: setOpacity + Sets the opacity of the Element, and sets also visibility == "hidden" if opacity == 0, and visibility = "visible" if opacity == 1. + + Arguments: + opacity - Accepts numbers from 0 to 1. + + Example: + >$('myElement').setOpacity(0.5) //make it 50% transparent + */ + + setOpacity: function(opacity){ + if (opacity == 0){ + if(this.style.visibility != "hidden") this.style.visibility = "hidden"; + } else { + if(this.style.visibility != "visible") this.style.visibility = "visible"; + } + if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; + if (window.ie) this.style.filter = "alpha(opacity=" + opacity*100 + ")"; + this.style.opacity = this.opacity = opacity; + return this; + }, + + /* + Property: getStyle + Returns the style of the Element given the property passed in. + + Arguments: + property - the css style property you want to retrieve + + Example: + >$('myElement').getStyle('width'); //returns "400px" + >//but you can also use + >$('myElement').getStyle('width').toInt(); //returns "400" + + Returns: + the style as a string + */ + + getStyle: function(property){ + property = property.camelCase(); + var style = this.style[property] || false; + if (!$chk(style)){ + if (property == 'opacity') return $chk(this.opacity) ? this.opacity : 1; + if (['margin', 'padding'].test(property)){ + return [this.getStyle(property+'-top') || 0, this.getStyle(property+'-right') || 0, + this.getStyle(property+'-bottom') || 0, this.getStyle(property+'-left') || 0].join(' '); + } + if (document.defaultView) style = document.defaultView.getComputedStyle(this, null).getPropertyValue(property.hyphenate()); + else if (this.currentStyle) style = this.currentStyle[property]; + } + return (style && property.test('color', 'i') && style.test('rgb')) ? style.rgbToHex() : style; + }, + + /* + Property: addEvent + Attaches an event listener to a DOM element. + + Arguments: + type - the event to monitor ('click', 'load', etc) without the prefix 'on'. + fn - the function to execute + + Example: + >$('myElement').addEvent('click', function(){alert('clicked!')}); + */ + + addEvent: function(type, fn){ + this.events = this.events || {}; + this.events[type] = this.events[type] || {'keys': [], 'values': []}; + if (!this.events[type].keys.test(fn)){ + this.events[type].keys.push(fn); + if (this.addEventListener){ + this.addEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, fn, false); + } else { + fn = fn.bind(this); + this.attachEvent('on'+type, fn); + this.events[type].values.push(fn); + } + } + return this; + }, + + addEvents: function(source){ + if (source){ + for (var type in source) this.addEvent(type, source[type]); + } + return this; + }, + + /* + Property: removeEvent + Works as Element.addEvent, but instead removes the previously added event listener. + */ + + removeEvent: function(type, fn){ + if (this.events && this.events[type]){ + var pos = this.events[type].keys.indexOf(fn); + if (pos == -1) return this; + var key = this.events[type].keys.splice(pos,1)[0]; + if (this.removeEventListener){ + this.removeEventListener((type == 'mousewheel' && window.gecko) ? 'DOMMouseScroll' : type, key, false); + } else { + this.detachEvent('on'+type, this.events[type].values.splice(pos,1)[0]); + } + } + return this; + }, + + /* + Property: removeEvents + removes all events of a certain type from an element. if no argument is passed in, removes all events. + */ + + removeEvents: function(type){ + if (this.events){ + if (type){ + if (this.events[type]){ + this.events[type].keys.each(function(fn){ + this.removeEvent(type, fn); + }, this); + this.events[type] = null; + } + } else { + for (var evType in this.events) this.removeEvents(evType); + this.events = null; + } + } + return this; + }, + + /* + Property: fireEvent + executes all events of the specified type present in the element. + */ + + fireEvent: function(type, args){ + if (this.events && this.events[type]){ + args = args || []; + if ($type(args) != 'array') args = [args]; + this.events[type].keys.each(function(fn){ + fn.apply(this, args); + }, this); + } + }, + + getBrother: function(what){ + var el = this[what+'Sibling']; + while ($type(el) == 'whitespace') el = el[what+'Sibling']; + return $(el); + }, + + /* + Property: getPrevious + Returns the previousSibling of the Element, excluding text nodes. + + Example: + >$('myElement').getPrevious(); //get the previous DOM element from myElement + + Returns: + the sibling element or undefined if none found. + */ + + getPrevious: function(){ + return this.getBrother('previous'); + }, + + /* + Property: getNext + Works as Element.getPrevious, but tries to find the nextSibling. + */ + + getNext: function(){ + return this.getBrother('next'); + }, + + /* + Property: getFirst + Works as , but tries to find the firstChild. + */ + + getFirst: function(){ + var el = this.firstChild; + while ($type(el) == 'whitespace') el = el.nextSibling; + return $(el); + }, + + /* + Property: getLast + Works as , but tries to find the lastChild. + */ + + getLast: function(){ + var el = this.lastChild; + while ($type(el) == 'whitespace') el = el.previousSibling; + return $(el); + }, + + /* + Property: getParent + returns the $(element.parentNode) + */ + + getParent: function(){ + return $(this.parentNode); + }, + + /* + Property: getChildren + returns all the $(element.childNodes), excluding text nodes. Returns as . + */ + + getChildren: function(){ + return $$(this.childNodes); + }, + + /* + Property: setProperty + Sets an attribute for the Element. + + Arguments: + property - the property to assign the value passed in + value - the value to assign to the property passed in + + Example: + >$('myImage').setProperty('src', 'whatever.gif'); //myImage now points to whatever.gif for its source + */ + + setProperty: function(property, value){ + switch (property){ + case 'class': this.className = value; break; + case 'style': this.setStyles(value); break; + case 'name': if (window.ie6){ + var el = $(document.createElement('<'+this.getTag()+' name="'+value+'" />')); + $each(this.attributes, function(attribute){ + if (attribute.name != 'name') el.setProperty(attribute.name, attribute.value); + }); + if (this.parentNode) this.replaceWith(el); + return el; + } + default: this.setAttribute(property, value); + } + return this; + }, + + /* + Property: setProperties + Sets numerous attributes for the Element. + + Arguments: + source - an object with key/value pairs. + + Example: + >$('myElement').setProperties({ + > src: 'whatever.gif', + > alt: 'whatever dude' + >}); + >whatever dude + */ + + setProperties: function(source){ + for (var property in source) this.setProperty(property, source[property]); + return this; + }, + + /* + Property: setHTML + Sets the innerHTML of the Element. + + Arguments: + html - the new innerHTML for the element. + + Example: + >$('myElement').setHTML(newHTML) //the innerHTML of myElement is now = newHTML + */ + + setHTML: function(html){ + this.innerHTML = html; + return this; + }, + + /* + Property: getProperty + Gets the an attribute of the Element. + + Arguments: + property - the attribute to retrieve + + Example: + >$('myImage').getProperty('src') // returns whatever.gif + + Returns: + the value, or an empty string + */ + + getProperty: function(property){ + return (property == 'class') ? this.className : this.getAttribute(property); + }, + + /* + Property: getTag + Returns the tagName of the element in lower case. + + Example: + >$('myImage').getTag() // returns 'img' + + Returns: + The tag name in lower case + */ + + getTag: function(){ + return this.tagName.toLowerCase(); + }, + + getOffsets: function(){ + var el = this, offsetLeft = 0, offsetTop = 0; + do { + offsetLeft += el.offsetLeft || 0; + offsetTop += el.offsetTop || 0; + el = el.offsetParent; + } while (el); + return {'x': offsetLeft, 'y': offsetTop}; + }, + + /* + Property: scrollTo + scrolls the element to the specified coordinated (if the element has an overflow) + + Arguments: + x - the x coordinate + y - the y coordinate + + Example: + >$('myElement').scrollTo(0, 100) + */ + + scrollTo: function(x, y){ + this.scrollLeft = x; + this.scrollTop = y; + }, + + /* + Property: getSize + return an Object representing the size/scroll values of the element. + + Example: + (start code) + $('myElement').getSize(); + (end) + + Returns: + (start code) + { + 'scroll': {'x': 100, 'y': 100}, + 'size': {'x': 200, 'y': 400}, + 'scrollSize': {'x': 300, 'y': 500} + } + (end) + */ + + getSize: function(){ + return { + 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, + 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, + 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} + }; + }, + + /* + Property: getTop + Returns the distance from the top of the window to the Element. + */ + + getTop: function(){ + return this.getOffsets().y; + }, + + /* + Property: getLeft + Returns the distance from the left of the window to the Element. + */ + + getLeft: function(){ + return this.getOffsets().x; + }, + + /* + Property: getPosition + Returns an object with width, height, left, right, top, and bottom, representing the values of the Element + + Example: + (start code) + var myValues = $('myElement').getPosition(); + (end) + + Returns: + (start code) + { + width: 200, + height: 300, + left: 100, + top: 50, + right: 300, + bottom: 350 + } + (end) + */ + + getPosition: function(){ + var offs = this.getOffsets(); + var obj = { + 'width': this.offsetWidth, + 'height': this.offsetHeight, + 'left': offs.x, + 'top': offs.y + }; + obj.right = obj.left + obj.width; + obj.bottom = obj.top + obj.height; + return obj; + }, + + /* + Property: getValue + Returns the value of the Element, if its tag is textarea, select or input. no multiple select support. + */ + + getValue: function(){ + switch (this.getTag()){ + case 'select': if (this.selectedIndex != -1) return this.options[this.selectedIndex].value; break; + case 'input': if (!(this.checked && ['checkbox', 'radio'].test(this.type)) && !['hidden', 'text', 'password'].test(this.type)) break; + case 'textarea': return this.value; + } + return false; + } + +}); + +var Window = window; + +window.addEvent = document.addEvent = Element.prototype.addEvent; +window.removeEvent = document.removeEvent = Element.prototype.removeEvent; + +var Garbage = { + + elements: [], + + collect: function(element){ + Garbage.elements.push(element); + }, + + trash: function(){ + window.removeEvent('unload', Garbage.trash); + Garbage.elements.each(function(el){ + el.removeEvents(); + for (var p in Element.prototype) HTMLElement[p] = window[p] = document[p] = el[p] = null; + el.extend = null; + }); + } + +}; + +window.addEvent('unload', Garbage.trash); + +/* +Script: Event.js + Event class + +Author: + Valerio Proietti, , Michael Jackson, + +License: + MIT-style license. +*/ + +/* +Class: Event + Cross browser methods to manage events. + +Arguments: + event - the event + +Properties: + shift - true if the user pressed the shift + control - true if the user pressed the control + alt - true if the user pressed the alt + meta - true if the user pressed the meta key + code - the keycode of the key pressed + page.x - the x position of the mouse, relative to the full window + page.y - the y position of the mouse, relative to the full window + client.x - the x position of the mouse, relative to the viewport + client.y - the y position of the mouse, relative to the viewport + key - the key pressed as a lowercase string. key also returns 'enter', 'up', 'down', 'left', 'right', 'space', 'backspace', 'delete', 'esc'. Handy for these special keys. + target - the event target + relatedTarget - the event related target + +Example: + (start code) + $('myLink').onkeydown = function(event){ + var event = new Event(event); + //event is now the Event class. + alert(event.key); //returns the lowercase letter pressed + alert(event.shift); //returns true if the key pressed is shift + if (event.key == 's' && event.control) alert('document saved'); + }; + (end) +*/ + +var Event = new Class({ + + initialize: function(event){ + this.event = event || window.event; + this.type = this.event.type; + this.target = this.event.target || this.event.srcElement; + if (this.target.nodeType == 3) this.target = this.target.parentNode; // Safari + this.shift = this.event.shiftKey; + this.control = this.event.ctrlKey; + this.alt = this.event.altKey; + this.meta = this.event.metaKey; + if (['DOMMouseScroll', 'mousewheel'].test(this.type)){ + this.wheel = this.event.wheelDelta ? (this.event.wheelDelta / (window.opera ? -120 : 120)) : -(this.event.detail || 0) / 3; + } else if (this.type.test('key')){ + this.code = this.event.which || this.event.keyCode; + for (var name in Event.keys){ + if (Event.keys[name] == this.code) var special = name; + } + this.key = special || String.fromCharCode(this.code).toLowerCase(); + + } else if (this.type.test('mouse') || this.type == 'click'){ + this.page = { + 'x': this.event.pageX || this.event.clientX + document.documentElement.scrollLeft, + 'y': this.event.pageY || this.event.clientY + document.documentElement.scrollTop + }; + this.client = { + 'x': this.event.pageX ? this.event.pageX - window.pageXOffset : this.event.clientX, + 'y': this.event.pageY ? this.event.pageY - window.pageYOffset : this.event.clientY + }; + this.rightClick = (this.event.which == 3) || (this.event.button == 2); + switch (this.type){ + case 'mouseover': this.relatedTarget = this.event.relatedTarget || this.event.fromElement; break; + case 'mouseout': this.relatedTarget = this.event.relatedTarget || this.event.toElement; + } + } + }, + + /* + Property: stop + cross browser method to stop an event + */ + + stop: function() { + this.stopPropagation(); + this.preventDefault(); + return this; + }, + + /* + Property: stopPropagation + cross browser method to stop the propagation of an event + */ + + stopPropagation: function(){ + if (this.event.stopPropagation) this.event.stopPropagation(); + else this.event.cancelBubble = true; + return this; + }, + + /* + Property: preventDefault + cross browser method to prevent the default action of the event + */ + + preventDefault: function(){ + if (this.event.preventDefault) this.event.preventDefault(); + else this.event.returnValue = false; + return this; + } + +}); + +Event.keys = { + 'enter': 13, + 'up': 38, + 'down': 40, + 'left': 37, + 'right': 39, + 'esc': 27, + 'space': 32, + 'backspace': 8, + 'delete': 46 +}; + +Function.extend({ + + /* + Property: bindWithEvent + automatically passes mootools Event Class. + + Arguments: + bind - optional, the object that the "this" of the function will refer to. + + Returns: + a function with the parameter bind as its "this" and as a pre-passed argument event or window.event, depending on the browser. + + Example: + >function myFunction(event){ + > alert(event.clientx) //returns the coordinates of the mouse.. + >}; + >myElement.onclick = myFunction.bindWithEvent(myElement); + */ + + bindWithEvent: function(bind, args){ + return this.create({'bind': bind, 'arguments': args, 'event': Event}); + } + +}); + + +/* +Script: Common.js + Contains common implementations for custom classes. In Mootools is implemented in and . + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* +Class: Chain + An "Utility" Class. Its methods can be implemented with into any . + Currently implemented in and . In for example, is used to execute a list of function, one after another, once the effect is completed. + The functions will not be fired all togheter, but one every completion, to create custom complex animations. + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity'); + + myFx.start(1,0).chain(function(){ + myFx.start(0,1); + }).chain(function(){ + myFx.start(1,0); + }).chain(function(){ + myFx.start(0,1); + }); + //the element will appear and disappear three times + (end) +*/ + +var Chain = new Class({ + + /* + Property: chain + adds a function to the Chain instance stack. + + Arguments: + fn - the function to append. + */ + + chain: function(fn){ + this.chains = this.chains || []; + this.chains.push(fn); + return this; + }, + + /* + Property: callChain + Executes the first function of the Chain instance stack, then removes it. The first function will then become the second. + */ + + callChain: function(){ + if (this.chains && this.chains.length) this.chains.splice(0, 1)[0].delay(10, this); + }, + + /* + Property: clearChain + Clears the stack of a Chain instance. + */ + + clearChain: function(){ + this.chains = []; + } + +}); + +/* +Class: Events + An "Utility" Class. Its methods can be implemented with into any . + In Class, for example, is used to give the possibility add any number of functions to the Effects events, like onComplete, onStart, onCancel + +Example: + (start code) + var myFx = new Fx.Style('element', 'opacity').addEvent('onComplete', function(){ + alert('the effect is completed'); + }).addEvent('onComplete', function(){ + alert('I told you the effect is completed'); + }); + + myFx.start(0,1); + //upon completion it will display the 2 alerts, in order. + (end) +*/ + +var Events = new Class({ + + /* + Property: addEvent + adds an event to the stack of events of the Class instance. + */ + + addEvent: function(type, fn){ + if (fn != Class.empty){ + this.events = this.events || {}; + this.events[type] = this.events[type] || []; + if (!this.events[type].test(fn)) this.events[type].push(fn); + } + return this; + }, + + /* + Property: fireEvent + fires all events of the specified type in the Class instance. + */ + + fireEvent: function(type, args, delay){ + if (this.events && this.events[type]){ + this.events[type].each(function(fn){ + fn.create({'bind': this, 'delay': delay, 'arguments': args})(); + }, this); + } + return this; + }, + + /* + Property: removeEvent + removes an event from the stack of events of the Class instance. + */ + + removeEvent: function(type, fn){ + if (this.events && this.events[type]) this.events[type].remove(fn); + return this; + } + +}); + +/* +Class: Options + An "Utility" Class. Its methods can be implemented with into any . + Used to automate the options settings, also adding Class when the option begins with on. +*/ + +var Options = new Class({ + + /* + Property: setOptions + sets this.options + + Arguments: + defaults - the default set of options + options - the user entered options. can be empty too. + + Note: + if your Class has implemented, every option beginning with on, followed by a capital letter (onComplete) becomes an Class instance event. + */ + + setOptions: function(defaults, options){ + this.options = Object.extend(defaults, options); + if (this.addEvent){ + for (var option in this.options){ + if (($type(this.options[option]) == 'function') && option.test('^on[A-Z]')) this.addEvent(option, this.options[option]); + } + } + return this; + } + +}); + +/* +Script: Dom.js + Css Query related function and extensions + +Author: + Valerio Proietti, + +License: + MIT-style license. +*/ + +/* Section: Utility Functions */ + +/* +Function: $E + Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. + +Arguments: + selector - the css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Example: + >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' + +Returns: + a DOM element - the first element that matches the selector +*/ + +function $E(selector, filter){ + return ($(filter) || document).getElement(selector); +}; + +/* +Function: $ES + Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. + See Also: for an alternate syntax. + +Returns: + an array of dom elements that match the selector within the filter + +Arguments: + selector - css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Examples: + >$ES("a") //gets all the anchor tags; synonymous with $$("a") + >$ES('a','myElement') //get all the anchor tags within $('myElement') +*/ + +function $ES(selector, filter){ + return ($(filter) || document).getElementsBySelector(selector); +}; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: getElements + Gets all the elements within an element that match the given (single) selector. + + Arguments: + selector - the css selector to match + + Example: + >$('myElement').getElements('a'); // get all anchors within myElement + + Credits: + Say thanks to Christophe Beyls for the new regular expression that rules getElements, a big step forward in terms of speed. + */ + + getElements: function(selector){ + var filters = []; + selector.clean().split(' ').each(function(sel, i){ + var param = sel.match('^(\\w*|\\*)(?:#([\\w_-]+)|\\.([\\w_-]+))?(?:\\[["\']?(\\w+)["\']?(?:([\\*\\^\\$]?=)["\']?(\\w*)["\']?)?\\])?$'); + //PARAM ARRAY: 0 = full string: 1 = tag; 2 = id; 3 = class; 4 = attribute; 5 = operator; 6 = value; + if (!param) return; + param[1] = param[1] || '*'; + if (i == 0){ + if (param[2]){ + var el = this.getElementById(param[2]); + if (!el || ((param[1] != '*') && (Element.prototype.getTag.call(el) != param[1]))) return; + filters = [el]; + } else { + filters = $A(this.getElementsByTagName(param[1])); + } + } else { + filters = Elements.prototype.filterByTagName.call(filters, param[1]); + if (param[2]) filters = Elements.prototype.filterById.call(filters, param[2]); + } + if (param[3]) filters = Elements.prototype.filterByClassName.call(filters, param[3]); + if (param[4]) filters = Elements.prototype.filterByAttribute.call(filters, param[4], param[6], param[5]); + }, this); + return $$(filters); + }, + + /* + Property: getElementById + Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. + + Arguments: + id - the id of the element to find. + */ + + getElementById: function(id){ + var el = document.getElementById(id); + if (!el) return false; + for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ + if (!parent) return false; + } + return el; + }, + + /* + Property: getElement + Same as , but returns only the first. Alternate syntax for <$E>, where filter is the Element. + */ + + getElement: function(selector){ + return this.getElementsBySelector(selector)[0]; + }, + + /* + Property: getElementsBySelector + Same as , but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. + + */ + + getElementsBySelector: function(selector){ + var els = []; + selector.split(',').each(function(sel){ + els.extend(this.getElements(sel)); + }, this); + return $$(els); + } + +}); + +document.extend = Object.extend; + +/* Section: document related functions */ + +document.extend({ + /* + Function: document.getElementsByClassName + Returns all the elements that match a specific class name. + Here for compatibility purposes. can also be written: document.getElements('.className'), or $$('.className') + */ + + getElementsByClassName: function(className){ + return document.getElements('.'+className); + }, + getElement: Element.prototype.getElement, + getElements: Element.prototype.getElements, + getElementsBySelector: Element.prototype.getElementsBySelector + +}); + +/* +Class: Elements + Methods for dom queries arrays, as <$$>. +*/ + +Elements.extend({ + + //internal methods + + filterById: function(id, tag){ + var found = []; + this.each(function(el){ + if (el.id == id) found.push(el); + }); + return found; + }, + + filterByClassName: function(className){ + var found = []; + this.each(function(el){ + if (Element.prototype.hasClass.call(el, className)) found.push(el); + }); + return found; + }, + + filterByTagName: function(tagName){ + var found = []; + this.each(function(el){ + found.extend(el.getElementsByTagName(tagName)); + }); + return found; + }, + + filterByAttribute: function(name, value, operator){ + var found = []; + this.each(function(el){ + var att = el.getAttribute(name); + if (!att) return found; + if (!operator) return found.push(el); + + switch (operator){ + case '*=': if (att.test(value)) found.push(el); break; + case '=': if (att == value) found.push(el); break; + case '^=': if (att.test('^'+value)) found.push(el); break; + case '$=': if (att.test(value+'$')) found.push(el); + } + return found; + }); + return found; + } + +}); + +/* +Script: Hash.js + Contains the class Hash. + +Author: + Christophe Beyls + +License: + MIT-style license. +*/ + +/* +Class: Hash + It wraps an object that it uses internally as a map. The user must use put(), get(), and remove() to add/change, retrieve and remove values, it must not access the internal object directly. With this implementation, null values are not allowed. + +Example: + (start code) + var hash = new Hash({a: 'hi', b: 'world', c: 'howdy'}); + hash.remove('b'); // b is removed. + hash.set('c', 'hello'); + hash.get('c'); // returns 'hello' + hash.length // returns 2 (a and b) + (end) +*/ + +var Hash = new Class({ + + length: 0, + + initialize: function(obj) { + this.obj = {}; + for (var property in obj) { + this.obj[property] = obj[property]; + this.length++; + } + }, + + get: function(key) { + return this.obj[key]; + }, + + set: function(key, value) { + if (value == null) return false; + if (this.obj[key] == undefined) this.length++; + this.obj[key] = value; + return this; + }, + + remove: function(key) { + if (this.obj[key] == undefined) return false; + var obj = {}; + this.length--; + for (var property in this.obj){ + if (property != key) obj[property] = this.obj[property]; + } + this.obj = obj; + return this; + }, + + each: function(fn, bind) { + for (var property in this.obj) fn.call(bind || this, property, this.obj[property]); + }, + + extend: function(obj){ + this.initialize(Object.extend(this.obj, obj)); + return this; + }, + + empty: function() { + return (this.length == 0); + }, + + keys: function() { + var keys = []; + for (var property in this.obj) keys.push(property); + return keys; + }, + + values: function() { + var values = []; + for (var property in this.obj) values.push(this.obj[property]); + return values; + } + +}); + +/* +Function: $H + Shortcut to create an Hash from an Object. +*/ + +function $H(obj) { + return new Hash(obj); +}; + +/* +Script: Color.js + Contains the Color class. + +Author: + Michael Jackson + +License: + MIT-style license. +*/ + +/* +Class: Color + Creates a new Color Object, which is an array with some color specific methods. + +Example: + (start code) + var black = new Color('#000'); + var purple = new Color([255,0,255]); + // mix black with white and purple, each time at 10% of the new color + var darkpurple = black.mix('#fff', purple, 10); + $('myDiv').setStyle('background-color', darkpurple); + (end) +*/ + +var Color = new Class({ + + initialize: function(color){ + if (color.mix && color.invert) return color; + var rgb = (color.push) ? color : color.hexToRgb(true); + return Object.extend(rgb, Color.prototype); + }, + + mix: function(){ + var colors = $A(arguments); + var alpha = 50; + if ($type(colors[colors.length-1]) == 'number') alpha = colors.pop(); + var rgb = this.copy(); + colors.each(function(color){ + color = new Color(color); + for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha)); + }); + return new Color(rgb); + }, + + invert: function(){ + var rgb = []; + for (var i = 0; i < 3; i++) rgb.push(255 - this[i]); + return new Color(rgb); + } + +}); + +function $C(color){ + return new Color(color); +}; + +/* +Script: Window.Base.js + Contains Window.onDomReady and Window.disableImageCache + +License: + MIT-style license. +*/ + +/* +Class: Window + Cross browser methods to get the window size, onDomReady method. +*/ + +window.extend = Object.extend; + +window.extend({ + + /* + Function: window.disableImageCache + Disables background image chache for internex explorer, to prevent flickering. + To be called if you have effects with background images, and they flicker. + + Example: + Window.disableImageCache(); + */ + + disableImageCache: function(){ + if (this.ie6) try {document.execCommand("BackgroundImageCache", false, true);} catch (e){}; + }, + + addEvent: function(type, fn){ + if (type == 'domready'){ + if (this.loaded) fn(); + else if (!this.events || !this.events.domready){ + var domReady = function(){ + if (this.loaded) return; + this.loaded = true; + if (this.timer) this.timer = $clear(this.timer); + Element.prototype.fireEvent.call(this, 'domready'); + this.events.domready = null; + }.bind(this); + if (document.readyState && this.khtml){ //safari and konqueror + this.timer = function(){ + if (['loaded','complete'].test(document.readyState)) domReady(); + }.periodical(50); + } + else if (document.readyState && this.ie){ //ie + document.write(" + + + + +

My 1st demo

+ + +
+
+
+

Popup completion

+

+ popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion + popup stlye completion +

+ +
+
+

Emacs style completion

+

emacs stlye completion

+ + + +
+
+

Edit part

+

edit part

+ + + +
+
+ + diff --git a/nxhtml/nxhtml/html-chklnk.el b/nxhtml/nxhtml/html-chklnk.el new file mode 100644 index 0000000..6fdbb49 --- /dev/null +++ b/nxhtml/nxhtml/html-chklnk.el @@ -0,0 +1,168 @@ +;;; html-chklnk.el --- Check links in local HTML sites +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Wed Mar 15 14:46:17 2006 +(defconst html-chklnk:version "0.2") ;; Version: +;; Last-Updated: Tue Apr 10 04:12:32 2007 (7200 +0200) +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile + (when (> emacs-major-version 22) + (let* ((load-path load-path) + (this-file (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name)) + (this-dir (file-name-directory this-file))) + (add-to-list 'load-path (expand-file-name "../../lisp" this-dir)) + (require 'w32shell nil t)))) + + +(eval-when-compile (require 'html-site nil t)) +(require 'compile) + +;;;###autoload +(defgroup html-chklnk nil + "Customization group for html-chklnk." + :group 'nxhtml) + +(defcustom html-chklnk-dir + (file-name-as-directory + (expand-file-name + "html-chklnk" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +" + :type 'directory + :group 'html-chklnk) + +(defun html-chklnk-check-site-links (start-file) + "Check local file web site links. +Currently only internal links are checked." + (interactive + (progn + (html-site-current-ensure-site-defined) + (if (y-or-n-p "Start from a given file and check links from there? ") + (let* ((default-start (if (html-site-current-contains buffer-file-name) + buffer-file-name + (car (directory-files (html-site-current-site-dir) + nil + "\\.html?$")))) + (start-file + (read-file-name "Start checking from file: " + (html-site-current-site-dir) + nil + nil + default-start))) + (unless (html-site-dir-contains (html-site-current-site-dir) start-file) + (error "File %s is not in the site %s" start-file html-site-current)) + (list start-file)) + (list nil)))) + (let* ((default-directory html-chklnk-dir) + (compile-cmd (concat "perl link_checker.pl " + "--site=" + ;;(html-chklnk-convert-file-name + (html-site-current-site-dir) + ;;) + (if start-file + (concat " --start=" + ;;(html-chklnk-convert-file-name + start-file + ;;) + ) + ""))) + (compilation-buffer-name-function + '(lambda (dummy) (concat "** Checking links in site " + html-site-current " **"))) + (compilation-scroll-output t) + (compilation-error-regexp-alist-alist + '( + (html-chklnk + "^\\(.*\\)\\s-+at line \\([0-9]+\\):" + 1 ;; file + 2 ;; line + ))) + (compilation-error-regexp-alist '(html-chklnk)) + ;;(shell-file-name "cmd") + ;;(explicit-shell-file-name "cmd") + ;;(shell (concat exec-directory "cmdproxy.exe")) + ;;(old-w32shell nil) + ) + ;; There are trouble with perl paths +;; (when (featurep 'w32shell) +;; (when w32shell-current-shell-path +;; (setq old-w32shell w32shell-current-shell-path) +;; (w32shell-set-shell "cmd"))) + ;;(message "uses-cygwin=%s" uses-cygwin)(sit-for 8) + + (if (fboundp 'w32shell-save-shell) + (w32shell-save-shell + "cmd" + (compile compile-cmd)) + (compile compile-cmd)) + +;; (when old-w32shell +;; (cond ((string= old-w32shell w32shell-cygwin-bin) +;; (w32shell-set-shell "cygwin")) +;; ((string= old-w32shell w32shell-msys-bin) +;; (w32shell-set-shell "msys")))) + )) + +(defun html-chklnk-convert-file-name (filename) + (let ((uses-cygwin (and (featurep 'w32shell) + (string= w32shell-current-shell-path + w32shell-cygwin-bin))) + (case-fold-search t) + ) + (save-match-data + (if (and uses-cygwin + (string-match "^\\([a-z]\\):" filename)) + (concat "/cygdrive/" (match-string 1 filename) + (substring filename 2)) + filename)))) + + + + +(provide 'html-chklnk) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-chklnk.el ends here diff --git a/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm b/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm new file mode 100644 index 0000000..9cfcce8 --- /dev/null +++ b/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/LinkWalker.pm @@ -0,0 +1,774 @@ +### File: LinkWalker.pm +### Author: Lennart Borgman +### All rights reserved + +########################################################## +### UserAgent module +########################################################## +package LWP::WalkerUA; +require LWP::UserAgent; +@ISA = qw(LWP::UserAgent); + +### Mirror to another file (why???) +sub mirror +{ + my($self, $url, $file, $mirr_tmp) = @_; + die "no mirr_tmp" unless defined $mirr_tmp; + + LWP::Debug::trace('()'); + my $request = new HTTP::Request('GET', $url); + + if (-e $file) { + my($mtime) = (stat($file))[9]; + if($mtime) { + $request->header('If-Modified-Since' => + HTTP::Date::time2str($mtime)); + } + } + my $tmpfile = "$file-$$"; + + my $response = $self->request($request, $tmpfile); + if ($response->is_success) { + + my $file_length = (stat($tmpfile))[7]; + my($content_length) = $response->header('Content-length'); + + if (defined $content_length and $file_length < $content_length) { + unlink($tmpfile); + die "Transfer truncated: " . + "only $file_length out of $content_length bytes received\n"; + } elsif (defined $content_length and $file_length > $content_length) { + unlink($tmpfile); + die "Content-length mismatch: " . + "expected $content_length bytes, got $file_length\n"; + } else { + # OK + if (-e $mirr_tmp) { + # Some dosish systems fail to rename if the target exists + chmod 0777, $mirr_tmp; + unlink $mirr_tmp; + } + rename($tmpfile, $mirr_tmp) or + die "Cannot rename '$tmpfile' to '$mirr_tmp': $!\n"; + + if (my $lm = $response->last_modified) { + # make sure the file has the same last modification time + utime $lm, $lm, $mirr_tmp; + } + } + } else { + unlink($tmpfile); + } + return $response; +} + + +########################################################## +### Parser module +########################################################## +package HTML::WalkerParser; +require HTML::ParserTagEnd; +@ISA = qw(HTML::ParserTagEnd); +use strict; +use vars qw(%LINK_ELEMENT); + +# Elements that might contain links and the name of the link attribute +%LINK_ELEMENT = +( + body => 'background', + base => 'href', + a => 'href', + img => [qw(src lowsrc usemap)], # 'lowsrc' is a Netscape invention + form => 'action', + input => 'src', +'link' => 'href', # need quoting since link is a perl builtin + frame => 'src', + applet => [qw(codebase code)], + area => 'href', + iframe => 'src', # Netscape 2.0 extention + embed => 'src', # used in Netscape 2.0 for Shockwave and things like that +); + +my %LINKATTRIBS = ( + "href" => 1, + "src" => 1, + "action" => 1, + "background" => 1, + "usemap" => 1, + "code" => 1, + "codebase" => 1, + "lowsrc" => 1, + ); +my %MAYBECONT = ( + a => 'href', + area => 'href', + form => 'action', + frame => 'src', + iframe => 'src', + ); + +sub maybecont($$) { + my $tag = shift; + my $att = shift; + return unless exists $MAYBECONT{$tag}; + return ($MAYBECONT{$tag} eq $att); +} + +sub new { + my($class, $parsed_fh) = @_; + my $self = $class->SUPER::new; + $self->{parsed_fh} = $parsed_fh; + $self; +} + + + + + + + +########################################################## +### Walker module +########################################################## +package HTML::LinkWalker; +use strict; + +use IO::File; +use File::Copy qw(); +use File::Path qw(); +use PathSubs qw(); +use HTML::Entities; +use FindBin qw(); + + +########################################################## +### Globals +########################################################## +my $ua; +my $m_ua_personality = "LinkWalker/0.9"; +my %m_is_outside; +my %m_is_container; +my $m_bOnlyCont; +my @m_sLinkRoots; +my $m_subReport; +my $m_subAction; +my $m_subMirrorAction; + + +############################# +### Collecting info +############################# +my %m_CheckedLinks; +my %m_MissedLinks; + +sub tell_bad_link($$$$$) { + my $what = shift; + my $file = shift; + my $lnum = shift; + my $link = shift; + my $line = shift; + $file = "START" unless defined $file; + $lnum = "(start)" unless defined $lnum; + my $longMsg = "<<$what>>"; + my $shortMsg = $what; + if (defined $link) { + my @lines = split("\\s+", $line); + my $disp_line = join("\n\t\t ", @lines); + $longMsg .= ",\n\t\tlink=$link\n\t\t$disp_line"; + } + my @msg = ($shortMsg, $longMsg); + $m_CheckedLinks{$file}->{ERR}->{$lnum} = \@msg; + &$m_subReport("\t* Error * " . $what . "\n"); +} # tell_bad_link + + +############################# +### Helpers +############################# + +sub get_contenttype($) { + my $response = shift; + my @rh = $response->header("Content-Type"); + for my $r (@rh) { + my $c = $r; + if ((my $iPos = index($r, ";")) > -1) { + $c = substr($r, 0, $iPos); + } + return $c; + } +} +sub is_linked_contenttype($) { + my $response = shift; + return (get_contenttype($response) eq "text/html"); +} + +sub ending_is_container($) { + my $link_addr = shift; + $link_addr =~ s!#.*$!!; + $link_addr =~ s!\?.*$!!; + return (($link_addr =~ m!\.s?html?$!i) ? 1 : 0); +} + +my $m_sMirrorRoot; +my $m_bMirror = 1; + +sub mk_mirror_name($) { + my $orig_name = shift; + $orig_name =~ tr!\\!/!; + my $mirr_name = $orig_name; + my ($orig_host) = ($orig_name =~ m!(^https?://[^/]*)!i); + if (defined $orig_host) { + my $host = $orig_host; + $host =~ tr!:!_!; + $host =~ tr!/!_!; + $mirr_name =~ s!^$orig_host!$host!; + if (substr($mirr_name, -1) eq "/") { $mirr_name .= "default.html"; } + } else { + die "Can't find host in $orig_name\n"; + } + my $mirr_full = sMirrorRoot() . $mirr_name; + if (!$m_bMirror) { + my $sExt = $mirr_name; $sExt =~ s!.*\.([^\.]*$)!$1!; + $mirr_full = sMirrorRoot() . "temp.$sExt"; + } + my $mirr_fold = $mirr_full; + $mirr_fold =~ s![^/]*$!!; + File::Path::mkpath($mirr_fold, 0, 0777); + return $mirr_full; +} + +############################# +### Checks +############################# +sub is_outside($) { + my $uq_link_addr = shift; + if (!exists $m_is_outside{$uq_link_addr}) { + $m_is_outside{$uq_link_addr} = test_is_outside($uq_link_addr, \@m_sLinkRoots); + } + return $m_is_outside{$uq_link_addr}; +} +sub set_is_container($$) { + my $uq_link_addr = shift; + return if exists $m_is_container{$uq_link_addr}; + $m_is_container{$uq_link_addr} = shift; +} +sub is_outside_container($) { + my $uq_link_addr = shift; + if (exists $m_is_container{$uq_link_addr}) { + if ($m_is_container{$uq_link_addr}) { + return is_outside($uq_link_addr); + } + } +} +sub test_is_outside($$) { + my $uq_link_addr = shift; + my $link_roots = shift; + if (defined $link_roots) { + my $in_roots; + for my $link_root (@$link_roots) { + if (substr($uq_link_addr, 0, length($link_root)) eq $link_root) { + return 0; + } + } + return 1; + } +} # is_outside + + + +########################################################## +### Parsing +########################################################## + + +### Parser subs +sub HTML::WalkerParser::declaration { + my($self, $decl) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} +my $m_start_cb; +sub HTML::WalkerParser::start { + my($self, $tag, $attr, $ended) = @_; + &$m_start_cb($tag, $attr); + return unless defined $self->{parsed_fh}; + my $t = "<$tag"; + for my $k (keys %$attr) { + my $encoded = encode_entities($$attr{$k}); + $t .= qq( $k="$encoded"); + } + if ($ended) { + $t .= " />"; + } else { + $t .= ">"; + } + my $fh = $self->{parsed_fh}; + print $fh $t; +} +sub HTML::WalkerParser::end { + my ($self, $tag) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} +sub HTML::WalkerParser::text { + my ($self, $txt) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh $txt; +} +sub HTML::WalkerParser::comment { + my($self, $comment) = @_; + return unless defined $self->{parsed_fh}; + my $fh = $self->{parsed_fh}; + print $fh ""; +} + + + + +### Main parsing routine + +sub parse_file($$$$$$$$$) { + my ($file_name, $parsed_fh, $uq_link_addr, $link_roots, + $ref_links, $ref_anchs, $ref_lines, $ref_tagname, $ref_attname) = @_; + my $fh; + if (-d $file_name) { + $file_name = PathSubs::uniq_dir($file_name) . "default.html"; + $uq_link_addr .= "/" unless substr($uq_link_addr, -1) eq "/"; + $uq_link_addr .= "default.html"; + &$m_subReport("dir => $file_name\n"); + } + $fh = new IO::File($file_name); + die "Can't read $file_name: $!\n" unless defined $fh; + my $base_href; + my $n; + my $line; + my $uq_link_fold = $uq_link_addr; $uq_link_fold =~ s![^/]*$!!; + + my $start_cb = + sub { + my ($tag, $attr_hash) = @_; + for my $k (keys %$attr_hash) { + if (($k eq "id") || ($k eq "name")) { + my $v = $$attr_hash{$k}; + $$ref_anchs{$v} = $n; + $$ref_lines{$n} = $line; + } elsif (exists $LINKATTRIBS{$k}) { + my $v = $$attr_hash{$k}; + next if $v =~ m!^javascript:!; + next if $v =~ m!^ftp://!; + next if $v =~ m!^mailto://!; + if ($tag eq "base") { $base_href = $v if $k eq "href"; next; } + my $v_abs; my $v_rel; + my $v_is_abs = PathSubs::is_abs_path($v); + if ($v_is_abs) { + $v_abs = $v; + $v_rel = PathSubs::mk_relative_link($uq_link_addr, $v_abs); + } else { + $v_rel = $v; + if (defined $base_href) { + $v_abs = PathSubs::mk_abs_link($base_href, $v); + } else { + if (substr($v_rel, 0, 1) ne "#") { + $v_abs = $uq_link_fold . $v_rel; + } else { + $v_abs = $uq_link_addr . $v_rel; + } + $v_abs = PathSubs::resolve_dotdot($v_abs); + } + } + next if exists $m_CheckedLinks{$v_abs}; + if (is_outside($v_abs)) { + if (!$v_is_abs) { + if (ending_is_container($v_abs)) { + $m_CheckedLinks{$v_abs} = {}; + tell_bad_link("Outside relative link ($v_rel)", + $uq_link_addr, $n, $v, $line); + } + } + ### Skip outside absolute links + ### Could be things like banners etc... + next; + } + $$ref_links{$v_rel} = $n; + $$ref_lines{$n} = $line; + if (substr($v_rel, 0, 1) ne "#") { + my $v_rel_name = $v_rel; + $v_rel_name =~ s!#.*$!!; + $v_rel_name =~ s!\?.*$!!; + $$ref_tagname{$v_rel_name} = $tag; + $$ref_attname{$v_rel_name} = $k; + } + if ($v_is_abs && ($v_rel ne $v)) { $$attr_hash{$k} = $v_rel; } + } + } + }; # $start_cb + + $m_start_cb = $start_cb; + my $p = HTML::WalkerParser->new($parsed_fh); + while ($line = <$fh>) { + $n++; + $p->parse($line); + } + $fh->close(); +} # parse_file + + + +########################################################## +### Do the walk... +########################################################## +sub walk_link($$;$$$$) { + die "$#_" unless ($#_ == 1 || $#_ == 5); + my $link_fold = shift; + my $link_file = shift; + my $parent_url = shift; + my $parent_lnum = shift; + my $parent_link = shift; + my $parent_line = shift; + + my $link_addr = $link_fold . $link_file; + my $uq_link_addr; + my $is_file = ($link_addr !~ m!^https?://!i); + if ($is_file) { + $uq_link_addr = PathSubs::uniq_file($link_addr); + } else { + $uq_link_addr = PathSubs::resolve_dotdot($link_addr); + } + return if exists $m_CheckedLinks{$uq_link_addr}; + return if exists $m_MissedLinks{$uq_link_addr}; + $m_CheckedLinks{$uq_link_addr} = {}; + my $link_is_container = ending_is_container($uq_link_addr); + if ($link_is_container) { + set_is_container($uq_link_addr, 1); + return if is_outside($uq_link_addr); + } else { + return if $m_bOnlyCont; + } + my $response; + my $contenttype; + my $bDoRewrite; + my $file_name; + if ($is_file) { + if (!-r $uq_link_addr) { + tell_bad_link("Can't read file ($uq_link_addr)", + $parent_url, $parent_lnum, $parent_link, $parent_line); + $m_MissedLinks{$uq_link_addr} = 1; + return; + } + $file_name = $uq_link_addr; + } else { + $file_name = mk_mirror_name($uq_link_addr); + if (!defined $ua) { + $ua = new LWP::UserAgent; + $ua->agent($m_ua_personality); + #$ua->delay(0.1); + } + if ($m_bMirror) { + $response = $ua->mirror($uq_link_addr, $file_name); + &$m_subMirrorAction($uq_link_addr, $file_name, $response); + } else { + my $request = new HTTP::Request('GET', $uq_link_addr); + $response = $ua->request($request, $file_name); + } + #dump_response($response); exit; + if ($response->code != 304) { + if (!$response->is_success) { + tell_bad_link($response->status_line . " ($uq_link_addr)", + $parent_url, $parent_lnum, $parent_link, $parent_line); + $m_MissedLinks{$uq_link_addr} = 1; + return; + } + $bDoRewrite = $m_bMirror; + $contenttype = get_contenttype($response); + $link_is_container = is_linked_contenttype($response); + } + if ($uq_link_addr ne $response->base) { + if ($m_bMirror) { + my $base_file = mk_mirror_name($response->base); + if (!File::Copy::copy($file_name, $base_file)) { + die "Can't copy($file_name, $base_file): $!\n"; + } + if (my $lm = $response->last_modified) { utime $lm, $lm, $base_file; } + $file_name = $base_file; + } + $uq_link_addr = $response->base; + } + } + ### Test again, could be new info from net! + if ($link_is_container) { + set_is_container($uq_link_addr, 1); + return if is_outside($uq_link_addr); + } else { + return if $m_bOnlyCont; + return; + } + &$m_subReport("$uq_link_addr ..."); + + my %links; + my %anchs; + my %lines; + my %tagname; + my %attname; + my $parsed_fh; + my $parsed_file; + my $file_to_parse = $file_name; + if ($bDoRewrite) { + $parsed_file = $file_to_parse . "-p$$"; + &$m_subReport(" < $parsed_file"); + die "Can't create $parsed_file: $!\n" unless defined $parsed_fh; + print $parsed_fh "\n"; + } + &$m_subReport("\n"); + parse_file($file_to_parse, $parsed_fh, $uq_link_addr, + \@m_sLinkRoots, + \%links, \%anchs, \%lines, \%tagname, \%attname); + if (defined $parsed_fh) { + $parsed_fh->close(); + if (-e $file_name) { unlink $file_name or die "Can't unlink $file_name: $!"; } + rename($parsed_file, $file_name) or die "Can't rename($parsed_file, $file_name): $!\n"; + if (my $lm = $response->last_modified) { utime $lm, $lm, $file_name; } + } + ### Now we know... + if ($link_is_container) { return if is_outside($uq_link_addr); } + + $m_CheckedLinks{$uq_link_addr}->{ANC} = \%anchs; + my $file_dir; + if ($is_file) { + $file_dir = $uq_link_addr; + $file_dir =~ s![^/]*$!!; + #chdir $file_dir; + } + my $container_folder = $uq_link_addr; $container_folder =~ s![^/]*$!!; + &$m_subAction($uq_link_addr, $file_name, $contenttype); + for my $link (sort keys %links) { + # Next line is for onclick lines in prepared docs + next if ($link eq "#"); + my $lnum = $links{$link}; + my $line = $lines{$lnum}; + if ($link eq "") { + tell_bad_link("Empty link", $uq_link_addr, $lnum, $link, $line); + next; + } + if ($link =~ m!(.*)\?!) { $link = $1; } + my $anchor; + if ($link =~ m!(.*)#(.*)!) { $link = $1; $anchor = $2; } + if ($link eq "") { + if (!exists $anchs{$anchor}) { + tell_bad_link("Anchor not found ($anchor)", $uq_link_addr, $lnum, $link, $line); + } + next; + } + my $sub_fold; + my $sub_file; + my $uq_sublink; + if ($link =~ m!^https?://!i) { + $sub_fold = ""; + $sub_file = $link; + $uq_sublink = $link; + } else { + $sub_file = $link; + if ($is_file) { + $sub_fold = $file_dir; + $uq_sublink = PathSubs::uniq_file($sub_fold . $sub_file); + } else { + $sub_fold = $container_folder; + $uq_sublink = $sub_fold . $sub_file; + } + } + next if (exists $m_CheckedLinks{$uq_sublink}); + if (defined $anchor) { + $m_CheckedLinks{$uq_link_addr}->{EXTANC}->{$uq_sublink} = + { ANC=> $anchor, LINE=>$line, LNUM=>$lnum}; + } + if ($m_bOnlyCont) { + die "link=$link\tattr=$tagname{$link}\n" unless exists $tagname{$link}; + next unless maybecont($tagname{$link}, $attname{$link}); + } + if (is_outside($uq_link_addr)) { + if (maybecont($tagname{$link}, $attname{$link}) ) { + next; + } + } + walk_link($sub_fold, $sub_file, $uq_link_addr, $lnum, $link, $line); + } +} # walk_link + + + + +############################################ +### Some more checks! +############################################ +sub check_external_anchors() { + &$m_subReport("\nChecking external anchors...\n"); + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{"EXTANC"}) { + my $extanc_hash = ${$fnode}{"EXTANC"}; + for my $fx (keys %$extanc_hash) { + next unless (exists $m_CheckedLinks{$fx}); + my $ea_hash = ${$extanc_hash}{$fx}; + my $ea = ${$ea_hash}{ANC}; + my $fxnode = $m_CheckedLinks{$fx}; + my $fx_anc_hash = ${$fxnode}{"ANC"}; + if (!exists ${$fx_anc_hash}{$ea}) { + my $line = ${$ea_hash}{LINE}; + my $lnum = ${$ea_hash}{LNUM}; + &$m_subReport("From $f\n"); + tell_bad_link("Ext anchor not found ($fx#$ea)", + $f, $lnum, "$fx#$ea", $line); + } + } + } + } +} # check_external_anchors + + + +############################# +### Reporting +############################# +sub report_errors($$) { + my $bSum = shift; + my $bDet = shift; + my $errors_reported; + my $errors_found; + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{ERR}) { + $errors_found = 1; + last unless $bSum; + if (!defined $errors_reported) { + $errors_reported = 1; + &$m_subReport("\n\n*********** Summary ERRORS and WARNINGS **********\n"); + } + &$m_subReport("$f\n"); + my $err_hash = ${$fnode}{ERR}; + for my $e (sort keys %$err_hash) { + my $refE = ${$err_hash}{$e}; + &$m_subReport("\t" . ${$refE}[0] . "\n"); + } + } + } + undef $errors_reported; + if ($bDet) { + for my $f (sort keys %m_CheckedLinks) { + my $fnode = $m_CheckedLinks{$f}; + if (exists ${$fnode}{ERR}) { + if (!defined $errors_reported) { + $errors_reported = 1; + &$m_subReport("\n\n*********** Detailed ERRORS and WARNINGS **********\n"); + } + &$m_subReport("$f\n"); + my $err_hash = ${$fnode}{ERR}; + for my $e (sort keys %$err_hash) { + my $refE = ${$err_hash}{$e}; + &$m_subReport("\tat line $e: " . ${$refE}[1] . "\n"); + } + } + } + } + if ($errors_found) { + die "\n*** There where errors ***\n"; + } else { + &$m_subReport("No errors found\n"); + } +} # report_errors + +sub dump_response($) { + my $response = shift; + &$m_subReport( $response->code . " " . $response->message . "\n"); + &$m_subReport( "****************************************\n"); + #&$m_subReport( $response->request . "\n"); + #&$m_subReport( "****************************************\n"); + #&$m_subReport( $response->previous . "\n"); + #&$m_subReport( "****************************************\n"); + &$m_subReport( " i=" . $response->is_info . + ", s=" . $response->is_success . + ", r=" . $response->is_redirect . + ", e=" . $response->is_error . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( "content: " . $response->content . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( "base: " . $response->base . "\n"); + &$m_subReport( "****************************************\n"); + &$m_subReport( $response->as_string); + &$m_subReport( "****************************************\n"); + &$m_subReport( $response->current_age . "\n"); + &$m_subReport( "****************************************\n"); + my @rh = $response->header("Content-Type"); + for my $r (@rh) { &$m_subReport( "ct: $r\n"); } + &$m_subReport( "****************************************\n"); +} # dump_response + + +############################# +### Parameters +############################# +sub sMirrorRoot() { + my $val = shift; + $m_sMirrorRoot = PathSubs::get_temp_path() . "LinkWalker/" unless defined $m_sMirrorRoot; + my $old = $m_sMirrorRoot; + $m_sMirrorRoot = PathSubs::uniq_dir($val) if defined $val; + return $old; +} +sub bMirror(;$) { + my $val = shift; + my $old = $m_bMirror; + $m_bMirror = $val if defined $val; + $old; +} + +sub subReporter(;$) { + my $val = shift; + my $old = $m_subReport; + $m_subReport = $val if defined $val; + $old +} +sub subAction(;$) { + my $val = shift; + my $old = $m_subAction; + $m_subAction = $val if defined $val; + $old +} +sub bOnlyCont(;$) { + my $val = shift; + my $old = $m_bOnlyCont; + $m_bOnlyCont = $val if defined $val; + $old +} +sub ua_personality(;$) { + my $val = shift; + my $old = $m_ua_personality; + $m_ua_personality = $val if defined $val; + $old +} + +sub clear_roots() { @m_sLinkRoots = (); } +sub get_roots() { return \@m_sLinkRoots; } +sub add_root($) { push @m_sLinkRoots, shift; } +sub add_files_root($) { + my $file = shift; + my $default_root; + my ($host) = ($file =~ m!(^https?://[^/]*)!i); + if (defined $host) { + $default_root = $file; + } else { + die "Can't find $file\n" unless -e $file; + $default_root = PathSubs::uniq_file($file); + } + $default_root =~ s![^/]*$!!; + add_root($default_root); +} + +### Default actions +sub default_sub {} +$m_subReport = \&default_sub; +$m_subAction = \&default_sub; +$m_subMirrorAction = \&default_sub; + +1; diff --git a/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm b/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm new file mode 100644 index 0000000..78887b1 --- /dev/null +++ b/nxhtml/nxhtml/html-chklnk/PerlLib/HTML/ParserTagEnd.pm @@ -0,0 +1,448 @@ +package HTML::ParserTagEnd; + +# Author address: +### Modified for , Lennart + +use strict; +use HTML::Entities (); + +use vars qw($VERSION); +$VERSION = "2.23"; # $Date: 1999/06/09 10:27:16 $ + + +sub new +{ + my $class = shift; + my $self = bless { '_buf' => '', + '_strict_comment' => 0, + }, $class; + $self; +} + + +# A little note about the observed Netscape behaviour: +# +# It parse in the depreceated 'literal' mode, i.e. no tags are +# recognized until a is found. +# +# is parsed like
, i.e. tags are recognized.  +# are presentend in smaller font than 
+#
+# Netscape does not parse this comment correctly (it terminates the comment
+# too early):
+#
+#     more comment -->
+#
+# Netscape ignores '' within the 
+    
+    
+  
+  
+
+
+    
+      
+        
+
+      
+    
+ + + + + + + + +
+ + + + + +
+ + + + + + + +
%%TOC%%
+
+   +
+
+
+ + diff --git a/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css b/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css new file mode 100644 index 0000000..a6ffabb --- /dev/null +++ b/nxhtml/nxhtml/html-toc/html-toc/html-toc-template.css @@ -0,0 +1,141 @@ +/* Main structures >>>>>>>>>>>>>>> */ +.html-wtoc-maintop { + font-size: 1px; + font-size: 1em; + margin-top: 0em; + margin-bottom: 0em; +/* background-color:green; */ +} +.html-wtoc-main { +} + +td.html-wtoc-vdivline { + //background-color: #8be; + width: 0px; +} + +.html-wtoc-search-form { + margin-bottom: 0.1em; +} +.html-wtoc-search { + font-size: 0.8em; + color: green; +} +.html-wtoc-search a { + color: green; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Table of content >>>>>>>>>>>>>> */ + +#html-wtoc-id-hidetoc { + height: 20px; + border-bottom: 2px inset #ddf; + border-color: #dff; +} + +#html-wtoc-id-tocdiv { + width: 2.5em; + //background-color: #eff; +} +#html-wtoc-id-logo { + width: 100%; + height: 120px; + padding: 0em; + margin: 0em; + border: 0em; +} +#html-wtoc-id-toc { +} +#html-wtoc-id-tocwidth { + width: 18em; + height: 0em; + padding: 0em; + margin: 0em; + border: 0em; + line-height: 0em; +/* background-color: red; */ +} +#html-wtoc-id-toccol { + width: 18em; +} + +.html-wtoc-contcol { + background-color: #dFEfff; + background-color: #dFEfff; + background-color: #cd950c; + background-color: #eead0e; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Buttons etc >>>>>>>>>>>>>>> */ +.html-wtoc-button { + font-size: 0.75em; + font-size: 8pt; + color: #5A5D00; + background-color: #9cf; + background-color: #bcee68; + background-color: #a2cd5a; + padding: 0.2em; + Border-Width: 2px; + Border-Style: outset; + text-align: center; + border-color: #ddf; +} +a.html-wtoc-button { + text-decoration: none; + color: #5A5D00; +} +a.html-wtoc-button:hover { + text-decoration:none; + background-color: #6af; + color:#340; +} + +a.html-wtoc-buttonimg img { + width: 16px; + height: 16px; + padding: 4px; + border: 8px; +} +a.html-wtoc-buttonimg { + border:2px; + margin:2px; + margin-left:2px; + margin-right:2px; +} +a.html-wtoc-buttonimg { + font-size:1px; +} +a.html-wtoc-buttonimg:hover { + margin: 6px; + margin-left:0px; + margin-right:0px; + border-color: #ddf; + border-width: 2px; + border-style: outset; + background-color: #595C00; + background-color: #bef; + background-color: #b9ffb9; +} + +/* <<<<<<<<<<<<<<<<<<< */ + + +#nxhtml-link { + font-size: 0.7em; + text-align: center; + padding-top: 2em; + padding: 1em; +} + +.copyright { + color : #872; +} + diff --git a/nxhtml/nxhtml/html-toc/html-toc/html-toc.css b/nxhtml/nxhtml/html-toc/html-toc/html-toc.css new file mode 100644 index 0000000..a12cb65 --- /dev/null +++ b/nxhtml/nxhtml/html-toc/html-toc/html-toc.css @@ -0,0 +1,84 @@ +body { + margin: 0; +} +td { + font-size: 1em; +} + +/* Added by html-wtoc.pl >>>>>>>>>>>>> */ +.html-wtoc-mark { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + width: 20px; + padding: 0; + border: 0; + text-align: center; +} +.html-wtoc-contline { + width: 100%; +} + +.html-wtoc-margin { + width: 0.6em; +} +.html-wtoc-contents { + font-size: 0.9em; + padding: 1em; + background-color: #9cf; + background-color: #a2cd5a; + background-color: #efffcf; + background-color: #ffffdf; + -moz-border-radius-topleft: 2em; +} +.html-wtoc-contents td { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ +} +.html-wtoc-contents-a { + text-decoration: none; + color: #595C00; +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + border: 1px #9cf solid; + border: 1px #a2cd5a solid; + border: 1px #ffffc0 solid; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +.html-wtoc-contents a:hover { + text-decoration: none; + background-color: #b9ffb9; + border: 1px #6b8e23 solid; +} +.html-wtoc-currcont { + background-color: #738600; + color: #ffff2f; + background-color: #535600; + border: 1px #6b8e23 inset; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +a.html-wtoc-currcont { + text-decoration: none; +} +a.html-wtoc-currcont:hover { + background-color: #738600; + background-color: #536600; + background-color: #434620; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + + + + + diff --git a/nxhtml/nxhtml/html-toc/html-toc/html-toc.js b/nxhtml/nxhtml/html-toc/html-toc/html-toc.js new file mode 100644 index 0000000..7f22db7 --- /dev/null +++ b/nxhtml/nxhtml/html-toc/html-toc/html-toc.js @@ -0,0 +1,361 @@ + +// © Copyright 2006 Lennart Borgman, http://www.OurComments.org/. All rights reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth +// Floor, Boston, MA 02110-1301, USA. + + +var HTML_WTOC_NS_sCurrTocId; + + +HTML_WTOC_NS = { + + ///////////////////////////// + //// Basic event functions + ///////////////////////////// + + getEventObject : function (ev) { + var o; + if (window.event) + o = window.event.srcElement; + else if (null != ev) + o = ( ev.target ); + return o; + }, + getEvent : function (ev) { + if (window.event) { + return window.event; + } else if (null != ev) { + return ev; + } + }, + + eventStopPropagation : function (e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble=true; + }, + + eventPreventDefault : function (e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue=false; + }, + + ///////////////////////////// + //// TOC hide + ///////////////////////////// + + show_content : function (on) { + var toc = document.getElementById("html-wtoc-id-toccol").style; + var tdv = document.getElementById("html-wtoc-id-tocdiv").style; + var shw = document.getElementById("html-wtoc-id-showtoc").style; + var hid = document.getElementById("html-wtoc-id-hidetoc").style; + if (on) { + toc.display = ""; + tdv.display = ""; + shw.display = "none"; + hid.display = ""; + HTML_WTOC_NS.focus_page_link(0); + } else { + toc.display = "none"; + tdv.display = "none"; + shw.display = ""; + hid.display = "none"; + } + }, + + + + + + ///////////////////////////// + //// Open-Close + ///////////////////////////// + onblur_action : function(ev) { + HTML_WTOC_NS_sCurrTocId = null; + }, + onfocus_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + if (!o) return; + + HTML_WTOC_NS_sCurrTocId = o.id; + }, + onclick_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + var e = HTML_WTOC_NS.getEvent(ev); + if (13 == e.keyCode) return true; + if (!o) return true; + if ("IMG" == o.tagName) o = o.parentNode; + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + var sChildId = "toc_child_"+iId; + var sOldCurrTocId = HTML_WTOC_NS_sCurrTocId; + HTML_WTOC_NS.toggle_open(sChildId, o); + HTML_WTOC_NS_sCurrTocId = sOldCurrTocId; + return false; + }, + + toggle_open : function (id, parent) { + var child = document.getElementById(id).style; + var sInner = parent.innerHTML; + var re = new RegExp("[^/]*\.gif", "i"); + if ("none" == child.display) { + child.display = ""; + parent.innerHTML = sInner.replace(re, "down.gif")+""; + } else { + child.display = "none"; + parent.innerHTML = sInner.replace(re, "right.gif")+""; + } + }, + + + + ///////////////////////////// + //// Load + ///////////////////////////// + + onload_actions : function (iPageNum) { + document.body.onkeydown = HTML_WTOC_NS.onkeydown_action; + document.body.onmouseover = HTML_WTOC_NS.onmouseover_action; + var aATags = document.getElementsByTagName("a"); + for(var i = 0; i < aATags.length; i++) { + var o = aATags[i]; + if (null != HTML_WTOC_NS.getIdnumFromId(o.id)) { + o.onfocus = HTML_WTOC_NS.onfocus_action; + o.onblur = HTML_WTOC_NS.onblur_action; + if (o.id.substr(0, 12) == "opener_text_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.title = "Open/Close"; + } else if (o.id.substr(0, 7) == "opener_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.className = "html-wtoc-mark"; + o.title = "Open/Close"; + } + } + } + HTML_WTOC_NS.focus_page_link(iPageNum); + }, + focus_page_link : function (iPageNum) { + // Element might be hidden + try { + document.getElementById("toc_link_"+iPageNum).focus(); + } catch (exc) { + } + }, + + + + + + + + ///////////////////// + //// Mouse + ///////////////////// + + onmouseover_action : function (ev) { + if (null == HTML_WTOC_NS_sCurrTocId) return true; + var o = HTML_WTOC_NS.getEventObject(ev); + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + if (null == iId) return true; + o.focus(); + }, + + + + ///////////////////// + //// Key + ///////////////////// + + onkeydown_action: function (ev) { + var keyDown = 40; + var keyUp = 38; + var keyLeft = 37; + var keyRight = 39; + var keyReturn = 13; + var keyF2 = 113; + var keyInsert = 45; + // Opera + var keyOperaDown = 57386; + var keyOperaUp = 57385; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var keyOperaF2 = 57346; + var keyOperaInsert = 57394; + + var SwitchKey = keyInsert; + var SwitchKeyOpera = keyOperaInsert; + + var bUp; + var e = HTML_WTOC_NS.getEvent(ev); + if (null == HTML_WTOC_NS_sCurrTocId) { + switch (e.keyCode) { + case SwitchKey: + case SwitchKeyOpera: + HTML_WTOC_NS.focus_page_link(0); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + } + return true; + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + case keyRight: + case keyOperaRight: + HTML_WTOC_NS.handle_leftright_keys(e); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + case keyDown: + case keyOperaDown: + bUp = false; + break; + case keyUp: + case keyOperaUp: + bUp = true; + break; + case SwitchKey: + case SwitchKeyOpera: + if (null != HTML_WTOC_NS_sCurrTocId) { + var o = document.getElementById(HTML_WTOC_NS_sCurrTocId); + if (o) o.blur(); + HTML_WTOC_NS_sCurrTocId = null; + } + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + default: + //alert(e.keyCode); + return true; + } + var oOpener; + oOpener = HTML_WTOC_NS.getNextVisOpener(HTML_WTOC_NS_sCurrTocId, bUp); + oOpener.focus(); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + }, + + handle_leftright_keys: function (e) { + var keyLeft = 37; + var keyRight = 39; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var iId = HTML_WTOC_NS.getIdnumFromId(HTML_WTOC_NS_sCurrTocId); + if (null == iId) return; + var sId = "opener_" + iId; + var oOpener = document.getElementById(sId); + var sId = HTML_WTOC_NS_sCurrTocId; // It will be cleared before getNextVis + + var bOpenAction; + var bOpened; + var bUp; + var oChild = document.getElementById("toc_child_"+iId); + if (null == oChild) { + } else { + bOpened = (oChild.style.display != "none"); + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + bUp = true; + bOpenAction = (null != bOpened) && (bOpened); + break; + case keyRight: + case keyOperaRight: + bUp = false; + bOpenAction = (null != bOpened) && (!bOpened); + break; + default: + alert("bad key handling..."); + } + if (bOpenAction) { + oOpener.click(); + HTML_WTOC_NS_sCurrTocId = sId; + } else { + var oPrev = HTML_WTOC_NS.getNextVisOpener(sId, bUp); + oPrev.focus(); + } + }, + + + + + + + ////////////////////// + //// Util + ////////////////////// + getNameFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$1"); + return iId; + }, + getIdnumFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$2"); + return iId; + }, + + + getNextVisOpener: function (sId, bUp, bTrace) { + if (bTrace) alert("getNextVisOpener("+sId+","+bUp+")"); + var iId = HTML_WTOC_NS.getIdnumFromId(sId); + if (null == iId) { + alert("getNextVisOpener err iId==null"); + return; + } + var sIdName = HTML_WTOC_NS.getNameFromId(sId); + if (null == sIdName) { + alert("getNextVisOpener err sIdName==null"); + return; + } + var oOpener; + var iLoop = -2; + while (oOpener == null) { + if (bTrace) alert(iId); + if (iLoop++ > iMaxChildNum) { alert("Child num error"); return; } + if (!bUp) { + iId++; + } else { + iId--; + } + if (iId > iMaxChildNum) { iId = 0; } + if (iId < 0) { iId = iMaxChildNum; } + var s = sIdName+iId; + oOpener = document.getElementById(s); + if (oOpener != null) { + if (bTrace) alert(oOpener.offsetLeft); + if (oOpener.style.display == "none") { // All + oOpener = null; + } else if (oOpener.offsetLeft < 0) { // IE + oOpener = null; + } else if (0 == oOpener.scrollWidth) { // Opera + oOpener = null; + } + } + } + return oOpener; + } + + + +}; //HTML_WTOC_NS diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif b/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif new file mode 100644 index 0000000..0869f9f Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/blank12.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/down.gif b/nxhtml/nxhtml/html-toc/html-toc/img/down.gif new file mode 100644 index 0000000..30d6ecf Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/down.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif b/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif new file mode 100644 index 0000000..1c94b60 Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/freeCont.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png b/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png new file mode 100644 index 0000000..5254ef1 Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.png differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf b/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf new file mode 100644 index 0000000..f2ce5ce Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/gnu-m-x-160.xcf differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif b/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif new file mode 100644 index 0000000..9908895 Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/hideCont.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif b/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif new file mode 100644 index 0000000..4c1bca4 Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/nailCont.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif b/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif new file mode 100644 index 0000000..e824f5b Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/nosearch.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/right.gif b/nxhtml/nxhtml/html-toc/html-toc/img/right.gif new file mode 100644 index 0000000..2400cf1 Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/right.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/search.gif b/nxhtml/nxhtml/html-toc/html-toc/img/search.gif new file mode 100644 index 0000000..9f58dfd Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/search.gif differ diff --git a/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif b/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif new file mode 100644 index 0000000..7bd2e7d Binary files /dev/null and b/nxhtml/nxhtml/html-toc/html-toc/img/showCont.gif differ diff --git a/nxhtml/nxhtml/html-upl.el b/nxhtml/nxhtml/html-upl.el new file mode 100644 index 0000000..1ce2e98 --- /dev/null +++ b/nxhtml/nxhtml/html-upl.el @@ -0,0 +1,329 @@ +;;; html-upl.el --- Uploading of web sites +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Mon Mar 06 19:09:19 2006 +(defconst html-upl:version "0.3") ;; Version: +;; Last-Updated: 2008-03-22T01:23:01+0100 Sat +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; `cl', `html-site', `html-upl', `mail-prsvr', `mm-util', `timer', +;; `url-c', `url-parse', `url-vars'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile (require 'html-site nil t)) + +;;;###autoload +(defgroup html-upl nil + "Customization group for html-upl." + :group 'nxhtml) + +(defcustom html-upl-dir + (file-name-as-directory + (expand-file-name + "html-upl" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +The tools for html-upl includes: + +- ftpsync.pl +" + :type 'directory + :group 'html-upl) + +(defun html-upl-browse-remote () + (interactive) + (let ((url (html-site-local-to-web html-site-current + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + nil))) + (browse-url url))) +(defun html-upl-browse-remote-with-toc () + (interactive) + (let ((url (html-site-local-to-web html-site-current + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + t))) + (browse-url url))) +(defun html-upl-browse-remote-frames () + (interactive) + (let ((url (html-site-local-to-web (html-site-current-frames-file) + ;;buffer-file-name + (html-site-buffer-or-dired-file-name) + nil))) + (browse-url url))) + +;;;###autoload +(defun html-upl-upload-site-with-toc () + (interactive) + (html-upl-upload-site1 t)) + +;;;###autoload +(defun html-upl-upload-site () + (interactive) + (html-upl-upload-site1 nil)) +(defun html-upl-upload-site1(with-toc) + (html-site-current-ensure-site-defined) + (html-upl-ensure-site-has-host) + (let ((local-dir (if with-toc + (html-site-current-merge-dir) + (html-site-current-site-dir))) + (ftp-host (html-site-current-ftp-host)) + (ftp-user (html-site-current-ftp-user)) + (ftp-pw (html-site-current-ftp-password)) + (ftp-dir (if with-toc + (html-site-current-ftp-wtoc-dir) + (html-site-current-ftp-dir))) + (ftpsync-pl (expand-file-name "ftpsync.pl" html-upl-dir)) + ) + (unless (< 0 (length ftp-host)) + (error "Ftp host not defined")) + (unless (< 0 (length ftp-user)) + (error "Ftp user not defined")) + (unless (< 0 (length ftp-dir)) + (if with-toc + (error "Ftp remote directory for pages with TOC not defined") + (error "Ftp remote directory not defined"))) + (unless (< 0 (length ftp-pw)) + (setq ftp-pw (html-site-get-ftp-pw))) + (let* ( + (buffer (noshell-procbuf-setup "subprocess for upload")) + (remote-url (concat "ftp://" ftp-user ":" ftp-pw "@" ftp-host ftp-dir)) + (opt (list + "-v" + "-p" + local-dir + remote-url))) + (apply 'noshell-procbuf-run + buffer + "perl" "-w" + ftpsync-pl + opt + )))) + +(defun html-upl-ensure-site-has-host () + (let ((host (html-site-current-ftp-host))) + (unless (and host (< 0 (length host))) + (error "Site %s has no ftp host defined" html-site-current)))) + +;;;###autoload +(defun html-upl-remote-dired (dirname) + "Start dired for remote directory or its parent/ancestor." + (interactive (list + (read-directory-name "Local directory: " nil nil t))) + (html-site-current-ensure-file-in-site dirname) + (html-upl-ensure-site-has-host) + (let* ((local-dir dirname) + (remote-dir (html-site-current-local-to-remote local-dir nil)) + to-parent + res + msg) + (while (not res) + (condition-case err + (progn + (dired remote-dir) + (setq res t)) + (error ;;(lwarn 't :warning "err=%s" err) + (setq msg (error-message-string err)))) + ;; It does not look like we always get an error. Check where we are: + (when res + (unless (string= default-directory remote-dir) + (setq res nil) + (setq msg ""))) + (unless res + ;; 450 Requested file action not taken File unavailable (e.g. file busy). + ;; 550 Requested action not taken File unavailable (e.g. file not found, no access). + (if (or (string= msg "") + (save-match-data (string-match " \\(?:550\\|450\\) " msg))) + (progn + (if (not to-parent) + (setq to-parent (concat + (file-name-nondirectory remote-dir) + "/..")) + (setq to-parent (concat + (file-name-nondirectory remote-dir) + "/" + to-parent "/.."))) + ;;(setq local-dir (directory-file-name (file-name-directory (directory-file-name local-dir)))) + ;;(html-site-current-ensure-file-in-site local-dir) + ;;(setq remote-dir (html-site-current-local-to-remote local-dir nil)) + (setq remote-dir (directory-file-name (file-name-directory remote-dir))) + ) + (setq res msg)))) + (if (stringp res) + (error "%s" msg) + (when to-parent + (message "Remote dir not found, showing ancestor %s" to-parent))))) + +;;;###autoload +(defun html-upl-upload-file (filename) + "Upload a single file in a site. +For the definition of a site see `html-site-current'." + (interactive (list + (let ((use-dialog-box nil) + (f (file-relative-name + ;;(if (derived-mode-p 'dired-mode) (dired-get-file-for-visit) buffer-file-name) + (html-site-buffer-or-dired-file-name) + ))) + (read-file-name "File: " nil nil t f)) + )) + (html-site-current-ensure-file-in-site filename) + (html-upl-ensure-site-has-host) + (let* ((buffer (get-file-buffer filename)) + (remote-file (html-site-current-local-to-remote filename nil)) + (remote-buffer (get-file-buffer remote-file)) + (local-file filename)) + (when (or (not buffer-file-name) + (not (buffer-modified-p buffer)) + (and + (y-or-n-p (format "Buffer %s is modified. Save buffer and copy? " + (buffer-name buffer))) + (with-current-buffer buffer + (save-buffer) + (not (buffer-modified-p))))) + (when (= ?~ (string-to-char local-file)) + (setq local-file (expand-file-name local-file))) + (when (and (fboundp 'w32-short-file-name) + (string-match " " local-file)) + (setq local-file (w32-short-file-name local-file))) + (copy-file local-file + ;;(html-site-current-local-to-remote filename nil) + remote-file + 0) + (when remote-buffer + (with-current-buffer remote-buffer + (revert-buffer nil t t))) + (message "Upload ready") + ))) + +;;;###autoload +(defun html-upl-edit-remote-file () + (interactive) + (html-upl-edit-remote-file1 nil)) + +;;;###autoload +(defun html-upl-edit-remote-file-with-toc () + (interactive) + (html-upl-edit-remote-file1 t)) + +(defun html-upl-edit-remote-file1(with-toc) + (html-site-current-ensure-buffer-in-site) + (html-upl-ensure-site-has-host) + (let* ((remote-root (concat "/ftp:" + (html-site-current-ftp-user) + "@" (html-site-current-ftp-host) + ":" + (if with-toc + (html-site-current-ftp-wtoc-dir) + (html-site-current-ftp-dir)))) +;; (remote-file (html-site-path-in-mirror (html-site-current-site-dir) +;; buffer-file-name +;; remote-root)) + (remote-file (html-site-current-local-to-remote buffer-file-name nil)) + ) + (find-file remote-file))) + +;;;###autoload +(defun html-upl-ediff-file (filename) + "Run ediff on local and remote file. +FILENAME could be either the remote or the local file." + ;;(interactive "fFile (local or remote): ") + (interactive (list + (or (html-site-buffer-or-dired-file-name) + (read-file-name "File: ")))) + (html-upl-ensure-site-has-host) + (let* ((is-local (html-site-file-is-local filename)) + remote-name + local-name) + (if is-local + (progn + (html-site-current-ensure-file-in-site filename) + (setq remote-name (html-site-current-local-to-remote filename nil)) + (setq local-name filename)) + (setq local-name (html-site-current-remote-to-local filename nil)) + (html-site-current-ensure-file-in-site local-name) + (setq remote-name filename)) + (let ((local-buf (find-file local-name)) + (remote-buf (find-file remote-name))) + (ediff-buffers local-buf remote-buf)))) + +;;(defun html-site-buffer-or-dired-file-name () +;; (defun html-upl-ediff-buffer () +;; "Run ediff on local and remote buffer file. +;; The current buffer must contain either the local or the remote file." +;; (interactive) +;; (html-upl-ediff-file (buffer-file-name))) + +(provide 'html-upl) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-upl.el ends here + +;; (defun html-site-local-to-remote-path (local-file protocol with-toc) +;; (let ((remote-dir (if (eq protocol 'ftp) +;; (if with-toc +;; (html-site-current-ftp-wtoc-dir) +;; (html-site-current-ftp-dir)) +;; (if with-toc +;; (html-site-current-web-wtoc-dir) +;; (html-site-current-web-dir))))) +;; (html-site-path-in-mirror +;; (html-site-current-site-dir) local-file remote-dir))) + +;; (defun html-site-local-to-web (local-file with-toc) +;; (let ((web-file (html-site-local-to-remote-path local-file 'http with-toc)) +;; (web-host (html-site-current-web-host))) +;; (save-match-data +;; (unless (string-match "^https?://" web-host) +;; (setq web-host (concat "http://" web-host)))) +;; (when (string= "/" (substring web-host -1)) +;; (setq web-host (substring web-host 0 -1))) +;; (concat web-host web-file) +;; )) +;; +;;; Use tramp-tramp-file-p instead: +;; (defun html-upl-file-name-is-local (file-name) +;; "Return nil unless FILE-NAME is a Tramp file name." +;; (save-match-data +;; (not (string-match "^/[a-z]+:" file-name)))) + +;; (defun html-upl-remote-to-local (remote-file) +;; (let ((remote-site-dir (html-site-current-web-dir))) +;; (unless (html-site-dir-contains remote-site-dir remote-file) +;; (error ""))) +;; ) + diff --git a/nxhtml/nxhtml/html-upl/COPYING b/nxhtml/nxhtml/html-upl/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/nxhtml/nxhtml/html-upl/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/nxhtml/nxhtml/html-upl/Changes b/nxhtml/nxhtml/html-upl/Changes new file mode 100644 index 0000000..0bfd93c --- /dev/null +++ b/nxhtml/nxhtml/html-upl/Changes @@ -0,0 +1,115 @@ + +1.26 => 1.27 (2004-08-23) +========================= + + * Proposed and partially provided by Samuel Marshall + * enhanced timezone handling, should be perfect now + * new option -c, like -i but then asks interactively to let do it + * if FTP user/password are set to ?, they are asked for interactively + + +1.25 => 1.26 (2004-03-31) +========================= + + * fixed "dangerous" algorithm of synchronization direction + + +1.24 => 1.25 (2004-03-20) +========================= + + * fixed some 1.24 bugs + * clock offset computation now more resistant against very slow connections + * clock offset computation disabled for GET mode, so mirroring of foreign + stuff is now possible again + * default localdir of . disabled, therefore + * using . as localdir parameter does not cause a parsing error any more + * replaced damn indentation tabs in sourcecode by appropriate number of + spaces, so code is readable independent of tab settings + * enabled handling of ftpdir / + * handling of relative ftpdir corrected + + +1.23 => 1.24 (2003-10-11) +========================= + + By Michiel Steltman + + * handle files with blanks etc in names + * clock offset remote-local to reduce unnecessary transfers + * error handling + + +1.22 => 1.23 (2003-09-28) +========================= + + * New parameter timeout + + +1.21 => 1.22 (2003-03-24) +========================= + + * Now cuts of / at directory spec's end, to avoid pwd() being different + from target of cwd() (which lead to unneccesarry abortions) + + +1.20 => 1.21 (2003-03-24) +========================= + + * version information in sourcefile and output of -h command + + +1.11 => 1.20 (2003-03-22) +========================= + + * generally, most foreseeable problems are beeing checked, in particular: + + - unability to connect to FTP server + - unability to login into FTP server + - unability to change to local or remote base directory + - unability to change to remote subdirectory + - unability to create local or remote subdirectory + - unability to remove local or remote subdirectory + - unability to put or get a file within 3 trials + + All these errors (except the last one) leads to immediate abortion. + + +1.10 => 1.11 (2002-05-10) +========================= + + * Some optical corrections concerning output + + * Files are now automatically re-transferred until the size on both ends + matches + + * -? now corrrectly recognized + + +1.00 => 1.10 (2001-10-28) +========================= + + * config file support + This is mportant to avoid putting ftp passwords in the process list! + + * much more informative standard and verbose/debug output, including kind + of a advance information + + * better FTP-URL parsing supporting such without user/password + + * much better default values, e.g. ftp://ftp:anonymous@localhost/., ... + + * softlinks are now detected (locally and remote) and treated somewhat + correctly, i.e. they are ignored correctly ;-)) + + + +=> 1.00 (2001-10-26) +==================== + +* 1.0 created 2001-10-20 23:10 by Christoph Lechleitner + +Quite good for a 5 hour hack, isn't it? +O.K., I have already written similar programs for local file systems +in Pascal for DOS, Win3x and OS/2, and in VisualBasic for Win95b. + + diff --git a/nxhtml/nxhtml/html-upl/README b/nxhtml/nxhtml/html-upl/README new file mode 100644 index 0000000..3f9f505 --- /dev/null +++ b/nxhtml/nxhtml/html-upl/README @@ -0,0 +1,111 @@ +# README file for ftpsync.pl + + +Contents: +========= + +- Overview +- Why use ftpsync.pl instead of mirror, sitecopy, ...? +- Requirements/Restrictions +- Bug reports, Contact +- License +- Updates + + +Overview: +--------- + +ftpsync.pl synchronizes a local directory tree and a remote FTP directory tree. + +It was initally written to automize web publishing, but might be useful for +some other purposes, like mirroring not-too-large public sites, data +replication, and more. + +Call "ftpsync.pl -h" to get a short parameter explanation. + + +Why use ftpsync.pl instead of mirror, sitecopy, ...? +---------------------------------------------------- + +Yes, there are similar projects, so some comments on them: + +Compared to mirror, ftpsync.pl is capable of PUTing, not only GETing stuff +(Don't blame me if mirror is able to PUT, I could'nt find a way). + +Compared to sitecopy, ftpsync.pl has no problems, if the remote site has been +changed since its last run by other tools and activites. Unless network +problems or bugs occur, ftpsync.pl does a reliable synchronization. + +Compared to both, ftpsync.pl is very lightweight ;-)) + + +Requirements / Restrictions: +---------------------------- + +- Perl 5.6+ + ftpsync.pl was initially developed on Perl 5.6.0-81 on SuSE Linux 7.2, + older Perl 5.x version might work. Test reports welcome at ftpsync@ibcl.at! + +- File::Find, IO::Handle + IMHO parts of the basic perl package. + +- Net::FTP + Part of the perl-libnet package. + +- UNIX like operating systems on local system + Porting to DOS based systems should be easily done by changing the + directory separator. + +- Perhaps, the script does not work with all FTP servers + It is beeing tested only against UNIX based FTP servers. + + +Bug-Reports, Contact: +--------------------- + +Besides ftpsync.sourceforge.net, ftpsync@ibcl.at is a good target for comments +of any kind. + + +License: +-------- + +FTPSync.pl is GNU/GPL software and eMail ware. + + +FTPSync.pl as GNU/GPL software: +------------------------------- + +FTPSync.pl (ftpsync.pl) is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +See attached file COPYING. + + +FTPSync.pl as eMail ware: +------------------------- + +FTPSync.pl is also eMail-Ware, which means that the initial author +(Christoph Lechleitner) would like to get an eMail (to ftpsync@ibcl.at), +- if anyone uses the script on production level, +- if anyone distributes or advertises it in any way, +- if anyone starts to (try to) improve it. + + +Updates +------- + +The software and updates should be available from +http://ftpsync.sourceforge.net/ +http://www.ibcl.at/ossw/FTPSync diff --git a/nxhtml/nxhtml/html-upl/TODO b/nxhtml/nxhtml/html-upl/TODO new file mode 100644 index 0000000..923583d --- /dev/null +++ b/nxhtml/nxhtml/html-upl/TODO @@ -0,0 +1,2 @@ + +Nothing as of now. diff --git a/nxhtml/nxhtml/html-upl/ftpsync.pl b/nxhtml/nxhtml/html-upl/ftpsync.pl new file mode 100644 index 0000000..729d964 --- /dev/null +++ b/nxhtml/nxhtml/html-upl/ftpsync.pl @@ -0,0 +1,700 @@ +#!/usr/bin/perl +# +# ftpsync.pl +# +# See attached README file for any details, or call +# ftpsync.pl -h +# for quick start. +# +# LICENSE +# +# FTPSync.pl (ftpsync) is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# FTPSync.pl (ftpsync) is also eMail-Ware, which means that the initial author +# (Christoph Lechleitner) would like to get an eMail at ftpsync@ibcl.at, if +# - if anyone uses the script on production level, +# - if anyone distributes or advertises it in any way, +# - if anyone starts to (try to) improve it. +# +# +################################################################################ + +# +# Options etc. +# +#print "Starting imports.\n"; # For major problem debugging +printf STDERR "argv=@ARGV\n"; + +use File::Find; +use File::Listing; +use Net::FTP; +use strict; +# flushing ... +use IO::Handle; +STDOUT->autoflush(1); +STDERR->autoflush(1); + +sub dosync(); +sub print_syntax(); +sub print_options(); +sub buildremotetree(); +sub buildlocaltree(); +sub listremotedirs(); +sub parseRemoteURL(); + +# Option Variables +#print "Defining variables.\n"; # For major problem debugging +# meta +my $returncode=0; +my $configfile=$ENV{"HOME"}."/.ftpsync"; +# basics +my $localdir=""; +my $remoteURL=""; +my $syncdirection=""; +my $ftpuser="ftp"; +my $ftppasswd="anonymous"; +my $ftpserver="localhost"; +my $ftpdir=""; +my $ftptimeout=120; +my $syncoff=0; +# verbosity +my $doverbose=1; +my $dodebug=0; +my $doquiet=0; +my $doinfoonly=0; +my $infotext=""; +my $docheckfirst=0; + +# Read command line options/parameters +#print "Reading command line options.\n"; # For major problem debugging +my $curopt; +my @cloptions=(); +for $curopt (@ARGV) { + if ($curopt =~ /^cfg=/) { + $configfile=$'; + if (! -r $configfile) { print "Config file does not exist: ".$configfile."\n"; $returncode+=1; } + } else { + push @cloptions, $curopt; + } +} + +# Read Config File, if given +my @cfgfoptions=(); +if ($configfile ne "") { + if (-r $configfile) { + #print "Reading config file.\n"; # For major problem debugging + open (CONFIGFILE,"<$configfile"); + while () { + $_ =~ s/([ \n\r]*$|\.\.|#.*$)//gs; + if ($_ eq "") { next; } + if ( ($_ =~ /[^=]+=[^=]+/) || ($_ =~ /^-[a-zA-Z]+$/) ) { push @cfgfoptions, $_; } + } + close (CONFIGFILE); + } # else { print "Config file does not exist.\n"; } # For major problem debugging +} # else { print "No config file to read.\n"; } # For major problem debugging + +# Parse Options/Parameters +print "Parsing all options.\n"; # For major problem debugging +my $noofopts=0; +for $curopt (@cfgfoptions, @cloptions) { + if ($curopt =~ /^-[a-zA-Z]/) { + my $i; + for ($i=1; $i0) { $ftptimeout =$fvalue; } } + } + else { + if ($localdir eq "") { + $localdir = $curopt; + if ( $syncdirection eq "" ) + { $syncdirection="put"; } + } else { + print "ERROR: Unknown parameter: \"".$curopt."\"\n"; $returncode+=1 + } + } +} +if ($noofopts == 0) { print_syntax(); exit 0; } + +if($ftpuser eq "?") { print "User: "; $ftpuser=; chomp($ftpuser); } +if($ftppasswd eq "?") { print "Password: "; $ftppasswd=; chomp($ftppasswd); } + +if ($dodebug) { print_options(); } +# check options +if ( ($localdir eq "") || (! -d $localdir) ) +{ print "ERROR: Local directory does not exist: ".$localdir."\n"; $returncode+=1; } +#if ($localdir eq "") { print "ERROR: No localdir given.\n"; $returncode+=1; } +#if ( ($remoteURL eq "") { print "ERROR: No remoteURL given.\n"; $returncode+=1; } +if ($ftpserver eq "") { print "ERROR: No FTP server given.\n"; $returncode+=1; } +if ($ftpdir eq "") { print "ERROR: No FTP directory given.\n"; $returncode+=1; } +if ($ftpuser eq "") { print "ERROR: No FTP user given.\n"; $returncode+=1; } +if ($ftppasswd eq "") { print "ERROR: No FTP password given.\n"; $returncode+=1; } +if ($returncode > 0) { die "Aborting due to missing or wrong options! Call ftpsync -? for more information.\n"; } + + +#print "Exiting.\n"; exit 0; + +if ($dodebug) { print "\nFind out if ftp server is online & accessible.\n"; } +my $doftpdebug=($doverbose > 2); +my $ftpc = Net::FTP->new($ftpserver,Debug=>$doftpdebug,Timeout=>$ftptimeout) || die "Could not connect to $ftpserver\n"; +if ($dodebug) { print "Logging in as $ftpuser with password $ftppasswd.\n" } +$ftpc->login($ftpuser,$ftppasswd) || die "Could not login to $ftpserver as $ftpuser\n"; +my $ftpdefdir=$ftpc->pwd(); +if ($dodebug) { print "Remote directory is now ".$ftpdefdir."\n"; } +if ($ftpdir !~ /^\//) # insert remote login directory into relative ftpdir specification +{ if ($ftpdefdir eq "/") + { $ftpdir = $ftpdefdir . $ftpdir; } + else + { $ftpdir = $ftpdefdir . "/" . $ftpdir; } + if (!$doquiet) + { print "Absolute remote directory is $ftpdir\n"; } +} +if (substr($ftpdir, -1) eq "/") { + if (!$doquiet) + { print " Remote directory ends in /, removing this\n"; } + chop($ftpdir); +} +if ($dodebug) { print "Changing to remote directory $ftpdir.\n" } +$ftpc->binary() + or die "Cannot set binary mode :\n\t" . $ftpc->message; +$ftpc->cwd($ftpdir) + or die "Cannot cwd to $ftpdir :\n\t" . $ftpc->message; +if ($ftpc->pwd() ne $ftpdir) { + my $pwd = $ftpc->pwd(); + die "Could not change to remote base directory $ftpdir (at $pwd)\n"; } +if ($dodebug) { print "Remote directory is now ".$ftpc->pwd()."\n"; } + +if (! $doquiet) { print "\nDetermine s offset.\n"; } +if ($syncdirection eq "put") { clocksync($ftpc,"syncfile"); } + +# local & remote tree vars +#chdir $localdir; +my $ldl=length($localdir) + 1; +#my $ldl=length($localdir); +my %localfiledates=(); +my %localfilesizes=(); +my %localdirs=(); +my %locallinks=(); + +my %remotefilesizes=(); +my %remotefiledates=(); +my %remotedirs=(); +my %remotelinks=(); +my $curremotesubdir=""; + +# Build local & remote tree +if (! $doquiet) { print "\nBuilding local file tree.\n"; } +buildlocaltree(); +if (! $doquiet) { print "\nBuilding remote file tree.\n"; } +buildremotetree(); +listremotedirs(); +#if ($dodebug) { print "Quitting FTP connection.\n" } +#$ftpc->quit(); + +#print "Exiting.\n"; exit 0; + +# Work ... +if ($doinfoonly) { $docheckfirst=0; } +if ($docheckfirst) +{ print "Simulating synchronization.\n"; + $doinfoonly=1; + dosync(); + $doinfoonly=0; + print "\nOK to really update files? (y/n) [n] "; + my $yn=; + if ($yn =~ /^y/i) + { print "OK, going to do it.\n"; + } + else + { print "OK, exiting without actions.\n"; + exit 1; + } +} +if ($doinfoonly) { print "\nSimulating synchronization.\n"; } +elsif (! $doquiet) { print "\nStarting synchronization.\n"; } +dosync(); + +if (!$doquiet) { print "Done.\n"; } + +if ($dodebug) { print "Quitting FTP connection.\n" } +$ftpc->quit(); + +exit 0; + + + +# +# Subs +# + +sub buildlocaltree() { + find (\¬icelocalfile, $localdir."/"); + sub noticelocalfile { + if ($ldl > length($File::Find::name)) { return; } + #printf "name=%s, length(name)=%d, ldl=$ldl\n", $File::Find::name, length($File::Find::name); + my $relfilename=substr($File::Find::name,$ldl); + if (length($relfilename) == 0) { return; } + if (-d $_) { + if ($dodebug) { print "Directory: ".$File::Find::name."\n"; } + elsif (! $doquiet) { print ":"; } + $localdirs{$relfilename}="$relfilename"; + } + elsif (-f $_) { + #my @curfilestat=lstat $File::Find::name; + my @curfilestat=lstat $_; + my $curfilesize=$curfilestat[7]; + my $curfilemdt=$curfilestat[9]; + if ($dodebug) { print "File: ".$File::Find::name."\n"; + print "Modified ".$curfilemdt."\nSize ".$curfilesize." bytes\n"; } + elsif (! $doquiet) { print "."; } + $localfiledates{$relfilename}=$curfilemdt; + $localfilesizes{$relfilename}=$curfilesize; + } + elsif (-l $_) { + if ($dodebug) { print "Link: ".$File::Find::name."\n"; } + elsif (! $doquiet) { print ","; } + $locallinks{$relfilename}="$relfilename"; + } else { + #print "u ".$File::Find::name."\n"; + if (! $doquiet) { print "Ignoring file of unknown type: ".$File::Find::name."\n"; } + } + #if (! ($doquiet || $dodebug)) { print "\n"; } + #print "File mode is ".@curfilestat[2]."\n"; + } + if ($dodebug) { + print "Local dirs (relative to ".$localdir."/):\n"; + my $curlocaldir=""; + foreach $curlocaldir (keys(%localdirs)) + { print $curlocaldir."/\n"; } + print "Local files (relative to ".$localdir."/):\n"; + my $curlocalfile=""; + foreach $curlocalfile (keys(%localfiledates)) + { print $curlocalfile."\n"; } + } +} + + +sub buildremotetree() { + my @currecursedirs=(); + #$ftpc->ls() + # or die $ftpc->message . "\nCannot ls remote dir " . $ftpc->pwd(); + my @rfl = $ftpc->dir(); + # or @rfl=(); # we have to survive empty remote directories !!! + my $currf=""; + my $curyear = (gmtime(time))[5] + 1900; + my %monthtonr=(); + $monthtonr{"Jan"}=1; $monthtonr{"Feb"}=2; $monthtonr{"Mar"}=3; $monthtonr{"Apr"}=4; $monthtonr{"May"}=5; $monthtonr{"Jun"}=6; + $monthtonr{"Jul"}=7; $monthtonr{"Aug"}=8; $monthtonr{"Sep"}=9; $monthtonr{"Oct"}=10; $monthtonr{"Nov"}=11; $monthtonr{"Dec"}=12; + if ($dodebug) { print "Remote pwd is ".$ftpc->pwd()."\nDIRing.\n"; } + my $curlsline; + foreach $curlsline (parse_dir(\@rfl)) { + my ($cfname,$cftype,$cfsize,$cftime,$mode)=@$curlsline; + #if ($dodebug) { print "Analysing remote file/dir ".$currf."\n" }; + if ( $cftype ) { + if ($cfname eq ".") { next; } + if ($cfname eq "..") { next; } + if (substr($cftype,0,1) eq 'l') { # link, rest of string = linkto + my $curnrl; + if ($curremotesubdir eq "") { $curnrl = $cfname; } + else { $curnrl = $curremotesubdir."/".$cfname; } + $remotelinks{$curnrl}=$cfname; + if ($dodebug) { print "Link: ".$curnrl." -> ".$cfname."\n"; } + } + elsif ($cftype eq 'd') { + my $curnewrsd; + if ($curremotesubdir eq "") { $curnewrsd = $cfname; } + else { $curnewrsd = $curremotesubdir."/".$cfname; } + $remotedirs{$curnewrsd}=$curnewrsd; + if ($dodebug) { print "Directory: ".$curnewrsd."\n"; } + elsif (! $doquiet) { print ":"; } + push @currecursedirs, $cfname; + } + elsif ($cftype eq 'f') { #plain file + my $curnewrf; + if ($curremotesubdir eq "") { $curnewrf = $cfname; } + else { $curnewrf = $curremotesubdir."/".$cfname; } + #$remotefiledates{$curnewrf}=$cftime; + $remotefiledates{$curnewrf}=$ftpc->mdtm($cfname)+$syncoff; + if ($remotefiledates{$curnewrf} le 0) { die "Timeout detecting modification time of $curnewrf\n"; } + $remotefilesizes{$curnewrf}=$cfsize; + if ($remotefilesizes{$curnewrf} lt 0) { die "Timeout detecting size of $curnewrf\n"; } + if ($dodebug) { print "File: ".$curnewrf."\n"; } + elsif (! $doquiet) { print "."; } + } + elsif (! $doquiet) { print "Unkown file: $curlsline\n"; } + } + elsif ($dodebug) { print "Ignoring.\n"; } + } + #recurse + my $currecurseddir; + foreach $currecurseddir (@currecursedirs) + { my $oldcurremotesubdir; + $oldcurremotesubdir=$curremotesubdir; + if ($curremotesubdir eq "") { $curremotesubdir = $currecurseddir; } + else { $curremotesubdir .= "/".$currecurseddir; } + my $curcwddir=""; + if ($ftpdir eq "/") + { $curcwddir=$ftpdir.$curremotesubdir; } + else + { $curcwddir=$ftpdir."/".$curremotesubdir; } + if ($dodebug) { print "Change dir: ".$curcwddir."\n"; } + $ftpc->cwd($curcwddir) + or die "Cannot cwd to $curcwddir :\n\t" . $ftpc->message ; + if ($ftpc->pwd() ne $curcwddir) { + die "Could not cwd to $curcwddir :\n\t" . $ftpc->message ; } + if (! $doquiet) { print "\n"; } + buildremotetree(); + $ftpc->cdup(); + $curremotesubdir = $oldcurremotesubdir; + } +} + + +# Synchronize clocks. +sub clocksync { + my $conn = shift @_; + my $fn = shift @_; + my $fndidexist=1; + + if(! -f $fn) { + open(SF, ">$fn") or die "Cannot create $fn for time sync option"; + close(SF); + $fndidexist=0; + } + -z $fn or + die "File $fn for time sync must be empty."; + my $putsyncok=1; + $conn->put($fn) or $putsyncok=0; + if (!$putsyncok) + { unlink($fn); # cleanup! + die "Cannot send timesync file $fn"; + } + + my $now_here1 = time(); + my $now_there = $conn->mdtm($fn) or + die "Cannot get write time of timesync file $fn"; + my $now_here2 = time(); + + if ($now_here2 < $now_there) # remote is in the future + { $syncoff=($now_there - $now_here1); + $syncoff -= $syncoff % 60; + $syncoff = 0-$syncoff; + } + else + #if ($now_here1 > $now_there) # remote is the past # or equal + { $syncoff=($now_here2 - $now_there); + $syncoff -= $syncoff % 60; + } + + $conn->delete($fn); + + my $hrs = int(abs($syncoff)/3600); + my $mins = int(abs($syncoff)/60) - $hrs*60; + my $secs = abs($syncoff) - $hrs*3600 - $mins*60; + if (! $doquiet) { + printf("Clock sync offset: %d:%02d:%02d\n", $hrs, $mins, $secs); + } + unlink ($fn) unless $fndidexist; +} + + +sub dosync() +{ + chdir $localdir || die "Could not change to local base directory $localdir\n"; + if ($syncdirection eq "put") { + # create dirs missing at the target + if ($doinfoonly) { print "\nWould create new remote directories.\n"; } + elsif (! $doquiet) { print "\nCreating new remote directories.\n"; } + my $curlocaldir; + foreach $curlocaldir (sort { return length($a) <=> length($b); } keys(%localdirs)) + { if (! exists $remotedirs{$curlocaldir}) + { if ($doinfoonly) { print $curlocaldir."\n"; next; } + if ($doverbose) { print $curlocaldir."\n"; } + elsif (! $doquiet) { print "d"; } + if ($ftpc->mkdir($curlocaldir) ne $curlocaldir) { die "Could not create remote subdirectory $curlocaldir\n"; } + } + } + # copy files missing or too old at the target, synchronize timestamp _after_ copying + if ($doinfoonly) { print "\nWould copy new(er) local files.\n"; } + elsif (! $doquiet) { print "\nCopying new(er) local files.\n"; } + my $curlocalfile; + foreach $curlocalfile (sort { return length($b) <=> length($a); } keys(%localfiledates)) + { my $dorefresh=0; + if (! exists $remotefiledates{$curlocalfile}) { + $dorefresh=1; + $infotext="New: ".$curlocalfile." (".$localfilesizes{$curlocalfile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + elsif ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "n"; } + } + elsif ($remotefiledates{$curlocalfile} < $localfiledates{$curlocalfile}) { + $dorefresh=1; + $infotext="Newer: ".$curlocalfile." (".$localfilesizes{$curlocalfile}." bytes, ".$localfiledates{$curlocalfile}." versus ".$remotefiledates{$curlocalfile}.")\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + elsif ($remotefilesizes{$curlocalfile} != $localfilesizes{$curlocalfile}) { + $dorefresh=1; + $infotext="Changed (different sized): ".$curlocalfile." (".$localfilesizes{$curlocalfile}." versus ".$remotefilesizes{$curlocalfile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + if (! $dorefresh) { next; } + if ($dodebug) { print "Really PUTting file ".$curlocalfile."\n"; } + if ($ftpc->put($curlocalfile, $curlocalfile) ne $curlocalfile) + { print STDERR "Could not put localfile $curlocalfile\n"; } + my $retries = 3; + while ( ($ftpc->size($curlocalfile) != (lstat $curlocalfile)[7]) and ($retries-- > 0) ) + { if (! $doquiet) { print "Re-Transfering $curlocalfile\n"; } + if ($ftpc->put($curlocalfile, $curlocalfile) ne $curlocalfile) + { print STDERR "Could not re-put localfile $curlocalfile\n"; } + } + my $newremotemdt=$ftpc->mdtm($curlocalfile)+$syncoff; + utime ($newremotemdt, $newremotemdt, $curlocalfile); + } + # delete files too much at the target + if ($doinfoonly) { print "\nWould delete obsolete remote files.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete remote files.\n"; } + my $curremotefile; + foreach $curremotefile (keys(%remotefiledates)) + { if (not exists $localfiledates{$curremotefile}) + { if ($doinfoonly) { print $curremotefile."\n"; next; } + if ($doverbose) { print $curremotefile."\n"; } + elsif (! $doquiet) { print "r"; } + if ($ftpc->delete($curremotefile) ne 1) { die "Could not delete remote file $curremotefile\n"; } + } + } + # delete dirs too much at the target + if ($doinfoonly) { print "\nWould delete obsolete remote directories.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete remote directories.\n"; } + my $curremotedir; + foreach $curremotedir (sort { return length($b) <=> length($a); } keys(%remotedirs)) + { if (! exists $localdirs{$curremotedir}) + { if ($doinfoonly) { print $curremotedir."\n"; next; } + if ($doverbose) { print $curremotedir."\n"; } + elsif (! $doquiet) { print "R"; } + if ($ftpc->rmdir($curremotedir) ne 1) { die "Could not remove remote subdirectory $curremotedir\n"; } + } + } + } else { # $syncdirection eq "GET" + # create dirs missing at the target + if ($doinfoonly) { print "\nWould create new local directories.\n"; } + elsif (! $doquiet) { print "\nCreating new local directories.\n"; } + my $curremotedir; + foreach $curremotedir (sort { return length($a) <=> length($b); } keys(%remotedirs)) + { if (! exists $localdirs{$curremotedir}) + { if ($doinfoonly) { print $curremotedir."\n"; next; } + if ($doverbose) { print $curremotedir."\n"; } + elsif (! $doquiet) { print "d"; } + mkdir($curremotedir) || die "Could not create local subdirectory $curremotedir\n"; + } + } + # copy files missing or too old at the target, synchronize timestamp _after_ copying + if ($doinfoonly) { print "\nWould copy new(er) remote files.\n"; } + elsif (! $doquiet) { print "\nCopying new(er) remote files.\n"; } + my $curremotefile; + foreach $curremotefile (sort { return length($b) <=> length($a); } keys(%remotefiledates)) + { my $dorefresh=0; + if (! exists $localfiledates{$curremotefile}) { + $dorefresh=1; + $infotext="New: ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "n"; } + } + elsif ($remotefiledates{$curremotefile} > $localfiledates{$curremotefile}) { + $dorefresh=1; + $infotext="Newer: ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes, ".$remotefiledates{$curremotefile}." versus ".$localfiledates{$curremotefile}.")\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "u"; } + } + elsif ($remotefilesizes{$curremotefile} != $localfilesizes{$curremotefile}) { + $dorefresh=1; + $infotext="Changed (different sized): ".$curremotefile." (".$remotefilesizes{$curremotefile}." bytes)\n"; + if ($doinfoonly) { print $infotext; next; } + if ($doverbose) { print $infotext; } + elsif (! $doquiet) { print "c"; } + } + if (! $dorefresh) { next; } + if ($dodebug) { print "Really GETting file ".$curremotefile."\n"; } + my $rc=$ftpc->get($curremotefile, $curremotefile); + if ( ($rc eq undef) or ($rc ne $curremotefile) ) + { print STDERR "Could not get file ".$curremotefile."\n"; } + my $retries=3; + while ( ($ftpc->size($curremotefile) != (lstat $curremotefile)[7]) and ($retries-- > 0) ) + { if (! $doquiet) { print "Re-Transfering $curremotefile\n"; } + if ( ($rc eq undef) or ($rc ne $curremotefile) ) + { print STDERR "Could not get file ".$curremotefile."\n"; } + } + my $newlocalmdt=$remotefiledates{$curremotefile}; + utime ($newlocalmdt, $newlocalmdt, $curremotefile); + } + # delete files too much at the target + if ($doinfoonly) { print "\nWould delete obsolete local files.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete local files.\n"; } + my $curlocalfile; + foreach $curlocalfile (sort { return length($b) <=> length($a); } keys(%localfiledates)) + { if (not exists $remotefiledates{$curlocalfile}) + { if ($doinfoonly) { print $curlocalfile."\n"; next; } + if ($doverbose) { print $curlocalfile."\n"; } + elsif (! $doquiet) { print "r"; } + if (unlink($curlocalfile) ne 1) { die "Could not remove local file $curlocalfile\n"; } + } + } + # delete dirs too much at the target + if ($doinfoonly) { print "\nWould delete obsolete local directories.\n"; } + elsif (! $doquiet) { print "\nDeleting obsolete local directories.\n"; } + my $curlocaldir; + foreach $curlocaldir (keys(%localdirs)) + { if (! exists $remotedirs{$curlocaldir}) + { if ($doinfoonly) { print $curlocaldir."\n"; next; } + if ($doverbose) { print $curlocaldir."\n"; } + elsif (! $doquiet) { print "d"; } + rmdir($curlocaldir) || die "Could not remove local subdirectory $curlocaldir\n"; + } + } + } +} + + +sub listremotedirs() { + if ($dodebug) { + print "Remote dirs (relative to ".$ftpdir."):\n"; + my $curremotedir=""; + foreach $curremotedir (keys(%remotedirs)) + { print $curremotedir."/\n"; } + print "Remote files (relative to ".$ftpdir."):\n"; + my $curremotefile=""; + foreach $curremotefile (keys(%remotefiledates)) + { print $curremotefile."\n"; } + print "Remote links (relative to ".$ftpdir."):\n"; + my $curremotelink=""; + foreach $curremotelink (keys(%remotelinks)) + { print $curremotelink." -> ".$remotelinks{$curremotelink}."\n"; } + } +} +sub parseRemoteURL() { + if ($remoteURL =~ /^ftp:\/\/(([^@\/\\\:]+)(:([^@\/\\\:]+))?@)?([a-zA-Z01-9\.]+)\/(.*)/) { + #print "DEBUG: parsing ".$remoteURL."\n"; + #print "match 1 = ".$1."\n"; + #print "match 2 = ".$2."\n"; + #print "match 3 = ".$3."\n"; + #print "match 4 = ".$4."\n"; + #print "match 5 = ".$5."\n"; + #print "match 6 = ".$6."\n"; + #print "match 7 = ".$7."\n"; + if (length($2) > 0) { $ftpuser=$2; } + if (length($4) > 0) { $ftppasswd=$4; } + $ftpserver=$5; + $ftpdir=$6; + #if ($ftpdir eq "") { $ftpdir="/"; } + } +} + + +sub print_syntax() { + print "\n"; + print "FTPSync.pl 1.27 (2004-08-23)\n"; + print "\n"; + print " ftpsync [ options ] [ localdir remoteURL ]\n"; + print " ftpsync [ options ] [ remoteURL localdir ]\n"; + print " options = [-dgpqv] [ cfg|ftpuser|ftppasswd|ftpserver|ftpdir=value ... ] \n"; + print " localdir local directory, defaults to \".\".\n"; + print " ftpURL full FTP URL, scheme\n"; + print ' ftp://[ftpuser[:ftppasswd]@]ftpserver/ftpdir'."\n"; + print " ftpdir is relative, so double / for absolute paths as well as /\n"; + print " -c | -C like -i, but then prompts whether to actually do work\n"; + print " -d | -D turns debug output (including verbose output) on\n"; + print " -g | -G forces sync direction to GET (remote to local)\n"; + print " -h | -H turns debugging on\n"; + print " -i | -I forces info mode, only telling what would be done\n"; + print " -p | -P forces sync direction to PUT (local to remote)\n"; + print " -q | -Q turnes quiet operation on\n"; + print " -v | -V turnes verbose output on\n"; + print " cfg= read parameters and options from file defined by value.\n"; + print " ftpserver= defines the FTP server, defaults to \"localhost\".\n"; + print " ftpdir= defines the FTP directory, defaults to \".\" (/wo '\"') \n"; + print " ftpuser= defines the FTP user, defaults to \"ftp\".\n"; + print " ftppasswd= defines the FTP password, defaults to \"anonymous\".\n"; + print "\n"; + print " Later mentioned options and parameters overwrite those mentioned earlier.\n"; + print " Command line options and parameters overwrite those in the config file.\n"; + print " Don't use '\"', although mentioned default values might motiviate you to.\n"; + print "\n"; +} + + +sub print_options() { + print "\nPrinting options:\n"; + # meta + print "returncode = ", $returncode , "\n"; + print "configfile = ", $configfile , "\n"; + # basiscs + print "syncdirection = ", $syncdirection , "\n"; + print "localdir = ", $localdir , "\n"; + # FTP stuff + print "remoteURL = ", $remoteURL , "\n"; + print "ftpuser = ", $ftpuser , "\n"; + print "ftppasswd = ", $ftppasswd , "\n"; + print "ftpserver = ", $ftpserver , "\n"; + print "ftpdir = ", $ftpdir , "\n"; + # verbsityosity + print "doverbose = ", $doverbose , "\n"; + print "dodebug = ", $dodebug , "\n"; + print "doquiet = ", $doquiet , "\n"; + # + print "doinfoonly = ", $doinfoonly , "\n"; + print "\n"; +} diff --git a/nxhtml/nxhtml/html-wtoc.el b/nxhtml/nxhtml/html-wtoc.el new file mode 100644 index 0000000..94533da --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc.el @@ -0,0 +1,200 @@ +;;; html-wtoc.el --- Creating pages with site TOC +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: Sat Feb 11 00:06:14 2006 +(defconst html-wtoc:version "0.2") ;; Version: +;; Last-Updated: Sun Nov 04 21:49:34 2007 (3600 +0100) +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (add-to-list 'load-path default-directory load-path)) +(eval-when-compile (require 'html-site nil t)) + +;;;###autoload +(defgroup html-wtoc nil + "Customization group for html-wtoc." + :group 'nxhtml) + +(defcustom html-wtoc-dir + (file-name-as-directory + (expand-file-name + "html-wtoc" + (file-name-directory + (if load-file-name load-file-name buffer-file-name)))) + + "Directory where the tools needed are located. +The tools for html-wtoc includes: + +- html-wtoc.pl +- html-wtoc.js +- html-wtoc.css +- html-wtoc-template.htm +- html-wtoc-template.js +- html-wtoc-template.css +- img/ + +" + :type 'directory + :group 'html-wtoc) + +;; (defun html-wtoc-get-parsed-html-toc () +;; (save-excursion +;; (let ((toc-file (html-toc-file))) +;; (unless (file-exists-p toc-file) +;; (html-toc-write-toc-file)) +;; (with-current-buffer (find-file-noselect toc-file) +;; (goto-char (point-min)) +;; (let ((toc-begin (search-forward html-toc-mark-begin nil t)) +;; (toc-middle (search-forward html-toc-mark-middle nil t)) +;; toc-parsed) +;; (unless (and toc-begin toc-middle) +;; (error "Can't find table of contents in %s" toc-file)) +;; (setq toc-parsed (html-toc-parse-toc +;; (buffer-substring-no-properties +;; toc-begin toc-middle)))))))) + +;; (defun html-wtoc-get-atags (parsed-ul level) +;; (assert (eq 'ul (car parsed-ul))) +;; (let (atags) +;; (dolist (l parsed-ul) +;; (when (and (listp l) +;; (eq 'li (car l))) +;; (dolist (ll l) +;; (when (listp ll) +;; (when (eq 'a (car ll)) +;; (setq atags +;; (cons +;; (list level +;; (caddr ll) +;; (cdaadr ll)) +;; atags))) +;; (when (eq 'ul (car ll)) +;; (let ((subs (html-wtoc-get-atags ll (1+ level)))) +;; (dolist (s subs) +;; (setq atags (cons s atags))))))))) +;; (reverse atags))) + +;; (defcustom html-wtoc-pages-default-name "html-wtoc-pages.txt" +;; "Default file name sans directory for list of pages file. +;; This file is located in the same directory as `html-toc-file'." +;; :type 'string) + +;; (defun html-wtoc-pages-file () +;; (expand-file-name html-wtoc-pages-default-name +;; (file-name-directory (html-toc-file)))) + +(defun html-wtoc-browse-page-with-toc () + (interactive) + (unless buffer-file-name + (error "This buffer is not visiting a file")) + (html-site-current-ensure-site-defined) + (let ((merge-dir (html-site-current-merge-dir)) + merged-file + (in-site (html-site-dir-contains + (html-site-current-site-dir) + buffer-file-name))) + (unless merge-dir + (error "There is no output dir for pages with TOC defined for the site %s" + html-site-current)) + (unless in-site + (error "This buffer's file is not in %s" (html-site-current-site-dir))) + (setq merged-file + (expand-file-name + (file-relative-name buffer-file-name + (html-site-current-site-dir)) + (html-site-current-merge-dir))) + (unless (file-exists-p merged-file) + (error "The file %s does not yet exist.\nPlease do use `html-wtoc-write-merged' to create it." + merged-file)) + (browse-url-of-file merged-file))) + + +(defun html-wtoc-write-pages-with-toc (allow-overwrite) + "Merge the TOC with the pages. + +If an entry with the name MERGE-NAME exists in `html-wtoc-merges' +then this is chosen. Otherwise a new entry is created and added +to `html-wtoc-merges'. The entry has all necessary information to +do the merge. + +If `html-move-site-directory' has a non-nil value then the list +of completions when prompting for MERGE-NAME contains only those +merge names from `html-wtoc-merges' where the site directory has +the same value. Otherwise the completion list contains all merge +names and `html-move-site-directory' will be set to the chosen +merge's site directory. + +The merging of the pages and the table of contents is done in a +subprocess using a Perl script named html-wtoc.pl the directory +`html-wtoc-dir'. +" + (interactive (list (y-or-n-p "Allow overwrite? "))) + (html-site-current-ensure-site-defined) + (let ((pag-file (html-site-current-page-list)) + (out-dir (html-site-current-merge-dir)) + (tpl-file (html-site-current-merge-template)) + (html-wtoc-pl (expand-file-name "html-wtoc.pl" html-wtoc-dir)) + ) + (unless (< 0 (length pag-file)) + (error "Page list file not defined for site %s" html-site-current)) + (unless (file-exists-p pag-file) + (error "Can't find page file for site %s.\nHave you done M-x html-toc-create-pages-file?" + html-site-current)) + (unless (< 0 (length tpl-file)) + ;;(error "Template file not defined for site %s.\nPlease use customize to add this in `html-site-list'." html-site-current) + (setq tpl-file (expand-file-name "html-wtoc-template.html" html-wtoc-dir)) + ) + (let ( + (buffer (noshell-procbuf-setup "*Merging pages and TOC*")) + (opt (list + (concat "pages=" pag-file) + (concat "outroot=" out-dir) + (concat "template=" tpl-file)))) + (when allow-overwrite + (setq opt (cons "update=1" opt))) + (apply 'noshell-procbuf-run + buffer + "perl" "-w" + html-wtoc-pl "merge" + opt + )))) + +(provide 'html-wtoc) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; html-wtoc.el ends here diff --git a/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm b/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm new file mode 100644 index 0000000..e95b8d5 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/PerlLib/PathSubs.pm @@ -0,0 +1,207 @@ +# Copyright 2006 Lennart Borgman, http://OurComments.org/. All rights +# reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +package PathSubs; + +##################################################### +### This package contains general path handling +### routines and some win32 specific dito. +### The latter should ev be moved to a new module! +##################################################### +use strict; + +use File::Spec; + +### Absolute path names + +sub is_abs_path ($) { + my $path = shift; + return 0 if $path eq ""; + return 1 if File::Spec->file_name_is_absolute($path); + #return 1 if substr($path, 1, 1) eq ":"; # MSWin32 + #return 1 if substr($path, 0, 1) eq "/"; + return 1 if $path =~ /^https?:/i; + return 1 if $path =~ /^file:/i; + return 1 if $path =~ /^javascript:/i; + return 1 if $path =~ /^mailto:/i; +} +sub is_abs_netpath($) { + my $path = shift; + return 1 if $path =~ /^https?:/i; + # New + return 1 if $path =~ /^ftp:/i; + return 1 if $path =~ /^mailto:/i; +} + + +sub uniq_file($) { + my $fname = shift; + $fname =~ s!^\s+|\s+$!!g; + return "" if ($fname eq ""); + $fname = File::Spec->rel2abs($fname); + if (!File::Spec->file_name_is_absolute($fname)) { + die "File name is not absolute: $fname"; + } + #print STDERR "uniq_file($fname)\n"; + $fname =~ tr!\\!/!; + if (-e $fname) { + #print STDERR "exists $fname\n"; + ### There is an error in 522, compensate for this! + #die substr($fname, -1); + if (substr($fname, -1) eq "/") { chop $fname; } + #print STDERR "exists $fname\n"; + ### Translate .. + if (substr($fname, 1, 1) eq ":") { + my $ffname = Win32::GetFullPathName($fname); + ### Get case + my $lfname = Win32::GetLongPathName($ffname); + #print STDERR "lexists $lfname\n"; + $fname = $lfname if ($lfname ne ""); + } + } else { + #print STDERR "NOT exists $fname\n"; + if (substr($fname, -1) eq "/") { chop $fname; } + my $head = ""; + if (substr($fname, 0, 2) eq "//") { + $head = "//"; + $fname = substr($fname, 2); + } + my @fname = split("/", $fname); + my $tail = pop @fname; + $fname = uniq_dir($head . join("/", @fname)) . $tail; + } + if (substr($fname, 1, 1) eq ":") { + $fname = uc(substr($fname, 0, 1)) . substr($fname, 1); + #print STDERR "fname $fname\n"; + } + $fname =~ tr!\\!/!; + #print STDERR "fname ($fname)\n"; + return $fname; +} +sub uniq_dir($) { + my $dir = shift; + my $uq_dir = uniq_file($dir); + if (substr($uq_dir, -1) ne "/") { $uq_dir .= "/"; } + return $uq_dir; +} + + + +### Relative paths +sub _get_link_root($) { + my $lnk = shift; + if ($lnk =~ m!^(/|ftp://[^/]*|https?://[^/]*|[a-z]:/)!i) { + return $1; + } else { + return ""; + } +} + +sub resolve_dotdot($) { + my $orig_url = shift; + my $root = _get_link_root($orig_url); + return $orig_url if length($root) == length($orig_url); + my $url = substr($orig_url, length($root)); + if (substr($root, -1) eq "/") { + chop $root; + $url = "/$url"; + } + #die "$root\n$url"; + my $iPosSearch = 2; + #print "url=$url\n"; + while ((my $iPos = index($url, "/../", $iPosSearch)) > -1) { + my $sLeft = substr($url, 0, $iPos); + if (substr($sLeft, -2) eq "..") { + $iPosSearch += 3; + next; + } + my $sRight = substr($url, $iPos+3); + #print "url=$url\n"; + #print "iPos=$iPos\n"; + #print "sLeft=$sLeft\n"; + $sLeft =~ s!/[^/]*$!!; + #print "sLeft=$sLeft\n"; + #print "sRight=$sRight\n"; + $url = $sLeft . $sRight; + #print "\t***url=$url\n"; + #print "url=$url\n"; + } + if (index($url, "../") > -1) { + return $orig_url; + } + return $root . $url; +} + +sub mk_relative_link($$;$) { + my $from = shift; + my $to = shift; + my $norm = shift; + if ($norm) { + $from = uniq_file($from); + $to = uniq_file($to); + } + if (-e $from) { + $from = uniq_file($from); + } else { + $from = resolve_dotdot($from); + } + if (-e $to) { + $to = uniq_file($to); + } else { + $to = resolve_dotdot($to); + } + my $root_from = _get_link_root($from); + my $root_to = _get_link_root($to ); + if ($root_from ne $root_to) { + return $to; + } + my @from = split "/", $from; + my @to = split "/", $to; + while (@to) { + last if ($to[0] ne $from[0]); + shift @to; + shift @from; + } + if (@to == 1 && @from == 1) { + if (length($to[0]) > length($from[0])) { + if (substr($to[0], 0, length($from[0])+1) eq ($from[0] . "#")) { + return substr($to[0], length($from[0])); + } + } + } + my $rl; + for (1..$#from) { $rl .= "../"; } + $rl .= join("/", @to); + + return $rl; +} + + + +sub mk_absolute_link($$) { + my $from = shift; + my $rel_to = shift; + my $abs = $from; + $abs =~ s![^/]*$!!; + $abs .= $rel_to; + if (!is_abs_netpath($abs)) { $abs = uniq_file($abs); } + $abs; +} + + +1; diff --git a/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm b/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm new file mode 100644 index 0000000..ecdfd53 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/PerlLib/html_tags.pm @@ -0,0 +1,127 @@ +# Copyright 2006 Lennart Borgman, http://OurComments.org/. All rights +# reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + + +package html_tags; +use strict; + +use vars qw($AUTOLOAD); + +sub _make_attributes { + my($self,$attr) = @_; + return () unless $attr && ref($attr) && ref($attr) eq 'HASH'; + my(@att); + foreach (keys %{$attr}) { + my($key) = $_; + $key=~s/^\-//; # get rid of initial - if present + #$key=~tr/a-z_/A-Z-/; # parameters are upper case, use dashes + $key=~tr/A-Z_/a-z-/; # parameters are lower case in XHTML + push(@att,defined($attr->{$_}) ? qq/$key="$attr->{$_}"/ : qq/$key/); + } + return @att; +} + +sub _tag { + my $tag_name = shift; + my $part = shift; + my($attr) = ''; + if (ref($_[0]) && ref($_[0]) eq 'HASH') { + my(@attr) = html_tags::_make_attributes( '',shift() ); + $attr = " @attr" if @attr; + } + #return "<$tag_name$attr />" unless @_; + return "<$tag_name$attr />" if $part == 1; + return "<$tag_name$attr>" if $part == 2; + my($tag,$untag) = ("<$tag_name$attr\n>",""); + my @result = map { "$tag$_$untag" } (ref($_[0]) eq 'ARRAY') ? @{$_[0]} : "@_"; + return $result[0] if $part == 1; + return "@result"; +} + +sub _mk_tag_sub($$) { + my $name = shift; + my $package = shift; + my $caller = caller; + my $sep = ($name =~ s/^\*//); + my $lc_name = lc $name; + my $code = + ($lc_name =~ m/^(?:br|hr|input|img)$/ ? + "sub $package\:\:$name(;\$\$) { return $caller\:\:_tag('$lc_name',1,\@_); }\n" + : + "sub $package\:\:$name(\$;\$) { return $caller\:\:_tag('$lc_name',0,\@_); }\n" + ); + if ($sep) { + if ($lc_name eq "html") { + $code .= "sub $package\:\:start_$name(\$;\$\$) + {return $caller\:\:_start_html(\@_);}\n"; + $code .= "sub $package\:\:end_$name {return $caller\:\:_end_html();}\n"; + } else { + $code .= "sub $package\:\:start_$name(;\$\$) + {return $caller\:\:_tag('$lc_name',1,\@_);}\n"; + $code .= "sub $package\:\:end_$name {'';}\n"; + } + } + $code; +} +sub _start_html { + my $title = shift; + my $head_tags = shift; + my $body_attr = shift; + # compensate for perl laziness... (will not detect undef sub) + $head_tags = $head_tags . _tag("title", 0, $title); + my $start = + _tag("html", 2) . + _tag("head", 0, $head_tags) . + _tag("body", 2, $body_attr); +} +sub _end_html { + return ''; +} + +sub header(@) { + my @lines = @_; + my $header; + my $type; + while (@lines) { + my $key = shift @lines; my $value = shift @lines; + $header .= "$key: $value\n"; + $type = $value if $key =~ m/content-type/i; + } + $header .= "Content-type: text/html\n" unless defined $type; + $header .= "\n"; +} +sub import { + shift; + my %exported; + $exported{$_}++ for (@_); + my $caller = caller; + my $to_eval = "package $caller;\n"; + for my $name (keys %exported) { + die "Will not redefine $caller\:\:$name" if $caller->can($name); + my $func; + if ($name eq "header") { + $func = "sub header { html_tags::header(); }"; + } + $func = _mk_tag_sub($name, $caller) unless defined $func; + $to_eval .= "$func\n"; + } + eval $to_eval; + die $@ if $@; +} + +1; diff --git a/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css b/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css new file mode 100644 index 0000000..a6ffabb --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/html-wtoc-template.css @@ -0,0 +1,141 @@ +/* Main structures >>>>>>>>>>>>>>> */ +.html-wtoc-maintop { + font-size: 1px; + font-size: 1em; + margin-top: 0em; + margin-bottom: 0em; +/* background-color:green; */ +} +.html-wtoc-main { +} + +td.html-wtoc-vdivline { + //background-color: #8be; + width: 0px; +} + +.html-wtoc-search-form { + margin-bottom: 0.1em; +} +.html-wtoc-search { + font-size: 0.8em; + color: green; +} +.html-wtoc-search a { + color: green; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Table of content >>>>>>>>>>>>>> */ + +#html-wtoc-id-hidetoc { + height: 20px; + border-bottom: 2px inset #ddf; + border-color: #dff; +} + +#html-wtoc-id-tocdiv { + width: 2.5em; + //background-color: #eff; +} +#html-wtoc-id-logo { + width: 100%; + height: 120px; + padding: 0em; + margin: 0em; + border: 0em; +} +#html-wtoc-id-toc { +} +#html-wtoc-id-tocwidth { + width: 18em; + height: 0em; + padding: 0em; + margin: 0em; + border: 0em; + line-height: 0em; +/* background-color: red; */ +} +#html-wtoc-id-toccol { + width: 18em; +} + +.html-wtoc-contcol { + background-color: #dFEfff; + background-color: #dFEfff; + background-color: #cd950c; + background-color: #eead0e; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + +/* Buttons etc >>>>>>>>>>>>>>> */ +.html-wtoc-button { + font-size: 0.75em; + font-size: 8pt; + color: #5A5D00; + background-color: #9cf; + background-color: #bcee68; + background-color: #a2cd5a; + padding: 0.2em; + Border-Width: 2px; + Border-Style: outset; + text-align: center; + border-color: #ddf; +} +a.html-wtoc-button { + text-decoration: none; + color: #5A5D00; +} +a.html-wtoc-button:hover { + text-decoration:none; + background-color: #6af; + color:#340; +} + +a.html-wtoc-buttonimg img { + width: 16px; + height: 16px; + padding: 4px; + border: 8px; +} +a.html-wtoc-buttonimg { + border:2px; + margin:2px; + margin-left:2px; + margin-right:2px; +} +a.html-wtoc-buttonimg { + font-size:1px; +} +a.html-wtoc-buttonimg:hover { + margin: 6px; + margin-left:0px; + margin-right:0px; + border-color: #ddf; + border-width: 2px; + border-style: outset; + background-color: #595C00; + background-color: #bef; + background-color: #b9ffb9; +} + +/* <<<<<<<<<<<<<<<<<<< */ + + +#nxhtml-link { + font-size: 0.7em; + text-align: center; + padding-top: 2em; + padding: 1em; +} + +.copyright { + color : #872; +} + diff --git a/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html b/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html new file mode 100644 index 0000000..440ece7 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/html-wtoc-template.html @@ -0,0 +1,143 @@ + + + + + HEAD + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+ + + + +
+ Show table of content + + + +
+ + + + + +
+ + + + + + + +
%%TOC%%
+
+
+
+
+ + + + + + +
    +

+ +   +

+ %%PAGE%% +

 

+ +
+
+
 
+
+ + diff --git a/nxhtml/nxhtml/html-wtoc/html-wtoc.css b/nxhtml/nxhtml/html-wtoc/html-wtoc.css new file mode 100644 index 0000000..a12cb65 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/html-wtoc.css @@ -0,0 +1,84 @@ +body { + margin: 0; +} +td { + font-size: 1em; +} + +/* Added by html-wtoc.pl >>>>>>>>>>>>> */ +.html-wtoc-mark { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + width: 20px; + padding: 0; + border: 0; + text-align: center; +} +.html-wtoc-contline { + width: 100%; +} + +.html-wtoc-margin { + width: 0.6em; +} +.html-wtoc-contents { + font-size: 0.9em; + padding: 1em; + background-color: #9cf; + background-color: #a2cd5a; + background-color: #efffcf; + background-color: #ffffdf; + -moz-border-radius-topleft: 2em; +} +.html-wtoc-contents td { +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ +} +.html-wtoc-contents-a { + text-decoration: none; + color: #595C00; +/* background-color: #9cf; */ +/* background-color: #bcee68; */ +/* background-color: #a2cd5a; */ + border: 1px #9cf solid; + border: 1px #a2cd5a solid; + border: 1px #ffffc0 solid; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +.html-wtoc-contents a:hover { + text-decoration: none; + background-color: #b9ffb9; + border: 1px #6b8e23 solid; +} +.html-wtoc-currcont { + background-color: #738600; + color: #ffff2f; + background-color: #535600; + border: 1px #6b8e23 inset; + padding-left: 0.25em; + padding-right: 0; + margin: 1px; + display: block; +} +a.html-wtoc-currcont { + text-decoration: none; +} +a.html-wtoc-currcont:hover { + background-color: #738600; + background-color: #536600; + background-color: #434620; +} +/* <<<<<<<<<<<<<<<<<<< */ + + + + + + + + diff --git a/nxhtml/nxhtml/html-wtoc/html-wtoc.js b/nxhtml/nxhtml/html-wtoc/html-wtoc.js new file mode 100644 index 0000000..7f22db7 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/html-wtoc.js @@ -0,0 +1,361 @@ + +// © Copyright 2006 Lennart Borgman, http://www.OurComments.org/. All rights reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth +// Floor, Boston, MA 02110-1301, USA. + + +var HTML_WTOC_NS_sCurrTocId; + + +HTML_WTOC_NS = { + + ///////////////////////////// + //// Basic event functions + ///////////////////////////// + + getEventObject : function (ev) { + var o; + if (window.event) + o = window.event.srcElement; + else if (null != ev) + o = ( ev.target ); + return o; + }, + getEvent : function (ev) { + if (window.event) { + return window.event; + } else if (null != ev) { + return ev; + } + }, + + eventStopPropagation : function (e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble=true; + }, + + eventPreventDefault : function (e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue=false; + }, + + ///////////////////////////// + //// TOC hide + ///////////////////////////// + + show_content : function (on) { + var toc = document.getElementById("html-wtoc-id-toccol").style; + var tdv = document.getElementById("html-wtoc-id-tocdiv").style; + var shw = document.getElementById("html-wtoc-id-showtoc").style; + var hid = document.getElementById("html-wtoc-id-hidetoc").style; + if (on) { + toc.display = ""; + tdv.display = ""; + shw.display = "none"; + hid.display = ""; + HTML_WTOC_NS.focus_page_link(0); + } else { + toc.display = "none"; + tdv.display = "none"; + shw.display = ""; + hid.display = "none"; + } + }, + + + + + + ///////////////////////////// + //// Open-Close + ///////////////////////////// + onblur_action : function(ev) { + HTML_WTOC_NS_sCurrTocId = null; + }, + onfocus_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + if (!o) return; + + HTML_WTOC_NS_sCurrTocId = o.id; + }, + onclick_action : function(ev) { + var o = HTML_WTOC_NS.getEventObject(ev); + var e = HTML_WTOC_NS.getEvent(ev); + if (13 == e.keyCode) return true; + if (!o) return true; + if ("IMG" == o.tagName) o = o.parentNode; + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + var sChildId = "toc_child_"+iId; + var sOldCurrTocId = HTML_WTOC_NS_sCurrTocId; + HTML_WTOC_NS.toggle_open(sChildId, o); + HTML_WTOC_NS_sCurrTocId = sOldCurrTocId; + return false; + }, + + toggle_open : function (id, parent) { + var child = document.getElementById(id).style; + var sInner = parent.innerHTML; + var re = new RegExp("[^/]*\.gif", "i"); + if ("none" == child.display) { + child.display = ""; + parent.innerHTML = sInner.replace(re, "down.gif")+""; + } else { + child.display = "none"; + parent.innerHTML = sInner.replace(re, "right.gif")+""; + } + }, + + + + ///////////////////////////// + //// Load + ///////////////////////////// + + onload_actions : function (iPageNum) { + document.body.onkeydown = HTML_WTOC_NS.onkeydown_action; + document.body.onmouseover = HTML_WTOC_NS.onmouseover_action; + var aATags = document.getElementsByTagName("a"); + for(var i = 0; i < aATags.length; i++) { + var o = aATags[i]; + if (null != HTML_WTOC_NS.getIdnumFromId(o.id)) { + o.onfocus = HTML_WTOC_NS.onfocus_action; + o.onblur = HTML_WTOC_NS.onblur_action; + if (o.id.substr(0, 12) == "opener_text_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.title = "Open/Close"; + } else if (o.id.substr(0, 7) == "opener_") { + o.onclick = HTML_WTOC_NS.onclick_action; + o.className = "html-wtoc-mark"; + o.title = "Open/Close"; + } + } + } + HTML_WTOC_NS.focus_page_link(iPageNum); + }, + focus_page_link : function (iPageNum) { + // Element might be hidden + try { + document.getElementById("toc_link_"+iPageNum).focus(); + } catch (exc) { + } + }, + + + + + + + + ///////////////////// + //// Mouse + ///////////////////// + + onmouseover_action : function (ev) { + if (null == HTML_WTOC_NS_sCurrTocId) return true; + var o = HTML_WTOC_NS.getEventObject(ev); + var iId = HTML_WTOC_NS.getIdnumFromId(o.id); + if (null == iId) return true; + o.focus(); + }, + + + + ///////////////////// + //// Key + ///////////////////// + + onkeydown_action: function (ev) { + var keyDown = 40; + var keyUp = 38; + var keyLeft = 37; + var keyRight = 39; + var keyReturn = 13; + var keyF2 = 113; + var keyInsert = 45; + // Opera + var keyOperaDown = 57386; + var keyOperaUp = 57385; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var keyOperaF2 = 57346; + var keyOperaInsert = 57394; + + var SwitchKey = keyInsert; + var SwitchKeyOpera = keyOperaInsert; + + var bUp; + var e = HTML_WTOC_NS.getEvent(ev); + if (null == HTML_WTOC_NS_sCurrTocId) { + switch (e.keyCode) { + case SwitchKey: + case SwitchKeyOpera: + HTML_WTOC_NS.focus_page_link(0); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + } + return true; + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + case keyRight: + case keyOperaRight: + HTML_WTOC_NS.handle_leftright_keys(e); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + case keyDown: + case keyOperaDown: + bUp = false; + break; + case keyUp: + case keyOperaUp: + bUp = true; + break; + case SwitchKey: + case SwitchKeyOpera: + if (null != HTML_WTOC_NS_sCurrTocId) { + var o = document.getElementById(HTML_WTOC_NS_sCurrTocId); + if (o) o.blur(); + HTML_WTOC_NS_sCurrTocId = null; + } + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + default: + //alert(e.keyCode); + return true; + } + var oOpener; + oOpener = HTML_WTOC_NS.getNextVisOpener(HTML_WTOC_NS_sCurrTocId, bUp); + oOpener.focus(); + HTML_WTOC_NS.eventStopPropagation(e); + HTML_WTOC_NS.eventPreventDefault(e); + return false; + }, + + handle_leftright_keys: function (e) { + var keyLeft = 37; + var keyRight = 39; + var keyOperaLeft = 57387; + var keyOperaRight = 57388; + var iId = HTML_WTOC_NS.getIdnumFromId(HTML_WTOC_NS_sCurrTocId); + if (null == iId) return; + var sId = "opener_" + iId; + var oOpener = document.getElementById(sId); + var sId = HTML_WTOC_NS_sCurrTocId; // It will be cleared before getNextVis + + var bOpenAction; + var bOpened; + var bUp; + var oChild = document.getElementById("toc_child_"+iId); + if (null == oChild) { + } else { + bOpened = (oChild.style.display != "none"); + } + switch (e.keyCode) { + case keyLeft: + case keyOperaLeft: + bUp = true; + bOpenAction = (null != bOpened) && (bOpened); + break; + case keyRight: + case keyOperaRight: + bUp = false; + bOpenAction = (null != bOpened) && (!bOpened); + break; + default: + alert("bad key handling..."); + } + if (bOpenAction) { + oOpener.click(); + HTML_WTOC_NS_sCurrTocId = sId; + } else { + var oPrev = HTML_WTOC_NS.getNextVisOpener(sId, bUp); + oPrev.focus(); + } + }, + + + + + + + ////////////////////// + //// Util + ////////////////////// + getNameFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$1"); + return iId; + }, + getIdnumFromId: function (sId) { + var re = new RegExp("(.*?_)(\\d+)", "i"); + if (!re.test(sId)) return null; + var iId = sId.replace(re, "$2"); + return iId; + }, + + + getNextVisOpener: function (sId, bUp, bTrace) { + if (bTrace) alert("getNextVisOpener("+sId+","+bUp+")"); + var iId = HTML_WTOC_NS.getIdnumFromId(sId); + if (null == iId) { + alert("getNextVisOpener err iId==null"); + return; + } + var sIdName = HTML_WTOC_NS.getNameFromId(sId); + if (null == sIdName) { + alert("getNextVisOpener err sIdName==null"); + return; + } + var oOpener; + var iLoop = -2; + while (oOpener == null) { + if (bTrace) alert(iId); + if (iLoop++ > iMaxChildNum) { alert("Child num error"); return; } + if (!bUp) { + iId++; + } else { + iId--; + } + if (iId > iMaxChildNum) { iId = 0; } + if (iId < 0) { iId = iMaxChildNum; } + var s = sIdName+iId; + oOpener = document.getElementById(s); + if (oOpener != null) { + if (bTrace) alert(oOpener.offsetLeft); + if (oOpener.style.display == "none") { // All + oOpener = null; + } else if (oOpener.offsetLeft < 0) { // IE + oOpener = null; + } else if (0 == oOpener.scrollWidth) { // Opera + oOpener = null; + } + } + } + return oOpener; + } + + + +}; //HTML_WTOC_NS diff --git a/nxhtml/nxhtml/html-wtoc/html-wtoc.pl b/nxhtml/nxhtml/html-wtoc/html-wtoc.pl new file mode 100644 index 0000000..56c0e21 --- /dev/null +++ b/nxhtml/nxhtml/html-wtoc/html-wtoc.pl @@ -0,0 +1,1395 @@ +#! perl + +# Copyright 2006, 2007 Lennart Borgman, http://OurComments.org/. All +# rights reserved. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +use strict; +use File::Copy; +use File::Spec; +#use File::Path qw(); +use File::Path; +use File::Find qw(); +use FindBin; + +use lib "$FindBin::Bin/PerlLib"; +use PathSubs qw(); +use html_tags qw( +*html header +div +table Tr td +p hr br +a span img b +); + +### Script start parameters +my $m_param_action; +my $m_param_files = 1; +my $m_param_pnum = 0; +my $m_param_single = 0; +my $m_param_Template; +my $m_param_InPages; +my $m_param_OutRoot; +my @m_param_InRoot; +my $m_param_Overwrite; + +### Globals +my $m_iAlwaysOpenedLevel = 0; +my $m_sCommonIn; +my $m_sInPagesFolder; +my $m_sTemplateFolder; +my $m_sStartTemplate; +my $m_sBodyTemplate; +#my $m_sEndTemplate; +my $m_bBorders = 0; +my @pages; +my %page_num; +my %js_show_page; +my $m_TemplateTime; +my $m_InPagesTime; +my %m_linked_files; + +sub get_params(); +sub get_template(); +sub read_page_list($); +sub find_pages($$); +sub write_pages(); +sub send_page(); +sub find_template_files(); +sub find_linked_from_pages(); +sub copy_wtoc_files(); +sub copy_linked_files(); + +#push @pages, [$ind, $tit, $full_fil, $anc, $hrf, $trg, $tip]; +sub IND { 0 } +sub TIT { 1 } +sub FULL_FIL { 2 } +sub ANC { 3 } +sub HRF { 4 } +sub TRG { 5 } +sub TIP { 6 } + +########################################################## +### Main +########################################################## +print "\n"; +get_params(); +if ($m_param_action eq "FIND") { + find_pages(\@m_param_InRoot, $m_param_InPages); +} elsif($m_param_action eq "MERGE") { + get_template(); + read_page_list($m_param_InPages); + find_template_files(); + copy_wtoc_files(); + if ($m_param_files) { + write_pages(); + } else { + send_page(); + } + find_linked_from_pages(); + copy_linked_files(); +} elsif($m_param_action eq "TOC") { +} +exit; + +sub copy_if_newer_or_overwrite($$) { + my $in_file = shift; + my $out = shift; + my $out_file = $out; + if (-d $out) { + my ($in_v, $in_d, $in_f) = File::Spec->splitpath( $in_file ); + my ($out_v,$out_d,$out_f) = File::Spec->splitpath( $out, 1 ); + $out_file = File::Spec->catpath( $out_v, $out_d, $in_f ); + } + my $should_write = 1; + if (-e $out_file) { + if ($m_param_Overwrite) { + my $in_mdt = (stat $in_file)[9]; + my $outmdt = (stat $out_file)[9]; + if (($outmdt > $in_mdt)) { + $should_write = 0; + } + } else { + $should_write = 0; + } + } + if ($should_write) { + if (!File::Copy::syscopy($in_file, $out_file)) { + die "syscopy($in_file, $out_file): $!"; + } else { + print " $in_file => $out_file\n"; + } + } +} # copy_if_newer_or_overwrite + +sub copy_wtoc_files() { + print "\n**** Copy html-wtoc files\n"; + mkdir $m_param_OutRoot, 0777; + my $css_file = $FindBin::Bin . "/html-wtoc.css"; + copy_if_newer_or_overwrite($css_file, $m_param_OutRoot); + my $js_file = $FindBin::Bin . "/html-wtoc.js"; + copy_if_newer_or_overwrite($js_file, $m_param_OutRoot); + my $OutRootImg = $m_param_OutRoot . "img/"; + mkpath($OutRootImg); + my $imgsrc = $FindBin::Bin . "/img/"; + opendir(IMGDIR, $imgsrc) or die "Can't opendir $imgsrc: $!"; + while (my $imgfile = readdir(IMGDIR)) { + my $outimg = $OutRootImg . $imgfile; + $imgfile = $imgsrc . $imgfile; + #print STDERR ">>>$imgfile\n"; + if (-f $imgfile) { + copy_if_newer_or_overwrite($imgfile, $outimg); + } + } + closedir(IMGDIR); +} # copy_wtoc_files + +sub add_to_linked_files($$) { + my $from_file = shift; + my $to_file = shift; + if (exists $m_linked_files{$to_file}) { + my $old_from = $m_linked_files{$to_file}; + unless ($old_from eq $from_file) { + die "Both $from_file and $old_from should be copied to $to_file"; + } + } + $m_linked_files{$to_file} = $from_file; +} # add_to_linked_files + +sub copy_linked_files() { + print "\n**** Copy linked files\n"; + my %pages; + for my $pnum (0..$#pages) { + $pages{ full_in_name($pnum) } = 1; + } + for my $to_file (keys %m_linked_files) { + my $from_file = $m_linked_files{$to_file}; + unless (exists $pages{$from_file}) { + if (-e $from_file) { + mkpath4file($to_file); + copy_if_newer_or_overwrite($from_file, $to_file); + } + } + } +} # copy_linked_files + +sub find_linked_files($;$) { + my $in_file = shift; + my $out_file = shift; + $out_file = in2out($in_file) unless ($out_file); + my $whole = get_file($in_file); + while ($whole =~ m!(?:\s|^)(?:href|src)="(.*?)"!gis) { + my $l = $1; + next unless $l =~ m!\.(?:css|js|jpg|jpeg|gif|png)$!; + if (!File::Spec->file_name_is_absolute($l)) { + next if $l =~ m!^javascript:!; + next if $l =~ m!^http://!; + next if $l =~ m!^ftp://!; + next if $l =~ m!^mailto:!; + } + my $rel_l = $l; + my $full_in = $l; + if (File::Spec->file_name_is_absolute($l)) { + $rel_l = PathSubs::mk_relative_link($in_file, $l); + } else { + $full_in = PathSubs::mk_absolute_link($in_file, $l); + } + my $full_out = PathSubs::mk_absolute_link($out_file, $rel_l); + add_to_linked_files($full_in, $full_out); + } +} # find_linked_files + +sub find_template_files() { + print "\n**** Find files referenced in template file\n"; + my $in_file = $m_param_Template; + my $out_file = $m_param_OutRoot . "dummy.htm"; + find_linked_files($in_file, $out_file); +} +sub find_linked_from_pages() { + for my $pnum (0..$#pages) { + next unless defined $pages[$pnum][FULL_FIL]; + next unless $pages[$pnum][FULL_FIL] ne ""; + next if defined $pages[$pnum][TRG]; + find_linked_files( full_in_name($pnum) ); + } +} + +sub should_write_merged($$) { + my $pnum = shift; + my $out_file = shift; + my $should_write = 1; + if (-e $out_file) { + if ($m_param_Overwrite) { + my $srcmdt = page_src_time($pnum); + my $outmdt = (stat $out_file)[9]; + if (($outmdt > $srcmdt) + && ($outmdt > $m_TemplateTime) + && ($outmdt > $m_InPagesTime)) { + $should_write = 0; + } + } else { + $should_write = 0; + } + } + return $should_write; +} +sub write_pages() { + #print STDERR "*** param_OutRoot=$m_param_OutRoot\n"; + if ($m_param_single) { + my $out_file = $m_param_OutRoot . "single_$m_param_pnum.html"; + if (should_write_merged($m_param_pnum, $out_file)) { + my $page = create_single_page($m_param_pnum); + $page = shrink($page); + create_file_and_path($out_file, $page); + } + } else { + my $iPages = 0; + print "\n*** Creating pages:\n"; + for my $pnum (0..$#pages) { + next unless defined $pages[$pnum][FULL_FIL]; + next unless $pages[$pnum][FULL_FIL] ne ""; + next if defined $pages[$pnum][TRG]; + $iPages++; + my $out_file = full_out_name($pnum); + if (should_write_merged($pnum, $out_file)) { + my $page = create_page($pnum); + next unless $page; + print " Creating page $iPages: " . full_in_name($pnum) . "\n"; + $page = shrink($page); + print "\t=> $out_file\n"; + create_file_and_path($out_file, $page); + } + } + } +} # write_pages + +sub send_page() { + my $page = ($m_param_single ? + create_single_page($m_param_pnum) + : + create_page($m_param_pnum) ); + print $page; +} # send_page + +########################################################## +### Params +########################################################## +sub die_usage() { + my $sScript = $0; + $sScript =~ tr!\\!/!; + $sScript =~ s!.*/(.*)!$1!; + die qq(Usage: + Making preliminary file list: + $sScript find in="in-dir" pages="pages-file" [overwrite=1] + + Merging pages and table of contents: + $sScript merge pages="pages-file" outroot="out-dir" template="template-file" [overwrite=1] + + \n); +} +#use Getopt::Long; +sub get_params() { + $| = 1; + for my $arg (@ARGV) { print " "; print $arg; } print "\n\n"; + die_usage() unless $#ARGV > 0; + $m_param_action = $ARGV[0]; + $m_param_action =~ tr/a-z/A-Z/; + #push @m_param_InRoot, $FindBin::Bin . "/doc/"; + #$m_param_OutRoot = $FindBin::Bin . "/tmp/"; + #$m_param_Template = $FindBin::Bin . "/doc/home_template.htm"; + #$m_param_InPages = $FindBin::Bin . "/doc/toc_pages.txt"; + for (my $i = 1; $i <= $#ARGV; $i++) { + my ($k, $v) = ($ARGV[$i] =~ m!(.*?)=(.*)!); + $v =~ tr!\\!/!; + if ($k eq "in") { + $v = PathSubs::uniq_file($v); + $v .= "/" unless substr($v, -1) eq "/"; + push @m_param_InRoot, $v; + } elsif( $k eq "outroot") { + $v = PathSubs::uniq_dir($v); + $v .= "/" unless substr($v, -1) eq "/"; + $m_param_OutRoot = $v; + } elsif( $k eq "pages") { + $v = PathSubs::uniq_file($v); + $m_param_InPages = $v; + } elsif( $k eq "template") { + $v = PathSubs::uniq_file($v); + $m_param_Template = $v; + } elsif( $k eq "overwrite" ) { + $m_param_Overwrite = $v; + } elsif( $k eq "openedlevel" ) { + $m_iAlwaysOpenedLevel = $v * 1; + } else { + die "Unknown parameter: $ARGV[$i]\n"; + } + } + if($m_param_action eq "FIND") { + if ($#m_param_InRoot < 0) { die_usage(); } + if (! defined $m_param_InPages) { die_usage(); } + } elsif($m_param_action eq "MERGE") { + if (! defined $m_param_InPages) { die_usage(); } + if (! defined $m_param_OutRoot) { die_usage(); } + if (! defined $m_param_Template) { die_usage(); } + $m_sTemplateFolder = $m_param_Template; + $m_sTemplateFolder =~ s![^/]*$!!; + } else { + die_usage(); + } + + $m_sInPagesFolder = $m_param_InPages; + $m_sInPagesFolder =~ s![^/]*$!!; + print "Parameters:\n"; + print " " . $m_param_action . "\n"; + print " pages=" . $m_param_InPages . "\n"; + print " outroot=" . $m_param_OutRoot . "\n"; + print " template=" . $m_param_Template . "\n"; + if (defined $m_param_Overwrite) { + print " overwrite=" . $m_param_Overwrite . "\n"; + } + #if ($#m_param_InRoot == -1) { push @m_param_InRoot,$m_sInPagesFolder; } +} + +sub get_template() { + my $sTemplate = get_file($m_param_Template, 1); + $m_TemplateTime = (stat $m_param_Template)[9]; + $m_InPagesTime = (stat $m_param_InPages)[9]; + $sTemplate =~ s///gs; + if ( $sTemplate =~ m!(.*?)(.*)!si ) { + $m_sStartTemplate = $1; + $m_sBodyTemplate = $2; + #$m_sEndTemplate = $3; + } else { + die "Can't find body of template\n"; + } +} # get_template + +sub read_page_list($) { + my $sPagesFile = shift; + my @in_files; + open(P,$sPagesFile) or die "Can't open toc list file $sPagesFile: $!\n"; + while (my $sLine =

) { + chomp $sLine; + $sLine =~ s/^\s+|\s+$//g; + next if $sLine eq ""; + next if substr($sLine, 0, 1) eq ";"; + #print STDERR "$sLine\n"; + my ($ind, $tit, $ref, $tip, $trg, $ico) + = map { s/^\s+|\s+$//g; $_; } split("###", $sLine); + #warn "trg=$trg\n" if defined $trg; + my ($fil, $anc) = ("", ""); + my $hrf = ""; + my $full_fil = ""; + #$ref = "" unless defined $ref; + #print STDERR "ref=$ref\n"; + if (defined $ref) { + if (defined $trg) { undef $trg unless $trg ne ""; } + if ((defined $trg) || ($ref =~ m/https?:/i)) { + $hrf = $ref; + } else { + ($fil, $anc) = split('#', $ref); + if ($ind >= 0) { + if (File::Spec->file_name_is_absolute($fil)) { + $full_fil = $fil; + } else { + $full_fil = PathSubs::uniq_file($m_sInPagesFolder . $fil); + } + } + } + } + if ((!$tip) && ($full_fil ne "")) { + $tip = get_title($full_fil); + } + push @pages, [$ind, $tit, $full_fil, $anc, $hrf, $trg, $tip]; + push @in_files, $full_fil if !defined $trg; + } + close P; + $m_sCommonIn = get_common_root(\@in_files). "/"; +} # read_page_list + + + +sub get_common_root($) { + my $psRoots = shift; + my @sCommon; + for my $s (@$psRoots) { + my $full_s = PathSubs::uniq_file($s); + my @full_s = split("/", $full_s); + if ($#sCommon == -1) { + @sCommon = @full_s; + } else { + my $iMax = $#sCommon; if ($#full_s < $iMax) { $iMax = $#full_s; } + for (my $i = 0; $i <= $iMax; $i++) { + if ($sCommon[$i] ne $full_s[$i]) { + #print STDERR "$i: $sCommon[$i] != $full_s[$i]\n"; + @sCommon = @sCommon[0..$i-1]; + last; + } + } + } + } + my $sCommon = join("/", @sCommon); + return $sCommon; +} # get_common_root + + +sub find_pages($$) { + my $pasInRoot = shift; + my $sOutFile = shift; + if (!$m_param_Overwrite) { + die "Don't want to overwrite existing output file $sOutFile!\n" if -e $sOutFile; + } + my $root_level; + my $sList; + my $handle_file = + sub { + return unless m/.html?/i; + return if -d $_; + my $fname = PathSubs::uniq_file($_); + die "Can't read $fname\n" unless -r $_; + my $title = get_title($_); + my $level = $fname =~ tr!/!!; + $level -= $root_level; + my $rel_fname = PathSubs::mk_relative_link($sOutFile, $fname); + $sList .= "$level ### $title ### $rel_fname\n"; + }; + for my $sInRoot (@$pasInRoot) { + $sInRoot = PathSubs::uniq_file($sInRoot); + chop($sInRoot) if (substr($sInRoot, -1) eq "/"); + $root_level = $sInRoot =~ tr!/!!; + File::Find::find($handle_file, $sInRoot); + } + create_file($sOutFile, $sList); +} # find_pages + + +########################################################## +### File - page helpers +########################################################## + +sub file_name($) { + my $num = shift; + return $pages[$num][FULL_FIL]; +} +sub file_anchor($) { + my $num = shift; + return $pages[$num][ANC]; +} +sub file_href($) { + my $num = shift; + #die $pages[$num][HRF] if defined $pages[$num][HRF]; + return $pages[$num][HRF]; +} +sub file_target($) { + my $num = shift; + return $pages[$num][TRG]; +} +sub file_title($) { + my $num = shift; + return $pages[$num][TIT]; +} +sub file_tip($) { + my $num = shift; + return $pages[$num][TIP]; +} +sub full_in_name($) { + my $num = shift; + my $name = file_name($num); + return $name; +} +sub full_out_href($) { + my $num = shift; + my $anchor = file_anchor($num); + my $full_href = full_out_name($num); + warn "full_href is null" unless $full_href; + if ((defined $anchor) && ($anchor ne "")) { $full_href .= "#" . $anchor; } + return $full_href; +} +sub full_out_name($) { + my $num = shift; + my $in_name = file_name($num); + return unless $in_name; + my $anchor = file_anchor($num); + #$m_param_OutRoot . $name; + $anchor = ""; + my $name = substr($in_name, length($m_sCommonIn)); + if ($anchor) { + my $base; + my $ext; + for (my $i = length($name);$i>0;$i--) { + if (substr($name, $i, 1) eq ".") { + $base = substr($name, 0, $i-1); + $ext = substr($name, $i); + $name = $base . "_sharp_" . $anchor . $ext; + last; + } + } + } + $m_param_OutRoot . $name; +} +sub replace_name_link($) { + my $page = shift; + for my $k (keys %page_num) { + my $num = $page_num{$k}; + my $href = ($m_param_single ? "javascript:ShowPage($num)" : file_name($num)); + $page =~ s!%%$k%%!$href!gs; + } + return $page; +} + +########################################################## +### File name helpers +########################################################## +sub in2out($) { + my $in_name = shift; + die "in2out: File name is not abs: $in_name" unless File::Spec->file_name_is_absolute($in_name); + my $name = substr($in_name, length($m_sCommonIn)); + $m_param_OutRoot . $name; +} + +########################################################## +### File reading/writing +########################################################## + +sub mkpath4file($) { + my $file = shift; + my $path = $file; + $path =~ s|[^/]*$||; + File::Path::mkpath($path); +} +sub create_file($$) { + my ($out_file, $page) = @_; + if (!$m_param_Overwrite) { + if (-e $out_file) { die "Will not overwrite $out_file\n"; } + } + open(OUT, ">$out_file") or die "Can't create $out_file: $!"; + print OUT $page; + close OUT; + chmod 0111|((stat $out_file)[2]&07777), $out_file +} +sub create_file_and_path($$) { + my ($out_file, $page) = @_; + mkpath4file($out_file); + create_file($out_file, $page); +} + + +sub get_file($$) { + my ($file, $need) = @_; + if (open(FL, $file)) { + local $/; + my $whole = ; + close FL; + return $whole; + } else { + my $err = $!; + die "Can't open $file: $err\n" if $need; + return ""; + } +} + +sub get_title($) { + my $file = shift; + open(H, $file) or die "Can't open and get title from $file: $!"; + while (my $line = ) { + if ($line =~ m!(.*?)!i) { close H; return $1; } + } + close H; +} + + + +########################################################## +### Html parsing etc +########################################################## + +sub get_head_from_file($) { + my $fname = shift; + my $err; + my $head = get_head(get_file($fname, 1), \$err); + die "\n\n$fname\n\t" . $err if defined $err; + return $head; +} +# BUG: These actually requires parsing of the file, but it does not +# seem very important: +sub get_head($$) { + my $html = shift; + my $perr = shift; + return "" unless $html; + $html =~ s///g; + if ($html =~ m!(.*)!is) { + return $1; + } + $$perr = "Can't find -tag in $html\n"; +} +sub get_body($) { + my $html = shift; + return "" unless $html; + $html =~ s///gs; + if ($html =~ m!]*>(.*)!is) { + return $1; + } + die "Can't find -tag in $html\n"; +} + +sub shrink($) { + my $str = shift; + my $out_str = ""; + my @str = split("\n", $str); + my $in_pre = 0; + for my $s (@str) { + if ($s =~ m!

!i)  { $in_pre = 1; }
+        if ($s =~ m!
!i) { $in_pre = 0; } + $s =~ s!^(\s*)!! unless $in_pre; + $out_str .= $s . "\n"; + } + return $out_str; + $str =~ s!^(\s*)!!gm; + $str; +} + + +########################################################## +### Making what we see +########################################################## + +sub mk_search() { + return "" if ! $m_param_single; + return qq[ + + Sök + ]; +} +sub mk_main_table($$$$$) { + my $left = shift; + my $main = shift; + my $srch_table = shift; + my $sFile = shift; + my $pNum = shift; + my $search_tr = ""; + if ($m_param_single) { + $search_tr = + Tr( + td("  ") + . td({-valign=>'bottom', }, mk_search(), ) ) + } + my $cont_table = + table( + { -border=>"$m_bBorders", -cellpadding=>0, -cellspacing=>0, + -width=>"100%", + -id=>"html-wtoc-contents", + #-style=>"display:", + -summary=>"Table of contents", + }, + Tr( + #td("  ") + td({-class=>"html-wtoc-margin"}) + . td({-valign=>'top'}, $left) ) + . $search_tr + ) + ; + my $page = $m_sBodyTemplate; + $page = replace_template_links($m_sBodyTemplate, $sFile); + $page =~ s!%%TOC%%!$cont_table!; + $page =~ s!%%PAGE%%!$main!; + return $page; +} # mk_main_table + + +sub find_ind_level_prev($) { + my $lThis = shift; + for (my $i = $lThis - 1; $i > 0; $i--) { + my $ind_lev = $pages[$i][IND]; + if ($ind_lev < 50) { return $ind_lev; } + } + return undef; +} +sub find_ind_level_next($) { + my $lThis = shift; + #print "find_ind_level_next($lThis)"; + #print ", "; + #print file_title($lThis); + #print "\n"; + #for (my $i = $lThis; $i < $#pages; $i++) { + for (my $i = $lThis + 1; $i <= $#pages; $i++) { + my $ind_lev = $pages[$i][IND]; + if ($ind_lev < 50) { return $ind_lev; } + } + return undef; +} + + + + + + + + +sub mk_opener_elem($$$) { + my $iPi = shift; + my $sHref = shift; + my $bOpened = shift; + my $Aattrib = + { + -id =>"opener_$iPi", + }; + if ($sHref) { $$Aattrib{href} = $sHref; } + my $sImg; + my $sAlt; + if ($bOpened) { + $sImg = "down"; + $sAlt = "Close"; + } else { + $sImg = "right"; + $sAlt = "Open"; + } + return + a( + $Aattrib, + img({ + -src=>"img/$sImg.gif", + -alt=>$sAlt, + -border=>0, + -width=>12, + -height=>12, + }, + ), + ); +} # mk_opener_elem + +sub mk_content($) { + my $pnum = shift; + if (!$pages[$pnum]) { + return br(); + } + my $cont; + my @father; + my @child_trace; + my $this_indent = $pages[$pnum][IND]; + my $this_file = $pages[$pnum][FULL_FIL]; + if ($this_indent == -2) { + return ""; + } + my $this_href = full_out_name($pnum); + #my $anchor = file_anchor($pnum); + #if (defined $anchor) { $this_href .= "#" . $anchor; } + my @size; + $size[0] = "1em"; + $size[1] = "0.8em"; + $size[2] = "0.8em"; + + + + ### Open all main level nodes + my @opened; # rename to visible!!!!! + for my $pi (0..$#pages) { + my $indent = $pages[$pi][IND]; + if ($indent <= $m_iAlwaysOpenedLevel) { + $opened[$pi] = 1; + } else { + $opened[$pi] = 0; # more simple to handle + } + } + + + + ### Open ancestors and older sisters (if not a standalone node) + my $pnum_indent = $pages[$pnum][IND]; + my $high_open = $pnum_indent; + my $standalone_open = 10; + if ($high_open < $standalone_open) { ### Not a standalone node + for (my $pi = $pnum; $pi >= 0; $pi--) { + my $pi_indent = $pages[$pi][IND]; + if ($high_open >= $pi_indent) { + $opened[$pi] = 1; + $high_open = $pi_indent; + for (my $ps = $pi+1; $ps <= $#pages; $ps++) { + my $ps_indent = $pages[$ps][IND]; + last if $ps_indent < $pi_indent; + $opened[$ps] = 1 if $ps_indent == $pi_indent; + } + } + last if $pi_indent == 0; + } + } + + + + + ### Open direct childs and younger sisters + my $maybe_child = 1; + my $more_sisters = 1; + my $max_open_indent = $pnum_indent; + for my $pi ($pnum+1..$#pages) { + my $pi_indent = $pages[$pi][IND]; + if ($pi_indent <= $max_open_indent) { $maybe_child = 0; } + if ($pi_indent < $pnum_indent) { $more_sisters = 0; } + if ($pi_indent == $pnum_indent) { + if ($more_sisters) { $opened[$pi] = 1; } + $maybe_child = 0; + } elsif ($pi_indent == $pnum_indent+1) { + if ($maybe_child) { $opened[$pi] = 1; } + } + } + #exit if $pnum == 3; + + + + + ### Open all in the same file (necessary for non-JavaScript) + for my $pi (0..$#pages) { + my $file = $pages[$pi][FULL_FIL]; + #printf STDERR "file - open=(%s)\n", $file; + #if ($file eq $this_file) { + if ($file eq $this_file) { + $opened[$pi] = 1; + } + if ($file eq "") { + if ($pi < $#pages) { + if ($pages[$pi][IND] < $pages[$pi+1][IND]) { + $opened[$pi+1] = 1; + } + } + } + if ($pages[$pi][IND] > 10) { + $opened[$pi] = 0; + #print ">>>>>>>>\$opened[$pi] = 0;\n"; + } + #print STDERR "+++++++++\$opened[$pi] = $opened[$pi]\n"; + } + + + + + ### Make the actual contents + my $tooltip; + my $child_id; + for my $pi (0..$#pages) { +# if (!$pages[$pi][FULL_FIL] && !$pages[$pi][HRF]) { +# my $txt = file_title($pi); #$pages[$pi][TIT]; +# $txt = qq(


) if $txt eq "-"; +# $cont .= $txt; +# $cont .= br(); +# next; +# } + my $txt = file_title($pi); #$pages[$pi][TIT]; + if ($txt eq "-") { + $txt = qq(


); + $cont .= $txt; + $cont .= br(); + next; + } + #if ($pages[$pi][TRG]) { + # next; + #} + #next if ! defined $opened[$pi]; + #next if ! $opened[$pi]; + my $ind_lev = $pages[$pi][IND]; + next if $ind_lev > 50; + my $ind_lev_next = find_ind_level_next($pi); + #my $ind_lev_prev = find_ind_level_prev($pi); + + my $this_entry = ""; + + ### Child id from previous row + if (defined $child_id) { + my $display = ""; + if (!$opened[$pi]) { + $display = qq(style="display:none"); + } else { + } + $this_entry .= "\n

\n"; + undef $child_id; + } + my $opener_elem = ""; #qq( ); + my $childs_are_visible = ($pi == $pnum); + if ($pi < $#pages) { + if ($pages[$pi][IND] < $pages[$pi+1][IND]) { + if ($opened[$pi+1]) { $childs_are_visible = 1; } + } + } + #if ($pages[$pi][IND] < $m_iAlwaysOpenedLevel) { $childs_are_visible = 1; } + + my $file_href; + my $target; + my $href; + my $href_self; + my $target_attrib; + my $title = file_title($pi); + my $file_name = file_name($pi); + if ($title) { + $file_href = file_href($pi); # || ""; + $target = file_target($pi); + $href = + ($file_name ? + ($m_param_files ? + ($m_param_single ? "JavaScript:ShowPage($pi);" : + ($file_href ne ""? $file_href + : + PathSubs::mk_relative_link($this_href, full_out_href($pi)))) + : + ($m_param_single ? "JavaScript:ShowPage($pi)" : "?pnum=$pi") + ) + : + (File::Spec->splitpath($this_href))[2]); + if ($pi == $pnum) { + $href_self = $this_href; + if ($href_self =~ m!([^/\\]*$)!) { + $href_self = $1; + } + } + $target_attrib = (defined $target? qq(target="$target"): ""); + } else { + $href = ""; + $target_attrib = ""; + } + + if (defined $ind_lev_next && $ind_lev_next > $ind_lev) { + $child_id = "toc_child_$pi"; + #print " child_id=$child_id\n"; + push @child_trace, $child_id; + $opener_elem = mk_opener_elem($pi, + ($href? $href : $href_self), + $childs_are_visible); + } + $title =~ s/_/ /go; + my $indent = ($ind_lev ? " " x (($ind_lev-1) * 4) : ""); + my $size = $size[$ind_lev]; + $title = b($title) if $ind_lev == 0; + + my $Aattrib = + { + id=>"toc_link_$pi", + onclick=>"html_wtoc_nailing(this)", + }; + if (!$file_name) { + $Aattrib = + { + id=>"opener_text_$pi", + }; + } + if ($pi == $pnum) { + ### Current page + $$Aattrib{class} = "html-wtoc-currcont"; + $$Aattrib{title} = "You are here"; + $$Aattrib{href} = $href_self; + $this_entry .= + table({ + -cellspacing=>0, + -cellpadding=>0, + -class=>"html-wtoc-contline", + -border=>0, + -summary=>"Formatter", + }, + Tr({ + }, + td({ + }, + a( + $Aattrib, + $indent . $title . " " + ) + ) + . td({ + -class=>"html-wtoc-mark", + }, + $opener_elem + ) + ) + ); + + + + + } else { + ### Link to other page + if (file_title($pi)) { + $tooltip = $pages[$pi][TIP]; + if (!defined $tooltip) { $tooltip = "Go to the page $title"; } + $$Aattrib{class} = "html-wtoc-contents-a"; + my $a_or_span; + if (!defined $href) { + $a_or_span = span($Aattrib, $indent . $title); + } else { + $$Aattrib{title} = $tooltip; + $$Aattrib{href} = $href; + if (defined $target) { $$Aattrib{target} = $target; } + $a_or_span = a($Aattrib, $indent . $title); + } + $this_entry .= + table({ + -cellspacing=>0, + -cellpadding=>0, + -class=>"html-wtoc-contline", + -border=>0, + -summary=>"Formatter", + }, + Tr({ + }, + td({ + }, + $a_or_span + ) + . td({ + -class=>"html-wtoc-mark", + }, + $opener_elem + ) + ) + ); + } else { + $this_entry .= $indent . " " . $title; + #die $this_entry; + } + } + if ((!defined $ind_lev_next) || $ind_lev_next <= $ind_lev) { + my $ind_end = $ind_lev; + if (defined $ind_lev_next) { $ind_end = $ind_lev_next+1; } + for (my $i = $ind_end; $i <= $ind_lev; $i++) { + my $end_id = pop @child_trace; + if (defined $end_id) { + $this_entry .= "
"; # end childs' span + #print " end $end_id\n"; + } + } + } + $cont .= $this_entry; + $father[$ind_lev] = $pi; + } #for my $pi (0..$#pages) + + $cont = div({-class=>"html-wtoc-contents"}, $cont) . p(" "); + #$cont =~ s|<|\n<|gms; + #$cont =~ tr!\n\r! !; + $cont =~ s{ + (\ssrc=)"(.*?)" + } + { + my $s1 = $1; + my $src = $2; + if (!PathSubs::is_abs_path($src)) { + my $srcabs = PathSubs::mk_absolute_link(full_out_name(0), $src); + $src = PathSubs::mk_relative_link(full_out_name($pnum), $srcabs); + }; + "${s1}\"$src\""; + }egsmx; + $cont; +} # mk_content + +sub mk_main_window($) { + my $pnum = shift; + my $full_name = full_in_name($pnum); + return unless defined $full_name; + return get_body(get_file($full_name, 1)); +} + + + + + + + + +########################################################## +### The JavaScripts and styles we need +########################################################## + +sub mk_style($) { + return ""; + my $pnum = shift; + my $rel_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "html-wtoc.css"); + return qq(\n); +} +sub mk_js($) { + my $pnum = shift; + return <<__HTML_END_JS_PNUM__; + +__HTML_END_JS_PNUM__ + return ""; + my $single_js = ""; + if ($m_param_single) { + $single_js = qq[if (!document.all) { navigate("0.html"); }]; + my $page_info = "var page_name = new Array;\n"; + for my $i (0..$#pages) { + my $page_name = file_title($i); #$pages[$i][TIT]; + $page_info .= qq[ page_name[$i] = "$page_name";\n]; + } + $single_js .= $page_info; + } + my $sch_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "search.js"); + my $top_link = + PathSubs::mk_relative_link(full_out_name($pnum), $m_param_OutRoot . "html-wtoc.js"); + return <<__HTML_END_JS__; + + + +__HTML_END_JS__ +} + +########################################################## +### Page creation +########################################################## + +sub replace_template_links($$) { + my $template = shift; + my $sFile = shift; + $template =~ s{\ssrc="(.*?)"} + { + my $sSrc = $m_param_OutRoot . $1; + my $sRelSrc = PathSubs::mk_relative_link($sFile, $sSrc); + qq( src="$sRelSrc"); + }exg; + $template =~ s{\shref="(.*?)"} + { + my $sOld = $1; + if ((lc substr($sOld, 0, 11)) eq "javascript:") { + qq( href="$sOld"); + } elsif (PathSubs::is_abs_netpath($sOld)) { + qq( href="$sOld"); + } else { + my $sSrc = $m_param_OutRoot . $sOld; + my $sRelSrc = PathSubs::mk_relative_link($sFile, $sSrc); + qq( href="$sRelSrc"); + } + }exg; + return $template; +} # replace_template_links + +sub mk_start_of_page($) { + my $pnum = shift; + my $page = ""; + my $page_style = mk_style($pnum); + my $page_js = mk_js($pnum); + my $sFile = full_out_name($pnum); + my $head = ""; + $head .= $page_js; + $head .= $page_style; + $head .= get_head_from_file(full_in_name($pnum)); + $page .= header if !$m_param_files; + $page .= replace_template_links($m_sStartTemplate, $sFile); + $page =~ s!HEAD!$head!; + my $focus_pnum = $pnum; + my $ind_lev = $pages[$pnum][IND]; + if ($ind_lev > 50) { $focus_pnum = 0; } + $page =~ s!%%PNUM%%!$focus_pnum!; + return $page; +} # mk_start_of_page + +my %m_sCreatedPages; +sub page_src_time($) { + my $pnum = shift; + my $src_file = $pages[$pnum][FULL_FIL]; + return (stat $src_file)[9]; +} +sub create_page($) { + my $pnum = shift; + return unless $pages[$pnum][FULL_FIL]; + + my $out_name = full_out_name($pnum); + return if exists $m_sCreatedPages{$out_name}; + $m_sCreatedPages{$out_name} = 1; + + my $page = mk_start_of_page($pnum); + my $cont_win = mk_content($pnum); + my $main_win = mk_main_window($pnum); + $page .= mk_main_table( + $cont_win, + $main_win, + "", + $out_name, + $pnum, + ); + $page .= end_html; + $page = replace_name_link($page); + return $page; +} # create_page + + +__END__ + + + ########################################################## + ### Unused currently + ########################################################## + + sub build_ShowPage() { + for my $num (0..$#pages) { + $page_num{$pages[$num][FULL_FIL]} = $num; + my $fon = full_out_name($num); + if ($fon) { $js_show_page{$fon} = "ShowPage($num);"; } + } +} +build_ShowPage(); + + +sub mk_meta_enter_exit() { + return <<__HTML_EE__; + + +__HTML_EE__ +} + +########################################################## +### Single page +########################################################## + +sub mk_noscript() { + return <<__HTML_END_NOSCRIPT__; +