initial commit
[emacs-init.git] / auto-install / icicles-cmd1.el
1 ;;; icicles-cmd1.el --- Top-level commands for Icicles
2 ;;
3 ;; Filename: icicles-cmd1.el
4 ;; Description: Top-level commands for Icicles
5 ;; Author: Drew Adams
6 ;; Maintainer: Drew Adams
7 ;; Copyright (C) 1996-2011, Drew Adams, all rights reserved.
8 ;; Created: Mon Feb 27 09:25:04 2006
9 ;; Version: 22.0
10 ;; Last-Updated: Fri Sep  2 16:25:27 2011 (-0700)
11 ;;           By: dradams
12 ;;     Update #: 22215
13 ;; URL: http://www.emacswiki.org/cgi-bin/wiki/icicles-cmd1.el
14 ;; Keywords: extensions, help, abbrev, local, minibuffer,
15 ;;           keys, apropos, completion, matching, regexp, command
16 ;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x
17 ;;
18 ;; Features that might be required by this library:
19 ;;
20 ;;   `apropos', `apropos-fn+var', `avoid', `backquote', `bytecomp',
21 ;;   `cl', `cus-edit', `cus-face', `cus-load', `cus-start', `doremi',
22 ;;   `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
23 ;;   `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-face',
24 ;;   `icicles-fn', `icicles-mac', `icicles-mcmd', `icicles-opt',
25 ;;   `icicles-var', `image-dired', `kmacro', `levenshtein',
26 ;;   `misc-fns', `mouse3', `mwheel', `pp', `pp+', `regexp-opt',
27 ;;   `ring', `ring+', `strings', `thingatpt', `thingatpt+',
28 ;;   `wid-edit', `wid-edit+', `widget'.
29 ;;
30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 ;;
32 ;;; Commentary:
33 ;;
34 ;;  This is a helper library for library `icicles.el'.  It defines
35 ;;  top-level commands (and a few non-interactive functions used in
36 ;;  those commands).  Library `icicles-cmd2.el' is a continuation of
37 ;;  this file (a single file for all top-level commands would be too
38 ;;  large to upload to Emacs Wiki).
39 ;;
40 ;;  For commands to be used mainly in the minibuffer or buffer
41 ;;  `*Completions*', see `icicles-mcmd.el'.
42 ;;
43 ;;  For Icicles documentation, see `icicles-doc1.el' and
44 ;;  `icicles-doc2.el'.
45 ;;
46 ;;  If you use the byte-compiled version of this library,
47 ;;  `icicles-cmd1.elc', in Emacs 23, then it must be byte-compiled
48 ;;  using Emacs 23.  Otherwise, Icicles key completion (and perhaps
49 ;;  other things?) will not work correctly.
50 ;;
51 ;;  Macros defined here:
52 ;;
53 ;;    `icicle-define-bookmark-command',
54 ;;    `icicle-define-bookmark-command-1',
55 ;;    `icicle-define-bookmark-other-window-command'.
56 ;;
57 ;;  Commands defined here - (+) means a multi-command:
58 ;;
59 ;;    (+)`clear-option', (+)`icicle-add-buffer-candidate',
60 ;;    (+)`icicle-add-buffer-config',
61 ;;    `icicle-add-entry-to-saved-completion-set',
62 ;;    `icicle-bbdb-complete-name', (+)`icicle-bookmark',
63 ;;    (+)`icicle-bookmark-all-tags',
64 ;;    (+)`icicle-bookmark-all-tags-other-window',
65 ;;    (+)`icicle-bookmark-all-tags-regexp',
66 ;;    (+)`icicle-bookmark-all-tags-regexp-other-window',
67 ;;    (+)`icicle-bookmark-bookmark-list',
68 ;;    `icicle-bookmark-bookmark-list-narrow',
69 ;;    (+)`icicle-bookmark-cmd', (+)`icicle-bookmark-desktop',
70 ;;    `icicle-bookmark-desktop-narrow', (+)`icicle-bookmark-dired',
71 ;;    (+)`icicle-bookmark-dired-other-window',
72 ;;    `icicle-bookmark-dired-narrow',
73 ;;    (+)`icicle-bookmarked-buffer-list',
74 ;;    (+)`icicle-bookmarked-file-list', (+)`icicle-bookmark-file',
75 ;;    (+)`icicle-bookmark-file-all-tags',
76 ;;    (+)`icicle-bookmark-file-all-tags-other-window',
77 ;;    (+)`icicle-bookmark-file-all-tags-regexp',
78 ;;    (+)`icicle-bookmark-file-all-tags-regexp-other-window',
79 ;;    (+)`icicle-bookmark-file-other-window',
80 ;;    `icicle-bookmark-file-narrow',
81 ;;    (+)`icicle-bookmark-file-some-tags',
82 ;;    (+)`icicle-bookmark-file-some-tags-other-window',
83 ;;    (+)`icicle-bookmark-file-some-tags-regexp',
84 ;;    (+)`icicle-bookmark-file-some-tags-regexp-other-window',
85 ;;    (+)`icicle-bookmark-file-this-dir',
86 ;;    (+)`icicle-bookmark-file-this-dir-other-window',
87 ;;    (+)`icicle-bookmark-file-this-dir-all-tags',
88 ;;    (+)`icicle-bookmark-file-this-dir-all-tags-other-window',
89 ;;    (+)`icicle-bookmark-file-this-dir-all-tags-regexp',
90 ;;    (+)`icicle-bookmark-file-this-dir-all-tags-regexp-other-window',
91 ;;    (+)`icicle-bookmark-file-this-dir-some-tags',
92 ;;    (+)`icicle-bookmark-file-this-dir-some-tags-other-window',
93 ;;    (+)`icicle-bookmark-file-this-dir-some-tags-regexp',
94 ;;    (+)`icicle-bookmark-file-this-dir-some-tags-regexp-other-window',
95 ;;    (+)`icicle-bookmark-gnus',
96 ;;    (+)`icicle-bookmark-gnus-other-window',
97 ;;    `icicle-bookmark-gnus-narrow',
98 ;;    (+)`icicle-bookmark-info-other-window',
99 ;;    `icicle-bookmark-info-narrow', `icicle-bookmark-jump',
100 ;;    `icicle-bookmark-jump-other-window', (+)`icicle-bookmark-list',
101 ;;    (+)`icicle-bookmark-local-file',
102 ;;    (+)`icicle-bookmark-local-file-other-window',
103 ;;    `icicle-bookmark-local-file-narrow', (+)`icicle-bookmark-man',
104 ;;    (+)`icicle-bookmark-man-other-window',
105 ;;    `icicle-bookmark-man-narrow', (+)`icicle-bookmark-non-file',
106 ;;    (+)`icicle-bookmark-non-file-other-window',
107 ;;    `icicle-bookmark-non-file-narrow',
108 ;;    (+)`icicle-bookmark-other-window', (+)`icicle-bookmark-region',
109 ;;    (+)`icicle-bookmark-region-other-window',
110 ;;    `icicle-bookmark-region-narrow',
111 ;;    (+)`icicle-bookmark-remote-file',
112 ;;    (+)`icicle-bookmark-remote-file-other-window',
113 ;;    `icicle-bookmark-remote-file-narrow',
114 ;;    `icicle-bookmark-save-marked-files',
115 ;;    `icicle-bookmark-save-marked-files-as-project',
116 ;;    `icicle-bookmark-save-marked-files-more',
117 ;;    `icicle-bookmark-save-marked-files-persistently',
118 ;;    `icicle-bookmark-save-marked-files-to-variable',
119 ;;    `icicle-bookmark-set', (+)`icicle-bookmark-some-tags',
120 ;;    (+)`icicle-bookmark-some-tags-other-window',
121 ;;    (+)`icicle-bookmark-some-tags-regexp',
122 ;;    (+)`icicle-bookmark-some-tags-regexp-other-window',
123 ;;    (+)`icicle-bookmark-specific-buffers',
124 ;;    `icicle-bookmark-specific-buffers-narrow',
125 ;;    (+)`icicle-bookmark-specific-buffers-other-window',
126 ;;    (+)`icicle-bookmark-specific-files',
127 ;;    `icicle-bookmark-specific-files-narrow',
128 ;;    (+)`icicle-bookmark-specific-files-other-window',
129 ;;    (+)`icicle-bookmark-this-buffer',
130 ;;    `icicle-bookmark-this-buffer-narrow',
131 ;;    (+)`icicle-bookmark-this-buffer-other-window',
132 ;;    (+)`icicle-bookmark-url', `icicle-bookmark-url-narrow',
133 ;;    (+)`icicle-bookmark-url-other-window', (+)`icicle-bookmark-w3m',
134 ;;    (+)`icicle-bookmark-w3m-other-window',
135 ;;    `icicle-bookmark-w3m-narrow', (+)`icicle-buffer',
136 ;;    (+)`icicle-buffer-config', (+)`icicle-buffer-list',
137 ;;    (+)`icicle-buffer-other-window', `icicle-cd-for-abs-files',
138 ;;    `icicle-cd-for-loc-files', (+)`icicle-clear-history',
139 ;;    (+)`icicle-clear-current-history', (+)`icicle-color-theme',
140 ;;    `icicle-comint-dynamic-complete',
141 ;;    `icicle-comint-dynamic-complete-filename',
142 ;;    `icicle-comint-replace-by-expanded-filename',
143 ;;    (+)`icicle-command-abbrev', (+)`icicle-command-abbrev-command',
144 ;;    (+)`icicle-completing-yank', `icicle-customize-apropos',
145 ;;    `icicle-customize-apropos-faces',
146 ;;    `icicle-customize-apropos-groups',
147 ;;    `icicle-customize-apropos-options',
148 ;;    `icicle-customize-apropos-options-of-type',
149 ;;    (+)`icicle-customize-face',
150 ;;    (+)`icicle-customize-face-other-window',
151 ;;    `icicle-customize-icicles-group', `icicle-dabbrev-completion',
152 ;;    (+)`icicle-delete-file', (+)`icicle-delete-window',
153 ;;    (+)`icicle-delete-windows', (+)`icicle-directory-list',
154 ;;    (+)`icicle-dired', `icicle-dired-chosen-files',
155 ;;    `icicle-dired-chosen-files-other-window',
156 ;;    (+)`icicle-dired-other-window', `icicle-dired-project',
157 ;;    `icicle-dired-project-other-window',
158 ;;    `icicle-dired-saved-file-candidates',
159 ;;    `icicle-dired-saved-file-candidates-other-window',
160 ;;    `icicle-dired-save-marked',
161 ;;    `icicle-dired-save-marked-as-project',
162 ;;    `icicle-dired-save-marked-more',
163 ;;    `icicle-dired-save-marked-persistently',
164 ;;    `icicle-dired-save-marked-to-variable',
165 ;;    `icicle-doremi-increment-variable+',
166 ;;    `icicle-ess-complete-filename',
167 ;;    `icicle-ess-complete-object-name',
168 ;;    `icicle-ess-internal-complete-object-name',
169 ;;    `icicle-ess-R-complete-object-name',
170 ;;    (+)`icicle-execute-extended-command',
171 ;;    (+)`icicle-execute-named-keyboard-macro', (+)`icicle-face-list',
172 ;;    (+)`icicle-file', (+)`icicle-file-list',
173 ;;    (+)`icicle-file-other-window', (+)`icicle-find-file',
174 ;;    (+)`icicle-find-file-absolute',
175 ;;    (+)`icicle-find-file-absolute-other-window',
176 ;;    (+)`icicle-find-file-in-tags-table',
177 ;;    (+)`icicle-find-file-in-tags-table-other-window',
178 ;;    (+)`icicle-find-file-other-window',
179 ;;    (+)`icicle-find-file-read-only',
180 ;;    (+)`icicle-find-file-read-only-other-window',
181 ;;    (+)`icicle-find-first-tag',
182 ;;    (+)`icicle-find-first-tag-other-window', (+)`icicle-find-tag',
183 ;;    `icicle-grep-saved-file-candidates',
184 ;;    `icicle-gud-gdb-complete-command', (+)`icicle-increment-option',
185 ;;    (+)`icicle-increment-variable', (+)`icicle-insert-buffer',
186 ;;    (+)`icicle-kill-buffer', (+)`icicle-kmacro',
187 ;;    `icicle-lisp-complete-symbol', (+)`icicle-locate-file',
188 ;;    (+)`icicle-locate-file-no-symlinks',
189 ;;    (+)`icicle-locate-file-no-symlinks-other-window',
190 ;;    (+)`icicle-locate-file-other-window',
191 ;;    (+)`icicle-other-window-or-frame', `icicle-pop-tag-mark',
192 ;;    `icicle-pp-eval-expression', (+)`icicle-recent-file',
193 ;;    (+)`icicle-recent-file-other-window',
194 ;;    `icicle-recompute-shell-command-candidates',
195 ;;    (+)`icicle-remove-buffer-candidate',
196 ;;    (+)`icicle-remove-buffer-config',
197 ;;    `icicle-remove-entry-from-saved-completion-set',
198 ;;    (+)`icicle-remove-file-from-recentf-list',
199 ;;    (+)`icicle-remove-saved-completion-set',
200 ;;    `icicle-repeat-complex-command',
201 ;;    (+)`icicle-reset-option-to-nil',
202 ;;    (+)`icicle-select-bookmarked-region', (+)`icicle-select-frame',
203 ;;    `icicle-select-frame-by-name', (+)`icicle-select-window',
204 ;;    `icicle-select-window-by-name', `icicle-send-bug-report',
205 ;;    (+)`icicle-set-option-to-t',
206 ;;    `icicle-shell-dynamic-complete-command',
207 ;;    `icicle-shell-dynamic-complete-environment-variable',
208 ;;    `icicle-shell-dynamic-complete-filename',
209 ;;    (+)`icicle-toggle-option', (+)`icicle-yank-maybe-completing',
210 ;;    (+)`toggle'.
211 ;;
212 ;;  Non-interactive functions defined here:
213 ;;
214 ;;    `custom-variable-p', `icicle-binary-option-p',
215 ;;    `icicle-bookmark-cleanup', `icicle-bookmark-cleanup-on-quit',
216 ;;    `icicle-bookmark-delete-action', `icicle-bookmark-help-string',
217 ;;    `icicle-bookmark-jump-1', `icicle-clear-history-1',
218 ;;    `icicle-clear-history-entry',
219 ;;    `icicle-comint-dynamic-complete-as-filename',
220 ;;    `icicle-comint-dynamic-simple-complete',
221 ;;    `icicle-comint-replace-orig-completion-fns',
222 ;;    `icicle-command-abbrev-action',
223 ;;    `icicle-command-abbrev-matching-commands',
224 ;;    `icicle-command-abbrev-record', `icicle-command-abbrev-regexp',
225 ;;    `icicle-customize-faces', `icicle-dabbrev--abbrev-at-point',
226 ;;    `icicle-default-buffer-names',
227 ;;    `icicle-delete-file-or-directory',
228 ;;    `icicle-execute-extended-command-1', `icicle-explore',
229 ;;    `icicle-find-first-tag-action',
230 ;;    `icicle-find-first-tag-other-window-action',
231 ;;    `icicle-find-tag-action', `icicle-find-tag-define-candidates',
232 ;;    `icicle-find-tag-define-candidates-1',
233 ;;    `icicle-find-tag-final-act', `icicle-find-tag-help',
234 ;;    `icicle-find-tag-quit-or-error', `icicle-insert-for-yank',
235 ;;    `icicle-kill-a-buffer-and-update-completions',
236 ;;    `icicle-kmacro-action', `icicle-lisp-completion-at-point',
237 ;;    (+)`icicle-locate-file-1', `icicle-locate-file-action',
238 ;;    `icicle-locate-file-other-window-action',
239 ;;    `icicle-make-file+date-candidate', `icicle-make-frame-alist',
240 ;;    `icicle-make-window-alist',
241 ;;    `icicle-bookmark-propertize-candidate',
242 ;;    `icicle-pp-display-expression',
243 ;;    `icicle-remove-buffer-candidate-action',
244 ;;    `icicle-remove-buffer-config-action',
245 ;;    `icicle-remove-from-recentf-candidate-action',
246 ;;    `icicle-remove-saved-set-action',
247 ;;    `icicle-shell-command-on-file',
248 ;;    `icicle-shell-dynamic-complete-as-command',
249 ;;    `icicle-shell-dynamic-complete-as-environment-variable'.
250 ;;
251 ;;  Internal variables defined here:
252 ;;
253 ;;    `icicle-locate-file-action-fn',
254 ;;    `icicle-locate-file-no-symlinks-p'.
255 ;;
256 ;;
257 ;;  ***** NOTE: The following functions defined in `dabbrev.el' have
258 ;;              been REDEFINED HERE:
259 ;;
260 ;;  `dabbrev-completion' - Use Icicles minibuffer completion when there
261 ;;                         are multiple candidates.
262 ;;
263 ;;
264 ;;  ***** NOTE: The following functions defined in `bbdb-com.el' have
265 ;;              been REDEFINED HERE:
266 ;;              (BBDB is available here: http://bbdb.sourceforge.net/.)
267 ;;
268 ;;  `bbdb-complete-name' - Use Icicles minibuffer completion when there
269 ;;                         are multiple candidates.
270 ;;
271 ;;
272 ;;  ***** NOTE: The following functions defined in `lisp.el' have
273 ;;              been REDEFINED in Icicles:
274 ;;
275 ;;  `lisp-complete-symbol' - Selects `*Completions*' window even if on
276 ;;                           another frame.
277 ;;
278 ;;
279 ;;  ***** NOTE: The following function defined in `simple.el' has
280 ;;              been REDEFINED HERE:
281 ;;
282 ;;  `repeat-complex-command' - Use `completing-read' to read command.
283 ;;
284 ;;
285 ;;  ***** NOTE: The following functions defined in `cus-edit.el' have
286 ;;              been REDEFINED HERE:
287 ;;
288 ;;  `customize-apropos', `customize-apropos-faces',
289 ;;  `customize-apropos-groups', `customize-apropos-options' -
290 ;;     Use `completing-read' to read the regexp.
291 ;;  `customize-face', `customize-face-other-window' - Multi-commands.
292 ;;
293 ;;
294 ;;  Key bindings made by Icicles: See "Key Bindings" in
295 ;;  `icicles-doc2.el'.
296 ;;
297 ;;  For descriptions of changes to this file, see `icicles-chg.el'.
298  
299 ;;(@> "Index")
300 ;;
301 ;;  If you have library `linkd.el' and Emacs 22 or later, load
302 ;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
303 ;;  navigate around the sections of this doc.  Linkd mode will
304 ;;  highlight this Index, as well as the cross-references and section
305 ;;  headings throughout this file.  You can get `linkd.el' here:
306 ;;  http://dto.freeshell.org/notebook/Linkd.html.
307 ;;
308 ;;  (@> "Icicles Top-Level Commands, Part 1")
309  
310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
311 ;;
312 ;; This program is free software; you can redistribute it and/or
313 ;; modify it under the terms of the GNU General Public License as
314 ;; published by the Free Software Foundation; either version 3, or
315 ;; (at your option) any later version.
316 ;;
317 ;; This program is distributed in the hope that it will be useful,
318 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
319 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
320 ;; General Public License for more details.
321 ;;
322 ;; You should have received a copy of the GNU General Public License
323 ;; along with this program; see the file COPYING.  If not, write to
324 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
325 ;; Floor, Boston, MA 02110-1301, USA.
326 ;;
327 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
328 ;;
329 ;;; Code:
330
331 (eval-when-compile (require 'cl)) ;; pushnew
332                                   ;; plus, for Emacs < 21: dolist, push
333 (eval-when-compile (when (>= emacs-major-version 21) (require 'recentf))) ;; recentf-mode
334 (eval-when-compile (require 'dabbrev))
335   ;; dabbrev-case-fold-search, dabbrev-upcase-means-case-search, dabbrev--last-obarray,
336   ;; dabbrev--last-completion-buffer, dabbrev--last-abbreviation, dabbrev--check-other-buffers,
337   ;; dabbrev-case-replace, dabbrev--reset-global-variables, dabbrev--minibuffer-origin,
338   ;; dabbrev--find-all-expansions, dabbrev--substitute-expansion
339 (eval-when-compile (require 'bookmark))
340   ;; bookmark-all-names, bookmark-buffer-name, bookmark-current-bookmark
341 (eval-when-compile (require 'comint))
342   ;; comint-completion-addsuffix, comint-completion-autolist, comint-completion-fignore,
343   ;; comint-completion-recexact, comint-directory, comint-dynamic-complete-filename,
344   ;; comint-dynamic-complete-functions, comint-line-beginning-position,
345   ;; comint-match-partial-filename, comint-quote-filename
346 (eval-when-compile (require 'shell)) ;; shell-backward-command, shell-completion-execonly,
347   ;; shell-dynamic-complete-command, shell-dynamic-complete-environment-variable,
348   ;; shell-dynamic-complete-filename, shell-match-partial-variable
349 (eval-when-compile (require 'etags))
350   ;; file-of-tag, find-tag, find-tag-default, find-tag-default-function,
351   ;; find-tag-marker-ring, find-tag-other-window, goto-tag-location-function, snarf-tag-function,
352   ;; tag-find-file-of-tag-noselect, tags-case-fold-search,
353   ;; tags-lazy-completion-table, tags-table-files, visit-tags-table-buffer
354
355 ;; Commented out because `synonyms.el' soft-requires Icicles.
356 ;; (eval-when-compile (require 'synonyms nil t)) ;; (no error if not found):
357   ;; synonyms-ensure-synonyms-read-from-cache, synonyms-obarray
358 (eval-when-compile (require 'misc-cmds nil t)) ;; (no error if not found):
359   ;; kill-buffer-and-its-windows
360 (eval-when-compile (require 'bbdb nil t) (require 'bbdb-com nil t)) ;; (no error if not found):
361   ;; bbdb-auto-fill-function, bbdb-complete-name, bbdb-complete-name-allow-cycling,
362   ;; bbdb-complete-name-cleanup, bbdb-complete-name-hooks, bbdb-completion-display-record,
363   ;; bbdb-completion-predicate, bbdb-completion-type, bbdb-display-records-1,
364   ;; bbdb-dwim-net-address, bbdb-expand-mail-aliases, bbdb-extract-address-components-func,
365   ;; bbdb-gag-messages, bbdb-hashtable, bbdb-mapc, bbdb-pop-up-bbdb-buffer, bbdb-record-aka,
366   ;; bbdb-record-name, bbdb-record-net, bbdb-search-intertwingle, bbdb-string-trim
367 (require 'cus-edit)
368   ;; customize-apropos, customize-apropos-faces, customize-apropos-groups,
369   ;; customize-apropos-options, custom-buffer-create, custom-buffer-order-groups, customize-face,
370   ;; customize-face-other-window, custom-sort-items
371 (require 'misc-fns nil t)   ;; (no error if not found): another-buffer
372 (require 'frame-cmds nil t) ;; (no error if not found): delete-windows-on (my version)
373
374 (eval-when-compile
375  (or (condition-case nil
376          (load-library "icicles-mac")   ; Use load-library to ensure latest .elc.
377        (error nil))
378      (require 'icicles-mac)))           ; Require, so can load separately if not on `load-path'.
379   ;; icicle-assoc-delete-all, icicle-bind-file-candidate-keys, icicle-buffer-bindings,
380   ;; icicle-condition-case-no-debug, icicle-define-command, icicle-define-file-command,
381   ;; icicle-define-add-to-alist-command, icicle-file-bindings, icicle-unbind-file-candidate-keys
382 (require 'icicles-mcmd)
383   ;; icicle-yank
384 (require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
385   ;; icicle-add-proxy-candidates-flag, icicle-buffer-configs, icicle-buffer-extras,
386   ;; icicle-buffer-ignore-space-prefix-flag, icicle-buffer-match-regexp,
387   ;; icicle-buffer-no-match-regexp, icicle-buffer-predicate, icicle-buffer-require-match-flag,
388   ;; icicle-buffer-sort, icicle-color-themes, icicle-saved-completion-sets,
389   ;; icicle-sort-comparer, icicle-transform-function
390 (require 'icicles-var)                  ; (This is required anyway by `icicles-fn.el'.)
391   ;; icicle-candidate-action-fn, icicle-candidate-nb, icicle-candidates-alist,
392   ;; icicle-completion-candidates, icicle-current-input, icicle-extra-candidates,
393   ;; icicle-get-alist-candidate-function, icicle-incremental-completion-p, icicle-kmacro-alist,
394   ;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate,
395   ;; icicle-re-no-dot, icicle-saved-completion-candidates
396 (require 'icicles-fn)                   ; (This is required anyway by `icicles-mcmd.el'.)
397   ;; icicle-delete-dups, icicle-highlight-lighter, icicle-read-from-minibuf-nil-default
398
399
400
401 ;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
402 ;; These are probably benign - ignore them.  Icicles is designed to work with multiple
403 ;; versions of Emacs, and that fact provokes compiler warnings.  If you get byte-compiler
404 ;; errors (not warnings), then please report a bug, using `M-x icicle-send-bug-report'.
405
406 ;;; Some defvars to quiet byte-compiler a bit:
407
408 (when (< emacs-major-version 21)
409   (defvar eval-expression-debug-on-error))
410
411 (when (< emacs-major-version 22)
412   (defvar icicle-kmacro-alist)          ; In `icicles-var.el'
413   (defvar kmacro-ring)                  ; In `kmacro.el'
414   (defvar read-file-name-completion-ignore-case) ;  In `minibuffer.el'
415   (defvar recentf-list)                 ; In `recentf.el'
416   (defvar tags-case-fold-search))       ; In `etags.el'
417
418 (when (< emacs-major-version 23)
419   (defvar read-buffer-completion-ignore-case))
420
421 (defvar bbdb-complete-name-allow-cycling) ; In `bbdb-com.el'
422 (defvar bbdb-extract-address-components-func) ; In `bbdb-com.el'
423 (defvar bbdb-expand-mail-aliases)       ; In `bbdb-com.el'
424 (defvar bbdb-complete-name-hooks)       ; In `bbdb-com.el'
425 (defvar bbdb-completion-display-record) ; In `bbdb.el'
426 (defvar bbdb-completion-type)           ; In `bbdb.el'
427 (defvar bbdb-hashtable)                 ; In `bbdb.el'
428 (defvar bmkp-bookmark-name-length-max)  ; In `bookmark+-1.el'
429 (defvar bmkp-non-file-filename)         ; In `bookmark+-1.el'
430 (defvar bmkp-prompt-for-tags-flag)      ; In `bookmark+-1.el'
431 (defvar bmkp-sorted-alist)              ; In `bookmark+-1.el'
432 (defvar bookmark-current-point)         ; In `bookmark.el' for Emacs < 
433 (defvar color-theme)                    ; In `color-theme.el'
434 (defvar color-themes)                   ; In `color-theme.el'
435 (defvar color-theme-initialized)        ; In `color-theme.el'
436 (defvar ess-current-process-name)       ; In `ess-inf.el'
437 (defvar ess-mode-syntax-table)          ; In `ess-cust.el'
438 (defvar ess-use-R-completion)           ; In `ess-cust.el'
439 (defvar filesets-data)                  ; In `filesets.el'
440 (defvar find-tag-default-function)      ; In `etags.el'
441 (defvar find-tag-marker-ring)           ; In `etags.el'
442 (defvar goto-tag-location-function)     ; In `etags.el'
443 (defvar icicle-clear-history-hist)      ; In `icicle-clear-history-1',`icicle-clear-current-history'
444 (defvar icicle-window-alist)            ; In `icicle-select-window'
445 (defvar shell-completion-execonly)      ; In `shell.el'
446 (defvar snarf-tag-function)             ; In `etags.el'
447 (defvar w3m-current-title)              ; In `w3m.el'.
448
449 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
450  
451 ;;(@* "Icicles Top-Level Commands, Part 1")
452 ;;; Icicles Top-Level Commands, Part 1 .   .   .   .   .   .   .   .   .
453
454
455 ;; REPLACE ORIGINAL `pp-eval-expression' defined in `pp.el',
456 ;; saving it for restoration when you toggle `icicle-mode'.
457 ;;
458 ;; This is essentially the same as `pp-eval-expression' defined in `pp+.el'.
459 ;;
460 ;; 1. Read with completion, using `icicle-read-expression-map'.
461 ;; 2. Progress message added.
462 ;; 3. Added optional arg and insertion behavior.
463 ;; 4. Respect `icicle-pp-eval-expression-print-length', `icicle-pp-eval-expression-print-level',
464 ;;    and `eval-expression-debug-on-error'.
465 ;; 5. Adjusted to work in different Emacs releases.
466 ;;
467 ;;;###autoload
468 (defun icicle-pp-eval-expression (expression ; Bound to `M-:' in Icicle mode.
469                                   &optional insert-value)
470   "Evaluate Emacs-Lisp sexp EXPRESSION, and pretty-print its value.
471 Add the value to the front of the variable `values'.
472 With a prefix arg, insert the value into the current buffer at point.
473  With a negative prefix arg, if the value is a string, then insert it
474  into the buffer without double-quotes (`\"').
475 With no prefix arg:
476  If the value fits on one line (frame width) show it in the echo area.
477  Otherwise, show the value in buffer `*Pp Eval Output*'.
478
479 This command respects user options
480 `icicle-pp-eval-expression-print-length',
481 `icicle-pp-eval-expression-print-level', and
482 `eval-expression-debug-on-error'.
483
484 Emacs-Lisp mode completion and indentation bindings are in effect.
485
486 By default, Icicle mode remaps all key sequences that are normally
487 bound to `eval-expression' or `pp-eval-expression' to
488 `icicle-pp-eval-expression'.  If you do not want this remapping, then
489 customize option `icicle-top-level-key-bindings'."
490   (interactive
491    (list (read-from-minibuffer "Eval: " nil icicle-read-expression-map t 'read-expression-history)
492          current-prefix-arg))
493   (message "Evaluating...")
494   (if (or (not (boundp 'eval-expression-debug-on-error))
495           (null eval-expression-debug-on-error))
496       (setq values  (cons (eval expression) values))
497     (let ((old-value  (make-symbol "t"))
498           new-value)
499       ;; Bind debug-on-error to something unique so that we can
500       ;; detect when evaled code changes it.
501       (let ((debug-on-error  old-value))
502         (setq values     (cons (eval expression) values)
503               new-value  debug-on-error))
504       ;; If evaled code has changed the value of debug-on-error,
505       ;; propagate that change to the global binding.
506       (unless (eq old-value new-value)
507         (setq debug-on-error  new-value))))
508   (let ((print-length  icicle-pp-eval-expression-print-length)
509         (print-level   icicle-pp-eval-expression-print-level))
510     (cond (insert-value
511            (message "Evaluating...done. Value inserted.")
512            (setq insert-value  (prefix-numeric-value insert-value))
513            (if (or (not (stringp (car values))) (wholenump insert-value))
514                (pp (car values) (current-buffer))
515              (princ (car values) (current-buffer))))
516           (t (icicle-pp-display-expression (car values) "*Pp Eval Output*")))))
517
518
519 ;; REPLACE ORIGINAL in `pp.el':
520 ;; 1. Use no `emacs-lisp-mode-hook' or `change-major-mode-hook'.
521 ;; 2. Call `font-lock-fontify-buffer'.
522 ;;
523 (defun icicle-pp-display-expression (expression out-buffer-name)
524   "Prettify and show EXPRESSION in a way appropriate to its length.
525 If a temporary buffer is needed for representation, it is named
526 OUT-BUFFER-NAME."
527   (let* ((old-show-function  temp-buffer-show-function)
528          ;; Use this function to display the buffer.
529          ;; This function either decides not to display it at all
530          ;; or displays it in the usual way.
531          (temp-buffer-show-function
532           #'(lambda (buf)
533               (with-current-buffer buf
534                 (goto-char (point-min))
535                 (end-of-line 1)
536                 (if (or (< (1+ (point)) (point-max))
537                         (>= (- (point) (point-min)) (frame-width)))
538                     (let ((temp-buffer-show-function  old-show-function)
539                           (old-selected               (selected-window))
540                           (window                     (display-buffer buf)))
541                       (goto-char (point-min)) ; expected by some hooks ...
542                       (make-frame-visible (window-frame window))
543                       (unwind-protect
544                            (progn (select-window window)
545                                   (run-hooks 'temp-buffer-show-hook))
546                         (select-window old-selected)
547                         (message "Evaluating...done. See buffer `%s'."
548                                  out-buffer-name)))
549                   (message "%s" (buffer-substring (point-min) (point))))))))
550     (with-output-to-temp-buffer out-buffer-name
551       (pp expression)
552       (with-current-buffer standard-output
553         (setq buffer-read-only  nil)
554         ;; Avoid `let'-binding because `change-major-mode-hook' is local.
555         ;; IOW, avoid this runtime message:
556         ;; "Making change-major-mode-hook buffer-local while locally let-bound!"
557         ;; Suggestion from Stefan M.: Can just set these hooks instead of binding,
558         ;; because they are not permanent-local.  They'll be emptied and
559         ;; repopulated as needed by the call to emacs-lisp-mode.
560         (set (make-local-variable 'emacs-lisp-mode-hook) nil)
561         (set (make-local-variable 'change-major-mode-hook) nil)
562         (emacs-lisp-mode)
563         (set (make-local-variable 'font-lock-verbose) nil)
564         (font-lock-fontify-buffer)))))
565
566 (defun icicle-shell-command-on-file (file)
567   "Read a shell command and invoke it, passing FILE as an argument."
568   (dired-run-shell-command
569    (dired-shell-stuff-it (icicle-read-shell-command (format "! on `%s': " file)) (list file) nil)))
570
571 ;;;###autoload
572 (defun icicle-recompute-shell-command-candidates (&optional savep)
573   "Update option `icicle-shell-command-candidates-cache'.
574 Recompute the available shell commands using your search path.
575 Return the new option value.
576 With a prefix argument, the updated option is saved persistently.
577
578 If the value of option `icicle-guess-commands-in-path' is not `load',
579 then turning on Icicle mode (again) resets the cache value to ().
580 If the value of `icicle-guess-commands-in-path' is `first-use', then
581 the cache is updated when you next use it, but it is not saved."
582   (interactive "P")
583   (setq icicle-shell-command-candidates-cache  (icicle-compute-shell-command-candidates))
584   (when savep (funcall icicle-customize-save-variable-function
585                        'icicle-shell-command-candidates-cache
586                        icicle-shell-command-candidates-cache))
587   icicle-shell-command-candidates-cache)
588
589
590 ;; REPLACE ORIGINAL `comint-dynamic-complete' defined in `comint.el',
591 ;; saving it for restoration when you toggle `icicle-mode'.
592 ;;
593 ;; Uses Icicles completion when there are multiple candidates.
594 ;;
595 ;;;###autoload
596 (defun icicle-comint-dynamic-complete () ; Bound to `TAB' in Comint (and Shell) mode.
597   "Dynamically perform completion at point.
598 Calls the functions in `comint-dynamic-complete-functions', but with
599 Icicles functions substituted, to perform completion until a function
600 returns non-nil, at which point completion is assumed to have
601 occurred.
602
603 Uses Icicles completion."
604   (interactive)
605   ;; Need a symbol for `run-hook-with-args-until-success', so bind one.
606   (let ((hook  (icicle-comint-replace-orig-completion-fns)))
607     (run-hook-with-args-until-success 'hook)))
608
609 (defun icicle-comint-replace-orig-completion-fns ()
610   "Return `comint-dynamic-complete-functions', but with Icicles functions."
611   (let ((old  comint-dynamic-complete-functions)
612         (new  ())
613         pair)
614     (dolist (fn  old)
615       (if (setq pair  (assoc fn icicle-comint-dynamic-complete-replacements))
616           (push (eval (cadr pair)) new)
617         (push fn new)))
618     (nreverse new)))
619
620 ;;;###autoload
621 (defun icicle-comint-dynamic-complete-filename ()
622   "Dynamically complete the filename at point.
623 Completes if after a filename.  See `comint-match-partial-filename' and
624 `icicle-comint-dynamic-complete-as-filename'.
625 This function is similar to `comint-replace-by-expanded-filename', except that
626 it won't change parts of the filename already entered in the buffer; it just
627 adds completion characters to the end of the filename.  A completions listing
628 may be shown in a help buffer if completion is ambiguous.
629
630 Completion is dependent on the value of `comint-completion-addsuffix',
631 `comint-completion-recexact' and `comint-completion-fignore', and the timing of
632 completions listing is dependent on the value of `comint-completion-autolist'.
633
634 Returns t if successful.
635
636 Uses Icicles completion."
637   (interactive)
638   (when (comint-match-partial-filename)
639     (unless (window-minibuffer-p (selected-window)) (message "Completing file name..."))
640     (icicle-comint-dynamic-complete-as-filename)))
641
642 (defun icicle-comint-dynamic-complete-as-filename ()
643   "Dynamically complete at point as a filename.
644 See `icicle-comint-dynamic-complete-filename'.
645 Returns t if successful."
646   (let* ((completion-ignore-case         (if (boundp 'read-file-name-completion-ignore-case)
647                                              read-file-name-completion-ignore-case
648                                            (memq system-type '(ms-dos windows-nt cygwin))))
649          (completion-ignored-extensions  comint-completion-fignore)
650          (minibuffer-p                   (window-minibuffer-p (selected-window)))
651          (success                        t)
652          (dirsuffix                      (cond ((not comint-completion-addsuffix)         "")
653                                                ((not (consp comint-completion-addsuffix)) "/")
654                                                (t  (car comint-completion-addsuffix))))
655          (filesuffix                     (cond ((not comint-completion-addsuffix)         "")
656                                                ((not (consp comint-completion-addsuffix)) " ")
657                                                (t  (cdr comint-completion-addsuffix))))
658          (filename                       (comint-match-partial-filename))
659          (filename-beg                   (if filename (match-beginning 0) (point)))
660          (filename-end                   (if filename (match-end 0) (point)))
661          (filename                       (or filename ""))
662          (filedir                        (file-name-directory filename))
663          (filenondir                     (file-name-nondirectory filename))
664          (directory                      (if filedir (comint-directory filedir) default-directory))
665          (completion                     (file-name-completion filenondir directory)))
666     (cond ((null completion)
667            (if minibuffer-p
668                (minibuffer-message (format " [No completions of `%s']" filename))
669              (message "No completions of `%s'" filename))
670            (setq success  nil))
671           ((eq completion t)            ; Already completed: "the-file".
672            (insert filesuffix)
673            (unless minibuffer-p (message "Sole completion")))
674           ((string-equal completion "") ; A directory: "dir/" - complete it.
675            (icicle-condition-case-no-debug nil
676                (let* ((icicle-show-Completions-initially-flag      t)
677                       (icicle-incremental-completion-p             'display)
678                       (icicle-top-level-when-sole-completion-flag  t)
679                       (choice
680                        (save-excursion
681                          (save-window-excursion (read-file-name "Complete: " directory nil t)))))
682                  (when (and choice (not (string= choice directory)))
683                    (insert (comint-quote-filename
684                             (file-name-nondirectory (directory-file-name choice))))
685                    (insert (if (file-directory-p choice) dirsuffix filesuffix))))
686              (error nil)))
687           (t                            ; COMPLETION is the common prefix string.
688            (let ((file            (concat (file-name-as-directory directory) completion))
689                  (use-dialog-box  nil)) ; Inhibit use of open-file dialog box if called from menu.
690              ;; Insert completion.  The completion string might have a different case from
691              ;; what's in the prompt, if `read-file-name-completion-ignore-case' is non-nil.
692              (delete-region filename-beg filename-end)
693              (if filedir (insert (comint-quote-filename filedir)))
694              (insert (comint-quote-filename (directory-file-name completion)))
695              (cond ((symbolp (file-name-completion completion directory))
696                     ;; We inserted a unique completion.  Add suffix.
697                     (insert (if (file-directory-p file) dirsuffix filesuffix))
698                     (unless minibuffer-p (message "Completed")))
699                    ((and comint-completion-recexact comint-completion-addsuffix
700                          (string-equal filenondir completion)
701                          (file-exists-p file))
702                     ;; It's not unique, but user wants shortest match.
703                     (insert (if (file-directory-p file) dirsuffix filesuffix))
704                     (unless minibuffer-p (message "Completed shortest")))
705                    ;; It's not unique.  Let user choose a completion.
706                    ((or comint-completion-autolist (string-equal filenondir completion))
707                     (icicle-condition-case-no-debug nil
708                         (let* ((icicle-show-Completions-initially-flag      t)
709                                (icicle-incremental-completion-p             'display)
710                                (icicle-top-level-when-sole-completion-flag  t)
711                                (choice
712                                 (save-excursion
713                                   (save-window-excursion
714                                     (read-file-name
715                                      "Complete: " directory completion nil completion
716                                      (and (> emacs-major-version 21)
717                                           #'(lambda (f) (string-match completion f))))))))
718                           (when choice
719                             (delete-backward-char (length completion))
720                             (insert (comint-quote-filename
721                                      (file-name-nondirectory (directory-file-name choice))))
722                             (insert (if (file-directory-p choice) dirsuffix filesuffix))))
723                       (error nil)))
724                    (t (unless minibuffer-p (message "Partially completed")))))))
725     success))
726
727 ;;;###autoload
728 (defun icicle-shell-dynamic-complete-command ()
729   "Dynamically complete the command at point.
730 Similar to `icicle-comint-dynamic-complete-filename', but this
731 searches `exec-path' (minus the trailing Emacs library path) for
732 completion candidates.  Note that this may not be the same as the
733 shell's idea of the path.
734
735 Completion is dependent on the value of `shell-completion-execonly',
736 plus those that effect file completion.
737 See `icicle-shell-dynamic-complete-as-command'.
738
739 Returns t if successful.
740
741 Uses Icicles completion."
742   (interactive)
743   (let ((filename  (comint-match-partial-filename)))
744     (if (and filename
745              (save-match-data (not (string-match "[~/]" filename)))
746              (eq (match-beginning 0) (save-excursion (shell-backward-command 1) (point))))
747         (prog2 (unless (window-minibuffer-p (selected-window))
748                  (message "Completing command name..."))
749             (icicle-shell-dynamic-complete-as-command)))))
750
751 (defun icicle-shell-dynamic-complete-as-command ()
752   "Dynamically complete text at point as a command.
753 See `icicle-shell-dynamic-complete-filename'.
754 Return t if successful."
755   (let* ((filename       (or (comint-match-partial-filename) ""))
756          (filenondir     (file-name-nondirectory filename))
757          (path-dirs      (cdr (reverse exec-path)))
758          (cwd            (file-name-as-directory (expand-file-name default-directory)))
759          (ignored-extensions
760           (and comint-completion-fignore
761                (mapconcat #'(lambda (x) (concat (regexp-quote x) "$"))
762                           comint-completion-fignore "\\|")))
763          (dir            "")
764          (comps-in-dir   ())
765          (file           "")
766          (abs-file-name  "")
767          (completions    ()))
768     (while path-dirs                    ; Go thru each dir in the search path, finding completions.
769       (setq dir           (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
770             comps-in-dir  (and (file-accessible-directory-p dir)
771                                (file-name-all-completions filenondir dir)))
772       (while comps-in-dir               ; Go thru each completion, to see whether it should be used.
773         (setq file           (car comps-in-dir)
774               abs-file-name  (concat dir file))
775         (when (and (not (member file completions))
776                    (not (and ignored-extensions (string-match ignored-extensions file)))
777                    (or (string-equal dir cwd) (not (file-directory-p abs-file-name)))
778                    (or (null shell-completion-execonly) (file-executable-p abs-file-name)))
779           (setq completions  (cons file completions)))
780         (setq comps-in-dir  (cdr comps-in-dir)))
781       (setq path-dirs  (cdr path-dirs)))
782     (let ((success  (let ((comint-completion-addsuffix  nil)
783                           (icicle-candidate-help-fn
784                            #'(lambda (cand)
785                                (shell-command (concat "apropos " (shell-quote-argument cand))
786                                               "*Help*"))))
787                       (icicle-comint-dynamic-simple-complete filenondir completions))))
788       (when (and (memq success '(sole shortest)) comint-completion-addsuffix
789                  (not (file-directory-p (comint-match-partial-filename))))
790         (insert " "))
791       success)))
792
793 ;;;###autoload
794 (defun icicle-comint-replace-by-expanded-filename ()
795   "`comint-replace-by-expanded-filename', but uses Icicles completion.
796 Dynamically complete, expand, and canonicalize the filename at point."
797   (interactive)
798   (let ((filename  (comint-match-partial-filename)))
799     (when filename
800       (replace-match (expand-file-name filename) t t)
801       (icicle-comint-dynamic-complete-filename))))
802
803 (defun icicle-comint-dynamic-simple-complete (stub candidates)
804   "Dynamically complete STUB from CANDIDATES list.
805 Inserts completion characters at point by completing STUB from the
806 strings in CANDIDATES.  Uses Icicles completion if completion is
807 ambiguous.
808
809 Returns nil if no completion was inserted.
810 Returns `sole' if completed with the only completion match.
811 Returns `shortest' if completed with the shortest of the completion matches.
812 Returns `partial' if completed as far as possible with the completion matches.
813 Returns `listed' if a completion listing was shown.
814
815 See also `icicle-comint-dynamic-complete-filename'."
816   (let* ((completion-ignore-case  (memq system-type '(ms-dos windows-nt cygwin)))
817          (minibuffer-p            (window-minibuffer-p (selected-window)))
818          (suffix                  (cond ((not comint-completion-addsuffix)         "")
819                                         ((not (consp comint-completion-addsuffix)) " ")
820                                         (t  (cdr comint-completion-addsuffix))))
821          (candidates              (mapcar #'list candidates))
822          (completions             (all-completions stub candidates)))
823     (cond ((null completions)
824            (if minibuffer-p
825                (minibuffer-message (format " [No completions of `%s']" stub))
826              (message "No completions of `%s'" stub))
827            nil)
828           ((= 1 (length completions))
829            (let ((completion  (car completions)))
830              (if (string-equal completion stub)
831                  (unless minibuffer-p (message "Sole completion"))
832                (insert (substring completion (length stub)))
833                (unless minibuffer-p (message "Completed")))
834              (insert suffix)
835              'sole))
836           (t                            ; There's no unique completion.
837            (let ((completion  (try-completion stub candidates)))
838              ;; Insert the longest substring.
839              (insert (substring completion (length stub)))
840              (cond ((and comint-completion-recexact comint-completion-addsuffix
841                          (string-equal stub completion)
842                          (member completion completions))
843                     (insert suffix)     ; User wants shortest match.
844                     (unless minibuffer-p (message "Completed shortest"))
845                     'shortest)
846                    ((or comint-completion-autolist (string-equal stub completion))
847                     (icicle-condition-case-no-debug nil ;  Let user choose a completion.
848                         (let* ((icicle-show-Completions-initially-flag      t)
849                                (icicle-incremental-completion-p             'display)
850                                (icicle-top-level-when-sole-completion-flag  t)
851                                (choice (save-excursion
852                                          (completing-read "Complete: " (mapcar #'list completions)
853                                                           nil t nil nil completion))))
854                           (when choice
855                             (delete-backward-char (length completion))
856                             (insert choice suffix)))
857                       (error nil))
858                     'listed)
859                    (t
860                     (unless minibuffer-p (message "Partially completed"))
861                     'partial)))))))
862
863 ;;;###autoload
864 (defun icicle-shell-dynamic-complete-filename ()
865   "Dynamically complete the filename at point.
866 Completes only if point is at a suitable position for a filename
867 argument."
868   (interactive)
869   (let ((opoint  (point))
870         (beg     (comint-line-beginning-position)))
871     (when (save-excursion
872             (goto-char (if (re-search-backward "[;|&]" beg t) (match-end 0) beg))
873             (re-search-forward "[^ \t][ \t]" opoint t))
874       (icicle-comint-dynamic-complete-as-filename))))
875
876 ;;;###autoload
877 (defun icicle-shell-dynamic-complete-environment-variable ()
878   "`shell-dynamic-complete-environment-variable' but uses Icicles completion."
879   (interactive)
880   (require 'shell)
881   (let ((variable  (shell-match-partial-variable)))
882     (if (and variable (string-match "^\\$" variable))
883         (prog2 (unless (window-minibuffer-p (selected-window))
884                  (message "Completing variable name..."))
885             (icicle-shell-dynamic-complete-as-environment-variable)))))
886
887 (defun icicle-shell-dynamic-complete-as-environment-variable ()
888   "`shell-dynamic-complete-as-environment-variable' but uses Icicles completion."
889   (require 'shell)
890   (let* ((var                          (or (shell-match-partial-variable) ""))
891          (variable                     (substring var (or (string-match "[^$({]\\|$" var) 0)))
892          (variables                    (mapcar #'(lambda (x) (substring x 0 (string-match "=" x)))
893                                                process-environment))
894          (addsuffix                    comint-completion-addsuffix)
895          (comint-completion-addsuffix  nil)
896          (success                      (icicle-comint-dynamic-simple-complete variable variables)))
897     (if (memq success '(sole shortest))
898         (let* ((var           (shell-match-partial-variable))
899                (variable      (substring var (string-match "[^$({]" var)))
900                (protection    (cond ((string-match "{" var) "}")
901                                     ((string-match "(" var) ")")
902                                     (t "")))
903                (suffix        (cond ((null addsuffix) "")
904                                     ((file-directory-p
905                                       (comint-directory (getenv variable))) "/")
906                                     (t " "))))
907           (insert protection  suffix)))
908     success))
909
910 ;;;###autoload
911 (defun icicle-ess-complete-object-name (&optional listcomp)
912   "`ess-complete-object-name', but uses Icicles completion.
913 Complete `ess-language' object preceding point.
914 This is `icicle-ess-R-complete-object-name' if `ess-use-R-completion',
915 and `icicle-ess-internal-complete-object-name' otherwise."
916   (interactive "P")
917   (if ess-use-R-completion
918       (icicle-ess-R-complete-object-name)
919     (icicle-ess-internal-complete-object-name listcomp)))
920
921 ;;;###autoload
922 (defun icicle-ess-internal-complete-object-name (&optional listcomp)
923   "`ess-internal-complete-object-name', but uses Icicles completion.
924 Complete `ess-language' object preceding point."
925   (interactive "P")
926   (ess-make-buffer-current)
927   (if (memq (char-syntax (preceding-char)) '(?w ?_))
928       (let* ((comint-completion-addsuffix  nil)
929              (end                          (point))
930              (buffer-syntax                (syntax-table))
931              (beg                          (unwind-protect
932                                                 (save-excursion
933                                                   (set-syntax-table ess-mode-syntax-table)
934                                                   (backward-sexp 1)
935                                                   (point))
936                                              (set-syntax-table buffer-syntax)))
937              (full-prefix                  (buffer-substring beg end))
938              (pattern                      full-prefix)
939              (listname                  ; See if we're indexing a list with `$'
940               (and (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$" full-prefix)
941                    (setq pattern  (if (not (match-beginning 2))
942                                       ""
943                                     (substring full-prefix (match-beginning 2) (match-end 2))))
944                    (substring full-prefix (match-beginning 1) (match-end 1))))
945              (classname                 ; Are we trying to get a slot via `@' ?
946               (and (string-match "\\(.+\\)@\\(\\(\\sw\\|\\s_\\)*\\)$" full-prefix)
947                    (setq pattern  (if (not (match-beginning 2))
948                                       ""
949                                     (substring full-prefix (match-beginning 2) (match-end 2))))
950                    (progn (ess-write-to-dribble-buffer (format "(ess-C-O-Name : slots..) : patt=%s"
951                                                                pattern))
952                           (substring full-prefix (match-beginning 1) (match-end 1)))))
953              (components
954               (if listname
955                   (ess-object-names listname)
956                 (if classname
957                     (ess-slot-names classname)
958                   ;; Default case: It hangs here when options (error=recoves):
959                   (ess-get-object-list ess-current-process-name)))))
960         ;; Return non-nil to prevent history expansions
961         (or (icicle-comint-dynamic-simple-complete  pattern components) 'none))))
962
963 (defun icicle-ess-complete-filename ()
964   "`ess-complete-filename', but uses Icicles completion.
965 Do file completion only within strings, or when `!' call is used."
966   (if (comint-within-quotes
967        (1- (process-mark (get-buffer-process (current-buffer)))) (point))
968       (progn (if (featurep 'xemacs)
969                  (icicle-comint-dynamic-complete-filename) ; Work around XEmacs bug.  GNU Emacs and
970                (icicle-comint-replace-by-expanded-filename)) ; a working XEmacs return t in a string
971              t)))
972
973 ;;;###autoload
974 (defun icicle-ess-R-complete-object-name ()
975   "`ess-R-complete-object-name', but uses Icicles completion.
976 Completion in R."
977   (interactive)
978   (ess-make-buffer-current)
979   (let* ((comint-completion-addsuffix  nil)
980          (beg-of-line                  (save-excursion (comint-bol nil) (point)))
981          (end-of-line                  (point-at-eol))
982          (line-buffer                  (buffer-substring beg-of-line end-of-line))
983          (NS                           (if (ess-current-R-at-least '2.7.0)
984                                            "utils:::"
985                                          "rcompgen:::"))
986          (token-string                  ; Setup, including computation of the token
987           (progn
988             (ess-command (format (concat NS ".assignLinebuffer('%s')\n") line-buffer))
989             (ess-command (format (concat NS ".assignEnd(%d)\n") (- (point) beg-of-line)))
990             (car (ess-get-words-from-vector (concat NS ".guessTokenFromLine()\n")))))
991          (possible-completions          ; Compute and retrieve possible completions
992           (progn
993             (ess-command (concat NS ".completeToken()\n"))
994             (ess-get-words-from-vector (concat NS ".retrieveCompletions()\n")))))
995     (or (icicle-comint-dynamic-simple-complete token-string possible-completions) 'none)))
996
997 ;;;###autoload
998 (defun icicle-gud-gdb-complete-command (&optional command a b)
999   "`gud-gdb-complete-command', but uses Icicles completion.
1000 Perform completion on the GDB command preceding point."
1001   (interactive)
1002   (if command
1003       (setq command  (concat "p " command)) ; Used by gud-watch in mini-buffer.
1004     (let ((end  (point)))               ; Used in GUD buffer.
1005       (setq command  (buffer-substring (comint-line-beginning-position) end))))
1006   (let* ((command-word
1007           ;; Find the word break.  This match will always succeed.
1008           (and (string-match "\\(\\`\\| \\)\\([^ ]*\\)\\'" command)
1009                (substring command (match-beginning 2))))
1010          (complete-list
1011           (gud-gdb-run-command-fetch-lines (concat "complete " command)
1012                                            (current-buffer)
1013                                            ;; From string-match above.
1014                                            (match-beginning 2))))
1015     ;; Protect against old versions of GDB.
1016     (and complete-list
1017          (string-match "^Undefined command: \"complete\"" (car complete-list))
1018          (error "This version of GDB doesn't support the `complete' command"))
1019     ;; Sort the list like readline.
1020     (setq complete-list  (sort complete-list (function string-lessp)))
1021     ;; Remove duplicates.
1022     (let ((first   complete-list)
1023           (second  (cdr complete-list)))
1024       (while second
1025         (if (string-equal (car first) (car second))
1026             (setcdr first (setq second  (cdr second)))
1027           (setq first   second
1028                 second  (cdr second)))))
1029     ;; Add a trailing single quote if there is a unique completion
1030     ;; and it contains an odd number of unquoted single quotes.
1031     (and (= (length complete-list) 1)
1032          (let ((str    (car complete-list))
1033                (pos    0)
1034                (count  0))
1035            (while (string-match "\\([^'\\]\\|\\\\'\\)*'" str pos)
1036              (setq count  (1+ count)
1037                    pos    (match-end 0)))
1038            (and (= (mod count 2) 1)
1039                 (setq complete-list  (list (concat str "'"))))))
1040     ;; Let comint handle the rest.
1041     (icicle-comint-dynamic-simple-complete command-word complete-list)))
1042
1043
1044 ;; REPLACE ORIGINAL `dabbrev-completion' defined in `dabbrev.el',
1045 ;; saving it for restoration when you toggle `icicle-mode'.
1046 ;;
1047 ;; You can complete from an empty abbrev also.
1048 ;; Uses Icicles completion when there are multiple candidates.
1049 ;;
1050 (when (and (fboundp 'dabbrev-completion) (not (fboundp 'old-dabbrev-completion)))
1051   (defalias 'old-dabbrev-completion (symbol-function 'dabbrev-completion)))
1052
1053 ;;;###autoload
1054 (defun icicle-dabbrev-completion (&optional arg) ; Bound to `C-M-/' globally.
1055   "Completion on current word.
1056 Like \\[dabbrev-expand], but finds all expansions in the current buffer
1057 and presents suggestions for completion.
1058
1059 With a prefix argument, it searches all buffers accepted by
1060 `dabbrev-friend-buffer-function', to find the completions.
1061
1062 If the prefix argument is 16 (which comes from `C-u C-u'), then it
1063 searches *ALL* buffers.
1064
1065 With no prefix argument, it reuses an old completion list
1066 if there is a suitable one already."
1067   (interactive "*P")
1068   (unless (featurep 'dabbrev)
1069     (unless (require 'dabbrev nil t) (error "Library `dabbrev' not found"))
1070     (icicle-mode 1))                    ; Redefine `dabbrev-completion' to Icicles version.
1071   (dabbrev--reset-global-variables)
1072   (let* ((dabbrev-check-other-buffers  (and arg t)) ; Must be t
1073          (dabbrev-check-all-buffers    (and arg (= (prefix-numeric-value arg) 16)))
1074          (abbrev                       (icicle-dabbrev--abbrev-at-point))
1075          (ignore-case-p                (and (if (eq dabbrev-case-fold-search 'case-fold-search)
1076                                                 case-fold-search
1077                                               dabbrev-case-fold-search)
1078                                             (or (not dabbrev-upcase-means-case-search)
1079                                                 (string= abbrev (downcase abbrev)))))
1080          (my-obarray                   dabbrev--last-obarray)
1081          init)
1082     ;; If new abbreviation to expand, then expand it.
1083     (save-excursion
1084       (unless (and (null arg)
1085                    my-obarray
1086                    (or (eq dabbrev--last-completion-buffer (current-buffer))
1087                        (and (window-minibuffer-p (selected-window))
1088                             (eq dabbrev--last-completion-buffer (dabbrev--minibuffer-origin))))
1089                    dabbrev--last-abbreviation
1090                    (>= (length abbrev) (length dabbrev--last-abbreviation))
1091                    (string= dabbrev--last-abbreviation
1092                             (substring abbrev 0 (length dabbrev--last-abbreviation)))
1093                    (setq init  (try-completion abbrev my-obarray)))
1094         (setq dabbrev--last-abbreviation  abbrev)
1095         (let ((completion-list         (dabbrev--find-all-expansions abbrev ignore-case-p))
1096               (completion-ignore-case  ignore-case-p))
1097           ;; Make an obarray with all expansions
1098           (setq my-obarray  (make-vector (length completion-list) 0))
1099           (unless (> (length my-obarray) 0)
1100             (error "No dynamic expansion for \"%s\" found%s" abbrev
1101                    (if dabbrev--check-other-buffers "" " in this-buffer")))
1102           (dolist (string  completion-list)
1103             (cond ((or (not ignore-case-p) (not dabbrev-case-replace))
1104                    (intern string my-obarray))
1105                   ((string= abbrev (icicle-upcase abbrev))
1106                    (intern (icicle-upcase string) my-obarray))
1107                   ((string= (substring abbrev 0 1) (icicle-upcase (substring abbrev 0 1)))
1108                    (intern (capitalize string) my-obarray))
1109                   (t (intern (downcase string) my-obarray))))
1110           (setq dabbrev--last-obarray            my-obarray
1111                 dabbrev--last-completion-buffer  (current-buffer)
1112                 ;; Find the expanded common string.
1113                 init                             (try-completion abbrev my-obarray)))))
1114     ;; Let the user choose between the expansions
1115     (unless (stringp init) (setq init  abbrev))
1116     (cond
1117       ((and (not (string-equal init ""))
1118             (not (string-equal (downcase init) (downcase abbrev)))
1119             (<= (length (all-completions init my-obarray)) 1))
1120        (message "Completed (no other completions)")
1121        (if (< emacs-major-version 21)
1122            (dabbrev--substitute-expansion nil abbrev init)
1123          (dabbrev--substitute-expansion nil abbrev init nil))
1124        (when (window-minibuffer-p (selected-window)) (message nil)))
1125 ;;$$       ;; Complete text only up through the common root. NOT USED.
1126 ;;       ((and icicle-dabbrev-stop-at-common-root-p
1127 ;;             (not (string-equal init ""))
1128 ;;             (not (string-equal (downcase init) (downcase abbrev))))
1129 ;;        (message "Use `%s' again to complete further"
1130 ;;                 (icicle-key-description (this-command-keys)
1131 ;;                                         (not icicle-key-descriptions-use-<>-flag)))
1132 ;;        (if (< emacs-major-version 21)
1133 ;;            (dabbrev--substitute-expansion nil abbrev init)
1134 ;;          (dabbrev--substitute-expansion nil abbrev init nil))
1135 ;;        (when (window-minibuffer-p (selected-window)) (message nil))) ; $$ NEEDED?
1136       (t
1137        ;; String is a common root already.  Use Icicles completion.
1138        (icicle-highlight-lighter)
1139        (message "Making completion list...")
1140        (search-backward abbrev)
1141        (replace-match "")
1142        (condition-case nil
1143            (let* ((icicle-show-Completions-initially-flag  t)
1144                   (icicle-incremental-completion-p         'display)
1145                   (minibuffer-completion-table             my-obarray)
1146                   (choice
1147                    (completing-read "Complete: " my-obarray nil nil init nil init)))
1148              (when choice (insert choice)))
1149          (quit (insert abbrev)))))))
1150
1151 (defun icicle-dabbrev--abbrev-at-point ()
1152   "Like `dabbrev--abbrev-at-point', but returns \"\" if there is no match.
1153 Vanilla `dabbrev--abbrev-at-point' raises an error if no match."
1154   (let ((abv ""))
1155     (setq dabbrev--last-abbrev-location  (point)) ; Record the end of the abbreviation.
1156     (unless (bobp)
1157       (save-excursion                   ; Return abbrev at point
1158         ;; If we aren't right after an abbreviation, move point back to just after one.
1159         ;; This is so the user can get successive words by typing the punctuation followed by M-/.
1160         (save-match-data
1161           (when (and (save-excursion
1162                        (forward-char -1)
1163                        (not (looking-at
1164                              (concat "\\(" (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") "\\)+"))))
1165                      (re-search-backward (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") nil t))
1166             (forward-char 1)))
1167         (dabbrev--goto-start-of-abbrev) ; Now find the beginning of that one.
1168         (setq abv  (buffer-substring-no-properties dabbrev--last-abbrev-location (point)))))
1169     abv))
1170
1171
1172 ;; REPLACE ORIGINAL `bbdb-complete-name' defined in `bbdb-com.el',
1173 ;; saving it for restoration when you toggle `icicle-mode'.
1174 ;; Note: BBDB, the Insidious Big Brother Database, is available here:
1175 ;;       http://bbdb.sourceforge.net/.
1176 ;;
1177 ;; Uses Icicles completion when there are multiple candidates.
1178 ;;
1179 ;; Free vars here: `bbdb-*' are bound in `bbdb-com.el'.
1180 ;;;###autoload
1181 (defun icicle-bbdb-complete-name (&optional start-pos)
1182   "Complete the user full-name or net-address before point.
1183 Completes only up to the preceding newline, colon, or comma, or the
1184 value of START-POS.
1185
1186 If what has been typed is unique, insert an entry of the form \"User
1187 Name <net-addr>\" (but see `bbdb-dwim-net-address-allow-redundancy').
1188 If it is a valid completion but not unique, you can choose from the
1189 list of completions using Icicles completion.
1190
1191 If your input is completed and `bbdb-complete-name-allow-cycling' is
1192 true, then you can repeat to cycle through the nets for the matching
1193 record.
1194
1195 When called with a prefix arg, display a list of all nets.  You can
1196 control completion behaviour using `bbdb-completion-type'."
1197   (interactive)
1198   (unless (and (require 'bbdb nil t) (require 'bbdb-com nil t))
1199     (error "`icicle-bbdb-complete-name' requires BBDB"))
1200   (let* ((end                  (point))
1201          (beg                  (or start-pos (save-excursion (re-search-backward
1202                                                               "\\(\\`\\|[\n:,]\\)[ \t]*")
1203                                                              (goto-char (match-end 0)) (point))))
1204          (orig                 (buffer-substring beg end))
1205          (typed                (downcase orig))
1206          (pattern              (bbdb-string-trim typed))
1207          ;; DADAMS -
1208          ;; Replaced `(bbdb-hashtable)' by its expansion (bbdb-with-db-buffer ... bbdb-hashtable),
1209          ;; to avoid the silly macro altogether and simplify user byte-compiling a little.
1210          (ht                   (bbdb-with-db-buffer (bbdb-records nil t) bbdb-hashtable))
1211          ;; Make a list of possible completion strings (all-the-completions), and a flag to
1212          ;; indicate if there's a single matching record or not (only-one-p).
1213          (only-one-p           t)
1214          (all-the-completions  ())
1215          (pred
1216           #'(lambda (sym)
1217               (and (bbdb-completion-predicate sym)
1218                    (progn
1219                      (when (and only-one-p all-the-completions
1220                                 (or
1221                                  ;; Not sure about this. More than one record attached to the symbol?
1222                                  ;; Does that happen?
1223                                  (> (length (symbol-value sym)) 1)
1224                                  ;; This is the doozy. Multiple syms which all match the same record.
1225                                  (delete t (mapcar #'(lambda (x)
1226                                                        (equal (symbol-value x) (symbol-value sym)))
1227                                                    all-the-completions))))
1228                        (setq only-one-p  nil))
1229                      (if (memq sym all-the-completions)
1230                          nil
1231                        (setq all-the-completions  (cons sym all-the-completions)))))))
1232          (completion           (progn (all-completions pattern ht pred)
1233                                       (try-completion pattern ht)))
1234          (exact-match          (eq completion t)))
1235     (cond
1236       ;; No matches found OR you're trying completion on an already-completed record.
1237       ;; In the latter case, we might have to cycle through the nets for that record.
1238       ((or (null completion)
1239            (and bbdb-complete-name-allow-cycling
1240                 exact-match             ; Which is a net of the record
1241                 (member orig (bbdb-record-net (car (symbol-value (intern-soft pattern ht)))))))
1242        (bbdb-complete-name-cleanup)     ; Clean up the completion buffer, if it exists
1243        (unless (catch 'bbdb-cycling-exit ; Check for cycling
1244                  ;; Jump straight out if we're not cycling
1245                  (unless bbdb-complete-name-allow-cycling (throw 'bbdb-cycling-exit nil))
1246                  ;; Find the record we're working on.
1247                  (let* ((addr  (funcall bbdb-extract-address-components-func orig))
1248                         (rec  (and (listp addr)
1249                                    ;; For now, we ignore the case where this returns more than
1250                                    ;; one record.  Ideally, the last expansion would be stored
1251                                    ;; in a buffer-local variable, perhaps.
1252                                    (car (bbdb-search-intertwingle (caar addr)
1253                                                                   (car (cdar addr)))))))
1254                    (unless rec (throw 'bbdb-cycling-exit nil))
1255                    (if current-prefix-arg
1256                        ;; Use completion buffer
1257                        (let ((standard-output  (get-buffer-create "*Completions*")))
1258                          ;; A previously existing buffer has to be cleaned first
1259                          (with-current-buffer standard-output
1260                            (setq buffer-read-only  nil)
1261                            (erase-buffer))
1262                          (display-completion-list
1263                           (mapcar #'(lambda (n) (bbdb-dwim-net-address rec n))
1264                                   (bbdb-record-net rec)))
1265                          (delete-region beg end)
1266                          (switch-to-buffer standard-output))
1267                      ;; Use next address
1268                      (let* ((addrs      (bbdb-record-net rec))
1269                             (this-addr  (or (cadr (member (car (cdar addr)) addrs))
1270                                             (nth 0 addrs))))
1271                        (if (= (length addrs) 1)
1272                            (throw 'bbdb-cycling-exit t) ; No alternatives. don't signal an error.
1273                          ;; Replace with new mail address
1274                          (delete-region beg end)
1275                          (insert (bbdb-dwim-net-address rec this-addr))
1276                          (run-hooks 'bbdb-complete-name-hooks)
1277                          (throw 'bbdb-cycling-exit t))))))
1278          ;; FALL THROUGH.  Check mail aliases
1279          (when (and (or (not bbdb-expand-mail-aliases) (not (expand-abbrev)))
1280                     bbdb-complete-name-hooks)
1281            (message "No completion for `%s'" pattern) (icicle-ding)))) ; no matches
1282
1283       ;; Match for a single record. If cycling is enabled then we don't
1284       ;; care too much about the exact-match part.
1285       ((and only-one-p (or exact-match bbdb-complete-name-allow-cycling))
1286        (let* ((sym   (if exact-match (intern-soft pattern ht) (car all-the-completions)))
1287               (recs  (symbol-value sym))
1288               the-net match-recs lst primary matched)
1289          (while recs
1290            (when (bbdb-record-net (car recs))
1291              ;; Did we match on name?
1292              (let ((b-r-name  (or (bbdb-record-name (car recs)) "")))
1293                (if (string= pattern (substring (downcase b-r-name) 0
1294                                                (min (length b-r-name) (length pattern))))
1295                    (setq match-recs  (cons (car recs) match-recs)
1296                          matched     t)))
1297              ;; Did we match on aka?
1298              (unless matched
1299                (setq lst  (bbdb-record-aka (car recs)))
1300                (while lst
1301                  (if (string= pattern (substring (downcase (car lst)) 0
1302                                                  (min (length (downcase (car lst)))
1303                                                       (length pattern))))
1304                      (setq match-recs  (append match-recs (list (car recs)))
1305                            matched     t
1306                            lst         ())
1307                    (setq lst  (cdr lst)))))
1308              ;; Name didn't match name so check net matching
1309              (unless matched
1310                (setq lst      (bbdb-record-net (car recs))
1311                      primary  t)        ; primary wins over secondary...
1312                (while lst
1313                  (if (string= pattern (substring (downcase (car lst)) 0
1314                                                  (min (length (downcase (car lst)))
1315                                                       (length pattern))))
1316                      (setq the-net     (car lst)
1317                            lst         ()
1318                            match-recs  (if primary
1319                                            (cons (car recs) match-recs)
1320                                          (append match-recs (list (car recs))))))
1321                  (setq lst      (cdr lst)
1322                        primary  nil))))
1323            (setq recs     (cdr recs)    ; Next rec for loop.
1324                  matched  nil))
1325          (unless match-recs (error "Only exact matching record has net field"))
1326          ;; Replace the text with the expansion
1327          (delete-region beg end)
1328          (insert (bbdb-dwim-net-address (car match-recs) the-net))
1329          ;; If we're past fill-column, wrap at the previous comma.
1330          (when (and (bbdb-auto-fill-function) (>= (current-column) fill-column))
1331            (let ((p  (point))
1332                  bol)
1333              (save-excursion
1334                (beginning-of-line)
1335                (setq bol  (point))
1336                (goto-char p)
1337                (when (search-backward "," bol t) (forward-char 1) (insert "\n   ")))))
1338          ;; Update the *BBDB* buffer if desired.
1339          (when bbdb-completion-display-record
1340            (let ((bbdb-gag-messages  t))
1341              (bbdb-pop-up-bbdb-buffer)
1342              (bbdb-display-records-1 match-recs t)))
1343          (bbdb-complete-name-cleanup)
1344          ;; Call the exact-completion hook
1345          (run-hooks 'bbdb-complete-name-hooks)))
1346
1347       ;; Partial match.  Note: we can't use the trimmed version of the pattern here or
1348       ;; we'll recurse infinitely on e.g. common first names.
1349       ((and (stringp completion) (not (string= typed completion)))
1350        (delete-region beg end)
1351        (insert completion)
1352        (setq end  (point))
1353        (let ((last                              "")
1354              (bbdb-complete-name-allow-cycling  nil))
1355          (while (and (stringp completion) (not (string= completion last))
1356                      (setq last        completion
1357                            pattern     (downcase orig)
1358                            completion  (progn (all-completions pattern ht pred)
1359                                               (try-completion pattern ht))))
1360            (when (stringp completion) (delete-region beg end) (insert completion)))
1361          (bbdb-complete-name beg)))     ; RECURSE <================
1362
1363       ;; Exact match, but more than one record
1364       (t
1365        (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
1366        (let (dwim-completions uniq nets net name akas)
1367          ;; Collect all the dwim-addresses for each completion, but only once for each record.
1368          ;; Add if the net is part of the completions.
1369          (bbdb-mapc #'(lambda (sym)
1370                         (bbdb-mapc
1371                          #'(lambda (rec)
1372                              (unless (member rec uniq)
1373                                (setq uniq  (cons rec uniq)
1374                                      nets  (bbdb-record-net rec)
1375                                      name  (downcase (or (bbdb-record-name rec) ""))
1376                                      akas  (mapcar 'downcase (bbdb-record-aka rec)))
1377                                (while nets
1378                                  (setq net  (car nets))
1379                                  (when (cond
1380                                          ((and (member bbdb-completion-type ; Primary
1381                                                        '(primary primary-or-name))
1382                                                (member (intern-soft (downcase net) ht)
1383                                                        all-the-completions))
1384                                           (setq nets  ())
1385                                           t)
1386                                          ((and name (member bbdb-completion-type ; Name
1387                                                             '(nil name primary-or-name))
1388                                                (let ((cname  (symbol-name sym)))
1389                                                  (or (string= cname name)
1390                                                      (member cname akas))))
1391                                           (setq name  nil)
1392                                           t)
1393                                          ((and (member bbdb-completion-type '(nil net)) ; Net
1394                                                (member (intern-soft (downcase net) ht)
1395                                                        all-the-completions)))
1396                                          ;; (name-or-)primary
1397                                          ((and (member bbdb-completion-type
1398                                                        '(name-or-primary))
1399                                                (let ((cname  (symbol-name sym)))
1400                                                  (or (string= cname name)
1401                                                      (member cname akas))))
1402                                           (setq nets  ())
1403                                           t))
1404                                    (setq dwim-completions
1405                                          (cons (bbdb-dwim-net-address rec net)
1406                                                dwim-completions))
1407                                    (when exact-match (setq nets  ())))
1408                                  (setq nets  (cdr nets)))))
1409                          (symbol-value sym)))
1410                     all-the-completions)
1411          (cond ((and dwim-completions (null (cdr dwim-completions))) ; Insert the unique match.
1412                 (delete-region beg end) (insert (car dwim-completions)) (message ""))
1413                (t                       ; More than one match.  Use Icicles minibuffer completion.
1414                 (icicle-condition-case-no-debug nil
1415                     (let* ((icicle-show-Completions-initially-flag      t)
1416                            (icicle-incremental-completion-p             'display)
1417                            (icicle-top-level-when-sole-completion-flag  t)
1418                            (completion-ignore-case                      t)
1419                            (choice
1420                             (save-excursion
1421                               (completing-read "Complete: " (mapcar #'list dwim-completions)
1422                                                nil t pattern nil pattern))))
1423                       (when choice
1424                         (delete-region beg end)
1425                         (insert choice)))
1426                   (error nil))
1427                 (unless (eq (selected-window) (minibuffer-window))
1428                   (message "Making completion list...done")))))))))
1429
1430
1431 ;; REPLACE ORIGINAL `lisp-complete-symbol' (< Emacs 23.2),
1432 ;; defined in `lisp.el', saving it for restoration when you toggle `icicle-mode'.
1433 ;;
1434 ;; Select `*Completions*' window even if on another frame.
1435 ;;
1436 (unless (fboundp 'old-lisp-complete-symbol)
1437   (defalias 'old-lisp-complete-symbol (symbol-function 'lisp-complete-symbol)))
1438
1439 ;;;###autoload
1440 (defun icicle-lisp-complete-symbol (&optional predicate) ; `M-TAB' (`C-M-i', `ESC-TAB'), globally.
1441   "Complete the Lisp symbol preceding point against known Lisp symbols.
1442 If there is more than one completion, use the minibuffer to complete.
1443
1444 When called from a program, optional arg PREDICATE is a predicate
1445 determining which symbols are considered, e.g. `commandp'.
1446
1447 If PREDICATE is nil, the context determines which symbols are
1448 considered.  If the symbol starts just after an open-parenthesis, only
1449 symbols with function definitions are considered.  Otherwise, all
1450 symbols with function definitions, values or properties are
1451 considered."
1452   (interactive)
1453   (let* ((end            (point))
1454          (buffer-syntax  (syntax-table))
1455          (beg            (unwind-protect
1456                               (save-excursion
1457                                 (set-syntax-table emacs-lisp-mode-syntax-table)
1458                                 (backward-sexp 1)
1459                                 (while (= (char-syntax (following-char)) ?\') (forward-char 1))
1460                                 (point))
1461                            (set-syntax-table buffer-syntax)))
1462          (pattern       (buffer-substring beg end))
1463          (new           (try-completion pattern obarray)))
1464     (unless (stringp new) (setq new  pattern))
1465     (delete-region beg end)
1466     (insert new)
1467     (setq end  (+ beg (length new)))
1468     (if (and (not (string= new "")) (not (string= (downcase new) (downcase pattern)))
1469              (< (length (all-completions new obarray)) 2))
1470         (message "Completed (no other completions)")
1471       ;; Use minibuffer to choose a completion.
1472       (let* ((enable-recursive-minibuffers                (active-minibuffer-window))
1473              (icicle-top-level-when-sole-completion-flag  t)
1474              (icicle-orig-window                          (selected-window)) ; For alt actions.
1475              (alt-fn                                      nil)
1476              (icicle-show-Completions-initially-flag      t)
1477              (icicle-candidate-alt-action-fn
1478               (or icicle-candidate-alt-action-fn
1479                   (setq alt-fn  (icicle-alt-act-fn-for-type "symbol"))))
1480              (icicle-all-candidates-list-alt-action-fn ; M-|'
1481               (or icicle-all-candidates-list-alt-action-fn alt-fn
1482                   (icicle-alt-act-fn-for-type "symbol")))
1483              (predicate
1484               (or predicate
1485                   (save-excursion
1486                     (goto-char beg)
1487                     (if (not (eq (char-before) ?\( ))
1488                         #'(lambda (sym) ;why not just nil ?   -sm
1489                             (or (boundp sym) (fboundp sym) (symbol-plist sym)))
1490                       ;; If first element of parent list is not an open paren, assume that this is a
1491                       ;; funcall position: use `fboundp'.  If not, then maybe this is a variable in
1492                       ;; a `let' binding, so no predicate: use nil.
1493                       (and (not (condition-case nil
1494                                     (progn (up-list -2) (forward-char 1) (eq (char-after) ?\( ))
1495                                   (error nil)))
1496                            'fboundp))))))
1497         ;; $$$$$ Could bind `icicle-must-pass-after-match-predicate' to a predicate on interned
1498         ;;       candidate and pass nil as PRED to `completing-read'.  Don't bother for now.
1499         (setq new  (save-excursion (completing-read "Complete Lisp symbol: "
1500                                                     obarray predicate t new)))))
1501     (delete-region beg end)
1502     (insert new)))
1503
1504
1505 ;; REPLACE ORIGINAL `lisp-completion-at-point' (>= Emacs 23.2),
1506 ;; defined in `lisp.el', saving it for restoration when you toggle `icicle-mode'.
1507 ;;
1508 ;; Select `*Completions*' window even if on another frame.
1509 ;;
1510 (when (fboundp 'completion-at-point)    ; Emacs 23.2+.
1511   (unless (fboundp 'old-lisp-completion-at-point)
1512     (defalias 'old-lisp-completion-at-point (symbol-function 'lisp-completion-at-point))
1513     ;; Return a function that does all of the completion.
1514     (defun icicle-lisp-completion-at-point () #'icicle-lisp-complete-symbol)))
1515
1516 ;;;###autoload
1517 (defun icicle-customize-icicles-group ()
1518   "Customize Icicles options and faces.  View their documentation."
1519   (interactive)
1520   (customize-group-other-window 'Icicles))
1521
1522 ;;;###autoload
1523 (defun icicle-send-bug-report ()
1524   "Send a bug report about an Icicles problem."
1525   (interactive)
1526   (browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
1527 Icicles bug: \
1528 &body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'.  \
1529 Each Icicles file has a header `Update #' that you can use to identify it.\
1530 %%0A%%0AEmacs version: %s.")
1531                       (emacs-version))))
1532
1533
1534 ;; REPLACE ORIGINAL `customize-face' defined in `cus-edit.el',
1535 ;; saving it for restoration when you toggle `icicle-mode'.
1536 ;;
1537 ;; Multi-command version.
1538 ;;
1539 (unless (fboundp 'old-customize-face)
1540   (defalias 'old-customize-face (symbol-function 'customize-face)))
1541
1542 ;;;###autoload
1543 (defun icicle-customize-face (face)
1544   "Customize face FACE.
1545 Input-candidate completion and cycling are available.  While cycling,
1546 these keys with prefix `C-' are active:
1547
1548 `C-mouse-2', `C-RET' - Act on current completion candidate only
1549 `C-down'  - Move to next completion candidate and act
1550 `C-up'    - Move to previous completion candidate and act
1551 `C-next'  - Move to next apropos-completion candidate and act
1552 `C-prior' - Move to previous apropos-completion candidate and act
1553 `C-end'   - Move to next prefix-completion candidate and act
1554 `C-home'  - Move to previous prefix-completion candidate and act
1555 `M-!'     - Act on *all* candidates (or all that are saved):
1556             Customize all in the same buffer.
1557 `C-!'     - Act on *all* candidates (or all that are saved):
1558             Customize each in a separate buffer.
1559
1560 When candidate action and cycling are combined (e.g. `C-next'), option
1561 `icicle-act-before-cycle-flag' determines which occurs first.
1562
1563 With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
1564 `C-M-RET', `C-M-down', and so on) provide help about candidates.
1565
1566 Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
1567 or `C-g' to quit.
1568
1569 With a prefix argument, you can enter multiple faces at the same time
1570 with `RET' (in Emacs 22 or later).  This gives you the completion
1571 behavior of `customize-face' in vanilla Emacs.  The advantage is that
1572 the default value is the list of all faces under the cursor.  The
1573 disadvantage is that face candidates are not WYSIWYG in buffer
1574 `*Completions*'.
1575
1576 This is an Icicles command - see command `icicle-mode'."
1577   (interactive
1578    (list (let* ((icicle-list-use-nth-parts             '(1))
1579                 (icicle-candidate-action-fn
1580                  #'(lambda (x)
1581                      (old-customize-face (intern (icicle-transform-multi-completion x)))
1582                      (select-window (minibuffer-window))
1583                      (select-frame-set-input-focus (selected-frame))))
1584                 (icicle-all-candidates-list-action-fn  'icicle-customize-faces)
1585                 (icicle-orig-window                    (selected-window)) ; For alt actions.
1586                 (alt-fn                                nil)
1587                 (icicle-candidate-alt-action-fn
1588                  (or icicle-candidate-alt-action-fn
1589                      (setq alt-fn  (icicle-alt-act-fn-for-type "face"))))
1590                 (icicle-all-candidates-list-alt-action-fn ; M-|'
1591                  (or icicle-all-candidates-list-alt-action-fn
1592                      alt-fn (icicle-alt-act-fn-for-type "face"))))
1593            (if (and (> emacs-major-version 21) current-prefix-arg)
1594                (read-face-name "Customize face: " "all faces" t)
1595              (read-face-name "Customize face: ")))))
1596   (old-customize-face face))
1597
1598
1599 ;; REPLACE ORIGINAL `customize-face-other-window' defined in `cus-edit.el',
1600 ;; saving it for restoration when you toggle `icicle-mode'.
1601 ;;
1602 ;; Multi-command version.
1603 ;;
1604 (unless (fboundp 'old-customize-face-other-window)
1605   (defalias 'old-customize-face-other-window (symbol-function 'customize-face-other-window)))
1606
1607 ;;;###autoload
1608 (defun icicle-customize-face-other-window (face)
1609   "Customize face FACE in another window.
1610 Same as `icicle-customize-face' except it uses a different window."
1611   (interactive
1612    (list (let* ((icicle-list-use-nth-parts             '(1))
1613                 (icicle-candidate-action-fn
1614                  #'(lambda (x)
1615                      (old-customize-face-other-window (intern (icicle-transform-multi-completion x)))
1616                      (select-window (minibuffer-window))
1617                      (select-frame-set-input-focus (selected-frame))))
1618                 (icicle-all-candidates-list-action-fn  'icicle-customize-faces)
1619                 (icicle-orig-window                    (selected-window)) ; For alt actions.
1620                 (alt-fn                                nil)
1621                 (icicle-candidate-alt-action-fn
1622                  (or icicle-candidate-alt-action-fn
1623                      (setq alt-fn  (icicle-alt-act-fn-for-type "face"))))
1624                 (icicle-all-candidates-list-alt-action-fn ; M-|'
1625                  (or icicle-all-candidates-list-alt-action-fn
1626                      alt-fn (icicle-alt-act-fn-for-type "face"))))
1627            (if (and (> emacs-major-version 21) current-prefix-arg)
1628                (read-face-name "Customize face: " "all faces" t)
1629              (read-face-name "Customize face: ")))))
1630   (old-customize-face-other-window face))
1631
1632 (defun icicle-customize-faces (faces)
1633   "Open Customize buffer on all faces in list FACES."
1634   (let ((icicle-list-nth-parts-join-string  ": ")
1635         (icicle-list-join-string            ": ")
1636         ;; $$$$$$ (icicle-list-end-string             "")
1637         (icicle-list-use-nth-parts          '(1)))
1638     (custom-buffer-create
1639      (custom-sort-items
1640       (mapcar #'(lambda (f) (list (intern (icicle-transform-multi-completion f)) 'custom-face))
1641               faces)
1642       t custom-buffer-order-groups)
1643      "*Customize Apropos*")))
1644
1645
1646 ;; REPLACE ORIGINAL `customize-apropos' defined in `cus-edit.el',
1647 ;; saving it for restoration when you toggle `icicle-mode'.
1648 ;;
1649 ;; Uses `completing-read' to read the regexp.
1650 ;;
1651 (unless (fboundp 'old-customize-apropos)
1652   (defalias 'old-customize-apropos (symbol-function 'customize-apropos)))
1653
1654 ;;;###autoload
1655 (defun icicle-customize-apropos (regexp &optional all)
1656   "Customize all user options matching REGEXP.
1657 If ALL is `options', include only options.
1658 If ALL is `faces', include only faces.
1659 If ALL is `groups', include only groups.
1660 If ALL is t (interactively, with prefix arg), include options which
1661   are not user-settable, as well as faces and groups.
1662
1663 Use `S-TAB', [next], and [prior], to match regexp input - this lets
1664 you see what items will be available in the customize buffer."
1665   (interactive
1666    (let* ((pref-arg  current-prefix-arg)
1667           (icicle-must-pass-after-match-predicate
1668            #'(lambda (s)
1669                (setq s  (intern s))
1670                (or (get s 'custom-group)
1671                    (custom-facep s)
1672                    (and (boundp s) (or (get s 'saved-value)
1673                                        (custom-variable-p s)
1674                                        (if (null pref-arg)
1675                                            (user-variable-p s)
1676                                          (get s 'variable-documentation))))))))
1677      (list (completing-read "Customize (regexp): " obarray nil nil nil 'regexp-history)
1678            pref-arg)))
1679   (let ((found  nil))
1680     (mapatoms #'(lambda (symbol)
1681                   (when (string-match regexp (symbol-name symbol))
1682                     (when (and (not (memq all '(faces options))) ; groups or t
1683                                (get symbol 'custom-group))
1684                       (push (list symbol 'custom-group) found))
1685                     (when (and (not (memq all '(options groups))) ; faces or t
1686                                (custom-facep symbol))
1687                       (push (list symbol 'custom-face) found))
1688                     (when (and (not (memq all '(groups faces))) ; options or t
1689                                (boundp symbol)
1690                                (or (get symbol 'saved-value)
1691                                    (custom-variable-p symbol)
1692                                    (if (memq all '(nil options))
1693                                        (user-variable-p symbol)
1694                                      (get symbol 'variable-documentation))))
1695                       (push (list symbol 'custom-variable) found)))))
1696     (if (not found)
1697         (error "No matches")
1698       (custom-buffer-create (custom-sort-items found t custom-buffer-order-groups)
1699                             "*Customize Apropos*"))))
1700
1701 ;; Define this for Emacs 20 and 21
1702 (unless (fboundp 'custom-variable-p)
1703   (defun custom-variable-p (variable)
1704     "Return non-nil if VARIABLE is a custom variable."
1705     (or (get variable 'standard-value) (get variable 'custom-autoload))))
1706
1707
1708 ;; REPLACE ORIGINAL `customize-apropos-faces' defined in `cus-edit.el',
1709 ;; saving it for restoration when you toggle `icicle-mode'.
1710 ;;
1711 ;; Uses `completing-read' to read the regexp.
1712 ;;
1713 (unless (fboundp 'old-customize-apropos-faces)
1714   (defalias 'old-customize-apropos-faces (symbol-function 'customize-apropos-faces)))
1715
1716 ;;;###autoload
1717 (defun icicle-customize-apropos-faces (regexp)
1718   "Customize all user faces matching REGEXP.
1719 Use `S-TAB', [next], and [prior], to match regexp input - this lets
1720 you see what items will be available in the customize buffer."
1721   (interactive
1722    (let ((icicle-must-pass-after-match-predicate #'(lambda (s) (custom-facep (intern s)))))
1723      (list (completing-read "Customize faces (regexp): " obarray nil nil nil 'regexp-history))))
1724   (customize-apropos regexp 'faces))
1725
1726
1727 ;; REPLACE ORIGINAL `customize-apropos-groups' defined in `cus-edit.el',
1728 ;; saving it for restoration when you toggle `icicle-mode'.
1729 ;;
1730 ;; Uses `completing-read' to read the regexp.
1731 ;;
1732 (unless (fboundp 'old-customize-apropos-groups)
1733   (defalias 'old-customize-apropos-groups (symbol-function 'customize-apropos-groups)))
1734
1735 ;;;###autoload
1736 (defun icicle-customize-apropos-groups (regexp)
1737   "Customize all user groups matching REGEXP.
1738 Use `S-TAB', [next], and [prior], to match regexp input - this lets
1739 you see what items will be available in the customize buffer."
1740   (interactive
1741    (let ((icicle-must-pass-after-match-predicate  #'(lambda (s) (get (intern s) 'custom-group))))
1742      (list (completing-read "Customize groups (regexp): " obarray nil nil nil 'regexp-history))))
1743   (customize-apropos regexp 'groups))
1744
1745
1746 ;; REPLACE ORIGINAL `customize-apropos-options' defined in `cus-edit.el',
1747 ;; saving it for restoration when you toggle `icicle-mode'.
1748 ;;
1749 ;; Uses `completing-read' to read the regexp.
1750 ;;
1751 (unless (fboundp 'old-customize-apropos-options)
1752   (defalias 'old-customize-apropos-options (symbol-function 'customize-apropos-options)))
1753
1754 ;;;###autoload
1755 (defun icicle-customize-apropos-options (regexp &optional arg)
1756   "Customize all user options matching REGEXP.
1757 With prefix argument, include options which are not user-settable.
1758
1759 Use `S-TAB', [next], and [prior], to match regexp input - this lets
1760 you see what items will be available in the customize buffer."
1761   (interactive
1762    (let* ((pref-arg  current-prefix-arg)
1763           (icicle-must-pass-after-match-predicate
1764            #'(lambda (s)
1765                (setq s  (intern s))
1766                (and (boundp s) (or (get s 'saved-value)
1767                                    (custom-variable-p s)
1768                                    (if (null pref-arg)
1769                                        (user-variable-p s)
1770                                      (get s 'variable-documentation)))))))
1771      (list (completing-read "Customize options (regexp): " obarray nil nil nil 'regexp-history)
1772            pref-arg)))
1773   (customize-apropos regexp (or arg 'options)))
1774
1775
1776 ;; REPLACE ORIGINAL `customize-apropos-options-of-type' defined in `cus-edit+.el',
1777 ;; saving it for restoration when you toggle `icicle-mode'.
1778 ;;
1779 ;; Uses `completing-read' to read the regexp.
1780 ;;
1781 (when (and (fboundp 'customize-apropos-options-of-type)
1782            (not (fboundp 'old-customize-apropos-options-of-type)))
1783   (defalias 'old-customize-apropos-options-of-type
1784       (symbol-function 'customize-apropos-options-of-type)))
1785
1786 ;;;###autoload
1787 (defun icicle-customize-apropos-options-of-type (type regexp)
1788   "Customize all loaded customizable options of type TYPE that match REGEXP.
1789 With no prefix arg, each option is defined with `defcustom' type TYPE.
1790 With a prefix arg, either each option is defined with `defcustom' type
1791  TYPE or its current value is compatible with TYPE.
1792
1793 If TYPE is nil (the default value) then all `defcustom' variables are
1794 potential candidates.
1795
1796 Use `S-TAB', `next', and `prior', to match regexp input - this lets
1797 you see which options will be available in the customize buffer."
1798   (interactive
1799    (let ((typ       (car (condition-case err
1800                              (read-from-string
1801                               (let ((types ()))
1802                                 (mapatoms
1803                                  #'(lambda (cand)
1804                                      (when (custom-variable-p cand)
1805                                        (push (list (format "%s"
1806                                                            (format "%S" (get cand 'custom-type))))
1807                                              types))))
1808                                 (completing-read "Customize all options of type: "
1809                                                  (icicle-remove-duplicates types)
1810                                                  nil nil nil nil "nil")))
1811                            (end-of-file (error "No such custom type")))))
1812          (pref-arg  current-prefix-arg))
1813      (list typ  (let ((icicle-must-pass-after-match-predicate
1814                        #'(lambda (s)
1815                            (setq s  (intern s))
1816                            (and (boundp s)
1817                                 (or (not (fboundp 'indirect-variable)) (eq (indirect-variable s) s))
1818                                 (or (get s 'saved-value) (custom-variable-p s))
1819                                 (or (not typ) ; `typ' = nil means use all types.
1820                                     (if pref-arg
1821                                         (condition-case nil
1822                                             (icicle-var-is-of-type-p s (list typ))
1823                                           (error nil))
1824                                       (equal (get s 'custom-type) typ)))))))
1825                   (completing-read "Customize options matching (regexp): "
1826                                    obarray nil nil nil 'regexp-history)))))
1827   (custom-buffer-create (custom-sort-items
1828                          (mapcar #'(lambda (s) (list (intern s) 'custom-variable))
1829                                  icicle-completion-candidates)
1830                          t "*Customize Apropos*")))
1831
1832
1833 ;; REPLACE ORIGINAL `repeat-complex-command' defined in `simple.el',
1834 ;; saving it for restoration when you toggle `icicle-mode'.
1835 ;;
1836 ;; Uses `completing-read' to read the command to repeat, letting you use `S-TAB' and
1837 ;; `TAB' to see the history list and `C-,' to toggle sorting that display.
1838 ;;
1839 (unless (fboundp 'old-repeat-complex-command)
1840   (defalias 'old-repeat-complex-command (symbol-function 'repeat-complex-command)))
1841
1842 ;;;###autoload
1843 (defun icicle-repeat-complex-command (arg) ; Bound to `C-x ESC ESC', `C-x M-:' in Icicle mode.
1844   "Edit and re-evaluate the last complex command, or ARGth from last.
1845 A complex command is one that used the minibuffer.
1846 ARG is the prefix argument numeric value.
1847
1848 You can edit the past command you choose before executing it.  The
1849 Lisp form of the command is used.  If the command you enter differs
1850 from the previous complex command, then it is added to the front of
1851 the command history.
1852
1853 Icicles completion is available for choosing a past command.  You can
1854 still use the vanilla Emacs bindings `\\<minibuffer-local-map>\\[next-history-element]' and \
1855 `\\[previous-history-element]' to cycle inputs,
1856 and `\\[repeat-matching-complex-command]' to match regexp input, but Icicles input cycling (`up',
1857 `down', `next', `prior', `home', `end') and apropos completion
1858 \(`S-TAB') are superior and more convenient."
1859   (interactive "p")
1860   (let ((elt  (nth (1- arg) command-history))
1861         newcmd)
1862     (if elt
1863         (progn
1864           (setq newcmd
1865                 (let ((print-level                   nil)
1866                       (minibuffer-history-position   arg)
1867                       (minibuffer-history-sexp-flag  (1+ (minibuffer-depth))))
1868                   (unwind-protect
1869                        (let ((icicle-transform-function  'icicle-remove-duplicates))
1870                          (read (completing-read
1871                                 "Redo: " (mapcar #'(lambda (entry) (list (prin1-to-string entry)))
1872                                                  command-history)
1873                                 nil nil (prin1-to-string elt) (cons 'command-history arg)
1874                                 (prin1-to-string elt))))
1875                     ;; If command was added to command-history as a string, get rid of that.
1876                     ;; We want only evaluable expressions there.
1877                     (if (stringp (car command-history))
1878                         (setq command-history  (cdr command-history))))))
1879           ;; If command to be redone does not match front of history, add it to the history.
1880           (or (equal newcmd (car command-history))
1881               (setq command-history  (cons newcmd command-history)))
1882           (eval newcmd))
1883       (if command-history
1884           (error "Argument %d is beyond length of command history" arg)
1885         (error "There are no previous complex commands to repeat")))))
1886
1887 ;;;###autoload
1888 (defun icicle-add-entry-to-saved-completion-set (set-name entry type)
1889   "Add ENTRY to saved completion-candidates set SET-NAME.
1890 ENTRY is normally a single candidate (a string).
1891  With a prefix arg, however, and if option
1892  `icicle-filesets-as-saved-completion-sets-flag' is non-nil, then
1893  ENTRY is the name of an Emacs fileset (Emacs 22 or later).
1894 TYPE is the type of entry to add: `Fileset' or `Candidate'."
1895   (interactive
1896    (let ((typ (if (and current-prefix-arg icicle-filesets-as-saved-completion-sets-flag
1897                        (prog1 (or (require 'filesets nil t)
1898                                   (error "Feature `filesets' not provided"))
1899                          (filesets-init))
1900                        filesets-data)
1901                   'Fileset
1902                 'Candidate)))
1903      (list
1904       (save-selected-window
1905         (completing-read "Saved completion set: " icicle-saved-completion-sets nil t nil
1906                          'icicle-completion-set-history))
1907       (if (eq typ 'Fileset)
1908           (list ':fileset               ; Just save the fileset name, not the data.
1909                 (car (assoc (completing-read "Fileset to add: " filesets-data nil t)
1910                             filesets-data)))
1911         (completing-read "Candidate to add: " (mapcar #'list icicle-saved-completion-candidates)))
1912       typ)))
1913   (let ((file-name  (cdr (assoc set-name icicle-saved-completion-sets))))
1914     (unless (icicle-file-readable-p file-name) (error "Cannot read cache file `%s'" file-name))
1915     (let ((list-buf  (find-file-noselect file-name 'nowarn 'raw))
1916           candidates newcands entry-type)
1917       (unwind-protect
1918            (condition-case icicle-add-entry-to-saved-completion-set
1919                (when (listp (setq newcands  (setq candidates  (read list-buf))))
1920                  (message "Set `%s' read from file `%s'" set-name file-name))
1921              (error (error "Bad cache file.  %s"
1922                            (error-message-string icicle-add-entry-to-saved-completion-set))))
1923         (kill-buffer list-buf))
1924       (unless (consp newcands) (error "Bad data in cache file `%s'" file-name))
1925       (pushnew entry newcands :test #'equal)
1926       (setq entry  (if (eq type 'Fileset) (caar entry) entry))
1927       (if (= (length candidates) (length newcands))
1928           (message "%s `%s' is already in saved set `%s', file `%s'" type entry set-name file-name)
1929         (with-temp-message (format "Writing entry to cache file `%s'..." file-name)
1930           (with-temp-file file-name (prin1 newcands (current-buffer))))
1931         (message "%s `%s' added to saved set `%s', file `%s'" type entry set-name file-name)))))
1932
1933 ;;;###autoload
1934 (defun icicle-remove-entry-from-saved-completion-set (set-name)
1935   "Remove an entry from saved completion-candidates set SET-NAME.
1936 SET-NAME can be an Icicles saved completions set (cache file) or the
1937 name of an Emacs fileset.
1938
1939 The entry to remove can be a single completion candidate (a string) or
1940 an Emacs fileset.  You can thus remove a file name from a fileset or
1941 remove a fileset from an Icicles saved completion set.  (You can also
1942 remove a file name from a saved completion set.)  If a saved set has
1943 both a file and a fileset of the same name, then both are removed.
1944
1945 To use filesets here, use Emacs 22 or later, load library `filesets',
1946 use `(filesets-init)', and ensure that option
1947 `icicle-filesets-as-saved-completion-sets-flag' is non-nil."
1948   (interactive
1949    (list (completing-read "Saved completion set: "
1950                           (if (and icicle-filesets-as-saved-completion-sets-flag
1951                                    (featurep 'filesets) filesets-data)
1952                               (append filesets-data icicle-saved-completion-sets)
1953                             icicle-saved-completion-sets)
1954                           nil t nil 'icicle-completion-set-history)))
1955   (let* ((file-name                              (cdr (assoc set-name icicle-saved-completion-sets)))
1956          (candidates                             (icicle-get-candidates-from-saved-set
1957                                                   set-name 'dont-expand))
1958          (icicle-whole-candidate-as-text-prop-p  t)
1959          (entry
1960           (funcall icicle-get-alist-candidate-function
1961                    (completing-read
1962                     "Candidate to remove: "
1963                     (mapcar #'(lambda (e)
1964                                 (cond ((icicle-saved-fileset-p e) ; Swap `:fileset' with fileset name
1965                                        `(,(cadr e) ,(car e) ,@(cddr e)))
1966                                       ((consp e) e)
1967                                       (t (list e)))) ; Listify naked string.
1968                             candidates)
1969                     nil t))))
1970     (when (and (consp entry) (eq (cadr entry) ':fileset)) ; Swap back again: `:fileset' and name.
1971       (setq entry  `(,(cadr entry) ,(car entry) ,@(cddr entry))))
1972     (when (and (consp entry) (null (cdr entry))) (setq entry  (car entry))) ; Use just the string.
1973     ;; Delete any such candidate, then remove text properties used for completion.
1974     (setq candidates  (mapcar #'icicle-unpropertize (delete entry candidates)))
1975     (cond (file-name
1976            (with-temp-message           ; Remove from cache file.
1977                (format "Writing remaining candidates to cache file `%s'..." file-name)
1978              (with-temp-file file-name (prin1 candidates (current-buffer)))))
1979           ((icicle-saved-fileset-p (list ':fileset set-name)) ; Remove from fileset.
1980            (unless (require 'filesets nil t) (error "Feature `filesets' not provided"))
1981            (filesets-init)
1982            (let ((fst  (and filesets-data (assoc set-name filesets-data)))) ; The fileset itself.
1983              (unless fst (error "No such fileset: `%s'" set-name))
1984              (let ((fst-files  (filesets-entry-get-files fst)))
1985                (if (car (filesets-member entry fst-files :test 'filesets-files-equalp))
1986                    (if fst-files        ; Similar to code in `filesets-remove-buffer'.
1987                        (let ((new-fst  (list (cons ':files (delete entry fst-files)))))
1988                          (setcdr fst new-fst)
1989                          (filesets-set-config set-name 'filesets-data filesets-data))
1990                      (message "Cannot remove `%s' from fileset `%s'" entry set-name))
1991                  (message "`%s' not in fileset `%s'" entry set-name))))))
1992     (icicle-msg-maybe-in-minibuffer
1993      (concat (format "`%s' removed from %s `%s'"
1994                      (if (icicle-saved-fileset-p entry) (cadr entry) entry)
1995                      (if (icicle-saved-fileset-p entry) "fileset" "saved set")
1996                      set-name)
1997              (and file-name (format ", file `%s'" file-name))))))
1998
1999 ;;;###autoload (autoload 'icicle-remove-saved-completion-set "icicles-cmd1.el")
2000 (icicle-define-command icicle-remove-saved-completion-set ; Command name
2001   "Remove an entry from `icicle-saved-completion-sets'.
2002 Save the updated option.
2003 You are prompted to also delete the associated cache file.
2004 You can add entries to `icicle-saved-completion-sets' using command
2005 `icicle-add/update-saved-completion-set'." ; Doc string
2006   icicle-remove-saved-set-action
2007   "Remove set of completion candidates named: " ; `completing-read' args
2008   icicle-saved-completion-sets nil t nil 'icicle-completion-set-history nil nil
2009   ((icicle-whole-candidate-as-text-prop-p  t) ; Additional bindings
2010    (icicle-use-candidates-only-once-flag   t))
2011   nil nil (icicle-remove-Completions-window)) ; First code, undo code, last code
2012
2013 (defun icicle-remove-saved-set-action (set-name)
2014   "Remove saved set SET-NAME from `icicle-saved-completion-sets'."
2015   (let ((enable-recursive-minibuffers  t)
2016         (sets                          icicle-saved-completion-sets)
2017         set cache)
2018     (save-selected-window
2019       (select-window (minibuffer-window))
2020       (while (setq set    (assoc set-name sets)
2021                    cache  (cdr set))
2022         (when (file-exists-p cache)
2023           (if (y-or-n-p (format "Delete cache file `%s'? " cache))
2024               (when (condition-case err
2025                         (progn (delete-file cache) t)
2026                       (error (progn (message "%s" (error-message-string err)) nil)))
2027                 (message "DELETED `%s'" cache) (sit-for 1))
2028             (message "OK, file NOT deleted") (sit-for 1)))
2029         (setq sets  (delete set sets)))))
2030   (setq icicle-saved-completion-sets
2031         (icicle-assoc-delete-all set-name icicle-saved-completion-sets))
2032   (funcall icicle-customize-save-variable-function
2033            'icicle-saved-completion-sets
2034            icicle-saved-completion-sets)
2035   (message "Candidate set `%s' removed" set-name))
2036
2037 ;;;###autoload
2038 (defun icicle-bookmark-save-marked-files (&optional arg) ; Bound to `C-M->' in *Bookmark List*.
2039   "Save file names of marked bookmarks as a set of completion candidates.
2040 Saves file names in variable `icicle-saved-completion-candidates', by
2041 default.  Marked bookmarks that have no associated file are ignored.
2042 With a plain prefix arg (`C-u'), save candidates in a cache file.
2043 With a non-zero numeric prefix arg (`C-u N'), save candidates in a
2044  variable for which you are prompted.
2045 With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
2046  or later).  Use this only for file-name candidates, obviously.
2047  To subsequently use a fileset for candidate retrieval, option
2048  `icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
2049
2050 You can retrieve the saved set of file-name candidates during
2051 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2052 You can use the saved set of candidates for operations such as
2053 \\<minibuffer-local-completion-map>
2054 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2055 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2056 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2057
2058 You can use this command only from a bookmark-list display buffer
2059 \(`*Bookmark List*')."
2060   (interactive "P")
2061   (unless (fboundp 'bmkp-bmenu-get-marked-files)
2062     (error "Command `icicle-bookmark-save-marked-files' requires library `Bookmark+'"))
2063   (bmkp-bmenu-barf-if-not-in-menu-list)
2064   (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg))
2065
2066 ;;;###autoload
2067 (defun icicle-bookmark-save-marked-files-more (&optional arg) ; Bound to `C->' in *Bookmark List*.
2068   "Add the file names of the marked bookmarks to the saved candidates set.
2069 Marked bookmarks that have no associated file are ignored.
2070 Add candidates to `icicle-saved-completion-candidates', by default.
2071 A prefix argument acts the same as for `icicle-candidate-set-save'.
2072
2073 The existing saved candidates remain saved.  The current candidates
2074 are added to those already saved.
2075
2076 You can retrieve the saved set of candidates with `C-M-<'.
2077 You can use the saved set of candidates for operations such as
2078 \\<minibuffer-local-completion-map>
2079 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2080 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2081 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2082
2083 You can use this command only from a bookmark-list display buffer
2084 \(`*Bookmark List*')."
2085   (interactive "P")
2086   (unless (fboundp 'bmkp-bmenu-get-marked-files)
2087     (error "Command `icicle-bookmark-save-marked-files-more' requires library `Bookmark+'"))
2088   (bmkp-bmenu-barf-if-not-in-menu-list)
2089   (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg t))
2090
2091 ;;;###autoload
2092 (defun icicle-bookmark-save-marked-files-to-variable () ; Bound to `C-M-}' in *Bookmark List*.
2093   "Save the file names of the marked bookmarks to a variable.
2094 Marked bookmarks that have no associated file are ignored.
2095
2096 You can retrieve the saved set of file-name candidates during
2097 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2098 You can use the saved set of candidates for operations such as
2099 \\<minibuffer-local-completion-map>
2100 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2101 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2102 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2103
2104 You can use this command only from a bookmark-list display buffer
2105 \(`*Bookmark List*')."
2106   (interactive)
2107   (unless (fboundp 'bmkp-bmenu-get-marked-files)
2108     (error "Command `icicle-bookmark-save-marked-files-to-variable' requires library `Bookmark+'"))
2109   (bmkp-bmenu-barf-if-not-in-menu-list)
2110   (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) 99))
2111
2112 ;;;###autoload
2113 (defalias 'icicle-bookmark-save-marked-files-as-project ; Bound to `C-}' in *Bookmark List*.
2114     'icicle-bookmark-save-marked-files-persistently)
2115 ;;;###autoload
2116 (defun icicle-bookmark-save-marked-files-persistently (filesetp)
2117   "Save the file names of the marked bookmarks as a persistent set.
2118 Marked bookmarks that have no associated file are ignored.
2119 With no prefix arg, save in a cache file.
2120 With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
2121
2122 You can retrieve the saved set of file-name candidates during
2123 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2124 You can use the saved set of candidates for operations such as
2125 \\<minibuffer-local-completion-map>
2126 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2127 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2128 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2129
2130 You can use this command only from a bookmark-list display buffer
2131 \(`*Bookmark List*')."
2132   (interactive "P")
2133   (unless (fboundp 'bmkp-bmenu-get-marked-files)
2134     (error "This command requires library `Bookmark+'"))
2135   (bmkp-bmenu-barf-if-not-in-menu-list)
2136   (icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) (if filesetp 0 '(1))))
2137
2138 ;;;###autoload
2139 (defun icicle-dired-save-marked (&optional arg) ; Bound to `C-M->' in Dired.
2140   "Save the marked file names in Dired as a set of completion candidates.
2141 Saves file names in variable `icicle-saved-completion-candidates', by
2142 default.
2143 With a plain prefix arg (`C-u'), save candidates in a cache file.
2144 With a non-zero numeric prefix arg (`C-u N'), save candidates in a
2145  variable for which you are prompted.
2146 With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
2147  or later).  Use this only for file-name candidates, obviously.
2148  To subsequently use a fileset for candidate retrieval, option
2149  `icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
2150
2151 You can retrieve the saved set of file-name candidates during
2152 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2153 You can use the saved set of candidates for operations such as
2154 \\<minibuffer-local-completion-map>
2155 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2156 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2157 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2158
2159 You can use this command only from a Dired buffer."
2160   (interactive "P")
2161   (unless (eq major-mode 'dired-mode)
2162     (error "Command `icicle-dired-save-marked' must be called from a Dired buffer"))
2163   (icicle-candidate-set-save-1 (dired-get-marked-files) arg))
2164
2165 ;;;###autoload
2166 (defun icicle-dired-save-marked-more (&optional arg) ; Bound to `C->' in Dired.
2167   "Add the marked file names in Dired to the saved candidates set.
2168 Add candidates to `icicle-saved-completion-candidates', by default.
2169 A prefix argument acts the same as for `icicle-candidate-set-save'.
2170
2171 The existing saved candidates are still saved.  The current candidates
2172 are added to those already saved.
2173
2174 You can retrieve the saved set of candidates with `C-M-<'.
2175 You can use the saved set of candidates for operations such as
2176 \\<minibuffer-local-completion-map>
2177 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2178 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2179 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2180
2181 You can use this command only from a Dired buffer."
2182   (interactive "P")
2183   (unless (eq major-mode 'dired-mode)
2184     (error "`icicle-dired-save-marked-more' must be called from a Dired buffer"))
2185   (icicle-candidate-set-save-1 (dired-get-marked-files) arg t))
2186
2187 ;;;###autoload
2188 (defun icicle-dired-save-marked-to-variable () ; Bound to `C-M-}' in Dired.
2189   "Save the marked file names in Dired to a variable as a candidate set.
2190 You can retrieve the saved set of file-name candidates during
2191 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2192 You can use the saved set of candidates for operations such as
2193 \\<minibuffer-local-completion-map>
2194 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2195 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2196 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2197
2198 You can use this command only from a Dired buffer."
2199   (interactive)
2200   (icicle-candidate-set-save-1 (dired-get-marked-files) 99))
2201
2202 ;;;###autoload
2203 (defalias 'icicle-dired-save-marked-as-project ; Bound to `C-}' in Dired.
2204     'icicle-dired-save-marked-persistently)
2205 ;;;###autoload
2206 (defun icicle-dired-save-marked-persistently (filesetp)
2207   "Save the marked file names in Dired as a persistent set.
2208 With no prefix arg, save in a cache file.
2209 With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
2210
2211 You can retrieve the saved set of file-name candidates during
2212 completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
2213 You can use the saved set of candidates for operations such as
2214 \\<minibuffer-local-completion-map>
2215 `icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
2216 `icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
2217 `icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
2218
2219 You can use this command only from a Dired buffer."
2220   (interactive "P")
2221   (icicle-candidate-set-save-1 (dired-get-marked-files) (if filesetp 0 '(1))))
2222
2223
2224 (put 'icicle-dired-saved-file-candidates 'icicle-Completions-window-max-height 200)
2225 ;;;###autoload
2226 (defalias 'icicle-dired-chosen-files 'icicle-dired-saved-file-candidates)
2227 ;;;###autoload
2228 (defun icicle-dired-saved-file-candidates (prompt-for-dir-p)
2229   "Open Dired on a set of files and directories of your choice.
2230 If you have saved a set of file names using \\<minibuffer-local-completion-map>\
2231 `\\[icicle-candidate-set-save]', then it is used.
2232 If not, you are prompted to choose the files.
2233 With a prefix argument, you are prompted for the default directory to use.
2234 Otherwise, the current value of `default-directory' is used.
2235 Names that do not correspond to existing files are ignored.
2236 Existence of files with relative names is checked in the Dired
2237 directory (default directory)."
2238   (interactive "P")
2239   ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
2240   (unless icicle-saved-completion-candidates
2241     (error "%s" (substitute-command-keys "No saved completion candidates.  \
2242 Use \\<minibuffer-local-completion-map>`\\[icicle-candidate-set-save]' to save candidates")))
2243   (let* ((default-directory           (if prompt-for-dir-p
2244                                           (read-file-name "Directory: " nil default-directory nil)
2245                                         default-directory))
2246          (icicle-list-use-nth-parts   '(1))
2247          (file-names                  (icicle-remove-if
2248                                        #'(lambda (fil) (or (null fil) (not (file-exists-p fil))))
2249                                        (or (and icicle-saved-completion-candidates
2250                                                 (mapcar #'icicle-transform-multi-completion
2251                                                         icicle-saved-completion-candidates))
2252                                            (icicle-file-list)))))
2253     (dired (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
2254
2255 ;;;###autoload
2256 (defalias 'icicle-dired-chosen-files-other-window 'icicle-dired-saved-file-candidates-other-window)
2257 ;;;###autoload
2258 (defun icicle-dired-saved-file-candidates-other-window (prompt-for-dir-p) ; Bound `C-M-<' in Dired.
2259   "Open Dired in other window on set of files & directories of your choice.
2260 If you have saved a set of file names using \\<minibuffer-local-completion-map>\
2261 `\\[icicle-candidate-set-save]', then it is used.
2262 If not, you are prompted to choose the files.
2263 With a prefix arg, you are prompted for the default directory to use.
2264 Otherwise, the current value of `default-directory' is used.
2265 Names that do not correspond to existing files are ignored.
2266 Existence of files with relative names is checked in the Dired
2267 directory (default directory)."
2268   (interactive "P")
2269   ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
2270   (let* ((default-directory           (if prompt-for-dir-p
2271                                           (read-file-name "Directory: " nil default-directory nil)
2272                                         default-directory))
2273          (icicle-list-use-nth-parts   '(1))
2274          (file-names                  (icicle-remove-if
2275                                        #'(lambda (fil) (or (null fil) (not (file-exists-p fil))))
2276                                        (or (and icicle-saved-completion-candidates
2277                                                 (mapcar #'icicle-transform-multi-completion
2278                                                         icicle-saved-completion-candidates))
2279                                            (icicle-file-list)))))
2280     (dired-other-window (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
2281
2282 (put 'icicle-dired-project 'icicle-Completions-window-max-height 200)
2283 ;;;###autoload
2284 (defun icicle-dired-project (prompt-for-dir-p)
2285   "Open Dired on a saved project.
2286 A project is either a persistent completion set or an Emacs fileset.
2287 With a prefix argument, you are prompted for the directory.
2288 Otherwise, the default directory is assumed.
2289
2290 Project file names that do not correspond to existing files are
2291 ignored.  Existence of files with relative names is checked in the
2292 directory.
2293
2294 You can use `C-x m' during completion to access Dired bookmarks, if
2295 you use library `Bookmark+'."
2296   (interactive "P")
2297   (when (require 'bookmark+ nil t)
2298     (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-dired-other-window))
2299   (unwind-protect
2300        ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
2301        (let ((set-name  (completing-read "Project (saved file names): "
2302                                          (if (and icicle-filesets-as-saved-completion-sets-flag
2303                                                   (featurep 'filesets) filesets-data)
2304                                              (append filesets-data icicle-saved-completion-sets)
2305                                            icicle-saved-completion-sets)
2306                                          nil nil nil 'icicle-completion-set-history)))
2307          (icicle-retrieve-candidates-from-set set-name)
2308          (let* ((default-directory  (if prompt-for-dir-p
2309                                         (read-file-name "Dired directory: " nil
2310                                                         default-directory nil)
2311                                       default-directory))
2312                 (file-names         ()))
2313            (dolist (f  icicle-saved-completion-candidates)
2314              (when (file-exists-p f) (push f file-names)))
2315            (unless file-names (error "No files in project `%s' actually exist" set-name))
2316            (dired (cons (generate-new-buffer-name set-name)
2317                         (nreverse (mapcar #'(lambda (file)
2318                                               (if (file-name-absolute-p file)
2319                                                   (expand-file-name file)
2320                                                 file))
2321                                           file-names))))))
2322     (define-key minibuffer-local-completion-map "\C-xm" nil)))
2323
2324 ;;;###autoload
2325 (defun icicle-dired-project-other-window (prompt-for-dir-p) ; Bound to `C-{' in Dired.
2326   "Open Dired on a saved project in another window.
2327 A project is either a persistent completion set or an Emacs fileset.
2328 With a prefix argument, you are prompted for the directory.
2329 Otherwise, the default directory is assumed.
2330
2331 Project file names that do not correspond to existing files are
2332 ignored.  Existence of files with relative names is checked in the
2333 directory.
2334
2335 You can use `C-x m' during completion to access Dired bookmarks, if
2336 you use library `Bookmark+'."
2337   (interactive "P")
2338   (when (require 'bookmark+ nil t)
2339     (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-dired-other-window))
2340   (unwind-protect
2341        ;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
2342        (let ((set-name  (completing-read "Project (saved file names): "
2343                                          (if (and icicle-filesets-as-saved-completion-sets-flag
2344                                                   (featurep 'filesets) filesets-data)
2345                                              (append filesets-data icicle-saved-completion-sets)
2346                                            icicle-saved-completion-sets)
2347                                          nil nil nil 'icicle-completion-set-history)))
2348          (icicle-retrieve-candidates-from-set set-name)
2349          (let* ((default-directory  (if prompt-for-dir-p
2350                                         (read-file-name "Dired directory: " nil
2351                                                         default-directory nil)
2352                                       default-directory))
2353                 (file-names         ()))
2354            (dolist (f  icicle-saved-completion-candidates)
2355              (when (file-exists-p f) (push f file-names)))
2356            (unless file-names (error "No files in project `%s' actually exist" set-name))
2357            (dired-other-window (cons (generate-new-buffer-name set-name)
2358                                      (nreverse (mapcar #'(lambda (file)
2359                                                            (if (file-name-absolute-p file)
2360                                                                (expand-file-name file)
2361                                                              file))
2362                                                        file-names))))))
2363     (define-key minibuffer-local-completion-map "\C-xm" nil)))
2364
2365 ;;;###autoload
2366 (defun icicle-grep-saved-file-candidates (command-args)
2367   "Run `grep' on the set of completion candidates saved with \\<minibuffer-local-completion-map>\
2368 `\\[icicle-candidate-set-save]'.
2369 Saved names that do not correspond to existing files are ignored.
2370 Existence of files with relative names is checked in the default
2371 directory."
2372   (interactive
2373    (list
2374     (let ((file-names  ()))
2375       (unless icicle-saved-completion-candidates
2376         (error "%s" (substitute-command-keys "No saved completion candidates.  \
2377 Use \\<minibuffer-local-completion-map>`\\[icicle-candidate-set-save]' to save candidates")))
2378       (unless grep-command (grep-compute-defaults))
2379       (dolist (f  icicle-saved-completion-candidates) (when (file-exists-p f) (push f file-names)))
2380       (let ((default  (and (fboundp 'grep-default-command) (grep-default-command))))
2381         (read-from-minibuffer
2382          "grep <pattern> <files> :  "
2383          (let ((up-to-files  (concat grep-command "   ")))
2384            (cons (concat up-to-files (mapconcat #'identity icicle-saved-completion-candidates " "))
2385                  (- (length up-to-files) 2)))
2386          nil nil 'grep-history default)))))
2387   (grep command-args))
2388
2389 ;; Utility function.  Use it to define multi-commands that navigate.
2390 (defun icicle-explore (define-candidates-fn final-action-fn quit-fn error-fn cleanup-fn prompt
2391                                             &rest compl-read-args)
2392   "Icicle explorer: explore complex completion candidates.
2393 Navigate among locations or other entities represented by a set of
2394 completion candidates.  See `icicle-search' for a typical example.
2395
2396 Arguments:
2397  DEFINE-CANDIDATES-FN:
2398    Function of no args called to fill `icicle-candidates-alist' with
2399    the candidates.
2400  FINAL-ACTION-FN:
2401    Function of no args called after the final choice of candidate
2402    (after both `icicle-explore-final-choice' and
2403    `icicle-explore-final-choice-full' have been set).  Typically uses
2404    `icicle-explore-final-choice-full', the full candidate.
2405  QUIT-FN: Function of no args called if user uses `C-g'.
2406  ERROR-FN: Function of no args called if an error is raised.
2407  CLEANUP-FN: Function of no args called after exploring.
2408  PROMPT: Prompt string for `completing-read'.
2409  COMPL-READ-ARGS: `completing-read' args other than PROMPT and
2410    COLLECTION.
2411
2412 If there is only one candidate, then FINAL-ACTION-FN is called
2413 immediately.  The candidate is not available to act on (e.g. using
2414 ``C-S-RET').
2415
2416 Returns:
2417  The result of executing FINAL-ACTION-FN, if that arg is non-nil.
2418  Otherwise, `icicle-explore-final-choice-full'.
2419
2420 To use `icicle-explore' to define a multi-command, you must also bind
2421 `icicle-candidate-action-fn'.
2422
2423 Though `icicle-explore' is typically used to define navigation
2424 commands, it need not be.  It can be useful anytime you need to use
2425 `completing-read' and also provide specific behavior for quitting
2426 \(`C-g'), completion errors, and final actions."
2427   (let ((icicle-incremental-completion-flag     'always)
2428         (icicle-whole-candidate-as-text-prop-p  t)
2429         (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
2430         (icicle-act-before-cycle-flag           icicle-act-before-cycle-flag)
2431         (icicle-orig-pt-explore                 (point-marker))
2432         (icicle-orig-win-explore                (selected-window))
2433         result)
2434     (setq icicle-act-before-cycle-flag      nil
2435           icicle-candidates-alist           nil
2436           icicle-explore-final-choice       nil
2437           icicle-explore-final-choice-full  nil)
2438     (icicle-highlight-lighter)
2439     (message "Finding candidates...")
2440     (when define-candidates-fn (funcall define-candidates-fn))
2441     (unless icicle-candidates-alist (error "No candidates defined"))
2442     (when (= (length icicle-candidates-alist) 1)
2443       (setq icicle-explore-final-choice  (icicle-display-cand-from-full-cand
2444                                           (car icicle-candidates-alist))))
2445     (unwind-protect
2446          (icicle-condition-case-no-debug failure
2447              (progn
2448                (unless icicle-explore-final-choice
2449                  (setq icicle-explore-final-choice
2450                        (let ((icicle-remove-icicles-props-p  nil)) ; Keep Icicles text properties.
2451                          (apply #'completing-read prompt icicle-candidates-alist compl-read-args))))
2452                (setq icicle-explore-final-choice-full
2453                      (funcall icicle-get-alist-candidate-function
2454                               icicle-explore-final-choice 'no-error-p))
2455                (unless icicle-explore-final-choice-full (error "No such occurrence"))
2456                (setq result  (if final-action-fn
2457                                  (funcall final-action-fn)
2458                                icicle-explore-final-choice-full)))
2459            (quit (if quit-fn (funcall quit-fn) (keyboard-quit)))
2460            (error (when error-fn (funcall error-fn))
2461                   (error "%s" (error-message-string failure))))
2462       (setq result  (icicle-unpropertize result)) ; Finally remove any Icicles text properties.
2463       (when cleanup-fn (funcall cleanup-fn)))
2464     result))
2465
2466 ;;;###autoload (autoload 'icicle-execute-extended-command "icicles-cmd1.el")
2467 (icicle-define-command icicle-execute-extended-command ; Bound to `M-x' in Icicle mode.
2468   "Read command name, then read its arguments and call it.
2469 This is `execute-extended-command', turned into a multi-command.
2470
2471 By default, Icicle mode remaps all key sequences that are normally
2472 bound to `execute-extended-command' to
2473 `icicle-execute-extended-command'.  If you do not want this remapping,
2474 then customize option `icicle-top-level-key-bindings'." ; Doc string
2475   icicle-execute-extended-command-1     ; Function to perform the action
2476   (format "Execute command%s: "         ; `completing-read' args
2477           (if current-prefix-arg
2478               (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
2479             ""))
2480   obarray nil t nil 'extended-command-history nil nil
2481   (;; Bindings
2482    (last-command                            last-command) ; Save and restore the last command.
2483    (use-file-dialog                         nil) ; `mouse-2' in `*Completions*' won't use dialog box.
2484    (alt-fn                                  nil)
2485    (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
2486    (icicle-must-pass-after-match-predicate  #'(lambda (c) (commandp (intern c))))
2487    (icicle-candidate-alt-action-fn
2488     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
2489    (icicle-all-candidates-list-alt-action-fn ; M-|'
2490     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
2491    icicle-new-last-cmd)                 ; Set in `icicle-execute-extended-command-1'.
2492   nil  nil                              ; First code, undo code
2493   (setq this-command  icicle-new-last-cmd)) ; Last code: this will update `last-command'
2494
2495 ;; Free vars here: `icicle-orig-buff' and `icicle-orig-window' are bound by `icicle-define-command'.
2496 ;;                 `icicle-new-last-cmd' and `icicle-orig-must-pass-after-match-pred' are bound in
2497 ;;                 `icicle-execute-extended-command'.
2498 (defun icicle-execute-extended-command-1 (cmd-name)
2499   "Action function to execute command or named keyboard macro CMD-NAME."
2500   (when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
2501   (when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
2502   (when (string= "" cmd-name) (error "No command name"))
2503
2504   (let* ((cmd                                       (intern cmd-name))
2505          ;; Rebind `icicle-candidate-action-fn' to a function that calls the
2506          ;; candidate CMD-NAME on a single argument that it reads.  This is
2507          ;; used only if CMD-NAME is a command that, itself, reads an input
2508          ;; argument with completion.  When that is the case, you can use
2509          ;; completion on that input, and if you do that, you can use `C-RET'
2510          ;; to use command CMD-NAME as a multi-command.  In other words, this
2511          ;; binding allows for two levels of multi-commands.
2512          (icicle-candidate-action-fn
2513           (and icicle-candidate-action-fn ; This is nil after the command name is read.
2514                #'(lambda (arg)
2515                    (setq arg  (icicle-transform-multi-completion arg))
2516                    (condition-case nil
2517                        (funcall cmd arg) ; Try to use string candidate `arg'.
2518                      ;; If that didn't work, use a symbol or number candidate.
2519                      (wrong-type-argument (funcall cmd (car (read-from-string arg))))
2520                      (wrong-number-of-arguments ; Punt - show help.
2521                       (funcall #'icicle-help-on-candidate)))
2522                    (select-window (minibuffer-window))
2523                    (select-frame-set-input-focus (selected-frame)))))
2524          (fn                                        (symbol-function cmd))
2525          (count                                     (prefix-numeric-value current-prefix-arg))
2526          ;; Rebind alternative action functions to nil, so we don't override the command we call.
2527          (icicle-candidate-alt-action-fn            nil)
2528          (icicle-all-candidates-list-alt-action-fn  nil))
2529     ;; Message showing what `cmd' is bound to.  This is pretty much a transcription of C code in
2530     ;; `keyboard.c'.  Not sure it DTRT when there is already a msg in the echo area.
2531     (when (and suggest-key-bindings (not executing-kbd-macro))
2532       (let* ((bindings   (where-is-internal cmd overriding-local-map t))
2533              (curr-msg   (current-message))
2534              (wait-time  (if curr-msg
2535                              (or (and (numberp suggest-key-bindings) suggest-key-bindings) 2)
2536                            0)))
2537         (when (and bindings (not (and (vectorp bindings) (eq (aref bindings 0) 'mouse-movement))))
2538           (when (and (sit-for wait-time) (atom unread-command-events))
2539             (let ((message-log-max  nil)) ; Don't log this message.
2540               (message "You can run the command `%s' with `%s'"
2541                        (symbol-name cmd)
2542                        (key-description bindings)))
2543             (when (and (sit-for wait-time) curr-msg) (message curr-msg))))))
2544     (cond ((arrayp fn)
2545            (let ((this-command  cmd)) (execute-kbd-macro fn count))
2546            (when (> count 1) (message "(%d times)" count)))
2547           (t
2548            (run-hooks 'post-command-hook)
2549            (run-hooks 'pre-command-hook)
2550            (let ((enable-recursive-minibuffers            t)
2551                  ;; Restore this before we invoke command, since it might use completion.
2552                  (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred)
2553                  ;; Bind, don't set `this-command'.  When you use `C-next', `this-command' needs
2554                  ;; to be `cmd' during the `C-RET' part, but `last-command' must not be `cmd'
2555                  ;; during the `next' part.
2556                  (this-command                            cmd))
2557              (call-interactively cmd 'record-it))))
2558     ;; After `M-x' `last-command' must be the command finally entered with `RET' or, if you end
2559     ;; with `C-g', the last command entered with `C-RET'.
2560     (setq icicle-new-last-cmd  cmd)))
2561
2562 ;; Inspired by Emacs partial completion and by library `exec-abbrev-cmd.el' (Tassilo Horn
2563 ;; <tassilo@member.fsf.org>).  The idea of command abbreviation is combined here with normal
2564 ;; command invocation, in an Icicles multi-command.
2565
2566 ;;;###autoload (autoload 'icicle-command-abbrev "icicles-cmd1.el")
2567 (icicle-define-command icicle-command-abbrev ; Bound to `C-x SPC' in Icicle mode.
2568   "Read command name or its abbreviation, read command args, call command.
2569 Read input, then call `icicle-command-abbrev-action' to act on it.
2570
2571 If `icicle-add-proxy-candidates-flag' is non-nil, then command
2572 abbreviations, as well as commands, are available as completion
2573 candidates.  Otherwise, only commands are available.  You can toggle
2574 this user option using `\\<minibuffer-local-completion-map>\\[icicle-toggle-proxy-candidates]'\
2575 in the minibuffer.
2576
2577 When an abbreviation is available, you can treat it just like a
2578 command.  The rest of this description covers the behavior of choosing
2579 an abbreviation.
2580
2581 If an abbreviation matches a single command name, then that command is
2582 invoked.  If it matches more than one, then you can use completion to
2583 choose one.
2584
2585 Hyphens (`-') in command names divide them into parts.  For example,
2586 `find-file' has two parts: `find' and `file'.  Each character of a
2587 command abbreviation corresponds to one part of each of the commands
2588 that match the abbreviation.  For example, abbreviation `ff' matches
2589 commands `find-file' and `focus-frame', and abbreviation `fg' matches
2590 `find-grep'.
2591
2592 User option `icicle-command-abbrev-match-all-parts-flag' = nil means
2593 that an abbreviation need not match all parts of a command name; it
2594 need match only a prefix.  For example, nil means that abbreviation
2595 `ff' also matches `find-file-other-window' and `fg' also matches
2596 `find-grep-dired'."                     ; Doc string
2597   icicle-command-abbrev-action          ; Function to perform the action
2598   prompt obarray nil nil nil 'icicle-command-abbrev-history nil nil ; `completing-read' args
2599   ((prompt                                  "Command or abbrev: ")
2600    (last-command                            last-command) ; Save and restore the last command.
2601    (icicle-sort-comparer                    'icicle-command-abbrev-used-more-p) ; Bindings.
2602    (icicle-proxy-candidates                 (let ((ipc  ())
2603                                                   abv)
2604                                               (dolist (entry  icicle-command-abbrev-alist  ipc)
2605                                                 (setq abv  (symbol-name (cadr entry)))
2606                                                 (unless (member abv ipc) (push abv ipc)))))
2607    (use-file-dialog                         nil) ; `mouse-2' in `*Completions*' won't use dialog box.
2608    (alt-fn                                  nil)
2609    (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
2610    (icicle-must-pass-after-match-predicate  #'(lambda (c) (commandp (intern c))))
2611    (icicle-candidate-alt-action-fn
2612     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
2613    (icicle-all-candidates-list-alt-action-fn ; M-|'
2614     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command"))))
2615   (when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt)) ; First code
2616   nil (setq icicle-proxy-candidates  nil)) ; Undo code, last code
2617
2618 (defun icicle-command-abbrev-action (abbrev-or-cmd)
2619   "Action function for `icicle-command-abbrev'.
2620 If ABBREV-OR-CMD is a command, call it.
2621 If ABBREV-OR-CMD is an abbreviation for a single command, invoke it.
2622 If ABBREV-OR-CMD is an abbreviation for multiple commands, call
2623 `icicle-command-abbrev-command', to let user choose commands.
2624 If ABBREV-OR-CMD is not an abbreviation or a command, raise an error."
2625   (setq abbrev-or-cmd  (intern abbrev-or-cmd))
2626   (let* ((not-cmdp                                  (not (commandp abbrev-or-cmd)))
2627          (regexp                                    (and (or not-cmdp
2628                                                              icicle-command-abbrev-priority-flag)
2629                                                          (icicle-command-abbrev-regexp
2630                                                           abbrev-or-cmd)))
2631          (icicle-commands-for-abbrev                (and (or not-cmdp
2632                                                              icicle-command-abbrev-priority-flag)
2633                                                          (icicle-command-abbrev-matching-commands
2634                                                           regexp)))
2635          (icicle-add-proxy-candidates-flag          icicle-add-proxy-candidates-flag)
2636          (icicle-proxy-candidates                   icicle-proxy-candidates)
2637          ;; Restore this before we invoke command, since it might use completion.
2638          ;; Free var `orig-must-pass...' is bound in `icicle-command-abbrev'.
2639          (icicle-must-pass-after-match-predicate    icicle-orig-must-pass-after-match-pred)
2640          ;; Rebind alternative action functions to nil, so we don't override command we call.
2641          (icicle-candidate-alt-action-fn            nil)
2642          (icicle-all-candidates-list-alt-action-fn  nil))
2643     (cond ((and not-cmdp (null icicle-commands-for-abbrev))
2644            (error "No such command or abbreviation `%s'" abbrev-or-cmd))
2645           (icicle-commands-for-abbrev
2646            (let* ((icicle-sort-comparer  'icicle-command-abbrev-used-more-p)
2647                   (cmd
2648                    (if (null (cdr icicle-commands-for-abbrev))
2649                        (prog1 (intern (caar icicle-commands-for-abbrev))
2650                          (push (caar icicle-commands-for-abbrev) extended-command-history)
2651                          (call-interactively (intern (caar icicle-commands-for-abbrev)) t))
2652                      (let ((enable-recursive-minibuffers  t))
2653                        (icicle-remove-Completions-window)
2654                        (icicle-command-abbrev-command)))))
2655              (icicle-command-abbrev-record abbrev-or-cmd cmd)))
2656           ((not not-cmdp) (call-interactively abbrev-or-cmd)))))
2657
2658 (defun icicle-command-abbrev-regexp (abbrev)
2659   "Return the command-matching regexp for ABBREV."
2660   (let ((char-list  (append (symbol-name abbrev) ()))
2661         (str        "^"))
2662     (dolist (c  char-list) (setq str  (concat str (list c) "[^-]*-")))
2663     (concat (substring str 0 (1- (length str)))
2664             (if icicle-command-abbrev-match-all-parts-flag "$" ".*$"))))
2665
2666 (defun icicle-command-abbrev-matching-commands (regexp)
2667   "Return a completion alist of commands that match REGEXP."
2668   (mapcar #'list (icicle-remove-if-not
2669                   #'(lambda (strg) (string-match regexp strg))
2670                   (let ((cmds  ()))
2671                     (mapatoms #'(lambda (symb)
2672                                   (when (commandp symb) (push (symbol-name symb) cmds))))
2673                     cmds))))
2674
2675 ;;;###autoload (autoload 'icicle-command-abbrev-command "icicles-cmd1.el")
2676 (icicle-define-command icicle-command-abbrev-command
2677   "Read command name, then read its arguments and call command." ; Doc string
2678   icicle-execute-extended-command-1     ; Function to perform the action
2679   (format "Command abbreviated%s%s: "   ; `completing-read' arguments
2680           (cond ((and icicle-current-input (not (string= "" icicle-current-input)))
2681                  (format " `%s'" icicle-current-input))
2682                 (icicle-candidate-nb
2683                  (format " `%s'" (elt icicle-completion-candidates icicle-candidate-nb)))
2684                 (t ""))
2685           (if current-prefix-arg
2686               (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
2687             ""))
2688   icicle-commands-for-abbrev nil t nil 'extended-command-history nil nil
2689   (;; Bindings
2690    (use-file-dialog                   nil) ; `mouse-2' in `*Completions*' shouldn't use file dialog.
2691    (alt-fn                            nil)
2692    (icicle-candidate-alt-action-fn
2693     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
2694    (icicle-all-candidates-list-alt-action-fn ; M-|'
2695     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
2696    (icicle-add-proxy-candidates-flag  nil) ; No abbrevs - just commands here.
2697    (last-command                      last-command) ; Save and restore the last command.
2698    icicle-new-last-cmd)                 ; Set in `icicle-execute-extended-command-1'.
2699   nil nil                               ; First code, undo code
2700   (setq this-command  icicle-new-last-cmd) ; Last code: this will update `last-command'.
2701   'NON-INTERACTIVE)                     ; This is not a real command.
2702
2703 (defun icicle-command-abbrev-record (abbrev command)
2704   "Record ABBREV and COMMAND in `icicle-command-abbrev-alist'."
2705   (let ((entry  (assq command icicle-command-abbrev-alist)))
2706     (when (and abbrev command)
2707       (if entry
2708           (setq icicle-command-abbrev-alist  (cons (list command abbrev (1+ (car (cddr entry))))
2709                                                    (delete entry icicle-command-abbrev-alist)))
2710         (push (list command abbrev 1) icicle-command-abbrev-alist)))))
2711
2712 ;;;###autoload (autoload 'icicle-execute-named-keyboard-macro "icicles-cmd1.el")
2713 (icicle-define-command icicle-execute-named-keyboard-macro ; Bound to `C-x M-e' in Icicle mode.
2714   "Read the name of a keyboard macro, then execute it."
2715   icicle-execute-extended-command-1     ; Function to perform the action
2716   (format "Execute keyboard macro%s: "  ; `completing-read' args
2717           (if current-prefix-arg
2718               (format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
2719             ""))
2720   obarray nil t nil 'icicle-kmacro-history nil nil
2721   ((last-command                            last-command) ; Save and restore the last command.
2722    (alt-fn                                  nil)
2723    (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
2724    (icicle-must-pass-after-match-predicate
2725     #'(lambda (fn) (setq fn  (intern fn)) (and (commandp fn) (arrayp (symbol-function fn)))))
2726    (icicle-candidate-alt-action-fn
2727     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "command"))))
2728    (icicle-all-candidates-list-alt-action-fn ; M-|'
2729     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))))
2730
2731 ;;;###autoload (autoload 'icicle-kmacro "icicles-cmd1.el")
2732 (when (require 'kmacro nil t)
2733   (icicle-define-command icicle-kmacro  ; Bound to `S-f4' in Icicle mode (Emacs 22+).
2734     "Execute a keyboard macro according to its position in `kmacro-ring'.
2735 Macros in the keyboard macro ring are given names `1', `2', and so on,
2736 for use as completion candidates.
2737
2738 With prefix argument, repeat macro that many times (but see below).
2739 If a macro is still being defined, end it first, then execute it.
2740
2741 Since this is a multi-command, you can execute any number of macros
2742 any number of times in a single invocation.  In particular, you can
2743 execute a given macro repeatedly using `C-RET' (be sure you use `TAB'
2744 first, to make it the current candidate).
2745
2746 If you use a prefix arg for `icicle-kmacro', then each multi-command
2747 action (e.g. `C-RET') repeats the macro that number of times.  However
2748 if you use a prefix arg for an individual action, then the action
2749 repeats the macro that number of times.  Without its own prefix arg,
2750 an action uses the base prefix arg you used for `icicle-kmacro'."
2751     icicle-kmacro-action                ; Function to perform the action
2752     (format "Execute keyboard macro%s: " ; `completing-read' args
2753             (if current-prefix-arg
2754                 (format " (prefix %s)" (prefix-numeric-value current-prefix-arg))
2755               ""))
2756     (let ((count  0))
2757       (setq icicle-kmacro-alist
2758             (mapcar #'(lambda (x) (cons (format "%d" (setq count  (1+ count))) x))
2759                     (reverse (if nil kmacro-ring (cons (kmacro-ring-head) kmacro-ring))))))
2760     nil 'NO-EXIT-WO-MATCH nil 'icicle-kmacro-history
2761     (and (kmacro-ring-head) (null kmacro-ring) "1") nil
2762     ((icicle-pref-arg  current-prefix-arg))    ; Additional bindings
2763     (progn                              ; First code
2764       (when defining-kbd-macro (kmacro-end-or-call-macro current-prefix-arg) (error "Done"))
2765       (unless (or (kmacro-ring-head) kmacro-ring) (error "No keyboard macro defined"))))
2766
2767   ;; Free vars here: `icicle-orig-buff' & `icicle-orig-window' are bound by `icicle-define-command'.
2768   ;;                 `icicle-pref-arg' is bound in `icicle-kmacro'.
2769   (defun icicle-kmacro-action (cand)
2770     "Action function for `icicle-kmacro'."
2771     (when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
2772     (when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
2773     (let* ((count  (if current-prefix-arg (prefix-numeric-value current-prefix-arg) icicle-pref-arg))
2774            (macro  (cadr (assoc cand icicle-kmacro-alist))))
2775       (unless macro (error "No such macro: `%s'" cand))
2776       (execute-kbd-macro macro count #'kmacro-loop-setup-function)
2777       (when (> count 1) (message "(%d times)" count)))))
2778
2779 ;;;###autoload (autoload 'icicle-set-option-to-t "icicles-cmd1.el")
2780 (icicle-define-command icicle-set-option-to-t ; Command name
2781   "Set option to t.  This makes sense for binary (toggle) options.
2782 By default, completion candidates are limited to user options that
2783 have `boolean' custom types.  However, there are many \"binary\" options
2784 that allow other non-nil values than t.
2785
2786 You can use a prefix argument to change the set of completion
2787 candidates, as follows:
2788
2789  - With a non-negative prefix arg, all user options are candidates.
2790  - With a negative prefix arg, all variables are candidates." ; Doc string
2791   (lambda (opt) (set (intern opt) t) (message "`%s' is now t" opt)) ; Action function
2792   "Set option to t: " obarray nil 'must-confirm nil ; `completing-read' args
2793   (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
2794   ((enable-recursive-minibuffers          t) ; Bindings
2795    (icicle-use-candidates-only-once-flag  t)
2796    (alt-fn                                nil)
2797    (icicle-must-pass-after-match-predicate
2798     (cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
2799            #'(lambda (x)
2800                (setq x  (intern x)) (and (boundp x) (user-variable-p x) (eq nil (symbol-value x)))))
2801           (current-prefix-arg
2802            #'(lambda (x)
2803                (setq x  (intern x)) (and (boundp x) (eq nil (symbol-value x)))))
2804           (t
2805            #'(lambda (x)
2806                (setq x  (intern x))
2807                (and (boundp x) (icicle-binary-option-p x) (eq nil (symbol-value x)))))))
2808    (icicle-candidate-alt-action-fn
2809     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
2810    (icicle-all-candidates-list-alt-action-fn ; M-|'
2811     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
2812
2813 ;;;###autoload (autoload 'icicle-clear-history "icicles-cmd1.el")
2814 (icicle-define-command icicle-clear-history
2815   "Clear a minibuffer history of selected entries.
2816 You are prompted for the history to clear, then you are prompted for
2817 the entries to delete from it.  You can use multi-command completion
2818 for both inputs.  That is, you can act on multiple histories and
2819 delete multiple entries from each.
2820
2821 For convenience, you can use `S-delete' the same way as `C-RET': Each
2822 of them deletes the current entry candidate from the history.
2823
2824 With a prefix argument, empty the chosen history completely
2825 \(you are not prompted to choose history entries to delete).
2826
2827 `icicle-act-before-cycle-flag' is bound to t here during completion of
2828 history entries, so `C-next' and so on act on the current candidate."
2829   icicle-clear-history-1                ; Function to perform the action
2830   "History to clear: " icicle-clear-history-hist-vars ; `completing-read' args
2831   nil t nil nil (symbol-name minibuffer-history-variable) nil
2832   ((icicle-pref-arg                 current-prefix-arg) ; Bindings
2833    (enable-recursive-minibuffers    t)
2834    (icicle-transform-function       'icicle-remove-duplicates)
2835    (icicle-clear-history-hist-vars  `((,(symbol-name minibuffer-history-variable))
2836                                       (,(symbol-name 'icicle-previous-raw-file-name-inputs))
2837                                       (,(symbol-name 'icicle-previous-raw-non-file-name-inputs))))
2838    (icicle-delete-candidate-object  'icicle-clear-history-entry))
2839   (mapatoms #'(lambda (x) (when (and (boundp x) (consp (symbol-value x)) ; First code
2840                                      (stringp (car (symbol-value x)))
2841                                      (string-match "-\\(history\\|ring\\)\\'" (symbol-name x)))
2842                             (push (list (symbol-name x)) icicle-clear-history-hist-vars)))))
2843
2844 ;; Free vars here: `icicle-pref-arg' is bound in `icicle-clear-history'.
2845 (defun icicle-clear-history-1 (hist)
2846   "Action function for `icicle-clear-history' history-variable candidates."
2847   (setq hist  (intern hist))
2848   (if (not icicle-pref-arg)
2849       (let* ((icicle-candidate-action-fn              'icicle-clear-history-entry)
2850              (icicle-transform-function               'icicle-remove-duplicates)
2851              (icicle-clear-history-hist               hist)
2852              (icicle-use-candidates-only-once-flag    t)
2853              (icicle-show-Completions-initially-flag  t)
2854              (icicle-act-before-cycle-flag            t))
2855         (when hist                      ; Maybe there are no more, due to deletion actions.
2856           (funcall icicle-candidate-action-fn
2857                    (completing-read "Clear input: " (mapcar #'list (symbol-value hist)) nil t))))
2858     (set hist nil))
2859   (unless hist (message "History `%s' is now empty" hist))
2860   nil)
2861
2862 ;; Free vars here: `icicle-clear-history-hist' is bound in `icicle-clear-history-1'
2863 ;; and in `icicle-clear-current-history'.
2864 (defun icicle-clear-history-entry (cand)
2865   "Action function for history entry candidates in `icicle-clear-history'."
2866   (unless (string= "" cand)
2867     (set icicle-clear-history-hist
2868          (icicle-remove-if
2869           #'(lambda (x)
2870               (string= (icicle-substring-no-properties cand) (icicle-substring-no-properties x)))
2871           (symbol-value icicle-clear-history-hist)))
2872     ;; We assume here that CAND was in fact present in the history originally.
2873     (message "`%s' deleted from history `%s'" cand icicle-clear-history-hist))
2874   nil)
2875
2876 ;;;###autoload (autoload 'icicle-clear-current-history "icicles-cmd1.el")
2877 (icicle-define-command icicle-clear-current-history ; Bound to `M-i' in minibuffer.
2878   "Clear current minibuffer history of selected entries.
2879 You are prompted for the history entries to delete.
2880
2881 With a prefix argument, however, empty the history completely
2882 \(you are not prompted to choose history entries to delete).
2883
2884 `icicle-act-before-cycle-flag' is bound to t here during completion of
2885 history entries, so `C-next' and so on act on the current candidate."
2886   icicle-clear-history-entry            ; Action function
2887   "Clear input: " (mapcar #'list (symbol-value icicle-clear-history-hist)) ; `completing-read' args
2888   nil t nil nil nil nil
2889   ((icicle-pref-arg                         current-prefix-arg) ; Bindings
2890    (enable-recursive-minibuffers            t)
2891    (icicle-transform-function               'icicle-remove-duplicates)
2892    (icicle-use-candidates-only-once-flag    t)
2893    (icicle-show-Completions-initially-flag  t)
2894    (icicle-clear-history-hist               minibuffer-history-variable))
2895   (when icicle-pref-arg                 ; First code
2896     (icicle-ding)                       ; Use `error' just to exit and make sure message is seen.
2897     (if (not (yes-or-no-p (format "Are you sure you want to empty `%s' completely? "
2898                                   minibuffer-history-variable)))
2899         (error "")
2900       (set minibuffer-history-variable nil)
2901       (error "History `%s' is now empty" minibuffer-history-variable))))
2902
2903 (when (and icicle-define-alias-commands-flag (not (fboundp 'clear-option)))
2904   (defalias 'clear-option 'icicle-reset-option-to-nil))
2905
2906 ;;;###autoload (autoload 'icicle-reset-option-to-nil "icicles-cmd1.el")
2907 (icicle-define-command icicle-reset-option-to-nil ; Command name
2908   "Set option to nil.  This makes sense for binary and list options.
2909 By default, the set of completion candidates is limited to user
2910 options.  Note: it is *not* limited to binary and list options.
2911 With a prefix arg, all variables are candidates." ; Doc string
2912   (lambda (opt) (set (intern opt) nil) (message "`%s' is now nil" opt)) ; Action function
2913   "Clear option (set it to nil): " obarray nil t nil ; `completing-read' args
2914   (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history)
2915   nil nil
2916   ((enable-recursive-minibuffers          t) ; Bindings
2917    (icicle-use-candidates-only-once-flag  t)
2918    (alt-fn                                nil)
2919    (icicle-must-pass-after-match-predicate
2920     (if current-prefix-arg
2921         #'(lambda (x) (setq x  (intern x)) (and (boundp x) (symbol-value x)))
2922       #'(lambda (x) (setq x  (intern x)) (and (boundp x) (user-variable-p x) (symbol-value x)))))
2923    (icicle-candidate-alt-action-fn
2924     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
2925    (icicle-all-candidates-list-alt-action-fn ; M-|'
2926     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
2927
2928 (when (and icicle-define-alias-commands-flag (not (fboundp 'toggle)))
2929   (defalias 'toggle 'icicle-toggle-option))
2930
2931 ;;;###autoload (autoload 'icicle-toggle-option "icicles-cmd1.el")
2932 (icicle-define-command icicle-toggle-option ; Command name
2933   "Toggle option's value.  This makes sense for binary (toggle) options.
2934 By default, completion candidates are limited to user options that
2935 have `boolean' custom types.  However, there are many \"binary\" options
2936 that allow other non-nil values than t.
2937
2938 You can use a prefix argument to change the set of completion
2939 candidates, as follows:
2940
2941  - With a non-negative prefix arg, all user options are candidates.
2942  - With a negative prefix arg, all variables are candidates." ; Doc string
2943   (lambda (opt)                         ; Action function
2944     (let ((sym  (intern opt)))
2945       (set sym (not (eval sym))) (message "`%s' is now %s" opt (eval sym))))
2946   "Toggle value of option: " obarray nil 'must-confirm nil ; `completing-read' args
2947   (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
2948   ((enable-recursive-minibuffers  t)    ; Bindings
2949    (alt-fn                        nil)
2950    (icicle-must-pass-after-match-predicate
2951     (cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
2952            #'(lambda (c) (user-variable-p (intern c))))
2953           (current-prefix-arg #'(lambda (c) (boundp (intern c))))
2954           (t                  #'(lambda (c) (icicle-binary-option-p (intern c))))))
2955    (icicle-candidate-alt-action-fn
2956     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
2957    (icicle-all-candidates-list-alt-action-fn ; M-|'
2958     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
2959
2960 (defun icicle-binary-option-p (symbol)
2961   "Non-nil if SYMBOL is a user option that has custom-type `boolean'."
2962   (eq (get symbol 'custom-type) 'boolean))
2963
2964 ;;;###autoload (autoload 'icicle-increment-option "icicles-cmd1.el")
2965 (icicle-define-command icicle-increment-option ; Command name
2966   "Increment option's value using the arrow keys (`up', `down').
2967 Completion candidates are limited to options that have `integer',
2968 `float', and `number' custom types.
2969 This command needs library `doremi.el'." ; Doc string
2970   (lambda (opt)                         ; Action function
2971     (let ((sym                                     (intern opt))
2972           ;; Restore this before we read number, since that might use completion.
2973           (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
2974       (icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") t)
2975       (message "`%s' is now %s" opt (eval sym))))
2976   "Increment value of option: " obarray nil 'must-confirm nil ; `completing-read' args
2977   (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
2978   ((enable-recursive-minibuffers            t) ; Bindings
2979    (alt-fn                                  nil)
2980    (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
2981    (icicle-must-pass-after-match-predicate
2982     #'(lambda (s) (memq (get (intern s) 'custom-type) '(number integer float))))
2983    (icicle-candidate-alt-action-fn
2984     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "option"))))
2985    (icicle-all-candidates-list-alt-action-fn ; M-|'
2986     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option"))))
2987   (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))) ; First code
2988
2989 ;;;###autoload (autoload 'icicle-increment-variable "icicles-cmd1.el")
2990 (icicle-define-command icicle-increment-variable ; Command name
2991   "Increment variable's value using the arrow keys (`up', `down').
2992 With a prefix arg, only numeric user options are candidates.
2993 With no prefix arg, all variables are candidates, even those that are
2994  not numeric. 
2995 This command needs library `doremi.el'." ; Doc string
2996   (lambda (var)                         ; Action function
2997     (let ((sym                                     (intern var))
2998           ;; Restore this before we read number, since that might use completion.
2999           (icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
3000       (icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") prefix-arg)
3001       (message "`%s' is now %s" var (eval sym))))
3002   "Increment value of variable: " obarray nil 'must-confirm nil ; `completing-read' args
3003   (if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
3004   ((enable-recursive-minibuffers            t) ; Bindings
3005    (prefix-arg                              current-prefix-arg)
3006    (alt-fn                                  nil)
3007    (icicle-orig-must-pass-after-match-pred  icicle-must-pass-after-match-predicate)
3008    (icicle-must-pass-after-match-predicate
3009     (if prefix-arg
3010         #'(lambda (s) (memq (get (intern s) 'custom-type) '(number integer float)))
3011       #'(lambda (s) (boundp (intern s)))))
3012    (icicle-candidate-alt-action-fn
3013     (or icicle-candidate-alt-action-fn
3014         (setq alt-fn  (icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
3015    (icicle-all-candidates-list-alt-action-fn ; M-|'
3016     (or icicle-all-candidates-list-alt-action-fn alt-fn
3017         (icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
3018   (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))) ; First code
3019
3020 ;;;###autoload
3021 (defun icicle-doremi-increment-variable+ (variable &optional increment optionp)
3022   "Increment VARIABLE by INCREMENT (default 1).
3023 Use arrow key `up' or `down' or mouse wheel to increase or decrease.
3024 You can use the `Meta' key (e.g. `M-up') to increment in larger steps.
3025
3026 Interactively, you can choose VARIABLE using completion.
3027 With a prefix arg, only user options are available to choose from.
3028 Raises an error if VARIABLE's value is not a number."
3029   (interactive
3030    (let ((symb                                      (or (and (fboundp 'symbol-nearest-point)
3031                                                              (symbol-nearest-point))
3032                                                         (and (symbolp (variable-at-point))
3033                                                              (variable-at-point))))
3034          (enable-recursive-minibuffers              t)
3035          (icicle-orig-must-pass-after-match-pred    icicle-must-pass-after-match-predicate)
3036          (icicle-must-pass-after-match-predicate    (if current-prefix-arg
3037                                                         #'(lambda (s) (user-variable-p (intern s)))
3038                                                       #'(lambda (s) (boundp (intern s))))))
3039      (list (intern (completing-read "Increment variable: " obarray nil t nil nil
3040                                     (and symb (symbol-name symb)) t))
3041            ;; Restore this before we read number, since that might use completion.
3042            (let ((icicle-must-pass-after-match-predicate  icicle-orig-must-pass-after-match-pred))
3043              (icicle-read-number "Increment (amount): "))
3044            current-prefix-arg)))
3045   (unless (require 'doremi nil t) (error "This command needs library `doremi.el'."))
3046   (unless increment (setq increment 1))
3047   (unless (numberp (symbol-value variable))
3048     (error "Variable's value is not a number: %S" (symbol-value variable)))
3049   (doremi (lambda (new-val)
3050             (set variable  new-val)
3051             new-val)
3052           (symbol-value variable)
3053           increment))
3054
3055 ;;;###autoload (autoload 'icicle-bookmark-list "icicles-cmd1.el")
3056 (icicle-define-command icicle-bookmark-list ; Command name
3057   "Choose a list of bookmark names.
3058 If `icicle-bookmark-types' is non-nil, then it is a list of bookmark
3059 types and only bookmarks of those types are candidates.
3060
3061 You can use `S-delete' during completion to delete a candidate bookmark.
3062 The list of bookmark names (strings) is returned." ; Doc string
3063   (lambda (name) (push (icicle-substring-no-properties (icicle-transform-multi-completion name))
3064                        bmk-names))      ; Action function
3065   "Choose bookmark (`RET' when done): " icicle-candidates-alist nil ; `completing-read' args
3066   (not icicle-show-multi-completion-flag)
3067   nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
3068   (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
3069   ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
3070    (completion-ignore-case                 bookmark-completion-ignore-case)
3071    (icicle-list-use-nth-parts              '(1))
3072    (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
3073                                                nil
3074                                              (if (facep 'file-name-shadow)
3075                                                  '((2 (face file-name-shadow))
3076                                                    (3 (face bookmark-menu-heading)))
3077                                                '((3 (face bookmark-menu-heading))))))
3078    (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
3079    (icicle-whole-candidate-as-text-prop-p  t)
3080    (icicle-transform-before-sort-p         t)
3081    (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
3082    (types                                  icicle-bookmark-types)
3083    (icicle-candidates-alist                ())
3084    (bmk-names                              ())
3085    (icicle-sort-orders-alist
3086     (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
3087               ("by bookmark name" . icicle-alpha-p))
3088             (and (featurep 'bookmark+)
3089                  (append
3090                   '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
3091                     ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
3092                   (and (icicle-set-intersection types '("info" "region"))
3093                        '(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
3094                   (and (icicle-set-intersection types '("gnus" "region"))
3095                        '(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
3096                   (and (icicle-set-intersection types '("url" "region"))
3097                        '(("by URL" (bmkp-url-cp) icicle-alpha-p)))
3098                   (and (icicle-set-difference types
3099                                               '("bookmark-list" "desktop" "gnus" "info" "man" "url"))
3100                        '(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
3101                                               bmkp-local-file-type-cp bmkp-handler-cp)
3102                           icicle-alpha-p)))
3103                   (and (icicle-set-difference
3104                         types '("bookmark-list" "desktop" "dired" "non-file"))
3105                        '(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
3106                   (and (icicle-set-intersection types
3107                                                 '("local-file" "file" "dired" "region"))
3108                        '(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
3109                          ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
3110                          ("by last local file access"
3111                           (bmkp-local-file-accessed-more-recently-cp)
3112                           icicle-alpha-p)
3113                          ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
3114                           icicle-alpha-p)))
3115                   (and (not (equal types '("desktop")))
3116                        '(("by last buffer or file access"
3117                           (bmkp-buffer-last-access-cp
3118                            bmkp-local-file-accessed-more-recently-cp)
3119                           icicle-alpha-p)))
3120                   (and (get-buffer "*Bookmark List*")
3121                        '(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
3122                           icicle-alpha-p)))))
3123             '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
3124               ("case insensitive" . icicle-case-insensitive-string-less-p))))         
3125    (icicle-candidate-help-fn
3126     #'(lambda (cand)
3127         (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
3128           (setq cand  (funcall icicle-get-alist-candidate-function cand))
3129           (setq cand  (cons (caar cand) (cdr cand))))
3130         (if (featurep 'bookmark+)
3131             (if current-prefix-arg
3132                 (bmkp-describe-bookmark-internals cand)
3133               (bmkp-describe-bookmark cand))
3134           (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand))))))
3135   (progn                                ; First code
3136     (message "Gathering bookmarks...")
3137     (unless types  (setq types '(all)))
3138     (dolist (type  types)
3139       (setq icicle-candidates-alist
3140             (nconc icicle-candidates-alist
3141                    (if (not (featurep 'bookmark+))
3142                        (mapcar #'(lambda (cand) (list (icicle-candidate-short-help
3143                                                        (icicle-bookmark-help-string cand)
3144                                                        (icicle-bookmark-propertize-candidate cand))))
3145                                (if (eq type 'all)
3146                                    bookmark-alist
3147                                  (funcall (intern (format "bmkp-%s-alist-only" type)))))
3148                      (bookmark-maybe-load-default-file) ; Load bookmarks, define `bookmark-alist'.
3149                      (mapcar (if icicle-show-multi-completion-flag
3150                                  #'(lambda (bmk)
3151                                      ;; Ignore errors, e.g. from bad bookmark.
3152                                      (icicle-condition-case-no-debug nil
3153                                          (let* ((bname     (bookmark-name-from-full-record bmk))
3154                                                 (guts      (bookmark-get-bookmark-record bmk))
3155                                                 (file      (bookmark-get-filename bmk))
3156                                                 (buf       (bmkp-get-buffer-name bmk))
3157                                                 (file/buf
3158                                                  (if (and buf
3159                                                           (equal file bmkp-non-file-filename))
3160                                                      buf
3161                                                    file))
3162                                                 (tags      (bmkp-get-tags bmk)))
3163                                            (cons `(,(icicle-candidate-short-help
3164                                                      (icicle-bookmark-help-string bname)
3165                                                      (icicle-bookmark-propertize-candidate bname))
3166                                                    ,file/buf
3167                                                    ,@(and tags (list (format "%S" tags))))
3168                                                  guts))
3169                                        (error nil)))
3170                                #'(lambda (bmk)
3171                                    ;; Ignore errors, e.g. from bad bookmark.
3172                                    (icicle-condition-case-no-debug nil
3173                                        (let ((bname  (bookmark-name-from-full-record bmk))
3174                                              (guts   (bookmark-get-bookmark-record bmk)))
3175                                          (cons (icicle-candidate-short-help
3176                                                 (icicle-bookmark-help-string bname)
3177                                                 (icicle-bookmark-propertize-candidate bname))
3178                                                guts))
3179                                      (error nil))))
3180                              (bmkp-sort-omit
3181                               (if (eq type 'all)
3182                                   bookmark-alist
3183                                 (funcall (intern (format "bmkp-%s-alist-only" type)))))))))))
3184   (icicle-bookmark-cleanup-on-quit)     ; Undo code
3185   (prog1 (setq bmk-names  (nreverse (delete "" bmk-names))) ; Last code - return the list.
3186     (icicle-bookmark-cleanup)
3187     (when (interactive-p) (message "Bookmarks: %S" bmk-names))))
3188
3189 ;;;###autoload
3190 (defun icicle-bookmark-cmd (&optional parg) ; Bound to what `bookmark-set' is bound to (`C-x r m').
3191   "Set bookmark or visit bookmark(s).
3192 With a negative prefix arg, visit bookmark(s), using
3193   `icicle-bookmark-other-window' (see that command for more info).
3194
3195 Otherwise, set a bookmark, as follows:
3196
3197 * No prefix arg: Prompt for the bookmark name.
3198
3199   If feature `bookmark+' is present:
3200
3201   . You can use (lax) completion for the bookmark name.
3202     The candidates are bookmarks in the current buffer (or all
3203     bookmarks if there are none in this buffer).
3204
3205   . If the region is active and nonempty, then use the buffer name
3206     followed by the region prefix as the default name.
3207
3208   If feature `bookmark+' is not present, then completion is not
3209   available, and the default bookmark name is the last one used in
3210   this buffer.
3211
3212   Note: You can use command `icicle-bookmark-set' with a numeric
3213   prefix arg if you want to complete against all bookmark names,
3214   instead of those for the current buffer.
3215
3216 * Plain prefix arg (`C-u'): Same as no prefix arg, but do not
3217   overwrite any existing bookmark that has the same name.
3218
3219 * Non-negative numeric prefix arg: Do not prompt for bookmark name.
3220   If feature `bookmark+' is present and the region is active and
3221     nonempty, then use the buffer name followed by a prefix of the
3222     region text as the bookmark name.
3223   Otherwise, use the buffer name followed by the text of the current
3224     line, starting at point.
3225   Use at most `icicle-bookmark-name-length-max' chars, in either case.
3226   If the prefix arg is 0, then do not overwrite any existing bookmark
3227     that has the same name.
3228
3229 By default, Icicle mode remaps all key sequences that are normally
3230 bound to `bookmark-set' to `icicle-bookmark-cmd'.  If you do not want
3231 this remapping, then customize option `icicle-top-level-key-bindings'.
3232 In particular, you might prefer to remap `bookmark-set' to
3233 `icicle-bookmark-set' (see Note, above)."
3234   (interactive "P")
3235   (if (and parg (< (prefix-numeric-value parg) 0))
3236       (icicle-bookmark-other-window)
3237     (if (or (not parg) (consp parg))
3238         (icicle-bookmark-set nil parg 'PSEUDO-INTERACTIVEP)
3239       (let* ((regionp    (and (featurep 'bookmark+)  transient-mark-mode  mark-active
3240                               (not (eq (region-beginning) (region-end)))))
3241              (name-beg   (if regionp (region-beginning) (point)))
3242              (name-end   (if regionp (region-end) (save-excursion (end-of-line) (point))))
3243              (def-name   (concat (buffer-name) ": " (buffer-substring name-beg name-end)))
3244              (trim-name  (replace-regexp-in-string
3245                           "\n" " " (substring def-name 0 (min icicle-bookmark-name-length-max
3246                                                               (length def-name))))))
3247         (message "Setting bookmark `%s'" trim-name) (sit-for 2)
3248         (bookmark-set trim-name (and parg (or (consp parg)
3249                                               (zerop (prefix-numeric-value parg)))))))))
3250
3251 ;;;###autoload
3252 (defun icicle-bookmark-set (&optional name parg interactivep) ; `C-x r m'
3253   "With `Bookmark+', this is `bookmark-set' with Icicles multi-completions.
3254 In particular, you can use (lax) completion for the bookmark name.
3255 Without library `Bookmark+', this is the same as vanilla Emacs
3256 `bookmark-set'."
3257   (interactive (list nil current-prefix-arg t))
3258   (if (not (featurep 'bookmark+))
3259       (bookmark-set name parg)
3260     (unwind-protect
3261          (let ((enable-recursive-minibuffers           t) ; In case read input, e.g. File changed...
3262                (completion-ignore-case                 bookmark-completion-ignore-case)
3263                (prompt                                 "Bookmark: ")
3264                (icicle-list-use-nth-parts              '(1))
3265                (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
3266                                                            nil
3267                                                          (if (facep 'file-name-shadow)
3268                                                              '((2 (face file-name-shadow))
3269                                                                (3 (face bookmark-menu-heading)))
3270                                                            '((3 (face bookmark-menu-heading))))))
3271                (icicle-transform-function              (and (not (interactive-p))
3272                                                             icicle-transform-function))
3273                (icicle-whole-candidate-as-text-prop-p  t)
3274                (icicle-transform-before-sort-p         t)
3275                (icicle-sort-orders-alist
3276                 (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
3277                           ("by bookmark name" . icicle-alpha-p))
3278                         (and (featurep 'bookmark+)
3279                              '(("by last bookmark access" (bmkp-bookmark-last-access-cp)
3280                                 icicle-alpha-p)
3281                                ("by bookmark visit frequency" (bmkp-visited-more-cp)
3282                                 icicle-alpha-p)
3283                                ("by last buffer or file access"
3284                                 (bmkp-buffer-last-access-cp
3285                                  bmkp-local-file-accessed-more-recently-cp)
3286                                 icicle-alpha-p)
3287                                ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
3288                                 icicle-alpha-p)
3289                                ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
3290                                ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
3291                                ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
3292                                ("by last local file access"
3293                                 (bmkp-local-file-accessed-more-recently-cp)
3294                                 icicle-alpha-p)
3295                                ("by last local file update"
3296                                 (bmkp-local-file-updated-more-recently-cp)
3297                                 icicle-alpha-p)
3298                                ("by Info location" (bmkp-info-cp) icicle-alpha-p)
3299                                ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
3300                                ("by URL" (bmkp-url-cp) icicle-alpha-p)
3301                                ("by bookmark type"
3302                                 (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
3303                                  bmkp-local-file-type-cp bmkp-handler-cp)
3304                                 icicle-alpha-p)))
3305                         '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
3306                           ("case insensitive" . icicle-case-insensitive-string-less-p))))
3307                (icicle-candidate-help-fn
3308                 #'(lambda (cand)
3309                     (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
3310                       (setq cand  (funcall icicle-get-alist-candidate-function cand))
3311                       (setq cand  (cons (caar cand) (cdr cand))))
3312                     (if (featurep 'bookmark+)
3313                         (if current-prefix-arg
3314                             (bmkp-describe-bookmark-internals cand)
3315                           (bmkp-describe-bookmark cand))
3316                       (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
3317                (icicle-candidates-alist
3318                 (if (not (featurep 'bookmark+))
3319                     (mapcar #'(lambda (cand)
3320                                 (list (icicle-candidate-short-help
3321                                        (icicle-bookmark-help-string cand)
3322                                        (icicle-bookmark-propertize-candidate cand))))
3323                             (bookmark-all-names)) ; Loads bookmarks file.
3324                   (bookmark-maybe-load-default-file) ; Loads bookmarks file.
3325                   (mapcar (if icicle-show-multi-completion-flag
3326                               #'(lambda (bmk)
3327                                   (let* ((bname     (bookmark-name-from-full-record bmk))
3328                                          (guts      (bookmark-get-bookmark-record bmk))
3329                                          (tags      (bmkp-get-tags bmk))
3330                                          (file      (bookmark-get-filename bmk))
3331                                          (buf       (bmkp-get-buffer-name bmk))
3332                                          (file/buf
3333                                           (if (and buf (equal file bmkp-non-file-filename))
3334                                               buf
3335                                             file)))
3336                                     (cons `(,(icicle-candidate-short-help
3337                                               (icicle-bookmark-help-string bname)
3338                                               (icicle-bookmark-propertize-candidate bname))
3339                                             ,file/buf
3340                                             ,@(and tags (list (format "%S" tags))))
3341                                           guts)))
3342                             #'(lambda (bmk)
3343                                 (let ((bname  (bookmark-name-from-full-record bmk))
3344                                       (guts   (bookmark-get-bookmark-record bmk)))
3345                                   (cons (icicle-candidate-short-help
3346                                          (icicle-bookmark-help-string bname)
3347                                          (icicle-bookmark-propertize-candidate bname))
3348                                         guts))))
3349                           (bmkp-sort-omit
3350                            (and (or (not parg) (consp parg)) ; No numeric PARG: all bookmarks.
3351                                 (or (bmkp-specific-buffers-alist-only)
3352                                     bookmark-alist)))))))
3353            (require 'bookmark)
3354            (when (featurep 'bookmark+)
3355              ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
3356              (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
3357                (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
3358                (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
3359                (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
3360                (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
3361                (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
3362                (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
3363                (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
3364                (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
3365                (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; C-M-@
3366                (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
3367                  'icicle-bookmark-specific-buffers-narrow)
3368                (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
3369                  'icicle-bookmark-specific-files-narrow)
3370                (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
3371                  'icicle-bookmark-this-buffer-narrow)
3372                (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
3373                  'icicle-bookmark-bookmark-list-narrow)
3374                (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
3375                  'icicle-bookmark-local-file-narrow)
3376                (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
3377                  'icicle-bookmark-info-narrow)
3378                (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
3379                  'icicle-bookmark-desktop-narrow)))
3380            (setq bookmark-current-point   (point)
3381                  bookmark-current-buffer  (current-buffer))
3382            (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
3383            (let* ((record   (bookmark-make-record))
3384                   (regionp  (and transient-mark-mode mark-active (not (eq (mark) (point)))))
3385                   (regname  (concat (buffer-name) ": "
3386                                     (buffer-substring (if regionp (region-beginning) (point))
3387                                                       (if regionp
3388                                                           (region-end)
3389                                                         (save-excursion (end-of-line) (point))))))
3390                   (defname  (bmkp-replace-regexp-in-string
3391                              "\n" " "
3392                              (cond (regionp
3393                                     (save-excursion
3394                                       (goto-char (region-beginning))
3395                                       (skip-chars-forward " ") (setq bookmark-yank-point  (point)))
3396                                     (substring regname 0 (min bmkp-bookmark-name-length-max
3397                                                               (length regname))))
3398                                    ((eq major-mode 'w3m-mode) w3m-current-title)
3399                                    ((eq major-mode 'gnus-summary-mode)
3400                                     (elt (gnus-summary-article-header) 1))
3401                                    ((memq major-mode '(Man-mode woman-mode))
3402                                     (buffer-substring (point-min) (save-excursion
3403                                                                     (goto-char (point-min))
3404                                                                     (skip-syntax-forward "^ ")
3405                                                                     (point))))
3406                                    (t (car record)))))
3407                   (bname    (or name
3408                                 (icicle-transform-multi-completion
3409                                  (bmkp-completing-read-lax "Set bookmark " defname
3410                                                                 icicle-candidates-alist
3411                                                                 nil bookmark-history)))))
3412              (when (string-equal bname "") (setq bname  defname))
3413              (bookmark-store bname (cdr record) (consp parg))
3414              (when (and bmkp-prompt-for-tags-flag interactivep)
3415                (bmkp-add-tags bname (bmkp-read-tags-completing)))
3416              (case (and (boundp 'bmkp-auto-light-when-set) bmkp-auto-light-when-set)
3417                (autonamed-bookmark       (when (bmkp-autonamed-bookmark-p bname)
3418                                            (bmkp-light-bookmark bname)))
3419                (non-autonamed-bookmark   (unless (bmkp-autonamed-bookmark-p bname)
3420                                            (bmkp-light-bookmark bname)))
3421                (any-bookmark             (bmkp-light-bookmark bname))
3422                (autonamed-in-buffer      (bmkp-light-bookmarks
3423                                           (bmkp-remove-if-not
3424                                            #'bmkp-autonamed-bookmark-p
3425                                            (bmkp-this-buffer-alist-only)) nil 'MSG))
3426                (non-autonamed-in-buffer  (bmkp-light-bookmarks
3427                                           (bmkp-remove-if
3428                                            #'bmkp-autonamed-bookmark-p
3429                                            (bmkp-this-buffer-alist-only)) nil 'MSG))
3430                (all-in-buffer            (bmkp-light-this-buffer nil 'MSG)))
3431              (run-hooks 'bmkp-after-set-hook)
3432              (if bookmark-use-annotations
3433                  (bookmark-edit-annotation bname)
3434                (goto-char bookmark-current-point))))
3435       (icicle-bookmark-cleanup))))
3436
3437 ;;;###autoload (autoload 'icicle-bookmark "icicles-cmd1.el")
3438 (icicle-define-command icicle-bookmark  ; Command name
3439   "Jump to a bookmark.
3440 With a plain prefix argument (`C-u'), reverse the effect of option
3441 `icicle-bookmark-refresh-cache-flag'.
3442
3443 During completion, you can use `S-delete' on a bookmark to delete it.
3444
3445 If you also use library `Bookmark+', then:
3446
3447  * `C-M-RET' shows detailed info about the current bookmark candidate.
3448    `C-u C-M-RET' shows the complete, internal info for the bookmark.
3449    Likewise, for the other candidate help keys: `C-M-down' etc.
3450    (And the mode line always shows summary info about the bookmark.)
3451    
3452  * You can use `C-,' to sort bookmarks in many different ways,
3453    according to their properties.
3454
3455  * In `*Completions*', the candidate bookmarks are highlighted
3456    according to their type.  You can customize the highlighting faces:
3457
3458   `bmkp-bad-bookmark'              - possibly bad bookmark
3459   `bmkp-bookmark-list'             - bookmark list
3460   `bmkp-buffer'                    - buffer
3461   `bmkp-desktop'                   - desktop
3462   `bmkp-function'                  - function bookmark
3463   `bmkp-gnus'                      - Gnus article
3464   `bmkp-info'                      - Info node
3465   `bmkp-local-directory'           - local directory
3466   `bmkp-local-file-with-region'    - local file with a region
3467   `bmkp-local-file-without-region' - local file without a region
3468   `bmkp-man'                       - `man' page
3469   `bmkp-non-file'                  - non-file (no current buffer)
3470   `bmkp-remote-file'               - remote-file
3471   `bmkp-sequence'                  - sequence bookmark
3472   `bmkp-url'                       - URL
3473
3474  * In `*Completions*', if option `icicle-show-multi-completion-flag'
3475    is non-nil, then each completion candidate is a multi-completion:
3476
3477     a. the bookmark name
3478     b. the bookmark file or buffer name
3479     c. any tags
3480
3481    You can match any parts of the multi-completion.  You can toggle
3482    the option (for the next command) using `M-m' during completion.
3483    For example, you can match all bookmarks that have tags by typing:
3484
3485      C-M-j . * C-M-j S-TAB
3486
3487    (Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string'.)
3488
3489  * You can narrow the current completion candidates to bookmarks of a
3490    given type:
3491
3492    `C-M-b'   - non-file (buffer) bookmarks
3493    `C-M-B'   - bookmark-list bookmarks
3494    `C-M-d'   - Dired bookmarks
3495    `C-M-f'   - file bookmarks
3496    `C-M-F'   - local-file bookmarks
3497    `C-M-g'   - Gnus bookmarks
3498    `C-M-I'   - Info bookmarks
3499    `C-M-K'   - desktop bookmarks
3500    `C-M-m'   - `man' pages
3501    `C-M-r'   - bookmarks with regions
3502    `C-M-u'   - URL bookmarks
3503    `C-M-w'   - W3M (URL) bookmarks
3504    `C-M-@'   - remote-file bookmarks
3505    `C-M-.'   - bookmarks for the current buffer
3506    `C-M-= b' - bookmarks for specific buffers
3507    `C-M-= f' - bookmarks for specific files
3508
3509    See also the individual multi-commands for different bookmark
3510    types: `icicle-bookmark-info-other-window' etc.
3511
3512 If you also use library `crosshairs.el', then the visited bookmark
3513 position is highlighted."               ; Doc string
3514   (lambda (cand) (icicle-bookmark-jump (icicle-transform-multi-completion cand))) ; Action
3515   prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag) ; `completing-read' args
3516   nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
3517   (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
3518   ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
3519    (completion-ignore-case                 bookmark-completion-ignore-case)
3520    (prompt                                 "Bookmark: ")
3521    (icicle-list-use-nth-parts              '(1))
3522    (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
3523                                                nil
3524                                              (if (facep 'file-name-shadow)
3525                                                  '((2 (face file-name-shadow))
3526                                                    (3 (face bookmark-menu-heading)))
3527                                                '((3 (face bookmark-menu-heading))))))
3528    (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
3529    (icicle-whole-candidate-as-text-prop-p  t)
3530    (icicle-transform-before-sort-p         t)
3531    (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
3532    (icicle-sort-orders-alist
3533     (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
3534               ("by bookmark name" . icicle-alpha-p))
3535             (and (featurep 'bookmark+)
3536                  '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
3537                    ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
3538                    ("by last buffer or file access" (bmkp-buffer-last-access-cp
3539                                                      bmkp-local-file-accessed-more-recently-cp)
3540                     icicle-alpha-p)
3541                    ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
3542                     icicle-alpha-p)
3543                    ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
3544                    ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
3545                    ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
3546                    ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
3547                     icicle-alpha-p)
3548                    ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
3549                     icicle-alpha-p)
3550                    ("by Info location" (bmkp-info-cp) icicle-alpha-p)
3551                    ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
3552                    ("by URL" (bmkp-url-cp) icicle-alpha-p)
3553                    ("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
3554                                         bmkp-local-file-type-cp bmkp-handler-cp)
3555                     icicle-alpha-p)))
3556             '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
3557               ("case insensitive" . icicle-case-insensitive-string-less-p))))
3558    (icicle-candidate-help-fn
3559     #'(lambda (cand)
3560         (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
3561           (setq cand  (funcall icicle-get-alist-candidate-function cand))
3562           (setq cand  (cons (caar cand) (cdr cand))))
3563         (if (featurep 'bookmark+)
3564             (if current-prefix-arg
3565                 (bmkp-describe-bookmark-internals cand)
3566               (bmkp-describe-bookmark cand))
3567           (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
3568    (icicle-candidates-alist
3569     (if (not (featurep 'bookmark+))
3570         (mapcar #'(lambda (cand)
3571                     (list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
3572                                                        (icicle-bookmark-propertize-candidate cand))))
3573                 (bookmark-all-names))   ; Loads bookmarks file, defining `bookmark-alist'.
3574       (bookmark-maybe-load-default-file) ; Loads bookmarks file, defining `bookmark-alist'.
3575       (mapcar (if icicle-show-multi-completion-flag
3576                   #'(lambda (bmk)
3577                       ;; Ignore errors, e.g. from bad or stale bookmark records.
3578                       (icicle-condition-case-no-debug nil
3579                           (let* ((bname     (bookmark-name-from-full-record bmk))
3580                                  (guts      (bookmark-get-bookmark-record bmk))
3581                                  (file      (bookmark-get-filename bmk))
3582                                  (buf       (bmkp-get-buffer-name bmk))
3583                                  (file/buf  (if (and buf (equal file bmkp-non-file-filename))
3584                                                 buf
3585                                               file))
3586                                  (tags      (bmkp-get-tags bmk)))
3587                             (cons `(,(icicle-candidate-short-help
3588                                       (icicle-bookmark-help-string bname)
3589                                       (icicle-bookmark-propertize-candidate bname))
3590                                     ,file/buf
3591                                     ,@(and tags (list (format "%S" tags))))
3592                                   guts))
3593                         (error nil)))
3594                 #'(lambda (bmk)
3595                     ;; Ignore errors, e.g. from bad or stale bookmark records.
3596                     (icicle-condition-case-no-debug nil
3597                         (let ((bname  (bookmark-name-from-full-record bmk))
3598                               (guts   (bookmark-get-bookmark-record bmk)))
3599                           (cons (icicle-candidate-short-help
3600                                  (icicle-bookmark-help-string bname)
3601                                  (icicle-bookmark-propertize-candidate bname))
3602                                 guts))
3603                       (error nil))))
3604               (or (and (or (and (not icicle-bookmark-refresh-cache-flag)
3605                                 (not (consp current-prefix-arg)))
3606                            (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
3607                        bmkp-sorted-alist)
3608                   (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist)))))))
3609   (progn                                ; First code
3610     (require 'bookmark)
3611     (when (featurep 'bookmark+)
3612       ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
3613       (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
3614         (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
3615         (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
3616         (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
3617         (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
3618         (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
3619         (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
3620         (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
3621         (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
3622         (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; `C-M-@'
3623         (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
3624           'icicle-bookmark-specific-buffers-narrow)
3625         (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
3626           'icicle-bookmark-specific-files-narrow)
3627         (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
3628           'icicle-bookmark-this-buffer-narrow)
3629         (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
3630           'icicle-bookmark-bookmark-list-narrow)
3631         (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
3632           'icicle-bookmark-local-file-narrow)
3633         (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
3634           'icicle-bookmark-info-narrow)
3635         (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
3636           'icicle-bookmark-desktop-narrow))))
3637   (icicle-bookmark-cleanup-on-quit)     ; Undo code
3638   (icicle-bookmark-cleanup))            ; Last code
3639
3640 ;;;###autoload (autoload 'icicle-bookmark-other-window "icicles-cmd1.el")
3641 (icicle-define-command icicle-bookmark-other-window ; Command name
3642   "Jump to a bookmark in another window.
3643 Same as `icicle-bookmark', but uses another window." ; Doc string
3644   (lambda (cand) (icicle-bookmark-jump-other-window (icicle-transform-multi-completion cand)))
3645   prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag) ; `completing-read' args
3646   nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
3647   (and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
3648   ((enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
3649    (completion-ignore-case                 bookmark-completion-ignore-case)
3650    (prompt                                 "Bookmark: ")
3651    (icicle-list-use-nth-parts              '(1))
3652    (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
3653                                                nil
3654                                              (if (facep 'file-name-shadow)
3655                                                  '((2 (face file-name-shadow))
3656                                                    (3 (face bookmark-menu-heading)))
3657                                                '((3 (face bookmark-menu-heading))))))
3658    (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
3659    (icicle-whole-candidate-as-text-prop-p  t)
3660    (icicle-transform-before-sort-p         t)
3661    (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
3662    (icicle-sort-orders-alist
3663     (append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
3664               ("by bookmark name" . icicle-alpha-p))
3665             (and (featurep 'bookmark+)
3666                  '(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
3667                    ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
3668                    ("by last buffer or file access" (bmkp-buffer-last-access-cp
3669                                                      bmkp-local-file-accessed-more-recently-cp)
3670                     icicle-alpha-p)
3671                    ("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
3672                     icicle-alpha-p)
3673                    ("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
3674                    ("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
3675                    ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
3676                    ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
3677                     icicle-alpha-p)
3678                    ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
3679                     icicle-alpha-p)
3680                    ("by Info location" (bmkp-info-cp) icicle-alpha-p)
3681                    ("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
3682                    ("by URL" (bmkp-url-cp) icicle-alpha-p)
3683                    ("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
3684                                         bmkp-local-file-type-cp bmkp-handler-cp)
3685                     icicle-alpha-p)))
3686             '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
3687               ("case insensitive" . icicle-case-insensitive-string-less-p))))
3688    (icicle-candidate-help-fn
3689     #'(lambda (cand)
3690         (when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
3691           (setq cand  (funcall icicle-get-alist-candidate-function cand))
3692           (setq cand  (cons (caar cand) (cdr cand))))
3693         (if (featurep 'bookmark+)
3694             (if current-prefix-arg
3695                 (bmkp-describe-bookmark-internals cand)
3696               (bmkp-describe-bookmark cand))
3697           (icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
3698    (icicle-candidates-alist
3699     (if (not (featurep 'bookmark+))
3700         (mapcar #'(lambda (cand)
3701                     (list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
3702                                                        (icicle-bookmark-propertize-candidate cand))))
3703                 (bookmark-all-names))   ; Loads bookmarks file, defining `bookmark-alist'.
3704       (bookmark-maybe-load-default-file) ; Loads bookmarks file, defining `bookmark-alist'.
3705       (mapcar (if icicle-show-multi-completion-flag
3706                   #'(lambda (bmk)
3707                       ;; Ignore errors, e.g. from bad or stale bookmark records.
3708                       (icicle-condition-case-no-debug nil
3709                           (let* ((bname     (bookmark-name-from-full-record bmk))
3710                                  (guts      (bookmark-get-bookmark-record bmk))
3711                                  (file      (bookmark-get-filename bmk))
3712                                  (buf       (bmkp-get-buffer-name bmk))
3713                                  (file/buf  (if (and buf (equal file bmkp-non-file-filename))
3714                                                 buf
3715                                               file))
3716                                  (tags      (bmkp-get-tags bmk)))
3717                             (cons `(,(icicle-candidate-short-help
3718                                       (icicle-bookmark-help-string bname)
3719                                       (icicle-bookmark-propertize-candidate bname))
3720                                     ,file/buf
3721                                     ,@(and tags (list (format "%S" tags))))
3722                                   guts))
3723                         (error nil)))
3724                 #'(lambda (bmk)
3725                     ;; Ignore errors, e.g. from bad or stale bookmark records.
3726                     (icicle-condition-case-no-debug nil
3727                         (let ((bname  (bookmark-name-from-full-record bmk))
3728                               (guts   (bookmark-get-bookmark-record bmk)))
3729                           (cons (icicle-candidate-short-help
3730                                  (icicle-bookmark-help-string bname)
3731                                  (icicle-bookmark-propertize-candidate bname))
3732                                 guts))
3733                       (error nil))))
3734               (or (and (or (and (not icicle-bookmark-refresh-cache-flag)
3735                                 (not (consp current-prefix-arg)))
3736                            (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
3737                        bmkp-sorted-alist)
3738                   (setq bmkp-sorted-alist  (bmkp-sort-omit bookmark-alist)))))))
3739   (progn                                ; First code
3740     (require 'bookmark)
3741     (when (featurep 'bookmark+)
3742       ;; Bind keys to narrow bookmark candidates by type.  Lax is for multi-completion case.
3743       (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
3744         (define-key (symbol-value map) "\C-\M-b" 'icicle-bookmark-non-file-narrow) ; `C-M-b'
3745         (define-key (symbol-value map) "\C-\M-d" 'icicle-bookmark-dired-narrow) ; `C-M-d'
3746         (define-key (symbol-value map) "\C-\M-f" 'icicle-bookmark-file-narrow) ; `C-M-f'
3747         (define-key (symbol-value map) "\C-\M-g" 'icicle-bookmark-gnus-narrow) ; `C-M-g'
3748         (define-key (symbol-value map) "\C-\M-m" 'icicle-bookmark-man-narrow) ; `C-M-m'
3749         (define-key (symbol-value map) "\C-\M-r" 'icicle-bookmark-region-narrow) ; `C-M-r'
3750         (define-key (symbol-value map) "\C-\M-u" 'icicle-bookmark-url-narrow) ; `C-M-u'
3751         (define-key (symbol-value map) "\C-\M-w" 'icicle-bookmark-w3m-narrow) ; `C-M-w'
3752         (define-key (symbol-value map) "\C-\M-@" 'icicle-bookmark-remote-file-narrow) ; `C-M-@'
3753         (define-key (symbol-value map) [(control meta ?=) ?b] ; `C-M-= b'
3754           'icicle-bookmark-specific-buffers-narrow)
3755         (define-key (symbol-value map) [(control meta ?=) ?f] ; `C-M-= f'
3756           'icicle-bookmark-specific-files-narrow)
3757         (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-= .'
3758           'icicle-bookmark-this-buffer-narrow)
3759         (define-key (symbol-value map) [(control meta ?B)] ; `C-M-B'
3760           'icicle-bookmark-bookmark-list-narrow)
3761         (define-key (symbol-value map) [(control meta ?F)] ; `C-M-F'
3762           'icicle-bookmark-local-file-narrow)
3763         (define-key (symbol-value map) [(control meta ?I)] ; `C-M-I'
3764           'icicle-bookmark-info-narrow)
3765         (define-key (symbol-value map) [(control meta ?K)] ; `C-M-K'
3766           'icicle-bookmark-desktop-narrow))))
3767   (icicle-bookmark-cleanup-on-quit)     ; Undo code
3768   (icicle-bookmark-cleanup))            ; Last code
3769
3770 (defun icicle-bookmark-delete-action (cand)
3771   "Delete bookmark candidate CAND, then update `bmkp-sorted-alist'."
3772   (bookmark-delete (icicle-transform-multi-completion cand))
3773   (when (or (and (not icicle-bookmark-refresh-cache-flag)
3774                  (not (consp current-prefix-arg)))
3775             (and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
3776     (setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist))))
3777
3778 (defun icicle-bookmark-propertize-candidate (cand)
3779   "Return bookmark name CAND, with a face indicating its type."
3780   (when (featurep 'bookmark+)
3781     (put-text-property
3782      0 (length cand) 'face
3783      (cond ((bmkp-sequence-bookmark-p cand)        'bmkp-sequence)
3784            ((bmkp-function-bookmark-p cand)        'bmkp-function)
3785            ((bmkp-bookmark-list-bookmark-p cand)   'bmkp-bookmark-list)
3786            ((bmkp-desktop-bookmark-p cand)         'bmkp-desktop)
3787            ((bmkp-info-bookmark-p cand)            'bmkp-info)
3788            ((bmkp-man-bookmark-p cand)             'bmkp-man)
3789            ((bmkp-gnus-bookmark-p cand)            'bmkp-gnus)
3790            ((bmkp-url-bookmark-p cand)             'bmkp-url)
3791            ((bmkp-remote-file-bookmark-p cand)     'bmkp-remote-file)
3792            ((and (bmkp-file-bookmark-p cand)
3793                  (file-directory-p
3794                   (bookmark-get-filename cand)))        'bmkp-local-directory)
3795            ((and (bmkp-local-file-bookmark-p cand)
3796                  (bmkp-region-bookmark-p cand))    'bmkp-local-file-with-region)
3797            ((bmkp-local-file-bookmark-p cand)      'bmkp-local-file-without-region)
3798            ((and (bmkp-get-buffer-name cand)
3799                  (get-buffer (bmkp-get-buffer-name cand))
3800                  (equal (bookmark-get-filename cand)
3801                         bmkp-non-file-filename))   'bmkp-buffer)
3802            ((not (bmkp-file-bookmark-p cand))      'bmkp-non-file)
3803            (t                                           'bmkp-bad-bookmark))
3804      cand))
3805   cand)
3806
3807 ;;;###autoload
3808 (defun icicle-bookmark-jump (bookmark)
3809   "Jump to BOOKMARK.
3810 If `crosshairs.el' is loaded, then highlight the target position.
3811 You probably don't want to use this.  Use `icicle-bookmark' instead."
3812   (interactive (list (bookmark-completing-read "Jump to bookmark" bookmark-current-bookmark)))
3813   (icicle-bookmark-jump-1 bookmark))
3814
3815 ;;;###autoload
3816 (defun icicle-bookmark-jump-other-window (bookmark)
3817   "Jump to BOOKMARK in another window.
3818 If `crosshairs.el' is loaded, then highlight the target position.
3819 You probably don't want to use this.  Use
3820 `icicle-bookmark-other-window' instead."
3821   (interactive (list (bookmark-completing-read "Jump to bookmark (other window)"
3822                                                bookmark-current-bookmark)))
3823   (icicle-bookmark-jump-1 bookmark 'other-window))
3824
3825 (defun icicle-bookmark-jump-1 (bookmark &optional other-window-p)
3826   "Helper function for `icicle-bookmark-jump(-other-window)'."
3827   (unless bookmark (error "No bookmark specified"))
3828   (bookmark-maybe-historicize-string bookmark)
3829   (if (fboundp 'bookmark--jump-via)
3830       (bookmark--jump-via bookmark (if other-window-p 'pop-to-buffer 'switch-to-buffer))
3831     (let ((cell  (bookmark-jump-noselect bookmark))) ; Emacs < 23 and without `Bookmark+'.
3832       (when cell
3833         (if other-window-p
3834             (pop-to-buffer (car cell) 'other-window)
3835           (switch-to-buffer (car cell)))
3836         (goto-char (cdr cell))
3837         (unless (pos-visible-in-window-p) (recenter icicle-recenter))
3838         (progn (run-hooks 'bookmark-after-jump-hook) t)
3839         ;; If there is an annotation for this bookmark, show it in a buffer.
3840         (when bookmark-automatically-show-annotations (bookmark-show-annotation bookmark)))))
3841   ;; Unless `bmkp-use-region' and bookmark has a region, show position using crosshairs.
3842   (unless (and (boundp 'bmkp-use-region) bmkp-use-region
3843                (fboundp 'bmkp-get-end-position) (bmkp-get-end-position bookmark)
3844                (/= (bookmark-get-position bookmark) (bmkp-get-end-position bookmark)))
3845     (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))))
3846 ;; $$$$$$   (select-window (minibuffer-window))
3847 ;; $$$$$$   (select-frame-set-input-focus (selected-frame)))
3848
3849 (defun icicle-bookmark-help-string (bookmark-name)
3850   "Return a help string for BOOKMARK-NAME." ; `bmkp-*' functions are defined in `Bookmark+'.
3851   ;; Use BOOKMARK-NAME, not full bookmark BMK, as arg to vanilla bookmark functions, for Emacs < 23.
3852   (let* ((bmk         (bookmark-get-bookmark bookmark-name))
3853          (buf         (and (fboundp 'bmkp-get-buffer-name) (bmkp-get-buffer-name bmk)))
3854          (file        (bookmark-get-filename bookmark-name))
3855          (start       (bookmark-get-position bookmark-name))
3856          (end         (and (fboundp 'bmkp-get-end-position) (bmkp-get-end-position bmk)))
3857          (annot       (bookmark-get-annotation bookmark-name))
3858          (sequence-p  (and (fboundp 'bmkp-sequence-bookmark-p)
3859                            (bmkp-sequence-bookmark-p bmk)))
3860          (function-p  (and (fboundp 'bmkp-function-bookmark-p)
3861                            (bmkp-function-bookmark-p bmk)))
3862          (blist-p     (and (fboundp 'bmkp-bookmark-list-bookmark-p)
3863                            (bmkp-bookmark-list-bookmark-p bmk)))
3864          (desktop-p   (and (fboundp 'bmkp-desktop-bookmark-p)
3865                            (bmkp-desktop-bookmark-p bmk)))
3866          (dired-p     (and (fboundp 'bmkp-dired-bookmark-p) (bmkp-dired-bookmark-p bmk)))
3867          (gnus-p      (and (fboundp 'bmkp-gnus-bookmark-p) (bmkp-gnus-bookmark-p bmk)))
3868          (info-p      (and (fboundp 'bmkp-info-bookmark-p) (bmkp-info-bookmark-p bmk)))
3869          (man-p       (and (fboundp 'bmkp-man-bookmark-p) (bmkp-man-bookmark-p bmk)))
3870          (url-p       (and (fboundp 'bmkp-url-bookmark-p) (bmkp-url-bookmark-p bmk)))
3871          type-info-p no-position-p)
3872     (when (or sequence-p function-p) (setq no-position-p  t))
3873     (concat (setq type-info-p
3874                   (cond (sequence-p (format "Sequence: %S" (bookmark-prop-get bmk 'sequence)))
3875                         (function-p (let ((fn  (bookmark-prop-get bmk 'function)))
3876                                       (if (symbolp fn) (format "Function: `%s'" fn) "Function")))
3877                         (desktop-p  "Desktop, ")
3878                         (dired-p    (format "Dired %s, " file))
3879                         (gnus-p     "Gnus, ")
3880                         (info-p     "Info, ")
3881                         (man-p      (let ((man-args  (bookmark-prop-get bmk 'man-args)))
3882                                       (if man-args
3883                                           (format "`man %s', " man-args)
3884                                         ;; WoMan has no variable for the cmd name.
3885                                         (format "%s, " (bookmark-prop-get bmk 'buffer-name)))))
3886                         (url-p      "URL, ")
3887                         (t nil)))
3888             (and (not dired-p)
3889                  (or (and file (or (not (boundp 'bmkp-non-file-filename))
3890                                    (not (equal file bmkp-non-file-filename)))
3891                           (format (if type-info-p "file `%s', " "File `%s', ") file))
3892                      (and buf (format (if type-info-p "buffer `%s', " "Buffer `%s', ") buf))))
3893             (and (not no-position-p)
3894                  (if (and end (> (- end start) 0))
3895                      (format "from %d to %d (%d chars)" start end (- end start))
3896                    (format "position %d" start)))
3897             (and annot (format ", %s" annot)))))
3898
3899 ;;; MUST keep this synchronized with any general Icicle-mode `C-M-' bindings in `icicles-mode.el'.
3900 ;;  That includes things like `icicle-read+insert-file-name-keys'.
3901 (defun icicle-bookmark-cleanup ()
3902   "Cleanup code for `icicle-bookmark'.
3903 Remove crosshairs highlighting and unbind filtering keys."
3904   (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))
3905   (when (featurep 'bookmark+)
3906     (dolist (map  '(minibuffer-local-must-match-map minibuffer-local-completion-map))
3907       (define-key (symbol-value map) "\C-\M-b" nil) ; `C-M-b'
3908       (define-key (symbol-value map) [(control meta ?B)] nil) ; `C-M-B'
3909       (define-key (symbol-value map) "\C-\M-d" nil) ; `C-M-d'
3910       (define-key (symbol-value map) "\C-\M-f" nil) ; `C-M-f'
3911       (define-key (symbol-value map) [(control meta ?F)] nil) ; `C-M-F'
3912       (dolist (key  icicle-read+insert-file-name-keys) ; `C-M-F' - overrides previous.
3913         (define-key (symbol-value map) key 'icicle-read+insert-file-name))
3914       (define-key (symbol-value map) "\C-\M-g" nil) ; `C-M-g'
3915       (define-key (symbol-value map) [(control meta ?I)] nil) ; `C-M-I' (`C-M-i' is `ESC TAB')
3916       (define-key (symbol-value map) [(control meta ?K)] nil) ; `C-M-K'
3917       (define-key (symbol-value map) "\C-\M-m" nil) ; `C-M-m'
3918       (define-key (symbol-value map) "\C-\M-r" nil) ; `C-M-r'
3919       (define-key (symbol-value map) "\C-\M-w" nil) ; `C-M-w'
3920       (define-key (symbol-value map) "\C-\M-@" nil) ; `C-M-@'
3921       (define-key (symbol-value map) [(control meta ?\.)] ; `C-M-.'
3922         'icicle-toggle-dot)             ; `icicles-mode.el'.
3923       (define-key (symbol-value map) [(control meta ?=) ?b] nil) ; `C-M-= b'
3924       (define-key (symbol-value map) [(control meta ?=) ?f] nil)))) ; `C-M-= f'
3925
3926 (defun icicle-bookmark-cleanup-on-quit ()
3927   "Do `icicle-bookmark-cleanup', then return to original window."
3928   (icicle-bookmark-cleanup)
3929   (when (window-live-p icicle-orig-window)
3930     (select-window icicle-orig-window)
3931     (select-frame-set-input-focus (selected-frame))))
3932
3933 ;;; These are minibuffer commands, but we define them here instead of in `icicles-mcmd.el'.
3934
3935 ;;;###autoload
3936 (defun icicle-bookmark-bookmark-list-narrow () ; Bound to `C-M-B' in minibuffer for completion.
3937   "Narrow the bookmark candidates to bookmark-list bookmarks."
3938   (interactive)
3939   (icicle-narrow-candidates-with-predicate
3940    #'(lambda (x) (bmkp-bookmark-list-bookmark-p
3941                   (funcall icicle-get-alist-candidate-function (car x))))))
3942
3943 ;;;###autoload
3944 (defun icicle-bookmark-desktop-narrow ()   ; Bound to `C-M-K' in minibuffer for bookmark completion.
3945   "Narrow the bookmark candidates to desktop bookmarks."
3946   (interactive)
3947   (icicle-narrow-candidates-with-predicate
3948    #'(lambda (x) (bmkp-desktop-bookmark-p
3949                   (funcall icicle-get-alist-candidate-function (car x))))))
3950
3951 ;;;###autoload
3952 (defun icicle-bookmark-dired-narrow ()   ; Bound to `C-M-d' in minibuffer for bookmark completion.
3953   "Narrow the bookmark candidates to Dired bookmarks."
3954   (interactive)
3955   (icicle-narrow-candidates-with-predicate
3956    #'(lambda (x) (bmkp-dired-bookmark-p
3957                   (funcall icicle-get-alist-candidate-function (car x))))))
3958
3959 ;;;###autoload
3960 (defun icicle-bookmark-file-narrow ()   ; Bound to `C-M-f' in minibuffer for bookmark completion.
3961   "Narrow the bookmark candidates to file bookmarks."
3962   (interactive)
3963   (icicle-narrow-candidates-with-predicate
3964    #'(lambda (x) (bmkp-file-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
3965
3966 ;;;###autoload
3967 (defun icicle-bookmark-gnus-narrow ()   ; Bound to `C-M-g' in minibuffer for bookmark completion.
3968   "Narrow the bookmark candidates to Gnus bookmarks."
3969   (interactive)
3970   (icicle-narrow-candidates-with-predicate
3971    #'(lambda (x) (bmkp-gnus-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
3972
3973 ;;;###autoload
3974 (defun icicle-bookmark-info-narrow ()   ; Bound to `C-M-I' in minibuffer for bookmark completion.
3975   "Narrow the bookmark candidates to Info bookmarks."
3976   (interactive)
3977   (icicle-narrow-candidates-with-predicate
3978    #'(lambda (x) (bmkp-info-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
3979
3980 ;;;###autoload
3981 (defun icicle-bookmark-local-file-narrow () ; Bound to `C-M-F' for bookmark completion.
3982   "Narrow the bookmark candidates to local-file bookmarks."
3983   (interactive)
3984   (icicle-narrow-candidates-with-predicate
3985    #'(lambda (x) (bmkp-local-file-bookmark-p
3986                   (funcall icicle-get-alist-candidate-function (car x))))))
3987
3988 ;;;###autoload
3989 (defun icicle-bookmark-man-narrow () ; Bound to `C-M-m' in minibuffer for bookmark completion.
3990   "Narrow the bookmark candidates to `man'-page bookmarks."
3991   (interactive)
3992   (icicle-narrow-candidates-with-predicate
3993    #'(lambda (x) (bmkp-man-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
3994
3995 ;;;###autoload
3996 (defun icicle-bookmark-non-file-narrow () ; Bound to `C-M-b' in minibuffer for bookmark completion.
3997   "Narrow the bookmark candidates to non-file (buffer-only) bookmarks."
3998   (interactive)
3999   (icicle-narrow-candidates-with-predicate
4000    #'(lambda (x) (bmkp-non-file-bookmark-p
4001                   (funcall icicle-get-alist-candidate-function (car x))))))
4002
4003 ;;;###autoload
4004 (defun icicle-bookmark-region-narrow () ; Bound to `C-M-r' in minibuffer for bookmark completion.
4005   "Narrow the bookmark candidates to bookmarks with regions."
4006   (interactive)
4007   (icicle-narrow-candidates-with-predicate
4008    #'(lambda (x) (bmkp-region-bookmark-p
4009                   (funcall icicle-get-alist-candidate-function (car x))))))
4010
4011 ;;;###autoload
4012 (defun icicle-bookmark-remote-file-narrow () ; Bound to `C-M-@' in minibuf for bookmark completion.
4013   "Narrow the bookmark candidates to remote-file bookmarks."
4014   (interactive)
4015   (icicle-narrow-candidates-with-predicate
4016    #'(lambda (x) (bmkp-remote-file-bookmark-p
4017                   (funcall icicle-get-alist-candidate-function (car x))))))
4018
4019 ;;;###autoload
4020 (defun icicle-bookmark-specific-buffers-narrow (buffers) ; `C-M-= b' for bookmark completion.
4021   "Narrow the bookmark candidates to bookmarks for specific BUFFERS.
4022 You are prompted for the BUFFERS."
4023   (interactive (let ((icicle-completion-candidates  icicle-completion-candidates))
4024                  (list (icicle-bookmarked-buffer-list))))
4025   (icicle-narrow-candidates-with-predicate
4026    `(lambda (x)
4027      (member (bmkp-get-buffer-name (funcall icicle-get-alist-candidate-function (car x)))
4028       ',buffers))))
4029
4030 ;;;###autoload
4031 (defun icicle-bookmark-specific-files-narrow (files) ; `C-M-= f' in minibuf for bookmark completion.
4032   "Narrow the bookmark candidates to bookmarks for specific FILES.
4033 You are prompted for the FILES."
4034   (interactive (list (icicle-bookmarked-file-list)))
4035   (icicle-narrow-candidates-with-predicate
4036    `(lambda (x)
4037      (member (bookmark-get-filename (funcall icicle-get-alist-candidate-function (car x)))
4038       ',files))))
4039
4040 ;;;###autoload
4041 (defun icicle-bookmark-this-buffer-narrow () ; `C-M-.' in minibuffer for bookmark completion.
4042   "Narrow the bookmark candidates to bookmarks for the current buffer."
4043   (interactive)
4044   (icicle-narrow-candidates-with-predicate
4045    #'(lambda (x)
4046        (with-current-buffer icicle-orig-buff
4047          (bmkp-this-buffer-p (funcall icicle-get-alist-candidate-function (car x)))))))
4048
4049 ;;;###autoload
4050 (defun icicle-bookmark-url-narrow ()    ; Bound to `C-M-u' in minibuffer for bookmark completion.
4051   "Narrow the bookmark candidates to URL bookmarks."
4052   (interactive)
4053   (icicle-narrow-candidates-with-predicate
4054    #'(lambda (x) (bmkp-url-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
4055
4056 ;;;###autoload
4057 (defun icicle-bookmark-w3m-narrow ()    ; Bound to `C-M-w' in minibuffer for bookmark completion.
4058   "Narrow the bookmark candidates to W3M (URL) bookmarks."
4059   (interactive)
4060   (icicle-narrow-candidates-with-predicate
4061    #'(lambda (x) (bmkp-w3m-bookmark-p (funcall icicle-get-alist-candidate-function (car x))))))
4062
4063 ;;;###autoload
4064 (defmacro icicle-define-bookmark-command-1 (otherp type prompt args)
4065   "Helper macro for `icicle-define*-bookmark-command' macros.
4066 The command defined raises an error unless library `Bookmark+' can be
4067 loaded."
4068   `(icicle-define-command
4069     ,(intern (format "icicle-bookmark-%s%s" type (if otherp "-other-window" ""))) ; Command name
4070     ,(format "Jump to a %s bookmark%s.
4071 Like `icicle-bookmark%s',
4072  but with %s bookmarks only.
4073 This is a multi-command version of
4074  `bmkp-%s-jump%s'.
4075 You need library `Bookmark+' for this command."
4076              type (if otherp " in other window" "")
4077              (if otherp "-other-window" "") type
4078              type (if otherp "-other-window" "")) ; Doc string
4079     (lambda (cand) (,(if otherp 'icicle-bookmark-jump-other-window 'icicle-bookmark-jump) ; Action fn.
4080                      (icicle-transform-multi-completion cand)))
4081     prompt1 icicle-candidates-alist nil ; `completing-read' args
4082     (not icicle-show-multi-completion-flag)
4083     nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
4084     nil nil
4085     ((IGNORED1                               (unless (require 'bookmark+ nil t) ; Additional bindings
4086                                                (error "You need library `Bookmark+' for this command")))
4087      (IGNORED2                               (bookmark-maybe-load-default-file)) ; `bookmark-alist'.
4088      (enable-recursive-minibuffers           t) ; In case we read input, e.g. File changed on disk...
4089      (completion-ignore-case                 bookmark-completion-ignore-case)
4090      (prompt1                                ,(or prompt
4091                                                   (format "%s%s bookmark: "
4092                                                           (capitalize (substring type 0 1))
4093                                                           (substring type 1 (length type)))))
4094      (icicle-list-use-nth-parts              '(1))
4095      (icicle-candidate-properties-alist      (if (not icicle-show-multi-completion-flag)
4096                                                  nil
4097                                                (if (facep 'file-name-shadow)
4098                                                    '((2 (face file-name-shadow))
4099                                                      (3 (face bookmark-menu-heading)))
4100                                                  '((3 (face bookmark-menu-heading))))))
4101      (icicle-transform-function              (if (interactive-p) nil icicle-transform-function))
4102      (icicle-whole-candidate-as-text-prop-p  t)
4103      (icicle-transform-before-sort-p         t)
4104      (icicle-delete-candidate-object         'icicle-bookmark-delete-action)
4105      (icicle-sort-orders-alist
4106       (append
4107        '(("in *Bookmark List* order")   ; Renamed from "turned OFF'.
4108          ("by bookmark name" . icicle-alpha-p)
4109          ("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
4110          ("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
4111        (and (member ,type '("info" "region"))
4112         '(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
4113        (and (member ,type '("gnus" "region"))
4114         '(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
4115        (and (member ,type '("url" "region"))
4116         '(("by URL" (bmkp-url-cp) icicle-alpha-p)))
4117        (and (not (member ,type '("bookmark-list" "desktop" "gnus" "info" "man" "url")))
4118         '(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
4119                                bmkp-local-file-type-cp bmkp-handler-cp)
4120            icicle-alpha-p)))
4121        (and (not (member ,type '("bookmark-list" "desktop" "dired" "non-file")))
4122         '(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
4123        (and (member ,type '("local-file" "file" "dired" "region"))
4124         '(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
4125           ("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
4126           ("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
4127            icicle-alpha-p)
4128           ("by last local file update" (bmkp-local-file-updated-more-recently-cp)
4129            icicle-alpha-p)))
4130        (and (not (string= ,type "desktop"))
4131         '(("by last buffer or file access" (bmkp-buffer-last-access-cp
4132                                             bmkp-local-file-accessed-more-recently-cp)
4133            icicle-alpha-p)))
4134        (and (get-buffer "*Bookmark List*")
4135         '(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
4136            icicle-alpha-p)))
4137        '(("by previous use alphabetically" . icicle-historical-alphabetic-p)
4138          ("case insensitive" . icicle-case-insensitive-string-less-p))))
4139      (icicle-candidate-help-fn
4140       #'(lambda (cand)
4141           (when icicle-show-multi-completion-flag
4142             (setq cand  (funcall icicle-get-alist-candidate-function cand))
4143             (setq cand  (cons (caar cand) (cdr cand))))
4144           (if current-prefix-arg
4145               (bmkp-describe-bookmark-internals cand)
4146             (bmkp-describe-bookmark cand))))
4147      (icicle-candidates-alist
4148       (mapcar (if icicle-show-multi-completion-flag
4149                   #'(lambda (bmk)
4150                       ;; Ignore errors, e.g. from bad or stale bookmark records.
4151                       (icicle-condition-case-no-debug nil
4152                           (let* ((bname     (bookmark-name-from-full-record bmk))
4153                                  (guts      (bookmark-get-bookmark-record bmk))
4154                                  (file      (bookmark-get-filename bmk))
4155                                  (buf       (bmkp-get-buffer-name bmk))
4156                                  (file/buf  (if (and buf (equal file bmkp-non-file-filename))
4157                                                 buf
4158                                               file))
4159                                  (tags      (bmkp-get-tags bmk)))
4160                             ;; Emacs 20 byte-compiler bug prevents using backslash syntax here.
4161                             (cons (append (list (icicle-candidate-short-help
4162                                                  (icicle-bookmark-help-string bname)
4163                                                  (icicle-bookmark-propertize-candidate bname))
4164                                                 file/buf)
4165                                           (and tags (list (format "%S" tags))))
4166                                   guts))
4167                         (error nil)))
4168                 #'(lambda (bmk)
4169                     ;; Ignore errors, e.g. from bad or stale bookmark records.
4170                     (icicle-condition-case-no-debug nil
4171                         (let ((bname  (bookmark-name-from-full-record bmk))
4172                               (guts   (bookmark-get-bookmark-record bmk)))
4173                           (cons (icicle-candidate-short-help
4174                                  (icicle-bookmark-help-string bname)
4175                                  (icicle-bookmark-propertize-candidate bname))
4176                                 guts))
4177                       (error nil))))
4178        (bmkp-sort-omit (funcall ',(intern (format "bmkp-%s-alist-only" type)) ,@args)))))
4179     nil                                 ; First code
4180     (icicle-bookmark-cleanup-on-quit)   ; Undo code
4181     (icicle-bookmark-cleanup)))         ; Last code
4182
4183 ;;;###autoload
4184 (defmacro icicle-define-bookmark-command (type &optional prompt &rest args)
4185   "Define an Icicles multi-command for jumping to bookmarks of type TYPE.
4186 TYPE is a string to be used for the doc string, default prompt, and in
4187  function names.  It should be lowercase and contain no spaces.
4188 Optional arg PROMPT is the completion prompt.
4189 ARGS is a list of any additional arguments to be passed to the
4190 appropriate `bmkp-TYPE-alist-only' function."
4191   `(icicle-define-bookmark-command-1 nil ,type ,prompt ,args))
4192
4193 ;;;###autoload
4194 (defmacro icicle-define-bookmark-other-window-command (type &optional prompt &rest args)
4195   "Same as `icicle-define-bookmark-command', but command uses other window."
4196   `(icicle-define-bookmark-command-1 t ,type ,prompt ,args))
4197
4198 ;; The following sexps macro-expand to define these commands:
4199 ;;  `icicle-bookmark-bookmark-list',
4200 ;;  `icicle-bookmark-desktop',
4201 ;;  `icicle-bookmark-dired',                 `icicle-bookmark-dired-other-window',
4202 ;;  `icicle-bookmark-file',                  `icicle-bookmark-file-other-window',
4203 ;;  `icicle-bookmark-file-all-tags',         `icicle-bookmark-file-all-tags-other-window',
4204 ;;  `icicle-bookmark-file-all-tags-regexp',  `icicle-bookmark-file-all-tags-regexp-other-window',
4205 ;;  `icicle-bookmark-file-some-tags',        `icicle-bookmark-file-some-tags-other-window',
4206 ;;  `icicle-bookmark-file-some-tags-regexp', `icicle-bookmark-file-some-tags-regexp-other-window',
4207 ;;  `icicle-bookmark-file-this-dir',         `icicle-bookmark-file-this-dir-other-window',
4208 ;;  `icicle-bookmark-file-this-dir-all-tags',
4209 ;;  `icicle-bookmark-file-this-dir-all-tags-other-window',
4210 ;;  `icicle-bookmark-file-this-dir-all-tags-regexp',
4211 ;;  `icicle-bookmark-file-this-dir-all-tags-regexp-other-window',
4212 ;;  `icicle-bookmark-file-this-dir-some-tags',
4213 ;;  `icicle-bookmark-file-this-dir-some-tags-other-window',
4214 ;;  `icicle-bookmark-file-this-dir-some-tags-regexp',
4215 ;;  `icicle-bookmark-file-this-dir-some-tags-regexp-other-window',
4216 ;;  `icicle-bookmark-gnus',                  `icicle-bookmark-gnus-other-window',
4217 ;;  `icicle-bookmark-info',                  `icicle-bookmark-info-other-window',
4218 ;;  `icicle-bookmark-local-file',            `icicle-bookmark-local-file-other-window',
4219 ;;  `icicle-bookmark-man',                   `icicle-bookmark-man-other-window',
4220 ;;  `icicle-bookmark-non-file',              `icicle-bookmark-non-file-other-window',
4221 ;;  `icicle-bookmark-region',                `icicle-bookmark-region-other-window',
4222 ;;  `icicle-bookmark-remote-file',           `icicle-bookmark-remote-file-other-window',
4223 ;;  `icicle-bookmark-specific-buffers',      `icicle-bookmark-specific-buffers-other-window'
4224 ;;  `icicle-bookmark-specific-files',        `icicle-bookmark-specific-files-other-window'
4225 ;;  `icicle-bookmark-all-tags',              `icicle-bookmark-all-tags-other-window'
4226 ;;  `icicle-bookmark-all-tags-regexp',       `icicle-bookmark-all-tags-regexp-other-window'
4227 ;;  `icicle-bookmark-some-tags',             `icicle-bookmark-some-tags-other-window'
4228 ;;  `icicle-bookmark-some-tags-regexp',      `icicle-bookmark-some-tags-regexp-other-window'
4229 ;;  `icicle-bookmark-this-buffer',           `icicle-bookmark-this-buffer-other-window'
4230 ;;  `icicle-bookmark-url',                   `icicle-bookmark-url-other-window'
4231 ;;  `icicle-bookmark-w3m',                   `icicle-bookmark-w3m-other-window'
4232
4233 ;; Other-window means nothing for a bookmark list or a desktop.
4234 ;;;###autoload (autoload 'icicle-bookmark-non-file "icicles-cmd1.el")
4235 (icicle-define-bookmark-command              "non-file")                      ; `C-x j b'
4236 ;;;###autoload (autoload 'icicle-bookmark-non-file-other-window "icicles-cmd1.el")
4237 (icicle-define-bookmark-other-window-command "non-file")                      ; `C-x 4 j b'
4238 ;;;###autoload (autoload 'icicle-bookmark-bookmark-list "icicles-cmd1.el")
4239 (icicle-define-bookmark-command              "bookmark-list")                 ; `C-x j B'
4240 ;;;###autoload (autoload 'icicle-bookmark-dired "icicles-cmd1.el")
4241 (icicle-define-bookmark-command              "dired")                         ; `C-x j d'
4242 ;;;###autoload (autoload 'icicle-bookmark-dired-other-window "icicles-cmd1.el")
4243 (icicle-define-bookmark-other-window-command "dired")                         ; `C-x 4 j d'
4244 ;;;###autoload (autoload 'icicle-bookmark-file "icicles-cmd1.el")
4245 (icicle-define-bookmark-command              "file")                          ; `C-x j f'
4246 ;;;###autoload (autoload 'icicle-bookmark-file-other-window "icicles-cmd1.el")
4247 (icicle-define-bookmark-other-window-command "file")                          ; `C-x 4 j f'
4248 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir "icicles-cmd1.el")
4249 (icicle-define-bookmark-command              "file-this-dir")                 ; `C-x j C-f'
4250 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-other-window "icicles-cmd1.el")
4251 (icicle-define-bookmark-other-window-command "file-this-dir")                 ; `C-x 4 j C-f'
4252 ;;;###autoload (autoload 'icicle-bookmark-gnus "icicles-cmd1.el")
4253 (icicle-define-bookmark-command              "gnus")                          ; `C-x j g'
4254 ;;;###autoload (autoload 'icicle-bookmark-gnus-other-window "icicles-cmd1.el")
4255 (icicle-define-bookmark-other-window-command "gnus")                          ; `C-x 4 j g'
4256 ;;;###autoload (autoload 'icicle-bookmark-info "icicles-cmd1.el")
4257 (icicle-define-bookmark-command              "info")                          ; `C-x j i'
4258 ;;;###autoload (autoload 'icicle-bookmark-info-other-window "icicles-cmd1.el")
4259 (icicle-define-bookmark-other-window-command "info")                          ; `C-x 4 j i'
4260 ;;;###autoload (autoload 'icicle-bookmark-desktop "icicles-cmd1.el")
4261 (icicle-define-bookmark-command              "desktop")                       ; `C-x j K'
4262 ;;;###autoload (autoload 'icicle-bookmark-local-file "icicles-cmd1.el")
4263 (icicle-define-bookmark-command              "local-file")                    ; `C-x j l'
4264 ;;;###autoload (autoload 'icicle-bookmark-local-file-other-window "icicles-cmd1.el")
4265 (icicle-define-bookmark-other-window-command "local-file")                    ; `C-x 4 j l'
4266 ;;;###autoload (autoload 'icicle-bookmark-man "icicles-cmd1.el")
4267 (icicle-define-bookmark-command              "man")                           ; `C-x j m'
4268 ;;;###autoload (autoload 'icicle-bookmark-man-other-window "icicles-cmd1.el")
4269 (icicle-define-bookmark-other-window-command "man")                           ; `C-x 4 j m'
4270 ;;;###autoload (autoload 'icicle-bookmark-remote-file "icicles-cmd1.el")
4271 (icicle-define-bookmark-command              "remote-file")                   ; `C-x j n'
4272 ;;;###autoload (autoload 'icicle-bookmark-remote-file-other-window "icicles-cmd1.el")
4273 (icicle-define-bookmark-other-window-command "remote-file")                   ; `C-x 4 j n'
4274 ;;;###autoload (autoload 'icicle-bookmark-region "icicles-cmd1.el")
4275 (icicle-define-bookmark-command              "region" "Select region: ")      ; `C-x j r'
4276 ;;;###autoload (autoload 'icicle-bookmark-region-other-window "icicles-cmd1.el")
4277 (icicle-define-bookmark-other-window-command "region" "Select region: ")      ; `C-x 4 j r'
4278 ;;;###autoload (autoload 'icicle-bookmark-all-tags "icicles-cmd1.el")
4279 (icicle-define-bookmark-command              "all-tags" nil                   ; `C-x j t *'
4280                                              (bmkp-read-tags-completing))
4281 ;;;###autoload (autoload 'icicle-bookmark-all-tags-other-window "icicles-cmd1.el")
4282 (icicle-define-bookmark-other-window-command "all-tags" nil                   ; `C-x 4 j t *'
4283                                              (bmkp-read-tags-completing))
4284 ;;;###autoload (autoload 'icicle-bookmark-some-tags "icicles-cmd1.el")
4285 (icicle-define-bookmark-command              "some-tags" nil                  ; `C-x j t +'
4286                                              (bmkp-read-tags-completing))
4287 ;;;###autoload (autoload 'icicle-bookmark-some-tags-other-window "icicles-cmd1.el")
4288 (icicle-define-bookmark-other-window-command "some-tags" nil                  ; `C-x 4 j t +'
4289                                              (bmkp-read-tags-completing))
4290 ;;;###autoload (autoload 'icicle-bookmark-all-tags-regexp "icicles-cmd1.el")
4291 (icicle-define-bookmark-command              "all-tags-regexp" nil            ; `C-x j t % *'
4292                                              (read-string "Regexp for tags: "))
4293 ;;;###autoload (autoload 'icicle-bookmark-all-tags-regexp-other-window "icicles-cmd1.el")
4294 (icicle-define-bookmark-other-window-command "all-tags-regexp" nil            ; `C-x 4 j t % *'
4295                                              (read-string "Regexp for tags: "))
4296 ;;;###autoload (autoload 'icicle-bookmark-some-tags-regexp "icicles-cmd1.el")
4297 (icicle-define-bookmark-command              "some-tags-regexp" nil           ; `C-x j t % +'
4298                                              (read-string "Regexp for tags: "))
4299 ;;;###autoload (autoload 'icicle-bookmark-some-tags-regexp-other-window "icicles-cmd1.el")
4300 (icicle-define-bookmark-other-window-command "some-tags-regexp" nil           ; `C-x 4 j t % +'
4301                                              (read-string "Regexp for tags: "))
4302 ;;;###autoload (autoload 'icicle-bookmark-file-all-tags "icicles-cmd1.el")
4303 (icicle-define-bookmark-command              "file-all-tags" nil              ; `C-x j t f *'
4304                                              (bmkp-read-tags-completing))
4305 ;;;###autoload (autoload 'icicle-bookmark-file-all-tags-other-window "icicles-cmd1.el")
4306 (icicle-define-bookmark-other-window-command "file-all-tags" nil              ; `C-x 4 j t f *'
4307                                              (bmkp-read-tags-completing))
4308 ;;;###autoload (autoload 'icicle-bookmark-file-some-tags "icicles-cmd1.el")
4309 (icicle-define-bookmark-command              "file-some-tags" nil             ; `C-x j t f +'
4310                                              (bmkp-read-tags-completing))
4311 ;;;###autoload (autoload 'icicle-bookmark-file-some-tags-other-window "icicles-cmd1.el")
4312 (icicle-define-bookmark-other-window-command "file-some-tags" nil             ; `C-x 4 j t f +'
4313                                              (bmkp-read-tags-completing))
4314 ;;;###autoload (autoload 'icicle-bookmark-file-all-tags-regexp "icicles-cmd1.el")
4315 (icicle-define-bookmark-command              "file-all-tags-regexp" nil       ; `C-x j t f % *'
4316                                              (read-string "Regexp for tags: "))
4317 ;;;###autoload (autoload 'icicle-bookmark-file-all-tags-regexp-other-window "icicles-cmd1.el")
4318 (icicle-define-bookmark-other-window-command "file-all-tags-regexp" nil       ; `C-x 4 j t f % *'
4319                                              (read-string "Regexp for tags: "))
4320 ;;;###autoload (autoload 'icicle-bookmark-file-some-tags-regexp "icicles-cmd1.el")
4321 (icicle-define-bookmark-command              "file-some-tags-regexp" nil      ; `C-x j t f % +'
4322                                              (read-string "Regexp for tags: "))
4323 ;;;###autoload (autoload 'icicle-bookmark-file-some-tags-regexp-other-window "icicles-cmd1.el")
4324 (icicle-define-bookmark-other-window-command "file-some-tags-regexp" nil      ; `C-x 4 j t f % +'
4325                                              (read-string "Regexp for tags: "))
4326 ;;;###autoload (autoload 'icicle-bookmark-this-dir-file-all-tags "icicles-cmd1.el")
4327 (icicle-define-bookmark-command              "file-this-dir-all-tags" nil ; `C-x j t C-f *'
4328                                              (bmkp-read-tags-completing))
4329 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-other-window "icicles-cmd1.el")
4330 (icicle-define-bookmark-other-window-command "file-this-dir-all-tags" nil ; `C-x 4 j t C-f *'
4331                                              (bmkp-read-tags-completing))
4332 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags "icicles-cmd1.el")
4333 (icicle-define-bookmark-command              "file-this-dir-some-tags" nil ; `C-x j t C-f +'
4334                                              (bmkp-read-tags-completing))
4335 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-other-window "icicles-cmd1.el")
4336 (icicle-define-bookmark-other-window-command "file-this-dir-some-tags" nil ; `C-x 4 j t C-f +'
4337                                              (bmkp-read-tags-completing))
4338 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-regexp "icicles-cmd1.el")
4339 (icicle-define-bookmark-command              "file-this-dir-all-tags-regexp" nil ; `C-x j t C-f % *'
4340                                              (read-string "Regexp for tags: "))
4341 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-all-tags-regexp-other-window "icicles-cmd1.el")
4342 (icicle-define-bookmark-other-window-command "file-this-dir-all-tags-regexp" nil ; `C-x 4 j t C-f % *'
4343                                              (read-string "Regexp for tags: "))
4344 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-regexp "icicles-cmd1.el")
4345 (icicle-define-bookmark-command              "file-this-dir-some-tags-regexp" nil ; `C-x j t C-f % +'
4346                                              (read-string "Regexp for tags: "))
4347 ;;;###autoload (autoload 'icicle-bookmark-file-this-dir-some-tags-regexp-other-window "icicles-cmd1.el")
4348 (icicle-define-bookmark-other-window-command "file-this-dir-some-tags-regexp" nil ; `C-x 4 j t C-f % +'
4349                                              (read-string "Regexp for tags: "))
4350 ;;;###autoload (autoload 'icicle-bookmark-url "icicles-cmd1.el")
4351 (icicle-define-bookmark-command              "url")                           ; `C-x j u'
4352 ;;;###autoload (autoload 'icicle-bookmark-url-other-window "icicles-cmd1.el")
4353 (icicle-define-bookmark-other-window-command "url")                           ; `C-x 4 j u'
4354 ;;;###autoload (autoload 'icicle-bookmark-w3m "icicles-cmd1.el")
4355 (icicle-define-bookmark-command              "w3m")                           ; `C-x j w'
4356 ;;;###autoload (autoload 'icicle-bookmark-w3m-other-window "icicles-cmd1.el")
4357 (icicle-define-bookmark-other-window-command "w3m")                           ; `C-x 4 j w'
4358 ;;;###autoload (autoload 'icicle-bookmark-this-buffer "icicles-cmd1.el")
4359 (icicle-define-bookmark-command              "this-buffer")                   ; `C-x j .'
4360 ;;;###autoload (autoload 'icicle-bookmark-this-buffer-other-window "icicles-cmd1.el")
4361 (icicle-define-bookmark-other-window-command "this-buffer")                   ; `C-x 4 j .'
4362 ;;;###autoload (autoload 'icicle-bookmark-specific-buffers "icicles-cmd1.el")
4363 (icicle-define-bookmark-command              "specific-buffers" nil           ; `C-x j = b'
4364                                              (icicle-bookmarked-buffer-list))
4365 ;;;###autoload (autoload 'icicle-bookmark-specific-buffers-other-window "icicles-cmd1.el")
4366 (icicle-define-bookmark-other-window-command "specific-buffers" nil           ; `C-x 4 j = b'
4367                                              (icicle-bookmarked-buffer-list))
4368 ;;;###autoload (autoload 'icicle-bookmark-specific-files "icicles-cmd1.el")
4369 (icicle-define-bookmark-command              "specific-files" nil             ; `C-x j = f'
4370                                              (icicle-bookmarked-file-list))
4371 ;;;###autoload (autoload 'icicle-bookmark-specific-files-other-window "icicles-cmd1.el")
4372 (icicle-define-bookmark-other-window-command "specific-files" nil             ; `C-x 4 j = f'
4373                                              (icicle-bookmarked-file-list))
4374 ;;;###autoload
4375 (defalias 'icicle-select-bookmarked-region 'icicle-bookmark-region-other-window)
4376
4377 ;;;###autoload
4378 (defun icicle-bookmarked-buffer-list ()
4379   "`icicle-buffer-list', but only for bookmarked buffers."
4380   (interactive)
4381   (let ((icicle-buffer-predicate  (lambda (buf) (member buf (bmkp-buffer-names)))))
4382     (icicle-buffer-list)))
4383   
4384 ;;;###autoload
4385 (defun icicle-bookmarked-file-list ()
4386   "`icicle-buffer-list', but only for bookmarked buffers."
4387   (interactive)
4388   (let ((use-file-dialog        nil)
4389         (icicle-file-predicate  (lambda (file) (member (expand-file-name file) (bmkp-file-names)))))
4390     (icicle-file-list)))
4391
4392 ;;;###autoload (autoload 'icicle-find-first-tag "icicles-cmd1.el")
4393 (icicle-define-command icicle-find-first-tag ; Command name
4394   "Find first tag in current tags table whose name matches your input.
4395 This is similar to standard command `find-tag', with these
4396 differences:
4397
4398 * This is a multi-command, so you can visit any number of tags.
4399
4400 * Only the first tag of several identical tags is a candidate, so you
4401   cannot visit the others.  That is, there is no equivalent to using
4402   `M-,' (`tags-loop-continue') after `find-tag' to find additional,
4403   identical tags.
4404
4405 * If `crosshairs.el' is loaded, the target position is highlighted.
4406
4407 To browse all tags (including duplicates) in all tags tables, use the
4408 more powerful Icicles multi-command `icicle-find-tag'.
4409
4410 By default, Icicle mode remaps all key sequences that are normally
4411 bound to `find-tag-other-window' to `icicle-find-first-tag'.  If you
4412 do not want this remapping, then customize option
4413 `icicle-top-level-key-bindings'."       ; Doc string
4414   icicle-find-first-tag-action          ; Action function
4415   "Find tag: "                          ; `completing-read' args
4416   (if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
4417   nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
4418                                'find-tag-default))
4419   nil
4420   ((completion-ignore-case  (progn (require 'etags) ; Bindings
4421                                    (if (and (boundp 'tags-case-fold-search)
4422                                             (memq tags-case-fold-search '(t nil)))
4423                                        tags-case-fold-search
4424                                      case-fold-search)))
4425    (case-fold-search        completion-ignore-case))
4426   nil nil                               ; First code, undo code
4427   (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))) ; Last code
4428
4429 (defun icicle-find-first-tag-action (cand)
4430   "Action function for `icicle-find-first-tag'."
4431   (find-tag cand)
4432   (when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
4433
4434 ;;;###autoload (autoload 'icicle-find-first-tag-other-window "icicles-cmd1.el")
4435 (icicle-define-command icicle-find-first-tag-other-window ; Command name
4436   "Find first tag in current tags table whose name matches your input.
4437 Same as `icicle-find-first-tag' except it uses a different window." ; Doc string
4438   icicle-find-first-tag-other-window-action ; Action function
4439   "Find tag other window: "             ; `completing-read' args
4440   (if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
4441   nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
4442                                'find-tag-default))
4443   nil
4444   ((completion-ignore-case  (progn (require 'etags)
4445                                    (if (and (boundp 'tags-case-fold-search) ; Bindings
4446                                             (memq tags-case-fold-search '(t nil)))
4447                                        tags-case-fold-search
4448                                      case-fold-search)))
4449    (case-fold-search        completion-ignore-case))
4450   nil nil                               ; First code, undo code
4451   (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))) ; Last code
4452
4453 (defun icicle-find-first-tag-other-window-action (cand)
4454   "Action function for `icicle-find-first-tag-other-window'."
4455   (find-tag-other-window cand)
4456   (when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
4457
4458 ;;;###autoload
4459 (defun icicle-find-tag (regexp &optional arg)
4460   "Navigate among all tags that match REGEXP.
4461 You are prompted for the REGEXP to match.  Enter REGEXP with `RET'.
4462 You can use completion to choose a tag in the current tags table as
4463 REGEXP.  You can use `\\[icicle-pop-tag-mark]' to return to your starting point.
4464
4465 All matching tags are shown, including duplicate tags from the same or
4466 different source files.  This means that you do not need `M-,' - you
4467 see all tags as candidates to visit.
4468
4469 By default:
4470
4471 * Tags from all tags files are candidates.
4472 * In `*Completions*', the source file name is shown after each tag.
4473
4474 A prefix argument changes this default behavior, as follows:
4475
4476 * ARG = 0 or ARG > 0: only the current tag table is used
4477 * ARG = 0 or ARG < 0: source file names are not shown
4478
4479 By default, Icicle mode remaps all key sequences that are normally
4480 bound to `find-tag' to `icicle-find-tag'.  If you do not want this
4481 remapping, then customize option `icicle-top-level-key-bindings'.
4482
4483 If `crosshairs.el' is loaded, then the target position is highlighted."
4484   (interactive
4485    (let* ((completion-ignore-case  (if (and (boundp 'tags-case-fold-search)
4486                                             (memq tags-case-fold-search '(t nil)))
4487                                        tags-case-fold-search
4488                                      case-fold-search))
4489           (case-fold-search        completion-ignore-case))
4490      (require 'etags)
4491      (list (completing-read "Find tag matching regexp: "
4492                             ;; $$$ Or should we just read a regexp against `regexp-history'?
4493                             (if (fboundp 'tags-lazy-completion-table)
4494                                 (tags-lazy-completion-table) ; Emacs 23+
4495                               'tags-complete-tag) ; Emacs < 23
4496                             nil nil nil 'find-tag-history
4497                             (funcall (or find-tag-default-function
4498                                          (get major-mode 'find-tag-default-function)
4499                                          'find-tag-default)))
4500            current-prefix-arg)))
4501
4502   (unwind-protect
4503        (let* ((icicle-whole-candidate-as-text-prop-p  t)
4504               (icicle-sort-comparer                   nil)
4505               (icicle-inhibit-sort-p                  t)
4506               (icicle-candidate-action-fn             'icicle-find-tag-action)
4507               (icicle-candidate-help-fn               'icicle-find-tag-help)
4508               (completion-ignore-case                 (if (and (boundp 'tags-case-fold-search)
4509                                                                (memq tags-case-fold-search
4510                                                                      '(t nil)))
4511                                                           tags-case-fold-search
4512                                                         case-fold-search))
4513               (case-fold-search                       completion-ignore-case)
4514               (orig-pt-find-tag                       (point-marker)))
4515
4516          (ring-insert find-tag-marker-ring orig-pt-find-tag) ; Record starting point.
4517          (icicle-explore #'(lambda () (icicle-find-tag-define-candidates regexp arg))
4518                          #'icicle-find-tag-final-act #'icicle-find-tag-quit-or-error
4519                          #'icicle-find-tag-quit-or-error nil
4520                          "Choose a tag: " nil nil nil 'find-tag-history))
4521     (when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))))
4522
4523 ;;;###autoload
4524 (defun icicle-pop-tag-mark ()
4525   "Like `pop-tag-mark', but uses `pop-to-buffer', not `switch-to-buffer'.
4526 By default, Icicle mode remaps all key sequences that are normally
4527 bound to `pop-tag-mark' to `icicle-pop-tag-mark'.  If you do not want
4528 this remapping, then customize option
4529 `icicle-top-level-key-bindings'."
4530   (interactive)
4531   (require 'etags)
4532   (when (ring-empty-p find-tag-marker-ring) (error "No previous locations for find-tag invocation"))
4533   (let ((marker  (ring-remove find-tag-marker-ring 0)))
4534     (pop-to-buffer (or (marker-buffer marker) (error "The marked buffer has been deleted")))
4535     (goto-char (marker-position marker))
4536     (unless (pos-visible-in-window-p) (recenter icicle-recenter))
4537     (set-marker marker nil nil)))
4538
4539 (defun icicle-find-tag-define-candidates (regexp arg)
4540   "Define candidates for `icicle-find-tag'.
4541 See `icicle-explore', argument DEFINE-CANDIDATES-FN."
4542   (save-excursion
4543     (let ((first-time  t)
4544           (morep       t))
4545       (setq icicle-candidates-alist  ())
4546       (while (and morep (visit-tags-table-buffer (not first-time)))
4547         (when (and arg (wholenump (prefix-numeric-value arg))) (setq morep  nil))
4548         (setq first-time               nil
4549               icicle-candidates-alist  (append icicle-candidates-alist
4550                                                (nreverse
4551                                                 (icicle-find-tag-define-candidates-1
4552                                                  regexp (> (prefix-numeric-value arg)
4553                                                            0)))))))))
4554
4555 (defun icicle-find-tag-define-candidates-1 (regexp show-file-p)
4556   "Helper function for `icicle-find-tag-define-candidates'.
4557 Returns completion alist of tag information for tags matching REGEXP.
4558 Include file name (label) if SHOW-FILE-P is non-nil.
4559
4560 If SHOW-FILE-P is nil, then alist items look like this:
4561
4562  (TAG TAG-INFO FILE-PATH GOTO-FUNC)
4563
4564 If SHOW-FILE-P is non-nil, then alist items look like this:
4565
4566  ((TAG FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC) or
4567
4568  (FILE-LABEL TAG-INFO FILE-PATH GOTO-FUNC) if no matching TAG.
4569
4570 TAG-INFO is what `snarf-tag-function' (e.g. `etags-snarf-tag')
4571 returns.  It is a cons (TEXT LINE . POSITION).
4572
4573 TEXT is the initial part of a line containing the tag.
4574 LINE is the line number.
4575 POSITION is the (one-based) char position of TEXT within the file.
4576
4577 If TEXT is t, it means the tag refers to exactly LINE or POSITION,
4578 whichever is present, LINE having preference, no searching.
4579 Either LINE or POSITION can be nil.  POSITION is used if present."
4580   (icicle-highlight-lighter)
4581   (message "Gathering tags...")
4582   (goto-char (point-min))
4583   (let ((temp-list  ()))
4584     (while (re-search-forward (concat regexp ".*\177*") nil t) ; Look before the DEL character.
4585       (beginning-of-line)
4586       (let* ((goto-func  goto-tag-location-function) ; e.g. `etags-goto-tag-location'.
4587              ;; TAG-INFO: If no specific tag, (t nil (point-min)). Else, (TEXT LINE . STARTPOS).
4588              ;; e.g. TEXT = "(defun foo ()" or just "foo" (if explicit),
4589              ;;      LINE = "148", STARTPOS = "1723"
4590              (tag-info (save-excursion (funcall snarf-tag-function))) ; e.g. `etags-snarf-tag'.
4591              (tag (if (eq t (car tag-info)) nil (car tag-info)))
4592              ;; FILE-PATH is absolute. FILE-LABEL is relative to `default-directory'.
4593              (file-path (save-excursion
4594                           (if tag (file-of-tag) (save-excursion (next-line 1) (file-of-tag)))))
4595              (file-label (expand-file-name file-path (file-truename default-directory))))
4596         (when (and tag (not (string= "" tag)) (= (aref tag 0) ?\( ))
4597           (setq tag  (concat tag " ...)")))
4598         (when (file-readable-p file-path)
4599           ;; Add item to alist.
4600           ;;   Item looks like this:         ((TAG FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC)
4601           ;;   or like this, if no matching tag: ((FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC)
4602           (cond (tag
4603                  (push `(,(if show-file-p
4604                               (list tag ; Make multi-completion cons: add file name to candidate.
4605                                     (progn (put-text-property 0 (length file-label) 'face
4606                                                               'icicle-candidate-part file-label)
4607                                            file-label))
4608                               tag)
4609                          ,tag-info ,file-path ,goto-func)
4610                        temp-list))
4611                 (show-file-p            ; No tag.  Use only the FILE-LABEL.
4612                  (push `((,(progn (put-text-property 0 (length file-label) 'face
4613                                                      'icicle-candidate-part file-label)
4614                                   file-label))
4615                          ,tag-info ,file-path ,goto-func)
4616                        temp-list)))))
4617       (forward-line))
4618     temp-list))                         ; Return the alist for this TAGS file.
4619
4620 (defun icicle-find-tag-action (ignored-string)
4621   "Action function for `icicle-find-tag'."
4622   ;; Ignore (TAG FILE-LABEL) part.  Use only (TAG-INFO FILE-PATH GOTO-FUNC) part.
4623   (let* ((cand       (cdr (elt (icicle-filter-alist icicle-candidates-alist
4624                                                     icicle-completion-candidates)
4625                                icicle-candidate-nb)))
4626          (tag-info   (nth 0 cand))
4627          (goto-func  (nth 2 cand)))
4628     (switch-to-buffer-other-window      ; Go to source file at FILE-PATH.
4629      (if (fboundp 'tag-find-file-of-tag-noselect)
4630          (tag-find-file-of-tag-noselect (nth 1 cand))
4631        (find-file-noselect (nth 1 cand))))
4632     (widen)
4633     (icicle-condition-case-no-debug err
4634         (funcall goto-func tag-info)    ; Go to text at TAG-INFO.
4635       (error (message "%s" (error-message-string err)) (sit-for 2) nil)))
4636   (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
4637   (select-window (minibuffer-window))
4638   (select-frame-set-input-focus (selected-frame)))
4639
4640 (defun icicle-find-tag-help (cand)
4641   "Use as `icicle-candidate-help-fn' for `icicle-find-first-tag'."
4642   (let* ((cand      (cdr (elt (icicle-filter-alist icicle-candidates-alist
4643                                                    icicle-completion-candidates)
4644                               icicle-candidate-nb)))
4645          (tag-info  (nth 0 cand)))
4646     (message (if (eq t (car tag-info))
4647                  "No tag - file name itself matches"
4648                (format "Line: %d, Position: %d, File: %s"
4649                        (cadr tag-info) (cddr tag-info) (nth 1 cand))))
4650     (sit-for 4)))
4651
4652 (defun icicle-find-tag-final-act ()
4653   "Go to the final tag choice."
4654   (let ((cand  (cdr icicle-explore-final-choice-full)))
4655     (unless cand (error "No such occurrence: %s" cand))
4656     (switch-to-buffer-other-window ; Go to source file at FILE-PATH.
4657      (if (fboundp 'tag-find-file-of-tag-noselect)
4658          (tag-find-file-of-tag-noselect (nth 1 cand))
4659        (find-file-noselect (nth 1 cand))))
4660     (widen)
4661     (funcall (nth 2 cand) (nth 0 cand)))) ; Go to text at TAG-INFO.
4662
4663 (defun icicle-find-tag-quit-or-error ()
4664   "Pop back to the last tag visited."
4665   (icicle-pop-tag-mark)
4666   (raise-frame))
4667
4668 ;;;###autoload
4669 (defun icicle-other-window-or-frame (arg) ; Bound to `C-x o' in Icicle mode.
4670   "Select a window or frame, by name or by order.
4671 This command combines Emacs commands `other-window' and `other-frame',
4672 together with Icicles multi-commands `icicle-select-window', and
4673 `icicle-select-frame'.  Use the prefix argument to choose, as follows:
4674
4675  With no prefix arg or a non-zero numeric prefix arg:
4676   If the selected frame has multiple windows, then this is
4677   `other-window'.  Otherwise, it is `other-frame'.
4678
4679  With a zero prefix arg (e.g. `C-0'):
4680   If the selected frame has multiple windows, then this is
4681   `icicle-select-window' with windows in the frame as candidates.
4682   Otherwise (single-window frame), this is `icicle-select-frame'.
4683
4684  With plain `C-u':
4685   If the selected frame has multiple windows, then this is
4686   `icicle-select-window' with windows from all visible frames as
4687   candidates.  Otherwise, this is `icicle-select-frame'.
4688
4689 By default, Icicle mode remaps all key sequences that are normally
4690 bound to `other-window' to `icicle-other-window-or-frame'.  If you do
4691 not want this remapping, then customize option
4692 `icicle-top-level-key-bindings'."
4693   (interactive "P")
4694   (let ((numarg  (prefix-numeric-value arg)))
4695     (cond ((consp arg)
4696            (if (one-window-p) (icicle-select-frame) (icicle-select-window)))
4697           ((zerop numarg)
4698            (if (one-window-p)
4699                (icicle-select-frame)
4700              (let ((current-prefix-arg  nil)) (icicle-select-window))))
4701           (t
4702            (if (one-window-p) (other-frame numarg) (other-window numarg))))))
4703
4704 ;;;###autoload (autoload 'icicle-select-frame "icicles-cmd1.el")
4705 (icicle-define-command icicle-select-frame ; Bound to `C-x 5 o' in Icicle mode.
4706   "Select frame by its name and raise it.
4707 A frame name in this context is suffixed as needed by [NUMBER], to
4708 make it unique.  For example, in a context where frames are named for
4709 their buffers and you have two frames showing buffer *Help*, one of
4710 the frames will be called `*Help*[2]' for use with this command." ; Doc string
4711   icicle-select-frame-by-name           ; Action function
4712   "Select frame: "                      ; `completing-read' args
4713   icicle-frame-alist nil t nil
4714   (if (boundp 'frame-name-history) 'frame-name-history 'icicle-frame-name-history)
4715   (cdr (assq 'name (frame-parameters (next-frame (selected-frame))))) nil
4716   ((icicle-frame-alist  (icicle-make-frame-alist)) ; Bindings
4717    (alt-fn              nil)
4718    (icicle-candidate-alt-action-fn
4719     (or icicle-candidate-alt-action-fn (setq alt-fn  (icicle-alt-act-fn-for-type "frame"))))
4720    (icicle-all-candidates-list-alt-action-fn ; M-|'
4721     (or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "frame")))))
4722
4723 ;;;###autoload
4724 (defun icicle-select-frame-by-name (name &optional frame-alist)
4725   "Select the frame named NAME, and raise it.
4726 Optional argument FRAME-ALIST is an alist of frames to choose from.
4727 Each element has the form (FNAME . FRAME), where FNAME names FRAME.
4728 See `icicle-make-frame-alist' for more about FNAME."
4729   (interactive (let* ((alist    (icicle-make-frame-alist))
4730                       (default  (car (rassoc (selected-frame) alist)))
4731                       (input    (completing-read "Select Frame: " alist nil t nil
4732                                                  'frame-name-history default)))
4733                  (list (if (= (length input) 0) default input)
4734                        alist)))
4735   (unless frame-alist (setq frame-alist  (or (and (boundp 'icicle-frame-alist) icicle-frame-alist)
4736                                              (icicle-make-frame-alist))))
4737   (let ((frame  (cdr (assoc name frame-alist))))
4738     (unless frame (error "No such frame: `%s'" name))
4739     (make-frame-visible frame)
4740     (select-frame-set-input-focus frame)))
4741
4742 (defun icicle-make-frame-alist ()
4743   "Return an alist of entries (FNAME . FRAME), where FNAME names FRAME.
4744 Frame parameter `name' is used as FNAME, unless there is more than one
4745 frame with the same name.  In that case, FNAME includes a suffix
4746 \[NUMBER], to make it a unique name.  The NUMBER order among frame
4747 names that differ only by their [NUMBER] is arbitrary."
4748   (let ((fr-alist  ())
4749         (count     2)
4750         fname new-name)
4751     (dolist (fr  (frame-list))
4752       (setq fname  (frame-parameter fr 'name))
4753       (if (not (assoc fname fr-alist))
4754           (push (cons fname fr) fr-alist)
4755         (setq new-name  fname)
4756         (while (assoc new-name fr-alist)
4757           (setq new-name  (format "%s[%d]" fname count)
4758                 count     (1+ count)))
4759         (push (cons new-name fr) fr-alist))
4760       (setq count  2))
4761     fr-alist))
4762
4763 ;;;###autoload (autoload 'icicle-select-window "icicles-cmd1.el")
4764 (icicle-define-command icicle-select-window ; Command name
4765 ;; Free vars here: `icicle-window-alist' is bound in Bindings form.
4766   "Select window by its name.
4767 With no prefix arg, candidate windows are those of the selected frame.
4768 With a prefix arg, windows of all visible frames are candidates.
4769
4770 A window name is the name of its displayed buffer, but suffixed as
4771 needed by [NUMBER], to make the name unique.  For example, if you have
4772 two windows showing buffer *Help*, one of the windows will be called
4773 `*Help*[2]' for use with this command." ; Doc string
4774   icicle-select-window-by-name          ; Action function
4775   "Select window: " icicle-window-alist nil t nil nil ; `completing-read' args
4776   (buffer-name (window-buffer (other-window 1))) nil
4777   ((icicle-window-alist  (icicle-make-window-alist current-prefix-arg)))) ; Bindings
4778
4779 ;; Free vars here: `icicle-window-alist' is bound in `icicle-select-window'.
4780 ;;;###autoload
4781 (defun icicle-select-window-by-name (name &optional window-alist)
4782   "Select the window named NAME.
4783 Optional argument WINDOW-ALIST is an alist of windows to choose from.
4784
4785 Interactively:
4786  A prefix arg means windows from all visible frames are candidates.
4787  No prefix arg means windows from the selected frame are candidates.
4788
4789 Each alist element has the form (WNAME . WINDOW), where WNAME names
4790 WINDOW.  See `icicle-make-window-alist' for more about WNAME.
4791
4792 If `crosshairs.el' is loaded, then the target position is highlighted."
4793   (interactive (let* ((alist    (icicle-make-window-alist current-prefix-arg))
4794                       (default  (car (rassoc (selected-window) alist)))
4795                       (input    (completing-read "Select Window: " alist nil t nil nil default)))
4796                  (list (if (= (length input) 0) default input) alist)))
4797   (unless window-alist
4798     (setq window-alist  (or (and (boundp 'icicle-window-alist) icicle-window-alist)
4799                             (icicle-make-window-alist))))
4800   (let ((window  (cdr (assoc name window-alist))))
4801     (unless window (error "No such window: `%s'" name))
4802     (select-window window)
4803     (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
4804     (select-frame-set-input-focus (selected-frame))))
4805
4806 (defun icicle-make-window-alist (&optional all-p)
4807   "Return an alist of entries (WNAME . WINDOW), where WNAME names WINDOW.
4808 The name of the buffer in a window is used as its name, unless there
4809 is more than one window displaying the same buffer.  In that case,
4810 WNAME includes a suffix [NUMBER], to make it a unique name.  The
4811 NUMBER order among window names that differ only by their [NUMBER] is
4812 arbitrary.
4813
4814 Non-nil argument ALL-P means use windows from all visible frames.
4815 Otherwise, use only windows from the selected frame."
4816   (let ((win-alist  ())
4817         (count      2)
4818         wname new-name)
4819     (walk-windows #'(lambda (w)
4820                       (setq wname  (buffer-name (window-buffer w)))
4821                       (if (not (assoc wname win-alist))
4822                           (push (cons wname w) win-alist)
4823                         (setq new-name  wname)
4824                         (while (assoc new-name win-alist)
4825                           (setq new-name  (format "%s[%d]" wname count)
4826                                 count     (1+ count)))
4827                         (push (cons new-name w) win-alist))
4828                       (setq count  2))
4829                   'no-mini
4830                   (if all-p 'visible 'this-frame))
4831     win-alist))
4832
4833 ;;;###autoload (autoload 'icicle-delete-windows "icicles-cmd1.el")
4834 (icicle-define-command icicle-delete-windows ; Command name
4835   "Delete windows showing a buffer, anywhere." ; Doc string
4836   delete-windows-on                     ; Action function
4837   "Delete windows on buffer: "          ; `completing-read' args
4838   (let ((cand-bufs  nil))
4839     (dolist (buf  (buffer-list))
4840       (when (get-buffer-window buf 0) (push (list (buffer-name buf)) cand-bufs)))
4841     cand-bufs)
4842   nil t nil 'buffer-name-history (buffer-name (current-buffer)) nil
4843   ((icicle-use-candidates-only-once-flag  t) ; Bindings
4844    (icicle-inhibit-try-switch-buffer      t)
4845    (icicle-candidate-alt-action-fn
4846     (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
4847    (icicle-all-candidates-list-alt-action-fn ; M-|'
4848     (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))))
4849
4850 ;;;###autoload
4851 (defun icicle-delete-window (bufferp)   ; Bound to `C-x 0' in Icicle mode.
4852   "`delete-window' or prompt for buffer and delete all its windows.
4853 When called from the minibuffer, remove the `*Completions*' window.
4854
4855 Otherwise:
4856  With no prefix argument, delete the selected window.
4857  With a prefix argument, prompt for a buffer and delete all windows,
4858    on any frame, that show that buffer.
4859
4860  With a prefix argument, this is an Icicles multi-command - see
4861  command `icicle-mode'.  Input-candidate completion and cycling are
4862  available.  While cycling, these keys with prefix `C-' are active:
4863
4864  `C-RET'   - Act on current completion candidate only
4865  `C-down'  - Move to next completion candidate and act
4866  `C-up'    - Move to previous completion candidate and act
4867  `C-next'  - Move to next apropos-completion candidate and act
4868  `C-prior' - Move to previous apropos-completion candidate and act
4869  `C-end'   - Move to next prefix-completion candidate and act
4870  `C-home'  - Move to previous prefix-completion candidate and act
4871  `C-!'     - Act on *all* candidates (or all that are saved),
4872              successively (careful!)
4873
4874  With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
4875  `C-M-RET', `C-M-down', and so on) provide help about candidates.
4876
4877  Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
4878  or `C-g' to quit.
4879
4880 By default, Icicle mode remaps all key sequences that are normally
4881 bound to `delete-window' to `icicle-delete-window'.  If you do not
4882 want this remapping, then customize option
4883 `icicle-top-level-key-bindings'."
4884   (interactive "P")
4885   (if (window-minibuffer-p (selected-window))
4886       (icicle-remove-Completions-window)
4887     (if bufferp (icicle-delete-windows) (delete-window))))
4888
4889 ;;;###autoload (autoload 'icicle-kill-buffer "icicles-cmd1.el")
4890 (icicle-define-command icicle-kill-buffer ; Bound to `C-x k' in Icicle mode.
4891   "Kill a buffer.
4892 With a positive prefix arg, only buffers visiting files are candidates.
4893 With a negative prefix arg, only buffers associated with the selected
4894  frame are candidates.
4895 With a zero prefix arg, only buffers that have the same mode as the
4896  current buffer are candidates.
4897
4898 You can use `C-x M' during completion to allow only buffers of a
4899 certain major mode as candidates.  You are prompted for the mode.
4900
4901 These options, when non-nil, control candidate matching and filtering:
4902
4903  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
4904  `icicle-buffer-extras'             - Extra buffers to display
4905  `icicle-buffer-match-regexp'       - Regexp that buffers must match
4906  `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
4907  `icicle-buffer-predicate'          - Predicate buffer must satisfy
4908  `icicle-buffer-sort'               - Sort function for candidates
4909
4910 By default, Icicle mode remaps all key sequences that are normally
4911 bound to `kill-buffer' to `icicle-kill-buffer'.  If you do not want
4912 this remapping, then customize option
4913 `icicle-top-level-key-bindings'.
4914
4915 Note: The prefix arg is tested, even when this is called
4916 noninteractively.  Lisp code can bind `current-prefix-arg' to control
4917 the behavior."                          ; Doc string
4918   icicle-kill-a-buffer-and-update-completions ; Action function
4919   "Kill buffer: "                       ; `completing-read' args
4920   (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
4921   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
4922   nil 'buffer-name-history (buffer-name (current-buffer)) nil
4923   (icicle-buffer-bindings)              ; Bindings
4924   (progn                                ; First code
4925     (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
4926     (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
4927   nil                                   ; Undo code
4928   (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
4929          (define-key minibuffer-local-must-match-map "\C-xM" nil)))
4930
4931 (defun icicle-kill-a-buffer-and-update-completions (buf)
4932   "Kill buffer BUF and update the set of completions."
4933   (setq buf  (get-buffer buf))
4934   (if buf
4935       (icicle-condition-case-no-debug err
4936           (if (not (buffer-live-p buf))
4937               (message "Buffer already deleted: `%s'" buf)
4938             (if (fboundp 'kill-buffer-and-its-windows)
4939                 (kill-buffer-and-its-windows buf) ; Defined in `misc-cmds.el'.
4940               (kill-buffer buf))
4941             ;; Update the set of completions, then update `*Completions*'.
4942             (setq minibuffer-completion-table  (mapcar #'(lambda (buf) (list (buffer-name buf)))
4943                                                        (buffer-list)))
4944             (icicle-complete-again-update))
4945         (error nil))
4946     (message "No such live buffer: `%s'" buf)))
4947
4948 (put 'icicle-buffer 'icicle-Completions-window-max-height 200)
4949 ;;;###autoload (autoload 'icicle-buffer "icicles-cmd1.el")
4950 (icicle-define-command icicle-buffer    ; Bound to `C-x b' in Icicle mode.
4951   "Switch to a different buffer.
4952 With a positive prefix arg, only buffers visiting files are candidates.
4953 With a negative prefix arg, only buffers associated with the selected
4954  frame are candidates.
4955 With a zero prefix arg, only buffers that have the same mode as the
4956  current buffer are candidates.
4957
4958 You can use `C-x m' during completion to access buffer (non-file)
4959  bookmarks, if you use library `Bookmark+'.
4960 You can use `S-delete' during completion to kill a candidate buffer.
4961
4962 You can use `C-x M' during completion to allow only buffers of a
4963 certain major mode as candidates.  You are prompted for the mode.
4964
4965 These options, when non-nil, control candidate matching and filtering:
4966
4967  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
4968  `icicle-buffer-extras'             - Extra buffers to display
4969  `icicle-buffer-match-regexp'       - Regexp that buffers must match
4970  `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
4971  `icicle-buffer-predicate'          - Predicate buffer must satisfy
4972  `icicle-buffer-sort'               - Sort function for candidates
4973
4974 For example, to show only buffers that are associated with files, set
4975 `icicle-buffer-predicate' to (lambda (buf) (buffer-file-name buf)).
4976
4977 Option `icicle-buffer-require-match-flag' can be used to override
4978 option `icicle-require-match-flag'.
4979
4980 Option `icicle-buffers-ido-like' non-nil gives this command a more
4981 Ido-like behavior.
4982
4983 See also command `icicle-buffer-config'.
4984
4985 By default, Icicle mode remaps all key sequences that are normally
4986 bound to `switch-to-buffer' to `icicle-buffer'.  If you do not want
4987 this remapping, then customize option
4988 `icicle-top-level-key-bindings'.
4989
4990 Note: The prefix arg is tested, even when this is called
4991 noninteractively.  Lisp code can bind `current-prefix-arg' to control
4992 the behavior."                          ; Doc string
4993   switch-to-buffer                      ; Action function
4994   "Switch to buffer: "                  ; `completing-read' args
4995   (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
4996   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
4997   nil 'buffer-name-history (icicle-default-buffer-names) nil
4998   (icicle-buffer-bindings)              ; Bindings
4999   (progn                                ; First code
5000     (when (require 'bookmark+ nil t)
5001       (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-non-file-other-window)
5002       (define-key minibuffer-local-must-match-map "\C-xm" 'icicle-bookmark-non-file-other-window))
5003     (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
5004     (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
5005   nil                                   ; Undo code
5006   (progn (define-key minibuffer-local-completion-map "\C-xm" nil) ; Last code
5007          (define-key minibuffer-local-must-match-map "\C-xm" nil)
5008          (define-key minibuffer-local-completion-map "\C-xM" nil)
5009          (define-key minibuffer-local-must-match-map "\C-xM" nil)))
5010
5011 ;; Free var here: `icicle-bufflist' is bound by `icicle-buffer-bindings'.
5012 (defun icicle-default-buffer-names ()
5013   "Default buffer names (Emacs 23+) or name (< Emacs 23)."
5014   (let ((bname  (buffer-name (if (fboundp 'another-buffer) ; In `misc-fns.el'.
5015                                  (another-buffer nil t)
5016                                (other-buffer (current-buffer))))))
5017     (if (> emacs-major-version 22)      ; Emacs 23 accepts a list of default values.
5018         (cons bname
5019               (mapcar #'buffer-name
5020                       (delete (current-buffer) ; Just keep the first 4.  (This could be an option.)
5021                               (icicle-first-N 4 (or icicle-bufflist (buffer-list))))))
5022       bname)))
5023
5024 ;; Free var here: `icicle-bufflist' is bound by `icicle-buffer-bindings'.
5025 (defun icicle-filter-buffer-cands-for-mode ()
5026   "Prompt for a major mode, then remove buffer candidates not in that mode."
5027   (interactive)
5028   (save-selected-window (icicle-remove-Completions-window))
5029   (let* ((enable-recursive-minibuffers  t)
5030          (mode
5031           (intern (completing-read
5032                    "Major mode: "
5033                    (icicle-remove-duplicates
5034                     (mapcar (lambda (buf) (with-current-buffer buf (list (symbol-name major-mode))))
5035                             icicle-bufflist))
5036                    nil t))))
5037     (setq icicle-must-pass-after-match-predicate
5038           `(lambda (buf)
5039             (with-current-buffer buf (eq major-mode ',mode)))))
5040   (icicle-complete-again-update))
5041
5042 ;;;###autoload (autoload 'icicle-buffer-other-window "icicles-cmd1.el")
5043 (icicle-define-command icicle-buffer-other-window ; Bound to `C-x 4 b' in Icicle mode.
5044   "Switch to a different buffer in another window.
5045 Same as `icicle-buffer' except it uses a different window." ; Doc string
5046   switch-to-buffer-other-window         ; Action function
5047   "Switch to buffer in other window: "  ; `completing-read' args
5048   (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
5049   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
5050   nil 'buffer-name-history (icicle-default-buffer-names) nil
5051   (icicle-buffer-bindings)              ; Bindings
5052   (progn                                ; First code
5053     (when (require 'bookmark+ nil t)
5054       (define-key minibuffer-local-completion-map "\C-xm" 'icicle-bookmark-non-file-other-window)
5055       (define-key minibuffer-local-must-match-map "\C-xm" 'icicle-bookmark-non-file-other-window))
5056     (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
5057     (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
5058   nil                                   ; Undo code
5059   (progn (define-key minibuffer-local-completion-map "\C-xm" nil) ; Last code
5060          (define-key minibuffer-local-must-match-map "\C-xm" nil)
5061          (define-key minibuffer-local-completion-map "\C-xM" nil)
5062          (define-key minibuffer-local-must-match-map "\C-xM" nil)))
5063
5064 ;;;###autoload (autoload 'icicle-insert-buffer "icicles-cmd1.el")
5065 (icicle-define-command icicle-insert-buffer
5066   "Multi-command version of `insert-buffer'.
5067 With a positive prefix arg, only buffers visiting files are candidates.
5068 With a negative prefix arg, only buffers associated with the selected
5069  frame are candidates.
5070 With a zero prefix arg, only buffers that have the same mode as the
5071  current buffer are candidates.
5072
5073 You can use `C-x M' during completion to allow only buffers of a
5074 certain major mode as candidates.  You are prompted for the mode.
5075
5076 You can use `S-delete' during completion to kill a candidate buffer.
5077
5078 These options, when non-nil, control candidate matching and filtering:
5079
5080  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
5081  `icicle-buffer-extras'             - Extra buffers to display
5082  `icicle-buffer-match-regexp'       - Regexp that buffers must match
5083  `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
5084  `icicle-buffer-predicate'          - Predicate buffer must satisfy
5085  `icicle-buffer-sort'               - Sort function for candidates
5086
5087 For example, to show only buffers that are associated with files, set
5088 `icicle-buffer-predicate' to (lambda (buf) (buffer-file-name buf)).
5089
5090 Option `icicle-buffer-require-match-flag' can be used to override
5091 option `icicle-require-match-flag'.
5092
5093 See also command `icicle-buffer-config'.
5094
5095 Note: The prefix arg is tested, even when this is called
5096 noninteractively.  Lisp code can bind `current-prefix-arg' to control
5097 the behavior."                          ; Doc string
5098   insert-buffer                         ; Action function
5099   "Buffer: "                            ; `completing-read' args
5100   (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
5101   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
5102   nil 'buffer-name-history (icicle-default-buffer-names) nil
5103   (icicle-buffer-bindings)              ; Bindings
5104   (progn                                ; First code
5105     (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
5106     (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
5107   nil                                   ; Undo code
5108   (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
5109          (define-key minibuffer-local-must-match-map "\C-xM" nil)))
5110
5111 ;;;###autoload (autoload 'icicle-add-buffer-candidate "icicles-cmd1.el")
5112 (icicle-define-command icicle-add-buffer-candidate ; Command name
5113   "Add buffer as an always-show completion candidate.
5114 Add the buffer to `icicle-buffer-extras'.  Save the updated option.
5115 With a positive prefix arg, only buffers visiting files are candidates.
5116 With a negative prefix arg, only buffers associated with the selected
5117  frame are candidates.
5118 With a zero prefix arg, only buffers that have the same mode as the
5119  current buffer are candidates.
5120
5121 You can use `S-delete' on any completion candidate to remove it from
5122 `icicle-buffer-extras'.
5123
5124 You can use `C-x M' during completion to allow only buffers of a
5125 certain major mode as candidates.  You are prompted for the mode.
5126
5127 Note: The prefix arg is tested, even when this is called
5128 noninteractively.  Lisp code can bind `current-prefix-arg' to control
5129 the behavior."                          ; Doc string
5130   (lambda (buf)
5131     (add-to-list 'icicle-buffer-extras buf) ; Action function
5132     (funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
5133     (message "Buffer `%s' added to always-show buffers" buf))
5134   "Buffer candidate to show always: "   ; `completing-read' args
5135   (mapcar #'(lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
5136   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs23.
5137   nil 'buffer-name-history (icicle-default-buffer-names) nil
5138   (icicle-buffer-bindings ((icicle-use-candidates-only-once-flag  t))) ; Bindings
5139   (progn                                ; First code
5140     (define-key minibuffer-local-completion-map "\C-xM" 'icicle-filter-buffer-cands-for-mode)
5141     (define-key minibuffer-local-must-match-map "\C-xM" 'icicle-filter-buffer-cands-for-mode))
5142   nil                                   ; Undo code
5143   (progn (define-key minibuffer-local-completion-map "\C-xM" nil) ; Last code
5144          (define-key minibuffer-local-must-match-map "\C-xM" nil)))
5145
5146 ;;;###autoload (autoload 'icicle-remove-buffer-candidate "icicles-cmd1.el")
5147 (icicle-define-command icicle-remove-buffer-candidate ; Command name
5148   "Remove buffer as an always-show completion candidate.
5149 Remove the buffer from `icicle-buffer-extras'.
5150 Save the updated option."               ; Doc string
5151   icicle-remove-buffer-candidate-action ; Action function
5152   "Remove buffer from always-show list: " ; `completing-read' args
5153   (mapcar #'list icicle-buffer-extras) nil t nil 'buffer-name-history (car icicle-buffer-extras) nil
5154   ((icicle-use-candidates-only-once-flag  t) ; Bindings
5155    (icicle-candidate-alt-action-fn
5156     (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
5157    (icicle-all-candidates-list-alt-action-fn ; M-|'
5158     (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer"))))
5159   (unless icicle-buffer-extras (error "`icicle-extra-buffers' is empty"))) ; First code
5160
5161 (defun icicle-remove-buffer-candidate-action (buf)
5162   "Action function for command `icicle-remove-buffer-candidate'."
5163   (setq icicle-buffer-extras  (delete buf icicle-buffer-extras))
5164   (funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
5165   (message "Buffer `%s' removed from always-show buffers" buf))
5166
5167 ;;;###autoload (autoload 'icicle-buffer-config "icicles-cmd1.el")
5168 (icicle-define-command icicle-buffer-config ; Command name
5169   "Choose a configuration of user options for `icicle-buffer'.
5170 You can use `S-delete' on any configuration during completion to
5171 remove it.  See user option `icicle-buffer-configs'.
5172 See also commands `icicle-add-buffer-config' and
5173 `icicle-remove-buffer-config'."         ; Doc string
5174   (lambda (config-name)                 ; Action function
5175     (let ((config  (assoc config-name icicle-buffer-configs)))
5176       (setq icicle-buffer-match-regexp     (elt config 1)
5177             icicle-buffer-no-match-regexp  (elt config 2)
5178             icicle-buffer-predicate        (elt config 3)
5179             icicle-buffer-extras           (elt config 4)
5180             icicle-buffer-sort             (elt config 5))))
5181   "Configuration: " icicle-buffer-configs nil t nil ; `completing-read' args
5182   'icicle-buffer-config-history nil nil
5183   ((icicle-delete-candidate-object  'icicle-remove-buffer-config-action))) ; Bindings
5184
5185 ;;;###autoload (autoload 'icicle-add-buffer-config "icicles-cmd1.el")
5186 (icicle-define-add-to-alist-command icicle-add-buffer-config ; Command name
5187   "Add buffer configuration to `icicle-buffer-configs'.
5188 You are prompted for the buffer configuration components.
5189 For the list of extra buffers to always display, you can choose them
5190 using `C-mouse-2', `C-RET', and so on, just as you would make any
5191 Icicles multiple choice."
5192   #'(lambda ()
5193       (let ((name            (read-from-minibuffer "Add buffer configuration.  Name: "))
5194             (match-regexp    (icicle-read-from-minibuf-nil-default
5195                               "Regexp to match: " nil nil nil 'regexp-history
5196                               icicle-buffer-match-regexp))
5197             (nomatch-regexp  (icicle-read-from-minibuf-nil-default
5198                               "Regexp not to match: " nil nil nil 'regexp-history
5199                               icicle-buffer-no-match-regexp))
5200             (pred            (icicle-read-from-minibuf-nil-default
5201                               "Predicate to satify: " nil nil nil
5202                               (if (boundp 'function-name-history)
5203                                   'function-name-history
5204                                 'icicle-function-name-history)
5205                               icicle-buffer-predicate))
5206             (sort-fn         (icicle-read-from-minibuf-nil-default
5207                               "Sort function: " nil nil t
5208                               (if (boundp 'function-name-history)
5209                                   'function-name-history
5210                                 'icicle-function-name-history)
5211                               (and icicle-buffer-sort (symbol-name icicle-buffer-sort))))
5212             (extras          (progn (message "Choose extra buffers to show...") (sit-for 1)
5213                                     (icicle-buffer-list)))) ; Do last, for convenience.
5214         (list name match-regexp nomatch-regexp pred extras sort-fn)))
5215   icicle-buffer-configs)
5216
5217 ;;;###autoload (autoload 'icicle-buffer-list "icicles-cmd1.el")
5218 (icicle-define-command icicle-buffer-list ; Command name
5219   "Choose a list of buffer names.
5220 With a positive prefix arg, only buffers visiting files are candidates.
5221 With a negative prefix arg, only buffers associated with the selected
5222 frame are candidates.
5223
5224 You can use `S-delete' during completion to kill a candidate buffer.
5225 The list of names (strings) is returned.
5226
5227 These options, when non-nil, control candidate matching and filtering:
5228
5229  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
5230  `icicle-buffer-extras'             - Extra buffers to display
5231  `icicle-buffer-match-regexp'       - Regexp that buffers must match
5232  `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
5233  `icicle-buffer-predicate'          - Predicate buffer must satisfy
5234  `icicle-buffer-sort'               - Sort function for candidates
5235
5236 Note: The prefix arg is tested, even when this is called
5237 noninteractively.  Lisp code can bind `current-prefix-arg' to control
5238 the behavior."                          ; Doc string
5239   (lambda (name) (push name buf-names)) ; Action function
5240   "Choose buffer (`RET' when done): "   ; `completing-read' args
5241   (mapcar #'(lambda (buf) (list (buffer-name buf)))
5242           (if current-prefix-arg
5243               (if (wholenump (prefix-numeric-value current-prefix-arg))
5244                   (icicle-remove-if-not #'(lambda (bf) (buffer-file-name bf)) (buffer-list))
5245                 (cdr (assq 'buffer-list (frame-parameters))))
5246             (buffer-list)))
5247   nil
5248   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5249   nil 'buffer-name-history nil nil
5250   ((buf-names                               ()) ; Bindings
5251    (completion-ignore-case                  (or (and (boundp 'read-buffer-completion-ignore-case)
5252                                                      read-buffer-completion-ignore-case)
5253                                                 completion-ignore-case))
5254    (icicle-must-match-regexp                icicle-buffer-match-regexp)
5255    (icicle-must-not-match-regexp            icicle-buffer-no-match-regexp)
5256    (icicle-must-pass-after-match-predicate  icicle-buffer-predicate)
5257    (icicle-require-match-flag               icicle-buffer-require-match-flag)
5258    (icicle-extra-candidates                 icicle-buffer-extras)
5259    (icicle-ignore-space-prefix-flag         icicle-buffer-ignore-space-prefix-flag)
5260    (icicle-delete-candidate-object          'icicle-kill-a-buffer) ; `S-delete' kills current buf
5261    (icicle-transform-function               'icicle-remove-dups-if-extras)
5262    (icicle-sort-comparer                    (or icicle-buffer-sort icicle-sort-comparer))
5263    (icicle-sort-orders-alist
5264     (append (list '("by last access")   ; Renamed from "turned OFF'.
5265                   '("*...* last" . icicle-buffer-sort-*...*-last)
5266                   '("by buffer size" . icicle-buffer-smaller-p)
5267                   '("by major mode name" . icicle-major-mode-name-less-p)
5268                   (and (fboundp 'icicle-mode-line-name-less-p)
5269                        '("by mode-line mode name" . icicle-mode-line-name-less-p))
5270                   '("by file/process name" . icicle-buffer-file/process-name-less-p))
5271             (delete '("turned OFF") icicle-sort-orders-alist)))
5272    (icicle-candidate-alt-action-fn
5273     (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
5274    (icicle-all-candidates-list-alt-action-fn ; M-|'
5275     (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
5276    (icicle-use-candidates-only-once-flag  t))
5277   nil nil                               ; First code, undo code
5278   (prog1 (setq buf-names  (nreverse (delete "" buf-names))) ; Last code - return the list of buffers
5279     (when (interactive-p) (message "Buffers: %S" buf-names))))
5280
5281 ;;;###autoload (autoload 'icicle-remove-buffer-config "icicles-cmd1.el")
5282 (icicle-define-command icicle-remove-buffer-config ; Command name
5283   "Remove buffer configuration from `icicle-buffer-configs'.
5284 Save the updated option."               ; Doc string
5285   icicle-remove-buffer-config-action    ; Action function
5286   "Remove buffer configuration: "       ; `completing-read' args
5287   (mapcar #'(lambda (config) (list (car config))) icicle-buffer-configs)
5288   nil t nil 'icicle-buffer-config-history (caar icicle-buffer-configs) nil
5289   ((icicle-use-candidates-only-once-flag  t))) ; Bindings
5290
5291 (defun icicle-remove-buffer-config-action (config-name)
5292   "Action function for command `icicle-remove-buffer-config'."
5293   (setq icicle-buffer-configs  (icicle-assoc-delete-all config-name icicle-buffer-configs))
5294   (funcall icicle-customize-save-variable-function 'icicle-buffer-configs icicle-buffer-configs)
5295   (message "Buffer configuration `%s' removed" config-name))
5296
5297 ;;;###autoload (autoload 'icicle-face-list "icicles-cmd1.el")
5298 (icicle-define-command icicle-face-list ; Command name
5299   "Choose a list of face names.  The list of names (strings) is returned." ; Doc string
5300   (lambda (name) (push (icicle-transform-multi-completion name) face-names)) ; Action function
5301   prompt (mapcar #'icicle-make-face-candidate (face-list)) nil ; `completing-read' args
5302   (not (stringp icicle-WYSIWYG-Completions-flag)) nil
5303   (if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history)
5304   nil nil
5305   ((prompt                                "Choose face (`RET' when done): ") ; Bindings
5306    (icicle-list-nth-parts-join-string     ": ")
5307    (icicle-list-join-string               ": ")
5308    ;; $$$$$$ (icicle-list-end-string                "")
5309    (icicle-list-use-nth-parts             '(1))
5310    (icicle-use-candidates-only-once-flag  t)
5311    (icicle-candidate-alt-action-fn
5312     (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "face")))
5313    (icicle-all-candidates-list-alt-action-fn ; M-|'
5314     (or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "face")))
5315    (face-names                            ()))
5316   (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
5317   nil                                   ; Undo code
5318   (prog1 (setq face-names  (nreverse (delete "" face-names))) ; Last code - return list of faces
5319     (when (interactive-p) (message "Faces: %S" face-names))))
5320
5321 ;;;###autoload (autoload 'icicle-color-theme "icicles-cmd1.el")
5322 (icicle-define-command icicle-color-theme ; Command name
5323   "Change color theme.
5324 You can use `S-delete' during completion to remove the current
5325 candidate from the list of color themes.
5326
5327 If you use `C-g' during this command, the previous color-theme
5328 snapshot is used to restore that color theme.
5329
5330 Remember too that you can use the pseudo-theme [Reset] to restore the
5331 last theme: `M-x color-theme-select [Reset]'.
5332
5333 By default, each time you invoke this command, a snapshot is first
5334 made of the current color theme (or current colors, if no theme is
5335 used).  Thus, by default, if you use `C-g', the colors restored are
5336 those used before you changed themes using this command.
5337
5338 However, if you use a prefix arg, then this command takes no new
5339 snapshot, unless no snapshot has ever been taken during this Emacs
5340 session.  This can be useful when experimenting, to restore not to the
5341 state just before this command invocation, but to some previous
5342 snapshot.
5343
5344 To use this command, you must have loaded library `color-theme.el',
5345 available from http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme." ; Doc string
5346   (lambda (theme)
5347     (when (string= "" theme) (error "No theme name entered (empty input)"))
5348     (funcall  (intern theme)))          ; Action function: just call the theme.
5349   "Theme: " icicle-color-themes nil t nil ; `completing-read' args
5350   (if (boundp 'color-theme-history) 'color-theme-history 'icicle-color-theme-history)
5351   nil nil
5352   ((icicle-delete-candidate-object  'icicle-color-themes) ; Bindings
5353    (prefix-arg                      current-prefix-arg))
5354   (progn (unless (prog1 (require 'color-theme nil t) ; First code
5355                    (when (and (fboundp 'color-theme-initialize) (not color-theme-initialized))
5356                      ;; NOTE: We need the `icicle-condition-case-no-debug' because of a BUG in
5357                      ;; `directory-files' for Emacs 20.  Bug reported to `color-theme.el'
5358                      ;; maintainer 2009-11-22.  The problem is that the default value of
5359                      ;; `color-theme-libraries' concats `file-name-directory', which ends in `/',
5360                      ;; with `/themes', not with `themes'.  So the result is `...//themes'.
5361                      ;; That is tolerated by Emacs 21+ `directory-files', but not for Emacs 20.
5362                      ;; Until this `color-theme.el' bug is fixed, Emacs 20 users will need to
5363                      ;; manually load `color-theme-libraries.el'.
5364                      (icicle-condition-case-no-debug nil
5365                          (let ((color-theme-load-all-themes  t))
5366                            (color-theme-initialize)
5367                            (setq color-theme-initialized  t))
5368                        (error nil))))
5369            (error "This command requires library `color-theme.el'"))
5370          (unless icicle-color-themes
5371            (setq icicle-color-themes
5372                  (delete '("bury-buffer")
5373                          (mapcar (lambda (entry) (list (symbol-name (car entry))))
5374                                  color-themes)))) ; Free here, defined in `color-theme.el'.
5375          ;; Create the snapshot, if not available.  Do this so users can also undo using
5376          ;; pseudo-theme `[Reset]'.
5377          (when (or (not prefix-arg)
5378                    (not (assq 'color-theme-snapshot color-themes))
5379                    (not (commandp 'color-theme-snapshot)))
5380            (fset 'color-theme-snapshot (color-theme-make-snapshot))
5381            (setq color-themes  (delq (assq 'color-theme-snapshot color-themes) color-themes)
5382                  color-themes  (delq (assq 'bury-buffer color-themes) color-themes)
5383                  color-themes  (append '((color-theme-snapshot
5384                                           "[Reset]" "Undo changes, if possible.")
5385                                          (bury-buffer "[Quit]" "Bury this buffer."))
5386                                        color-themes))))
5387   (color-theme-snapshot))               ; Undo code
5388
5389
5390 ;; Make delete-selection mode recognize yanking, so it replaces region text.
5391 (put 'icicle-completing-yank 'delete-selection 'yank)
5392 ;; Bound to `C-- C-y' via `icicle-yank-maybe-completing'.
5393 ;;;###autoload (autoload 'icicle-completing-yank "icicles-cmd1.el")
5394 (icicle-define-command icicle-completing-yank
5395   "Yank an entry from the `kill-ring', choosing it using completion.
5396 This is like `yank', but it does not rotate the `kill-ring'.
5397 The mark is pushed first, so the yanked text becomes the region.
5398 You can sort the candidates to yank - use `C-,'.
5399 You can use `S-delete' during completion to remove a candidate entry
5400 from the `kill-ring'."                  ; Doc string
5401   icicle-insert-for-yank                ; Action function
5402   "Insert: " (mapcar #'list kills-in-order) nil t nil 'icicle-kill-history ; `completing-read' args
5403   (car kills-in-order) nil
5404   ((icicle-transform-function       'icicle-remove-duplicates) ; Bindings
5405    (icicle-sort-comparer            nil)
5406    (icicle-delete-candidate-object  'kill-ring)
5407    (kills-in-order                  (icicle-delete-dups
5408                                      (append kill-ring-yank-pointer kill-ring nil)))))
5409
5410 (defun icicle-insert-for-yank (string)
5411   "`insert-for-yank', if defined; else, `insert' with `read-only' removed.
5412 Pushes the mark first, so the inserted text becomes the region."
5413   (setq this-command  'yank)
5414   (push-mark)
5415   (if (fboundp 'insert-for-yank)        ; Defined in `subr.el' (not required).
5416       (insert-for-yank string)
5417     (let ((opoint  (point)))
5418       (insert string)
5419       (let ((inhibit-read-only  t)) (remove-text-properties opoint (point) '(read-only nil))))))
5420
5421
5422 ;; Make delete-selection mode recognize yanking, so it replaces region text.
5423 (put 'icicle-yank-maybe-completing 'delete-selection 'yank)
5424 ;;;###autoload
5425 (defun icicle-yank-maybe-completing (&optional arg) ;  Bound to `C-y' (or what `yank' was bound to).
5426   "`icicle-completing-yank', `icicle-yank', or `icicle-yank-function'.
5427 If called from the minibuffer, call `icicle-yank'.
5428 Otherwise:
5429  With a negative prefix argument, call `icicle-completing-yank'.
5430  Otherwise, call the value of user option `icicle-yank-function' (by
5431  default, `yank')."
5432   (interactive "*P")
5433   (if (window-minibuffer-p (selected-window))
5434       (icicle-yank arg)
5435     (if (wholenump (prefix-numeric-value arg))
5436         (funcall icicle-yank-function arg)
5437       (icicle-completing-yank))))
5438
5439 ;;;###autoload (autoload 'icicle-delete-file "icicles-cmd1.el")
5440 (icicle-define-file-command icicle-delete-file ; Command name
5441   "Delete a file or directory.
5442 During completion (`*': requires library `Bookmark+'):
5443
5444  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5445    current-candidate file.  You are prompted for the tags.
5446  *You can use `C-x m' to access file bookmarks (not just autofiles).
5447   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5448   You can use `C-c +' to create a new directory.
5449   You can use `M-|' to open Dired on currently matching file names.
5450   You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
5451   icicle-delete-file-or-directory       ; Function to perform the action
5452   "Delete file or directory: " default-directory nil t nil nil ; `read-file-name' args
5453   (icicle-file-bindings)                ; Bindings
5454   (icicle-bind-file-candidate-keys)     ; First code
5455   nil                                   ; Undo code
5456   (icicle-unbind-file-candidate-keys))  ; Last code
5457
5458 (defun icicle-delete-file-or-directory (file)
5459   "Delete file or (empty) directory FILE."
5460   (icicle-condition-case-no-debug i-delete-file
5461       (if (eq t (car (file-attributes file)))
5462           (delete-directory file)
5463         (delete-file file))
5464     (error (message "%s" (error-message-string i-delete-file))
5465            (error "%s" (error-message-string i-delete-file)))))
5466
5467 ;; $$$$$ (icicle-define-command icicle-file-list ; Command name
5468 ;;   "Choose a list of file names.
5469 ;; You can use `S-delete' during completion to delete a candidate file.
5470 ;; The list of names (strings) is returned." ; Doc string
5471 ;;   (lambda (name) (push name file-names)) ; Function to perform the action
5472 ;;   "Choose file (`RET' when done): "     ; `completing-read' args
5473 ;;   (mapcar #'list (directory-files default-directory nil icicle-re-no-dot))
5474 ;;   nil nil nil 'file-name-history nil nil
5475 ;;   ((file-names nil)                     ; Additional bindings
5476 ;;    (icicle-delete-candidate-object  'icicle-delete-file-or-directory) ; `S-delete' deletes file.
5477 ;;    (icicle-use-candidates-only-once-flag  t))
5478 ;;   nil nil                               ; First code, undo code
5479 ;;   (prog1 (setq file-names  (nreverse (delete "" file-names))) ; Last code - return files list
5480 ;;     (when (interactive-p) (message "Files: %S" file-names))))
5481
5482 ;;;###autoload (autoload 'icicle-file-list "icicles-cmd1.el")
5483 (icicle-define-file-command icicle-file-list ; Command name
5484   "Choose a list of file and directory names (strings), and return it.
5485 Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
5486 and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
5487 You can navigate the directory tree, picking files and directories
5488 anywhere in the tree.
5489
5490 Remember too that you can use `C-!' to gather all of the file names
5491 matching your current input.  For example, apropos-completing with
5492 input `foo.*bar' and hitting `C-!' adds all file names matching that
5493 regexp.
5494
5495 You can use either `RET' or `C-g' to finish adding file names to the
5496 list.
5497
5498 During completion (`*': requires library `Bookmark+'):
5499
5500  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5501    current-candidate file.  You are prompted for the tags.
5502  *You can use `C-x m' to access file bookmarks (not just autofiles).
5503   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5504   You can use `C-c +' to create a new directory.
5505   You can use `M-|' to open Dired on currently matching file names.
5506   You can use `S-delete' to delete a candidate file or (empty) dir.
5507
5508 These options, when non-nil, control candidate matching and filtering:
5509
5510  `icicle-file-extras'           - Extra file names to display
5511  `icicle-file-match-regexp'     - Regexp that file names must match
5512  `icicle-file-no-match-regexp'  - Regexp file names must not match
5513  `icicle-file-predicate'        - Predicate file names must satisfy
5514  `icicle-file-sort'             - Sort function for candidates
5515
5516 For example, to show only names of files larger than 5000 bytes, set
5517 `icicle-file-predicate' to:
5518
5519   (lambda (file) (> (nth 5 (file-attributes file)) 5000))
5520
5521 Option `icicle-file-require-match-flag' can be used to override
5522 option `icicle-require-match-flag'.
5523
5524 Option `icicle-files-ido-like' non-nil gives this command a more
5525 Ido-like behavior."                     ; Doc string
5526   (lambda (name) (push name file-names)) ; Function to perform the action
5527   "Choose file (`RET' when done): " nil nil t nil nil ; `read-file-name' args
5528   (icicle-file-bindings                 ; Bindings
5529    ((file-names                         nil)
5530     (icicle-comp-base-is-default-dir-p  t)
5531     ;; $$$$$ (icicle-dir-candidate-can-exit-p (not current-prefix-arg))
5532     ))
5533   (icicle-bind-file-candidate-keys)     ; First code
5534   nil                                   ; Undo code
5535   (prog1 (setq file-names  (nreverse (delete "" file-names))) ; Last code - return list of files
5536     (icicle-unbind-file-candidate-keys)
5537     (when (interactive-p) (message "Files: %S" file-names))))
5538
5539 ;;;###autoload (autoload 'icicle-directory-list "icicles-cmd1.el")
5540 (icicle-define-file-command icicle-directory-list ; Command name
5541   "Choose a list of directory names (strings), and return it.
5542 Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
5543 and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
5544 You can navigate the directory tree, picking directories anywhere in
5545 the tree.
5546
5547 During completion (`*': requires library `Bookmark+'):
5548
5549  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5550    current-candidate file.  You are prompted for the tags.
5551  *You can use `C-x m' to access file bookmarks (not just autofiles).
5552   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5553   You can use `C-c +' to create a new directory.
5554   You can use `M-|' to open Dired on currently matching file names.
5555   You can use `S-delete' to delete a candidate file or (empty) dir.
5556
5557 These options, when non-nil, control candidate matching and filtering:
5558
5559  `icicle-file-extras'           - Extra directory names to display
5560  `icicle-file-match-regexp'     - Regexp directory names must match
5561  `icicle-file-no-match-regexp'  - Regexp dir names must not match
5562  `icicle-file-predicate'        - Predicate the dir names must satisfy
5563  `icicle-file-sort'             - Sort function for candidates
5564
5565 Option `icicle-file-require-match-flag' can be used to override
5566 option `icicle-require-match-flag'.
5567
5568 Option `icicle-files-ido-like' non-nil gives this command a more
5569 Ido-like behavior."                     ; Doc string
5570   (lambda (name) (push name dir-names)) ; Function to perform the action
5571   "Choose directory (`RET' when done): " ; `read-file-name' args
5572   nil nil t nil nil
5573   (icicle-file-bindings                 ; Bindings
5574    ((dir-names                          ())
5575     (user-file-pred                     icicle-file-predicate)
5576     (icicle-file-predicate              (if user-file-pred
5577                                             #'(lambda (f) (and (file-directory-p f)
5578                                                                (funcall user-file-pred f)))
5579                                           #'file-directory-p))
5580     (icicle-comp-base-is-default-dir-p  t)
5581     ;; $$$$$ (icicle-dir-candidate-can-exit-p (not current-prefix-arg))
5582     ))
5583   (icicle-bind-file-candidate-keys)     ; First code
5584   nil                                   ; Undo code
5585   (prog1 (setq dir-names  (nreverse (delete "" dir-names))) ; Last code - return the list of dirs
5586     (icicle-unbind-file-candidate-keys)
5587     (when (interactive-p) (message "Directories: %S" dir-names))))
5588
5589 ;;;###autoload (autoload 'icicle-dired "icicles-cmd1.el")
5590 (icicle-define-file-command icicle-dired
5591   "Multi-command version of `dired'.
5592
5593 During completion (`*': requires library `Bookmark+'):
5594
5595  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5596    current-candidate file.  You are prompted for the tags.
5597  *You can use `C-x m' to access file bookmarks (not just autofiles).
5598   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5599   You can use `C-c +' to create a new directory.
5600   You can use `M-|' to open Dired on currently matching file names.
5601   You can use `S-delete' to delete a candidate file or (empty) dir." ; Doc string
5602   (lambda (dir) (dired dir switches))   ; Function to perform the action
5603   "Dired (directory): " nil default-directory nil nil nil ; `read-file-name' args
5604   (icicle-file-bindings                 ; Bindings
5605    ((switches               (and current-prefix-arg
5606                                  (read-string "Dired listing switches: " dired-listing-switches)))
5607     (icicle-file-sort       (or icicle-file-sort 'icicle-dirs-first-p))
5608     (icicle-all-candidates-list-alt-action-fn ; M-|'
5609      (lambda (files) (let ((enable-recursive-minibuffers  t))
5610                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
5611   (icicle-bind-file-candidate-keys)     ; First code
5612   nil                                   ; Undo code
5613   (icicle-unbind-file-candidate-keys))  ; Last code
5614
5615 ;;;###autoload (autoload 'icicle-dired-other-window "icicles-cmd1.el")
5616 (icicle-define-file-command icicle-dired-other-window
5617   "Same as `icicle-dired', except uses another window."                           ; Doc string
5618   (lambda (dir) (dired-other-window dir switches)) ; Function to perform the action
5619   "Dired in other window (directory): " nil default-directory nil nil nil ; `read-file-name' args
5620   (icicle-file-bindings                 ; Bindings
5621    ((switches               (and current-prefix-arg
5622                                  (read-string "Dired listing switches: " dired-listing-switches)))
5623     (icicle-file-sort       (or icicle-file-sort 'icicle-dirs-first-p))
5624     (icicle-all-candidates-list-alt-action-fn ; M-|'
5625      (lambda (files) (let ((enable-recursive-minibuffers  t))
5626                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
5627   (icicle-bind-file-candidate-keys)     ; First code
5628   nil                                   ; Undo code
5629   (icicle-unbind-file-candidate-keys))  ; Last code
5630
5631
5632 (put 'icicle-file 'icicle-Completions-window-max-height 200)
5633 ;;;###autoload
5634 (defun icicle-file (arg)                ; Bound to `C-x C-f' in Icicle mode.
5635   "Visit a file or directory.
5636 With no prefix argument, use relative file names
5637  (`icicle-find-file').
5638 With a prefix argument, use absolute file names
5639  (`icicle-find-file-absolute').
5640 With a negative prefix argument, you can choose also by date:
5641  Completion candidates include the last modification date.
5642
5643 Note that when you use a prefix argument completion matches candidates
5644 as ordinary strings.  It knows nothing of file names per se.  In
5645 particular, you cannot use remote file-name syntax if you use a prefix
5646 argument.
5647
5648 During completion:
5649  You can use `C-x m' to access file bookmarks, if you use library
5650   `Bookmark+'.
5651  You can use `C-c +' to create a new directory.
5652  You can use `M-|' to open Dired on the currently matching file names.
5653  You can use `S-delete' to delete a candidate file or (empty)
5654   directory.
5655
5656 By default, Icicle mode remaps all key sequences that are normally bound
5657 to `find-file' to `icicle-file'.  If you do not want this remapping,
5658 then customize option `icicle-top-level-key-bindings'."
5659   (interactive "P")
5660   (if arg
5661       (if (wholenump (prefix-numeric-value arg))
5662           (let ((current-prefix-arg  nil)) (icicle-find-file-absolute))
5663         (icicle-find-file-absolute))
5664     (icicle-find-file)))
5665
5666
5667 (put 'icicle-file-other-window 'icicle-Completions-window-max-height 200)
5668 ;;;###autoload
5669 (defun icicle-file-other-window (arg)   ; Bound to `C-x 4 f' in Icicle mode.
5670   "Same as `icicle-file', except uses another window."
5671   (interactive "P")
5672   (if arg
5673       (if (wholenump (prefix-numeric-value arg))
5674           (let ((current-prefix-arg  nil)) (icicle-find-file-absolute-other-window))
5675         (icicle-find-file-absolute-other-window))
5676     (icicle-find-file-other-window)))
5677
5678
5679 (put 'icicle-find-file-absolute 'icicle-Completions-window-max-height 200)
5680 ;;;###autoload (autoload 'icicle-find-file-absolute "icicles-cmd1.el")
5681 (icicle-define-command icicle-find-file-absolute ; Command name
5682   "Visit a file or directory, given its absolute name.
5683 Unlike `icicle-find-file', the completion candidates are absolute, not
5684 relative, file names.  By default, the completion candidates are files
5685 in the current directory, but you can substitute other candidates by
5686 retrieving a saved candidate set.
5687
5688 Note that completion here matches candidates as ordinary strings.  It
5689 knows nothing of file names per se.  In particular, you cannot use
5690 remote file-name syntax.
5691
5692 Remember that you can use `\\<minibuffer-local-completion-map>\
5693 \\[icicle-toggle-hiding-common-match]' to hide the common match portion of
5694 each candidate.  That can be particularly helpful for files that are
5695 in a common directory.
5696
5697 With a prefix argument, you can choose also by date: Completion
5698 candidates include the last modification date.
5699
5700 During completion (`*': requires library `Bookmark+'):
5701
5702  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5703    current-candidate file.  You are prompted for the tags.
5704  *You can use `C-x m' to access file bookmarks (not just autofiles).
5705   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5706   You can use `C-c +' to create a new directory.
5707   You can use `M-|' to open Dired on currently matching file names.
5708   You can use `S-delete' to delete a candidate file or (empty) dir.
5709
5710 These options, when non-nil, control candidate matching and filtering:
5711
5712  `icicle-file-extras'           - Extra file names to display
5713  `icicle-file-match-regexp'     - Regexp that file names must match
5714  `icicle-file-no-match-regexp'  - Regexp file names must not match
5715  `icicle-file-predicate'        - Predicate file names must satisfy
5716  `icicle-file-sort'             - Sort function for candidates
5717
5718 For example, to show only names of files larger than 5000 bytes, set
5719 `icicle-file-predicate' to:
5720
5721   (lambda (file) (> (nth 5 (file-attributes file)) 5000))
5722
5723 Option `icicle-file-require-match-flag' can be used to override
5724 option `icicle-require-match-flag'.
5725
5726 Option `icicle-files-ido-like' non-nil gives this command a more
5727 Ido-like behavior."                     ; Doc string
5728   (lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
5729   prompt icicle-abs-file-candidates nil ; `completing-read' args
5730   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5731   default-directory 'file-name-history default-directory nil
5732   (icicle-file-bindings                 ; Bindings
5733    ((prompt                             "File or dir (absolute): ")
5734     (icicle-full-cand-fn                `(lambda (file)
5735                                           (setq file  (if (file-directory-p file)
5736                                                           (concat file "/")
5737                                                         file))
5738                                           ,(if current-prefix-arg
5739                                                '(icicle-make-file+date-candidate file)
5740                                                '(list file))))
5741     (icicle-abs-file-candidates         (mapcar icicle-full-cand-fn
5742                                                 (directory-files default-directory 'FULL nil 'NOSORT)))
5743     (icicle-all-candidates-list-alt-action-fn ; M-|'
5744      (lambda (files) (let ((enable-recursive-minibuffers  t))
5745                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
5746     (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
5747     (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
5748     (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))))
5749   (progn                                ; First code
5750     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
5751     (icicle-highlight-lighter)
5752     (message "Gathering files...")
5753     (icicle-bind-file-candidate-keys))
5754   nil                                   ; Undo code
5755   (icicle-unbind-file-candidate-keys))  ; Last code
5756
5757
5758 (put 'icicle-find-file-absolute-other-window 'icicle-Completions-window-max-height 200)
5759 ;;;###autoload (autoload 'icicle-find-file-absolute-other-window "icicles-cmd1.el")
5760 (icicle-define-command icicle-find-file-absolute-other-window ; Command name
5761   "Same as `icicle-find-file-absolute' except uses another window." ; Doc string
5762   (lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
5763   prompt icicle-abs-file-candidates nil ; `completing-read' args
5764   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5765   default-directory 'file-name-history default-directory nil
5766   (icicle-file-bindings                 ; Bindings
5767    ((prompt                             "File or dir (absolute): ")
5768     (icicle-full-cand-fn                `(lambda (file)
5769                                           (setq file  (if (file-directory-p file)
5770                                                           (concat file "/")
5771                                                         file))
5772                                           ,(if current-prefix-arg
5773                                                '(icicle-make-file+date-candidate file)
5774                                                '(list file))))
5775     (icicle-abs-file-candidates         (mapcar icicle-full-cand-fn
5776                                                 (directory-files default-directory 'FULL nil 'NOSORT)))
5777     (icicle-all-candidates-list-alt-action-fn ; M-|'
5778      (lambda (files) (let ((enable-recursive-minibuffers  t))
5779                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
5780     (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
5781     (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
5782     (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))))
5783   (progn                                ; First code
5784     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
5785     (icicle-highlight-lighter)
5786     (message "Gathering files...")
5787     (icicle-bind-file-candidate-keys))
5788   nil                                   ; Undo code
5789   (icicle-unbind-file-candidate-keys))  ; Last code
5790
5791 ;; This is a minibuffer command.  It is in this file because it is used only here.
5792 ;;;###autoload
5793 (defun icicle-cd-for-abs-files (dir)    ; Bound to `C-c C-d' in minibuffer for abs file completion.
5794   "Change `default-directory' during `icicle-find-file-absolute'."
5795   (interactive
5796    ;; Should not need to bind `minibuffer-completion-predicate'.  Emacs 23.2 bug, per Stefan.
5797    (let ((enable-recursive-minibuffers     t)
5798          (minibuffer-completion-predicate  minibuffer-completion-predicate))
5799      (list (funcall (if (fboundp 'read-directory-name)
5800                         #'read-directory-name
5801                       #'read-file-name)
5802                     "Change default directory: " nil nil
5803                     (and (member cd-path '(nil ("./"))) (null (getenv "CDPATH")))))))
5804   (cd dir)
5805   (let ((icicle-abs-file-candidates
5806          (mapcar #'(lambda (file)
5807                      (setq file  (if (file-directory-p file) (concat file "/") file))
5808                      (if icicle-list-use-nth-parts (icicle-make-file+date-candidate file) (list file)))
5809                  (directory-files default-directory 'full nil 'nosort))))
5810     (setq minibuffer-completion-table
5811           (car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
5812
5813
5814 (put 'icicle-find-file 'icicle-Completions-window-max-height 200)
5815 ;;;###autoload (autoload 'icicle-find-file "icicles-cmd1.el")
5816 (icicle-define-file-command icicle-find-file
5817   "Visit a file or directory.
5818 If you use a prefix argument when you act on a candidate file name,
5819 then you visit the file in read-only mode.
5820
5821 If you use a prefix arg for the command itself, this reverses the
5822 effect of using a prefix arg on individual candidates.  That is, with
5823 a prefix arg for the command, files are visited in read-only mode by
5824 default and a prefix arg for an individual file visits it without
5825 read-only mode.
5826
5827 During completion (`*': requires library `Bookmark+'):
5828
5829  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5830    current-candidate file.  You are prompted for the tags.
5831  *You can use `C-x m' to access file bookmarks (not just autofiles).
5832   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5833   You can use `C-c +' to create a new directory.
5834   You can use `M-|' to open Dired on currently matching file names.
5835   You can use `S-delete' to delete a candidate file or (empty) dir.
5836
5837 These options, when non-nil, control candidate matching and filtering:
5838
5839  `icicle-file-extras'           - Extra absolute file names to display
5840  `icicle-file-match-regexp'     - Regexp that file names must match
5841  `icicle-file-no-match-regexp'  - Regexp file names must not match
5842  `icicle-file-predicate'        - Predicate file names must satisfy
5843  `icicle-file-sort'             - Sort function for candidates
5844
5845 For example, to show only names of files larger than 5000 bytes, set
5846 `icicle-file-predicate' to:
5847
5848   (lambda (file) (> (nth 5 (file-attributes file)) 5000))
5849
5850 Option `icicle-file-require-match-flag' can be used to override
5851 option `icicle-require-match-flag'.
5852
5853 Option `icicle-files-ido-like' non-nil gives this command a more
5854 Ido-like behavior."                     ; Doc string
5855   (lambda (file)                        ; Function to perform the action
5856     (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
5857                      (or (and init-pref-arg        (not current-prefix-arg))
5858                          (and (not init-pref-arg)  current-prefix-arg))
5859                    init-pref-arg))
5860            (fn   (if r-o 'find-file-read-only 'find-file)))
5861       (funcall fn file 'WILDCARDS)))
5862   (concat "File or directory" (and init-pref-arg " (read-only)") ": ") ; `read-file-name' args
5863   nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
5864           (condition-case nil           ; E.g. error because not on file line (ignore)
5865               (abbreviate-file-name (dired-get-file-for-visit))
5866             (error nil))
5867         default-directory)
5868   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5869   nil nil
5870   (icicle-file-bindings                 ; Bindings
5871    ((init-pref-arg  current-prefix-arg)
5872     (icicle-all-candidates-list-alt-action-fn ; `M-|'
5873      (lambda (files) (let ((enable-recursive-minibuffers  t))
5874                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
5875   (icicle-bind-file-candidate-keys)     ; First code
5876   nil                                   ; Undo code
5877   (icicle-unbind-file-candidate-keys))  ; Last code
5878
5879 ;;;###autoload (autoload 'icicle-find-file-other-window "icicles-cmd1.el")
5880 (icicle-define-file-command icicle-find-file-other-window
5881   "Same as `icicle-find-file', except uses another window." ; Doc string
5882   (lambda (file)                        ; Function to perform the action
5883     (let* ((r-o  (if (eq this-command 'icicle-candidate-action)
5884                      (or (and init-pref-arg        (not current-prefix-arg))
5885                          (and (not init-pref-arg)  current-prefix-arg))
5886                    init-pref-arg))
5887            (fn   (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
5888       (funcall fn file 'WILDCARDS)))
5889   (concat "File or directory" (and init-pref-arg " (read-only)") ": ") ; `read-file-name' args
5890   nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
5891           (condition-case nil           ; E.g. error because not on file line (ignore)
5892               (abbreviate-file-name (dired-get-file-for-visit))
5893             (error nil))
5894         default-directory)
5895   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5896   nil nil
5897   (icicle-file-bindings                 ; Bindings
5898    ((init-pref-arg  current-prefix-arg)
5899     (icicle-all-candidates-list-alt-action-fn ; `M-|'
5900      (lambda (files) (let ((enable-recursive-minibuffers  t))
5901                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
5902   (icicle-bind-file-candidate-keys)     ; First code
5903   nil                                   ; Undo code
5904   (icicle-unbind-file-candidate-keys))  ; Last code
5905
5906
5907 (put 'icicle-find-file-read-only 'icicle-Completions-window-max-height 200)
5908 ;;;###autoload
5909 (defun icicle-find-file-read-only ()    ; Bound to `C-x C-r' in Icicle mode.
5910   "Visit a file or directory in read-only mode.
5911 If you use a prefix argument when you act on a candidate file name,
5912 then visit the file without read-only mode.
5913
5914 If you use a prefix arg for the command itself, this reverses the
5915 effect of using a prefix arg on individual candidates.  That is, with
5916 a prefix arg for the command, files are not visited in read-only mode
5917 by default and a prefix arg for an individual file visits it in
5918 read-only mode.
5919
5920 During completion (`*': requires library `Bookmark+'):
5921
5922  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5923    current-candidate file.  You are prompted for the tags.
5924  *You can use `C-x m' to access file bookmarks (not just autofiles).
5925   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5926   You can use `C-c +' to create a new directory.
5927   You can use `M-|' to open Dired on currently matching file names.
5928   You can use `S-delete' to delete a candidate file or (empty) dir."
5929   (interactive)
5930   (let ((current-prefix-arg  (not current-prefix-arg)))
5931     (icicle-find-file)))
5932
5933 ;;;###autoload
5934 (defun icicle-find-file-read-only-other-window () ; Bound to `C-x 4 r' in Icicle mode.
5935   "Same as `icicle-find-file-read-only' except uses another window."
5936   (interactive)
5937   (let ((current-prefix-arg  (not current-prefix-arg)))
5938     (icicle-find-file-other-window)))
5939
5940
5941 (put 'icicle-recent-file 'icicle-Completions-window-max-height 200)
5942 ;;;###autoload (autoload 'icicle-recent-file "icicles-cmd1.el")
5943 (icicle-define-command icicle-recent-file ; Command name
5944   "Open a recently used file.
5945 With a prefix argument, you can choose also by date: Completion
5946 candidates include the last modification date.
5947
5948 Note that completion here matches candidates as ordinary strings.  It
5949 knows nothing of file names per se.  In particular, you cannot use
5950 remote file-name syntax.
5951
5952 Remember that you can use `\\<minibuffer-local-completion-map>\
5953 \\[icicle-toggle-hiding-common-match]' to hide the common match portion of
5954 each candidate.  That can be particularly helpful for files that are
5955 in a common directory.
5956
5957 During completion (`*': requires library `Bookmark+'):
5958
5959  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
5960    current-candidate file.  You are prompted for the tags.
5961  *You can use `C-x m' to access file bookmarks (not just autofiles).
5962   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
5963   You can use `C-c +' to create a new directory.
5964   You can use `M-|' to open Dired on currently matching file names.
5965   You can use `S-delete' to delete a candidate file or (empty) dir.
5966
5967 You can use any of the alternative-action keys, such as `C-S-RET', to
5968 remove a candidate file from the recent files list, `recentf-list'.
5969 \(The file itself is not deleted.)
5970
5971 These options, when non-nil, control candidate matching and filtering:
5972
5973  `icicle-file-extras'           - Extra absolute file names to display
5974  `icicle-file-match-regexp'     - Regexp that file names must match
5975  `icicle-file-no-match-regexp'  - Regexp file names must not match
5976  `icicle-file-predicate'        - Predicate file names must satisfy
5977  `icicle-file-sort'             - Sort function for candidates
5978
5979 For example, to show only names of files larger than 5000 bytes, set
5980 `icicle-file-predicate' to:
5981
5982   (lambda (file) (> (nth 5 (file-attributes file)) 5000))
5983
5984 Option `icicle-file-require-match-flag' can be used to override
5985 option `icicle-require-match-flag'.
5986
5987 Option `icicle-files-ido-like' non-nil gives this command a more
5988 Ido-like behavior."                     ; Doc string
5989   (lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action function
5990   prompt icicle-abs-file-candidates nil ; `completing-read' args
5991   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
5992   nil 'file-name-history (car recentf-list) nil
5993   (icicle-file-bindings                 ; Bindings
5994    ((prompt                                 "Recent file (absolute): ")
5995     (icicle-full-cand-fn                `(lambda (file)
5996                                               (setq file  (if (file-directory-p file)
5997                                                               (concat file "/")
5998                                                             file))
5999                                               ,(if current-prefix-arg
6000                                                    '(icicle-make-file+date-candidate file)
6001                                                    '(list file))))
6002     (icicle-abs-file-candidates
6003      (progn (unless (boundp 'recentf-list) (require 'recentf))
6004             (when (fboundp 'recentf-mode) (recentf-mode 99))
6005             (unless (consp recentf-list)
6006               (error "No recently accessed files"))
6007             (mapcar #'(lambda (file)
6008                         (if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
6009                     recentf-list)))
6010     (icicle-candidate-alt-action-fn         'icicle-remove-from-recentf-candidate-action)
6011     (icicle-use-candidates-only-once-alt-p  t)
6012     (icicle-candidate-properties-alist      (and current-prefix-arg
6013                                                  '((1 (face icicle-candidate-part)))))
6014     (icicle-list-use-nth-parts              (and current-prefix-arg '(1)))
6015     (icicle-all-candidates-list-alt-action-fn ; M-|'
6016      (lambda (files) (let ((enable-recursive-minibuffers  t))
6017                        (dired-other-window (cons (read-string "Dired buffer name: ")
6018                                                  (mapcar #'icicle-transform-multi-completion
6019                                                          files))))))))
6020   (progn                                ; First code
6021     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
6022     (icicle-highlight-lighter)
6023     (message "Gathering files...")
6024     (icicle-bind-file-candidate-keys))
6025   nil                                   ; Undo code
6026   (icicle-unbind-file-candidate-keys))  ; Last code
6027
6028 ;;;###autoload (autoload 'icicle-recent-file-other-window "icicles-cmd1.el")
6029 (icicle-define-command icicle-recent-file-other-window ; Command name
6030   "Same as `icicle-recent-file' except uses another window." ; Doc string
6031   (lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS)) ; Action
6032   prompt icicle-abs-file-candidates nil ; `completing-read' args
6033   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
6034   nil 'file-name-history (car recentf-list) nil
6035   (icicle-file-bindings                 ; Bindings
6036    ((prompt                                 "Recent file (absolute): ")
6037     (icicle-full-cand-fn                    `(lambda (file)
6038                                               (setq file  (if (file-directory-p file)
6039                                                               (concat file "/")
6040                                                             file))
6041                                               ,(if current-prefix-arg
6042                                                    '(icicle-make-file+date-candidate file)
6043                                                    '(list file))))
6044     (icicle-abs-file-candidates
6045      (progn (unless (boundp 'recentf-list) (require 'recentf))
6046             (when (fboundp 'recentf-mode) (recentf-mode 99))
6047             (unless (consp recentf-list)
6048               (error "No recently accessed files"))
6049             (mapcar #'(lambda (file)
6050                         (if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
6051                     recentf-list)))
6052     (icicle-candidate-alt-action-fn         'icicle-remove-from-recentf-candidate-action)
6053     (icicle-use-candidates-only-once-alt-p  t)
6054     (icicle-candidate-properties-alist      (and current-prefix-arg
6055                                                  '((1 (face icicle-candidate-part)))))
6056     (icicle-list-use-nth-parts              (and current-prefix-arg '(1)))
6057     (icicle-all-candidates-list-alt-action-fn ; M-|'
6058      (lambda (files) (let ((enable-recursive-minibuffers  t))
6059                        (dired-other-window (cons (read-string "Dired buffer name: ")
6060                                                  (mapcar #'icicle-transform-multi-completion
6061                                                          files))))))))
6062   (progn                                ; First code
6063     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
6064     (icicle-highlight-lighter)
6065     (message "Gathering files...")
6066     (icicle-bind-file-candidate-keys))
6067   nil                                   ; Undo code
6068   (icicle-unbind-file-candidate-keys))  ; Last code
6069
6070 ;;;###autoload (autoload 'icicle-remove-file-from-recentf-list "icicles-cmd1.el")
6071 (icicle-define-command icicle-remove-file-from-recentf-list
6072   "Remove file from `recentf-list' - the list of recently used files."
6073   icicle-remove-from-recentf-candidate-action
6074   "Remove from recent files list, `recentf-list': "
6075   (mapcar #'list (progn (unless (boundp 'recentf-list) (require 'recentf))
6076                         (when (fboundp 'recentf-mode) (recentf-mode 99))
6077                         (unless (consp recentf-list) (error "No recently accessed files"))
6078                         recentf-list))
6079   nil (and (fboundp 'confirm-nonexistent-file-or-buffer) ; Emacs23.
6080            (confirm-nonexistent-file-or-buffer))
6081   nil 'file-name-history (car recentf-list) nil
6082   ((icicle-use-candidates-only-once-flag  t)))
6083
6084 (defun icicle-remove-from-recentf-candidate-action (file)
6085   "Action function for command `icicle-remove-file-from-recentf-list'."
6086   (setq recentf-list  (delete file recentf-list))
6087   (message "`%s' removed from `recentf-list'" file))
6088
6089
6090 (defvar icicle-locate-file-action-fn nil
6091   "Action function used in `icicle-locate-file-1'.")
6092
6093 (defvar icicle-locate-file-no-symlinks-p nil
6094   "Flag bound in `icicle-locate-file* for use by `icicle-files-within'.")
6095
6096
6097 (put 'icicle-locate-file 'icicle-Completions-window-max-height 200)
6098 ;;;###autoload
6099 (defun icicle-locate-file ()
6100   "Visit a file within a directory or its subdirectories.
6101 With a non-negative (>= 0) prefix argument, you are prompted for the
6102 directory.  Otherwise, the current directory is used.
6103
6104 With a non-positive (<= 0) prefix argument, you can choose also by
6105 date: Completion candidates include the last modification date.
6106
6107 The absolute names of all files within the directory and all of its
6108 subdirectories are targets for completion.  Regexp input is matched
6109 against all parts of the absolute name, not just the file-name part.
6110
6111 Remember that you can use `\\<minibuffer-local-completion-map>\
6112 \\[icicle-toggle-hiding-common-match]' to hide the common match portion of
6113 each candidate.  That can be particularly helpful for files that are
6114 in a common directory.
6115
6116 You can use this command to find all files within your file system
6117 that match a regexp, but be aware that gathering and matching the file
6118 names will take some time.
6119
6120 See also command `icicle-locate-file-no-symlinks', which does the same
6121 thing but without following symbolic links.
6122
6123 Remember that you can save the set of files matching your input using
6124 `\\[icicle-candidate-set-save]' or \
6125 `\\[icicle-candidate-set-save-persistently]'.  You can then retrieve quickly them later using
6126 `\\[icicle-candidate-set-retrieve]' or \
6127 `\\[icicle-candidate-set-retrieve-persistent]'.
6128
6129 Note that completion here matches candidates as ordinary strings.  It
6130 knows nothing of file names per se.  In particular, you cannot use
6131 remote file-name syntax.
6132
6133 During completion (`*': requires library `Bookmark+'):
6134
6135  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
6136    current-candidate file.  You are prompted for the tags.
6137  *You can use `C-x m' to access file bookmarks (not just autofiles).
6138   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
6139   You can use `C-c +' to create a new directory.
6140   You can use `M-|' to open Dired on currently matching file names.
6141   You can use `S-delete' to delete a candidate file or (empty) dir.
6142
6143 Directories in `icicle-ignored-directories' are ignored (skipped).  In
6144 addition, these options control candidate matching and filtering:
6145
6146  `icicle-file-extras'           - Extra file names to display
6147  `icicle-file-match-regexp'     - Regexp that file names must match
6148  `icicle-file-no-match-regexp'  - Regexp file names must not match
6149  `icicle-file-predicate'        - Predicate file names must satisfy
6150  `icicle-file-require-match-flag' - See `icicle-require-match-flag'
6151  `icicle-file-sort'             - Sort function for candidates
6152
6153 For example, to show only names of files larger than 5000 bytes, set
6154 `icicle-file-predicate' to:
6155
6156   (lambda (file) (> (nth 5 (file-attributes file)) 5000))"
6157   (interactive)
6158   (let ((icicle-locate-file-action-fn      'icicle-locate-file-action)
6159         (icicle-locate-file-no-symlinks-p  nil))
6160     (icicle-locate-file-1)))
6161
6162 ;;;###autoload
6163 (defun icicle-locate-file-other-window ()
6164   "Same as `icicle-locate-file' except uses another window.
6165 See also command `icicle-locate-file-no-symlinks-other-window', which
6166 does not follow symbolic links."
6167   (interactive)
6168   (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
6169         (icicle-locate-file-no-symlinks-p  nil))
6170     (icicle-locate-file-1)))
6171
6172 (put 'icicle-locate-file-no-symlinks 'icicle-Completions-window-max-height 200)
6173 ;;;###autoload
6174 (defun icicle-locate-file-no-symlinks ()
6175   "Same as `icicle-locate-file', except do not follow symlinks."
6176   (interactive)
6177   (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
6178         (icicle-locate-file-no-symlinks-p  t))
6179     (icicle-locate-file-1)))
6180
6181 ;;;###autoload
6182 (defun icicle-locate-file-no-symlinks-other-window ()
6183   "Same as `icicle-locate-file-no-symlinks', except uses another window."
6184   (interactive)
6185   (let ((icicle-locate-file-action-fn      'icicle-locate-file-other-window-action)
6186         (icicle-locate-file-no-symlinks-p  t))
6187     (icicle-locate-file-1)))
6188
6189 (defun icicle-locate-file-action (file)
6190   "Action function for `icicle-locate-file'."
6191   (find-file (icicle-transform-multi-completion file) 'WILDCARDS))
6192
6193 (defun icicle-locate-file-other-window-action (file)
6194   "Action function for `icicle-locate-file-other-window'."
6195   (find-file-other-window (icicle-transform-multi-completion file) 'WILDCARDS))
6196
6197 ;;;###autoload (autoload 'icicle-locate-file-1 "icicles-cmd1.el")
6198 (icicle-define-command icicle-locate-file-1
6199   "Helper function for `icicle-locate-file(-other-window)'." ; Doc string
6200   ;; `icicle-locate-file-action-fn' is free here.
6201   (lambda (f) (funcall icicle-locate-file-action-fn f)) ; Action function
6202   prompt icicle-abs-file-candidates nil ; `completing-read' args
6203   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
6204   nil 'file-name-history nil nil
6205   (icicle-file-bindings                 ; Bindings
6206    ((prompt                             "File (absolute): ")
6207     (dir                                (if (and current-prefix-arg
6208                                                  (wholenump (prefix-numeric-value
6209                                                              current-prefix-arg)))
6210                                             (read-file-name "Locate under which directory: " nil
6211                                                             default-directory nil)
6212                                           default-directory))
6213     (IGNORED--FOR-SIDE-EFFECT           (progn
6214                                           (icicle-highlight-lighter)
6215                                           (message "Gathering files within `%s' (this could take \
6216 a while)..." dir)))
6217     (icicle-full-cand-fn                `(lambda (file)
6218                                           (setq file  (if (file-directory-p file)
6219                                                           (concat file "/")
6220                                                         file))
6221                                           ,(if (<= (prefix-numeric-value current-prefix-arg) 0)
6222                                                '(icicle-make-file+date-candidate file)
6223                                                '(list file))))
6224     (icicle-abs-file-candidates         ; `icicle-locate-file-no-symlinks-p' is free here.
6225      (mapcar #'(lambda (file)
6226                  (if (<= (prefix-numeric-value current-prefix-arg) 0)
6227                      (icicle-make-file+date-candidate file)
6228                    (list file)))
6229              (icicle-files-within (directory-files dir 'full icicle-re-no-dot)
6230                                   nil icicle-locate-file-no-symlinks-p)))
6231     (use-dialog-box                     nil)
6232     (icicle-candidate-properties-alist  (and (<= (prefix-numeric-value current-prefix-arg) 0)
6233                                              '((1 (face icicle-candidate-part)))))
6234     (icicle-list-use-nth-parts          (and (<= (prefix-numeric-value current-prefix-arg) 0)
6235                                              '(1)))
6236     (icicle-all-candidates-list-alt-action-fn ; M-|'
6237      (lambda (files) (let ((enable-recursive-minibuffers  t))
6238                        (dired-other-window (cons (read-string "Dired buffer name: ")
6239                                                  (mapcar #'icicle-transform-multi-completion
6240                                                          files))))))))
6241   (progn                                ; First code
6242     (when (<= (prefix-numeric-value current-prefix-arg) 0)
6243       (put-text-property 0 1 'icicle-fancy-candidates t prompt))
6244     (icicle-highlight-lighter)
6245     (message "Gathering files...")
6246     (icicle-bind-file-candidate-keys))
6247   nil                                   ; Undo code
6248   (icicle-unbind-file-candidate-keys)   ; Last code
6249   'NON-INTERACTIVE)                     ; This is not a real command.
6250
6251 ;; This is a minibuffer command.  It is in this file because it is used only here.
6252 ;;;###autoload
6253 (defun icicle-cd-for-loc-files (dir &optional no-symlinks-p) ; Bound to `C-c C-d' in minibuf locate-*.
6254   "Change `default-directory' during `icicle-locate-file'.
6255 Optional arg NO-SYMLINKS-P non-nil means do not follow symbolic links."
6256   (interactive
6257    (save-selected-window
6258      ;; Should not need to bind `minibuffer-completion-predicate'.  Emacs 23.2 bug, per Stefan.
6259      (let ((minibuffer-completion-predicate  minibuffer-completion-predicate))
6260        (list (funcall (if (fboundp 'read-directory-name)
6261                           #'read-directory-name
6262                         #'read-file-name)
6263                       "Change default directory: " nil nil
6264                       (and (member cd-path '(nil ("./"))) (null (getenv "CDPATH"))))))))
6265   (cd dir)
6266   (let ((icicle-abs-file-candidates
6267          (mapcar #'(lambda (file)
6268                      (if icicle-list-use-nth-parts (icicle-make-file+date-candidate file) (list file)))
6269                  (icicle-files-within (directory-files dir 'full icicle-re-no-dot) nil no-symlinks-p))))
6270     (setq minibuffer-completion-table
6271           (car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
6272
6273
6274 (put 'icicle-find-file-in-tags-table 'icicle-Completions-window-max-height 200)
6275 ;;;###autoload (autoload 'icicle-find-file-in-tags-table "icicles-cmd1.el")
6276 (icicle-define-command icicle-find-file-in-tags-table ; Command name
6277   "Visit a file listed in a tags table.
6278 By default, the completion candidates are the file names listed in the
6279 current tags table, but you can substitute other candidates by
6280 retrieving a saved candidate set.  The default candidates appear as
6281 they did in the `etags' command that created the tags table, which
6282 typically means without directory names.
6283
6284 Completion here matches candidates as ordinary strings.  It knows
6285 nothing of file names per se.  In particular, you cannot use remote
6286 file-name syntax.  If a candidate is an absolute file name then you
6287 can complete against any and all parts of the name (including
6288 directory components).
6289
6290 `find-file' is called for the candidate(s) you choose, with the
6291 directory of the tags file as `default-directory'.
6292
6293 Remember that you can use `\\<minibuffer-local-completion-map>\
6294 \\[icicle-toggle-hiding-common-match]' to hide the common match portion of
6295 each candidate.  That can be particularly helpful for files that are
6296 in a common directory.
6297
6298 With a prefix argument, you can choose also by date: Completion
6299 candidates include the last modification date.
6300
6301 During completion (`*': requires library `Bookmark+'):
6302
6303  *You can use `C-x a +' or `C-x a -' to add or remove tags from the
6304    current-candidate file.  You are prompted for the tags.
6305  *You can use `C-x m' to access file bookmarks (not just autofiles).
6306   You can use `C-c C-d' (a la `cd') to change the `default-directory'.
6307   You can use `C-c +' to create a new directory.
6308   You can use `M-|' to open Dired on currently matching file names.
6309   You can use `S-delete' to delete a candidate file or (empty) dir.
6310
6311 These options, when non-nil, control candidate matching and filtering:
6312
6313  `icicle-file-extras'           - Extra file names to display
6314  `icicle-file-match-regexp'     - Regexp that file names must match
6315  `icicle-file-no-match-regexp'  - Regexp file names must not match
6316  `icicle-file-predicate'        - Predicate file names must satisfy
6317  `icicle-file-sort'             - Sort function for candidates
6318
6319 For example, to show only names of files larger than 5000 bytes, set
6320 `icicle-file-predicate' to:
6321
6322   (lambda (file) (> (nth 5 (file-attributes file)) 5000))
6323
6324 Option `icicle-file-require-match-flag' can be used to override
6325 option `icicle-require-match-flag'.
6326
6327 Option `icicle-files-ido-like' non-nil gives this command a more
6328 Ido-like behavior."                     ; Doc string
6329   (lambda (ff)
6330     (visit-tags-table-buffer 'same)     ; To pick up `default-directory' of TAGS table.
6331     (find-file (icicle-transform-multi-completion ff) 'WILDCARDS)) ; Action function
6332   prompt                                ; `completing-read' args
6333   (mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
6334           (save-excursion (let ((enable-recursive-minibuffers  t)) (visit-tags-table-buffer))
6335                           (tags-table-files)))
6336   nil
6337   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
6338   nil 'file-name-history nil nil
6339   (icicle-file-bindings                 ; Bindings
6340    ((prompt                             "File (in tags table): ")
6341     (icicle-full-cand-fn                `(lambda (file)
6342                                           (setq file  (if (file-directory-p file)
6343                                                           (concat file "/")
6344                                                         file))
6345                                           ,(if current-prefix-arg
6346                                                '(icicle-make-file+date-candidate file)
6347                                                '(list file))))
6348     (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
6349     (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
6350     (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))
6351     (icicle-all-candidates-list-alt-action-fn ; M-|'
6352      (lambda (files) (let ((enable-recursive-minibuffers  t))
6353                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
6354   (progn                                ; First code
6355     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
6356     (unless (require 'etags nil t) (error "`etags.el' is required"))
6357     (icicle-bind-file-candidate-keys))
6358   nil                                   ; Undo code
6359   (icicle-unbind-file-candidate-keys))  ; Last code
6360
6361
6362 (put 'icicle-find-file-in-tags-table-other-window 'icicle-Completions-window-max-height 200)
6363 ;;;###autoload (autoload 'icicle-find-file-in-tags-table-other-window "icicles-cmd1.el")
6364 (icicle-define-command icicle-find-file-in-tags-table-other-window ; Command name
6365   "Same as `icicle-find-file-in-tags-table', but uses another window." ; Doc string
6366   (lambda (ff)
6367     (visit-tags-table-buffer 'same)     ; To pick up `default-directory' of TAGS table.
6368     (find-file (icicle-transform-multi-completion ff) 'WILDCARDS)) ; Action function
6369   prompt                                ; `completing-read' args
6370   (mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
6371           (save-excursion (let ((enable-recursive-minibuffers  t)) (visit-tags-table-buffer))
6372                           (tags-table-files)))
6373   nil
6374   (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs23.
6375   nil 'file-name-history nil nil
6376   (icicle-file-bindings                 ; Bindings
6377    ((prompt                             "File (in tags table): ")
6378     (icicle-full-cand-fn                `(lambda (file)
6379                                           (setq file  (if (file-directory-p file)
6380                                                           (concat file "/")
6381                                                         file))
6382                                           ,(if current-prefix-arg
6383                                                '(icicle-make-file+date-candidate file)
6384                                                '(list file))))
6385     (icicle-special-candidate-regexp    (or icicle-special-candidate-regexp ".+/$"))
6386     (icicle-candidate-properties-alist  (and current-prefix-arg '((1 (face icicle-candidate-part)))))
6387     (icicle-list-use-nth-parts          (and current-prefix-arg '(1)))
6388     (icicle-all-candidates-list-alt-action-fn ; M-|'
6389      (lambda (files) (let ((enable-recursive-minibuffers  t))
6390                        (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
6391   (progn                                ; First code
6392     (when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
6393     (unless (require 'etags nil t) (error "`etags.el' is required"))
6394     (icicle-bind-file-candidate-keys))
6395   nil                                   ; Undo code
6396   (icicle-unbind-file-candidate-keys))  ; Last code
6397
6398 (defun icicle-make-file+date-candidate (file)
6399   "Return a multi-completion candidate: FILE + last modification date."
6400   (list (list file (format-time-string "%Y %m %d %T " (nth 5 (file-attributes file))))))
6401
6402 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6403
6404 (provide 'icicles-cmd1)
6405
6406 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6407 ;;; icicles-cmd1.el ends here