Download
(eval-when-compile (require 'cl))
(eval-when-compile (when (>= emacs-major-version 21) (require 'recentf)))
(require 'apropos-fn+var nil t)
(eval-when-compile
(when (< emacs-major-version 24)
(require 'dabbrev)))
(eval-when-compile (require 'bookmark))
(eval-when-compile (require 'comint))
(eval-when-compile (require 'cookie1 nil t))
(eval-when-compile (require 'shell))
(eval-when-compile (require 'etags))
(eval-when-compile (require 'yow nil t))
(eval-when-compile (require 'misc-cmds nil t))
(eval-when-compile (require 'bbdb nil t) (require 'bbdb-com nil t))
(require 'cus-edit)
(require 'misc-fns nil t)
(require 'frame-cmds nil t)
(require 'second-sel nil t)
(eval-when-compile
(or (condition-case nil
(load-library "icicles-mac")
(error nil))
(require 'icicles-mac)))
(require 'icicles-mcmd)
(require 'icicles-opt)
(require 'icicles-var)
(require 'icicles-fn)
(when (< emacs-major-version 21)
(defvar eval-expression-debug-on-error))
(when (< emacs-major-version 22)
(defvar history-delete-duplicates)
(defvar icicle-kmacro-alist)
(defvar kmacro-ring)
(defvar read-file-name-completion-ignore-case)
(defvar recentf-list)
(defvar tags-case-fold-search)
(defvar tooltip-mode))
(when (< emacs-major-version 23)
(defvar read-buffer-completion-ignore-case))
(when (< emacs-major-version 24)
(defvar minibuffer-local-filename-syntax))
(defvar apropos-do-all)
(defvar bbdb-complete-mail-allow-cycling)
(defvar bbdb-complete-name-allow-cycling)
(defvar bbdb-completion-list)
(defvar bbdb-extract-address-components-func)
(defvar bbdb-expand-mail-aliases)
(defvar bbdb-complete-name-hooks)
(defvar bbdb-completion-display-record)
(defvar bbdb-completion-type)
(defvar bbdb-hashtable)
(defvar bbdb-version)
(defvar bmkp-non-file-filename)
(defvar bmkp-prompt-for-tags-flag)
(defvar bmkp-sorted-alist)
(defvar bookmark-current-point)
(defvar color-theme)
(defvar color-themes)
(defvar color-theme-initialized)
(defvar cookie-cache)
(defvar dabbrev--last-obarray)
(defvar dabbrev--last-completion-buffer)
(defvar ess-current-process-name)
(defvar ess-mode-syntax-table)
(defvar ess-use-R-completion)
(defvar existing-bufs)
(defvar file-cache-alist)
(defvar filesets-data)
(defvar find-tag-default-function)
(defvar find-tag-marker-ring)
(defvar goto-tag-location-function)
(defvar icicle-buffer-easy-files)
(defvar icicle-clear-history-hist)
(defvar icicle--last-toggle-transforming-msg)
(defvar icicle-window-alist)
(defvar locate-make-command-line)
(defvar proced-signal-list)
(defvar shell-completion-execonly)
(defvar snarf-tag-function)
(defvar translation-table-for-input)
(defvar w3m-current-title)
(defvar yow-after-load-message)
(defvar yow-file)
(defvar yow-load-message)
(defun icicle-pp-eval-expression (expression
&optional insert-value)
"Evaluate Emacs-Lisp sexp EXPRESSION, and pretty-print its value.
Add the value to the front of the variable `values'.
With a prefix arg, insert the value into the current buffer at point.
With a negative prefix arg, if the value is a string, then insert it
into the buffer without double-quotes (`\"').
With no prefix arg:
If the value fits on one line (frame width) show it in the echo area.
Otherwise, show the value in buffer `*Pp Eval Output*'.
This command respects user options
`icicle-pp-eval-expression-print-length',
`icicle-pp-eval-expression-print-level', and
`eval-expression-debug-on-error'.
Emacs-Lisp mode completion and indentation bindings are in effect.
By default, Icicle mode remaps all key sequences that are normally
bound to `eval-expression' or `pp-eval-expression' to
`icicle-pp-eval-expression'. If you do not want this remapping, then
customize option `icicle-top-level-key-bindings'."
(interactive
(list (read-from-minibuffer "Eval: " nil icicle-read-expression-map t 'read-expression-history)
current-prefix-arg))
(message "Evaluating...")
(if (or (not (boundp 'eval-expression-debug-on-error))
(null eval-expression-debug-on-error))
(setq values (cons (eval expression) values))
(let ((old-value (make-symbol "t"))
new-value)
(let ((debug-on-error old-value))
(setq values (cons (eval expression) values)
new-value debug-on-error))
(unless (eq old-value new-value)
(setq debug-on-error new-value))))
(let ((print-length icicle-pp-eval-expression-print-length)
(print-level icicle-pp-eval-expression-print-level)
(deactivate-mark nil))
(cond (insert-value
(message "Evaluating...done. Value inserted.")
(setq insert-value (prefix-numeric-value insert-value))
(if (or (not (stringp (car values))) (wholenump insert-value))
(pp (car values) (current-buffer))
(princ (car values) (current-buffer))))
(t (icicle-pp-display-expression (car values) "*Pp Eval Output*")))))
(defun icicle-pp-display-expression (expression out-buffer-name)
"Prettify and show EXPRESSION in a way appropriate to its length.
If a temporary buffer is needed for representation, it is named
OUT-BUFFER-NAME."
(let* ((old-show-function temp-buffer-show-function)
(temp-buffer-show-function
`(lambda (buf)
(with-current-buffer buf
(goto-char (point-min))
(end-of-line 1)
(if (or (< (1+ (point)) (point-max))
(>= (- (point) (point-min)) (frame-width)))
(let ((temp-buffer-show-function ',old-show-function)
(old-selected (selected-window))
(window (display-buffer buf)))
(goto-char (point-min))
(make-frame-visible (window-frame window))
(unwind-protect
(progn (select-window window)
(run-hooks 'temp-buffer-show-hook))
(when (window-live-p old-selected) (select-window old-selected))
(message "Evaluating...done. See buffer `%s'."
out-buffer-name)))
(message "%s" (buffer-substring (point-min) (point))))))))
(with-output-to-temp-buffer out-buffer-name
(pp expression)
(with-current-buffer standard-output
(setq buffer-read-only nil)
(set (make-local-variable 'emacs-lisp-mode-hook) nil)
(set (make-local-variable 'change-major-mode-hook) nil)
(emacs-lisp-mode)
(set (make-local-variable 'font-lock-verbose) nil)
(font-lock-fontify-buffer)))))
(defun icicle-shell-command-on-file (file)
"Read a shell command and invoke it, passing FILE as an argument."
(dired-run-shell-command
(dired-shell-stuff-it (icicle-read-shell-command (format "! on `%s': " file)) (list file) nil)))
(defun icicle-recompute-shell-command-candidates (&optional savep)
"Update option `icicle-shell-command-candidates-cache'.
Recompute the available shell commands using your search path.
Return the new option value.
With a prefix argument, the updated option is saved persistently.
If the value of option `icicle-guess-commands-in-path' is not `load',
then turning on Icicle mode (again) resets the cache value to ().
If the value of `icicle-guess-commands-in-path' is `first-use', then
the cache is updated when you next use it, but it is not saved."
(interactive "P")
(setq icicle-shell-command-candidates-cache (icicle-compute-shell-command-candidates))
(when savep (funcall icicle-customize-save-variable-function
'icicle-shell-command-candidates-cache
icicle-shell-command-candidates-cache))
icicle-shell-command-candidates-cache)
(when (> emacs-major-version 23)
(defalias 'icicle-comint-completion-at-point 'icicle-comint-dynamic-complete))
(defun icicle-comint-dynamic-complete ()
"Dynamically perform completion at point.
Calls the functions in `comint-dynamic-complete-functions', but with
Icicles functions substituted, to perform completion until a function
returns non-nil. Return that value."
(interactive)
(let ((hook (icicle-comint-replace-orig-completion-fns)))
(run-hook-with-args-until-success 'hook)))
(defun icicle-comint-replace-orig-completion-fns ()
"Return `comint-dynamic-complete-functions', but with Icicles functions.
Get the Icicles functions from option
`icicle-comint-dynamic-complete-replacements'.
Only one (the first matching) replacement is made for any function."
(let ((result ())
(replacements (copy-sequence icicle-comint-dynamic-complete-replacements)))
(dolist (fn comint-dynamic-complete-functions)
(catch 'c-d-c-f-replacements-loop
(dolist (rep replacements)
(when (or (eq (car rep) fn)
(and (listp (car rep)) (memq fn (car rep))))
(push (eval (cadr rep)) result)
(unless (eq (car rep) fn) (push fn result))
(setq replacements (delete rep replacements))
(throw 'c-d-c-f-replacements-loop nil)))
(push fn result)))
(nreverse result)))
(defun icicle-comint-dynamic-complete-filename (&optional replace-to-eol-p)
"Dynamically complete the file name before point, using Icicles completion.
Similar to `comint-replace-by-expanded-filename', except that this
does not change parts of the file name already in the buffer before
point. It just appends completion characters at point.
Return t if successful, nil otherwise.
With a prefix arg, replace the rest of the line after point with the
completion choice. Otherwise, replace only the filename-matching text
before point.
Completion is dependent on the value of `comint-completion-addsuffix',
`comint-completion-recexact' and `comint-completion-fignore', and the
timing of completions listing is dependent on the value of
`comint-completion-autolist'. See also
`comint-match-partial-filename' and
`icicle-comint-dynamic-complete-as-filename'."
(interactive "P")
(require 'comint)
(when (comint-match-partial-filename)
(unless (window-minibuffer-p (selected-window)) (message "Completing file name..."))
(icicle-comint-dynamic-complete-as-filename replace-to-eol-p)))
(defun icicle-comint-dynamic-complete-as-filename (&optional replace-to-eol-p)
"Dynamically complete at point as a filename.
Optional arg REPLACE-TO-EOL-P non-nil means replace the rest of the
line after point with the completion choice.
Return t if successful.
See `icicle-comint-dynamic-complete-filename'."
(lexical-let* ((completion-ignore-case (if (boundp 'read-file-name-completion-ignore-case)
read-file-name-completion-ignore-case
(memq system-type '(ms-dos windows-nt cygwin))))
(completion-ignored-extensions comint-completion-fignore)
(minibuffer-p (window-minibuffer-p (selected-window)))
(success t)
(dirsuffix (cond ((not comint-completion-addsuffix) "")
((not (consp comint-completion-addsuffix)) "/")
(t (car comint-completion-addsuffix))))
(filesuffix (cond ((not comint-completion-addsuffix) "")
((not (consp comint-completion-addsuffix)) " ")
(t (cdr comint-completion-addsuffix))))
(filename (comint-match-partial-filename))
(filename-beg (if filename (match-beginning 0) (point)))
(filename-end (if filename
(if replace-to-eol-p
(line-end-position)
(match-end 0))
(point)))
(filename (or filename ""))
(filedir (file-name-directory filename))
(filenondir (file-name-nondirectory filename))
(directory (if filedir (comint-directory filedir) default-directory))
(completion (file-name-completion filenondir directory)))
(cond ((null completion)
(if minibuffer-p
(minibuffer-message (format " [No completions of `%s']" filename))
(message "No completions of `%s'" filename))
(setq success nil))
((eq completion t)
(insert filesuffix)
(unless minibuffer-p (message "Sole completion")))
((string-equal completion "")
(icicle-condition-case-no-debug nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
(choice
(save-excursion
(save-window-excursion (read-file-name "Complete: " directory nil t)))))
(when (and choice (not (string= choice directory)))
(insert (comint-quote-filename
(directory-file-name (file-relative-name choice directory))))
(insert (if (file-directory-p choice) dirsuffix filesuffix))
(when replace-to-eol-p (delete-region (point) (line-end-position)))))
(error nil)))
(t
(let ((file (concat (file-name-as-directory directory) completion))
(use-dialog-box nil))
(delete-region filename-beg filename-end)
(if filedir (insert (comint-quote-filename filedir)))
(insert (comint-quote-filename (directory-file-name completion)))
(cond ((symbolp (file-name-completion completion directory))
(insert (if (file-directory-p file) dirsuffix filesuffix))
(unless minibuffer-p (message "Completed")))
((and comint-completion-recexact comint-completion-addsuffix
(string-equal filenondir completion)
(or (icicle-file-remote-p file)
(file-exists-p file)))
(insert (if (file-directory-p file) dirsuffix filesuffix))
(unless minibuffer-p (message "Completed shortest")))
((or comint-completion-autolist (string-equal filenondir completion))
(icicle-condition-case-no-debug nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
(choice
(save-excursion
(save-window-excursion
(read-file-name
"Complete: " directory completion nil completion
(and (> emacs-major-version 21)
(lambda (f) (string-match completion f))))))))
(when choice
(delete-backward-char (length completion))
(insert (comint-quote-filename
(directory-file-name (file-relative-name choice directory))))
(insert (if (file-directory-p choice) dirsuffix filesuffix))))
(error nil)))
(t (unless minibuffer-p (message "Partially completed")))))))
success))
(defun icicle-shell-dynamic-complete-command ()
"Dynamically complete the command at point.
Similar to `icicle-comint-dynamic-complete-filename', but this
searches `exec-path' (minus the trailing Emacs library path) for
completion candidates. Note that this may not be the same as the
shell's idea of the path.
Completion is dependent on the value of `shell-completion-execonly',
plus those that effect file completion.
See `icicle-shell-dynamic-complete-as-command'.
Returns t if successful.
Uses Icicles completion."
(interactive)
(let ((filename (comint-match-partial-filename)))
(if (and filename
(save-match-data (not (string-match "[~/]" filename)))
(eq (match-beginning 0) (save-excursion (shell-backward-command 1) (point))))
(prog2 (unless (window-minibuffer-p (selected-window))
(message "Completing command name..."))
(icicle-shell-dynamic-complete-as-command)))))
(defun icicle-shell-dynamic-complete-as-command ()
"Dynamically complete text at point as a command.
See `icicle-shell-dynamic-complete-filename'.
Return t if successful."
(let* ((filename (or (comint-match-partial-filename) ""))
(filenondir (file-name-nondirectory filename))
(path-dirs (cdr (reverse exec-path)))
(cwd (file-name-as-directory (expand-file-name default-directory)))
(ignored-extensions
(and comint-completion-fignore
(mapconcat (lambda (x) (concat (regexp-quote x) "$")) comint-completion-fignore "\\|")))
(dir "")
(comps-in-dir ())
(file "")
(abs-file-name "")
(completions ()))
(while path-dirs
(setq dir (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
comps-in-dir (and (file-accessible-directory-p dir)
(file-name-all-completions filenondir dir)))
(while comps-in-dir
(setq file (car comps-in-dir)
abs-file-name (concat dir file))
(when (and (not (member file completions))
(not (and ignored-extensions (string-match ignored-extensions file)))
(or (string-equal dir cwd) (not (file-directory-p abs-file-name)))
(or (null shell-completion-execonly) (file-executable-p abs-file-name)))
(setq completions (cons file completions)))
(setq comps-in-dir (cdr comps-in-dir)))
(setq path-dirs (cdr path-dirs)))
(let ((success (let ((comint-completion-addsuffix nil)
(icicle-candidate-help-fn
(lambda (cand)
(with-output-to-temp-buffer "*Help*"
(princ (shell-command-to-string (concat "apropos "
(shell-quote-argument cand))))))))
(icicle-comint-dynamic-simple-complete filenondir completions))))
(when (and (memq success '(sole shortest)) comint-completion-addsuffix
(not (file-directory-p (comint-match-partial-filename))))
(insert " "))
success)))
(defun icicle-comint-replace-by-expanded-filename (&optional replace-to-eol-p)
"Dynamically complete, expand, and canonicalize the filename at point.
With a prefix arg, replace everthing past point on the current line.
Otherwise, replace only the filename-matching text before point.
Like vanilla `comint-replace-by-expanded-filename', but uses Icicles
completion."
(interactive "P")
(let ((filename (comint-match-partial-filename)))
(when filename
(replace-match (expand-file-name filename) t t)
(icicle-comint-dynamic-complete-filename replace-to-eol-p))))
(defun icicle-comint-dynamic-simple-complete (stub candidates)
"Dynamically complete STUB from CANDIDATES list.
Inserts completion characters at point by completing STUB from the
strings in CANDIDATES. Uses Icicles completion if completion is
ambiguous.
Returns nil if no completion was inserted.
Returns `sole' if completed with the only completion match.
Returns `shortest' if completed with the shortest of the completion matches.
Returns `partial' if completed as far as possible with the completion matches.
Returns `listed' if a completion listing was shown.
See also `icicle-comint-dynamic-complete-filename'."
(let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt cygwin)))
(minibuffer-p (window-minibuffer-p (selected-window)))
(suffix (cond ((not comint-completion-addsuffix) "")
((not (consp comint-completion-addsuffix)) " ")
(t (cdr comint-completion-addsuffix))))
(candidates (mapcar #'list candidates))
(completions (all-completions stub candidates)))
(cond ((null completions)
(if minibuffer-p
(minibuffer-message (format " [No completions of `%s']" stub))
(message "No completions of `%s'" stub))
nil)
((= 1 (length completions))
(let ((completion (car completions)))
(if (string-equal completion stub)
(unless minibuffer-p (message "Sole completion"))
(insert (substring completion (length stub)))
(unless minibuffer-p (message "Completed")))
(insert suffix)
'sole))
(t
(let ((completion (try-completion stub candidates)))
(insert (substring completion (length stub)))
(cond ((and comint-completion-recexact comint-completion-addsuffix
(string-equal stub completion)
(member completion completions))
(insert suffix)
(unless minibuffer-p (message "Completed shortest"))
'shortest)
((or comint-completion-autolist (string-equal stub completion))
(icicle-condition-case-no-debug nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
(choice (save-excursion
(completing-read "Complete: " (mapcar #'list completions)
nil t nil nil completion))))
(when choice
(delete-backward-char (length completion))
(insert choice suffix)))
(error nil))
'listed)
(t
(unless minibuffer-p (message "Partially completed"))
'partial)))))))
(defun icicle-shell-dynamic-complete-filename ()
"Dynamically complete the filename at point.
Completes only if point is at a suitable position for a filename
argument."
(interactive)
(let ((opoint (point))
(beg (comint-line-beginning-position)))
(when (save-excursion
(goto-char (if (re-search-backward "[;|&]" beg t) (match-end 0) beg))
(re-search-forward "[^ \t][ \t]" opoint t))
(icicle-comint-dynamic-complete-as-filename))))
(defun icicle-shell-dynamic-complete-environment-variable ()
"`shell-dynamic-complete-environment-variable' but uses Icicles completion."
(interactive)
(require 'shell)
(let ((variable (shell-match-partial-variable)))
(if (and variable (string-match "^\\$" variable))
(prog2 (unless (window-minibuffer-p (selected-window))
(message "Completing variable name..."))
(icicle-shell-dynamic-complete-as-environment-variable)))))
(defun icicle-shell-dynamic-complete-as-environment-variable ()
"`shell-dynamic-complete-as-environment-variable' but uses Icicles completion."
(require 'shell)
(let* ((var (or (shell-match-partial-variable) ""))
(variable (substring var (or (string-match "[^$({]\\|$" var) 0)))
(variables (mapcar (lambda (x) (substring x 0 (string-match "=" x)))
process-environment))
(addsuffix comint-completion-addsuffix)
(comint-completion-addsuffix nil)
(success (icicle-comint-dynamic-simple-complete variable variables)))
(if (memq success '(sole shortest))
(let* ((var (shell-match-partial-variable))
(variable (substring var (string-match "[^$({]" var)))
(protection (cond ((string-match "{" var) "}")
((string-match "(" var) ")")
(t "")))
(suffix (cond ((null addsuffix) "")
((file-directory-p (comint-directory (getenv variable))) "/")
(t " "))))
(insert protection suffix)))
success))
(unless (get 'icicle-ORIG-file 'widget-type)
(put 'icicle-ORIG-file 'widget-type (get 'file 'widget-type))
(put 'icicle-ORIG-file 'widget-documentation (get 'file 'widget-documentation)))
(define-widget 'icicle-file 'string
"Icicles version of the `file' widget.
Reads a file name from an editable text field, with Icicles completion."
:complete-function #'icicle-widget-file-complete
:prompt-value 'widget-file-prompt-value
:format "%{%t%}: %v"
:tag "File")
(defun icicle-widget-file-complete (&optional replace-to-eol-p)
"Perform Icicles completion on the file name at point.
Like `widget-file-complete' (`widget-complete', for Emacs 24+), but
allows Icicles completion.
With a prefix arg, replace everthing past point on the current line.
Otherwise, replace only the filename-matching text before point."
(interactive "P")
(if (and (boundp 'icicle-mode) icicle-mode)
(let ((comint-completion-addsuffix nil))
(icicle-comint-dynamic-complete-filename replace-to-eol-p))
(cond ((> emacs-major-version 23)
(let* ((field (widget-field-find (point)))
(start (widget-field-start field))
(end (max (point) (widget-field-text-end field))))
(completion-in-region start end #'completion-file-name-table)))
(t
(widget-file-complete)))))
(defun icicle-gud-gdb-complete-command (&optional command a b)
"`gud-gdb-complete-command', but uses Icicles completion.
Perform completion on the GDB command preceding point."
(interactive)
(if command
(setq command (concat "p " command))
(let ((end (point)))
(setq command (buffer-substring (comint-line-beginning-position) end))))
(let* ((command-word
(and (string-match "\\(\\`\\| \\)\\([^ ]*\\)\\'" command)
(substring command (match-beginning 2))))
(complete-list
(gud-gdb-run-command-fetch-lines (concat "complete " command)
(current-buffer)
(match-beginning 2))))
(and complete-list
(string-match "^Undefined command: \"complete\"" (car complete-list))
(icicle-user-error "This version of GDB does not support command `complete'"))
(setq complete-list (sort complete-list (function string-lessp)))
(let ((first complete-list)
(second (cdr complete-list)))
(while second
(if (string-equal (car first) (car second))
(setcdr first (setq second (cdr second)))
(setq first second
second (cdr second)))))
(and (= (length complete-list) 1)
(let ((str (car complete-list))
(pos 0)
(count 0))
(while (string-match "\\([^'\\]\\|\\\\'\\)*'" str pos)
(setq count (1+ count)
pos (match-end 0)))
(and (= (mod count 2) 1)
(setq complete-list (list (concat str "'"))))))
(icicle-comint-dynamic-simple-complete command-word complete-list)))
(when (< emacs-major-version 24)
(when (and (fboundp 'dabbrev-completion) (not (fboundp 'icicle-ORIG-dabbrev-completion)))
(defalias 'icicle-ORIG-dabbrev-completion (symbol-function 'dabbrev-completion)))
(defun icicle-dabbrev-completion (&optional arg)
"Completion on current word.
Like \\[dabbrev-expand], but finds all expansions in the current buffer
and presents suggestions for completion.
With a prefix argument, it searches all buffers accepted by
`dabbrev-friend-buffer-function', to find the completions.
If the prefix argument is 16 (which comes from `C-u C-u'), then it
searches *ALL* buffers.
With no prefix argument, it reuses an old completion list
if there is a suitable one already."
(interactive "*P")
(unless (featurep 'dabbrev)
(unless (require 'dabbrev nil t) (error "Library `dabbrev' not found"))
(icicle-mode 1))
(dabbrev--reset-global-variables)
(let* ((dabbrev-check-other-buffers (and arg t))
(dabbrev-check-all-buffers (and arg (= (prefix-numeric-value arg) 16)))
(abbrev (icicle-dabbrev--abbrev-at-point))
(ignore-case-p (and (if (eq dabbrev-case-fold-search 'case-fold-search)
case-fold-search
dabbrev-case-fold-search)
(or (not dabbrev-upcase-means-case-search)
(string= abbrev (downcase abbrev)))))
(my-obarray dabbrev--last-obarray)
init)
(save-excursion
(unless (and (null arg)
my-obarray
(or (eq dabbrev--last-completion-buffer (current-buffer))
(and (window-minibuffer-p (selected-window))
(eq dabbrev--last-completion-buffer (dabbrev--minibuffer-origin))))
dabbrev--last-abbreviation
(>= (length abbrev) (length dabbrev--last-abbreviation))
(string= dabbrev--last-abbreviation
(substring abbrev 0 (length dabbrev--last-abbreviation)))
(setq init (try-completion abbrev my-obarray)))
(setq dabbrev--last-abbreviation abbrev)
(let ((completion-list (dabbrev--find-all-expansions abbrev ignore-case-p))
(completion-ignore-case ignore-case-p))
(setq my-obarray (make-vector (length completion-list) 0))
(unless (> (length my-obarray) 0)
(icicle-user-error "No dynamic expansion for \"%s\" found%s" abbrev
(if dabbrev--check-other-buffers "" " in this-buffer")))
(dolist (string completion-list)
(cond ((or (not ignore-case-p) (not dabbrev-case-replace))
(intern string my-obarray))
((string= abbrev (icicle-upcase abbrev))
(intern (icicle-upcase string) my-obarray))
((string= (substring abbrev 0 1) (icicle-upcase (substring abbrev 0 1)))
(intern (capitalize string) my-obarray))
(t (intern (downcase string) my-obarray))))
(setq dabbrev--last-obarray my-obarray
dabbrev--last-completion-buffer (current-buffer)
init (try-completion abbrev my-obarray)))))
(unless (stringp init) (setq init abbrev))
(cond
((and (not (string-equal init ""))
(not (string-equal (downcase init) (downcase abbrev)))
(<= (length (all-completions init my-obarray)) 1))
(message "Completed (no other completions)")
(if (< emacs-major-version 21)
(dabbrev--substitute-expansion nil abbrev init)
(dabbrev--substitute-expansion nil abbrev init nil))
(when (window-minibuffer-p (selected-window)) (message nil)))
(t
(icicle-highlight-lighter)
(message "Making completion list...")
(search-backward abbrev)
(replace-match "")
(condition-case nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(minibuffer-completion-table my-obarray)
(choice
(completing-read "Complete: " my-obarray nil nil init nil init)))
(when choice (insert choice)))
(quit (insert abbrev)))))))
(defun icicle-dabbrev--abbrev-at-point ()
"Like `dabbrev--abbrev-at-point', but returns \"\" if there is no match.
Vanilla `dabbrev--abbrev-at-point' raises an error if no match."
(let ((abv ""))
(setq dabbrev--last-abbrev-location (point))
(unless (bobp)
(save-excursion
(save-match-data
(when (and (save-excursion
(forward-char -1)
(not (looking-at
(concat "\\(" (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") "\\)+"))))
(re-search-backward (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_") nil t))
(forward-char 1)))
(dabbrev--goto-start-of-abbrev)
(setq abv (buffer-substring-no-properties dabbrev--last-abbrev-location (point)))))
abv)))
(defun icicle-bbdb-complete-mail (&optional start-pos cycle-completion-buffer)
"In a mail buffer, complete the user name or mail address before point.
Completes up to the preceding newline, colon or comma, or the value of
START-POS.
Returns non-nil if there is a valid completion, else return nil.
You can control completion behaviour using `bbdb-completion-list'
\(`bbdb-completion-type' in older BBDB versions).
If what has been typed is unique, insert an entry \"User Name
<mail-address>\" - but see `bbdb-mail-allow-redundancy'
\(`bbdb-dwim-net-address-allow-redundancy' in older BBDB versions).
If it is a valid completion but not unique, you can choose from the
list of completions using Icicles completion.
If your input is completed and `bbdb-complete-mail-allow-cycling' is
true (`bbdb-complete-name-allow-cycling' for older BBDB versions),
you can repeat to cycle through the nets for the matching record.
When called with a prefix arg, display a list of all mail messages
available for cycling.
See your version of BBDB for more information."
(interactive (list nil current-prefix-arg))
(unless (and (require 'bbdb nil t) (require 'bbdb-com nil t)
(fboundp 'bbdb-complete-mail))
(icicle-user-error "`icicle-bbdb-complete-mail' requires a BBDB version such as 3.02"))
(bbdb-buffer)
(lexical-let* ((end (point))
(beg (or start-pos (save-excursion
(re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
(goto-char (match-end 0)) (point))))
(orig (buffer-substring beg end))
(typed (downcase orig))
(pattern (bbdb-string-trim typed))
(completion-ignore-case t)
(completion (try-completion pattern bbdb-hashtable #'bbdb-completion-predicate))
(all-the-completions ())
dwim-completions one-record done)
(when (and (stringp completion) (string-match "[:,]" completion))
(setq completion (substring completion 0 (match-beginning 0))))
(all-completions pattern bbdb-hashtable (lambda (sym)
(when (bbdb-completion-predicate sym)
(push sym all-the-completions))))
(let ((records (icicle-delete-dups (apply #'append (mapcar #'symbol-value all-the-completions)))))
(setq one-record (and (not (cdr records)) (car records))))
(icicle-remove-Completions-window)
(cond (one-record
(let ((completion-list (if (eq t bbdb-completion-list)
'(fl-name lf-name mail aka organization)
bbdb-completion-list))
(mails (bbdb-record-mail one-record))
mail elt)
(unless mails (error "Matching record has no `mail' field"))
(if (try-completion pattern (append (and (memq 'fl-name completion-list)
(list (or (bbdb-record-name one-record) "")))
(and (memq 'lf-name completion-list)
(list (or (bbdb-record-name-lf one-record) "")))
(and (memq 'aka completion-list)
(bbdb-record-field one-record 'aka-all))
(and (memq 'organization completion-list)
(bbdb-record-organization one-record))))
(setq mail (car mails)))
(unless mail (while (setq elt (pop mails))
(if (try-completion pattern (list elt))
(setq mail elt
mails ()))))
(unless mail (error "`icicle-bbdb-complete-mail': No match for `%s'" pattern))
(let ((address (bbdb-dwim-mail one-record mail)))
(if (string= address (buffer-substring-no-properties beg end))
(unless (and bbdb-complete-mail-allow-cycling (< 1 (length (bbdb-record-mail one-record))))
(setq done 'UNCHANGED))
(delete-region beg end)
(insert address)
(bbdb-complete-mail-cleanup address)
(setq done 'UNIQUE)))))
((and (stringp completion) (not (string= typed completion)))
(delete-region beg end)
(insert completion)
(setq done 'PARTIAL))
(completion
(let ((completion-list (if (eq t bbdb-completion-list)
'(fl-name lf-name mail aka organization)
bbdb-completion-list))
sname records)
(dolist (sym all-the-completions)
(setq sname (symbol-name sym))
(dolist (record (symbol-value sym))
(unless (memq record records)
(push record records)
(let ((mails (bbdb-record-mail record))
accept)
(when mails
(dolist (field completion-list)
(if (case field
(fl-name (bbdb-string= sname (bbdb-record-name record)))
(lf-name (bbdb-string= sname (bbdb-cache-lf-name (bbdb-record-cache record))))
(aka (member-ignore-case sname (bbdb-record-field record 'aka-all)))
(organization (member-ignore-case sname (bbdb-record-organization record)))
(primary (bbdb-string= sname (car mails)))
(otherwise nil))
(push (car mails) accept)
(when (eq field 'mail)
(dolist (mail mails)
(when (bbdb-string= sname mail) (push mail accept))))))
(when accept
(setq one-record record)
(dolist (mail (delete-dups accept))
(push (bbdb-dwim-mail record mail) dwim-completions))))))))
(cond ((not dwim-completions) (error "No mail address for \"%s\"" orig))
((eq 1 (length dwim-completions))
(delete-region beg end)
(insert (car dwim-completions))
(bbdb-complete-mail-cleanup (car dwim-completions))
(setq done 'UNIQUE))
(t
(setq done 'CHOOSE))))))
(when (and (not done) bbdb-complete-mail-allow-cycling)
(let* ((address (mail-extract-address-components orig))
(record (and (listp address) (car (bbdb-message-search (nth 0 address) (nth 1 address)))))
(mails (and record (bbdb-record-mail record))))
(when mails
(cond ((and (= 1 (length mails)) (string= (bbdb-dwim-mail record (car mails))
(buffer-substring-no-properties beg end)))
(setq done 'UNCHANGED))
(cycle-completion-buffer
(setq dwim-completions (mapcar (lambda (n) (bbdb-dwim-mail record n)) mails)
done 'CHOOSE))
(t
(let ((mail (or (nth 1 (or (icicle-member-ignore-case (nth 1 address) mails)
(icicle-member-ignore-case orig mails)))
(nth 0 mails))))
(delete-region beg end)
(insert (bbdb-dwim-mail record mail))
(setq done 'CYCLE)))))))
(when (eq done 'CHOOSE)
(unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
(icicle-condition-case-no-debug nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
(completion-ignore-case t)
(choice
(save-excursion (completing-read "Complete: " (mapcar #'list dwim-completions)
nil t pattern nil pattern))))
(when choice
(delete-region beg end)
(insert choice)))
(error nil))
(unless (eq (selected-window) (minibuffer-window)) (message "Making completion list...done")))
done))
(unless (eval-when-compile (and (featurep 'bbdb) (not (string-lessp bbdb-version "3"))))
(defun icicle-bbdb-complete-name (&optional start-pos)
"Complete the user full-name or net-address before point.
Completes only up to the preceding newline, colon, or comma, or the
value of START-POS.
If what has been typed is unique, insert an entry of the form \"User
Name <net-addr>\" (but see `bbdb-dwim-net-address-allow-redundancy').
If it is a valid completion but not unique, you can choose from the
list of completions using Icicles completion.
If your input is completed and `bbdb-complete-name-allow-cycling' is
true, then you can repeat to cycle through the nets for the matching
record.
When called with a prefix arg, display a list of all nets. You can
control completion behaviour using `bbdb-completion-type'."
(interactive)
(unless (and (require 'bbdb nil t) (require 'bbdb-com nil t)
(fboundp 'bbdb-complete-name))
(icicle-user-error "`icicle-bbdb-complete-name' requires a BBDB version such as 2.35"))
(lexical-let* ((end (point))
(beg (or start-pos (save-excursion (re-search-backward
"\\(\\`\\|[\n:,]\\)[ \t]*")
(goto-char (match-end 0)) (point))))
(orig (buffer-substring beg end))
(typed (downcase orig))
(pattern (bbdb-string-trim typed))
(ht (bbdb-with-db-buffer (bbdb-records nil t) bbdb-hashtable))
(only-one-p t)
(all-the-completions ())
(pred
(lambda (sym)
(and (bbdb-completion-predicate sym)
(progn
(when (and only-one-p
all-the-completions
(or
(> (length (symbol-value sym)) 1)
(delete t (mapcar (lambda (x)
(equal (symbol-value x) (symbol-value sym)))
all-the-completions))))
(setq only-one-p nil))
(if (memq sym all-the-completions)
nil
(setq all-the-completions (cons sym all-the-completions)))))))
(completion (progn (all-completions pattern ht pred)
(try-completion pattern ht)))
(exact-match (eq completion t)))
(cond
((or (null completion)
(and bbdb-complete-name-allow-cycling
exact-match
(member orig (bbdb-record-net (car (symbol-value (intern-soft pattern ht)))))))
(bbdb-complete-name-cleanup)
(unless (catch 'bbdb-cycling-exit
(unless bbdb-complete-name-allow-cycling (throw 'bbdb-cycling-exit nil))
(lexical-let* ((addr (funcall bbdb-extract-address-components-func orig))
(rec (and (listp addr)
(car (bbdb-search-intertwingle (caar addr)
(car (cdar addr)))))))
(unless rec (throw 'bbdb-cycling-exit nil))
(if current-prefix-arg
(let ((standard-output (get-buffer-create "*Completions*")))
(with-current-buffer standard-output
(setq buffer-read-only nil)
(erase-buffer))
(display-completion-list
(mapcar (lambda (n) (bbdb-dwim-net-address rec n))
(bbdb-record-net rec)))
(delete-region beg end)
(switch-to-buffer standard-output))
(let* ((addrs (bbdb-record-net rec))
(this-addr (or (cadr (member (car (cdar addr)) addrs)) (nth 0 addrs))))
(if (= (length addrs) 1)
(throw 'bbdb-cycling-exit t)
(delete-region beg end)
(insert (bbdb-dwim-net-address rec this-addr))
(run-hooks 'bbdb-complete-name-hooks)
(throw 'bbdb-cycling-exit t))))))
(when (and (or (not bbdb-expand-mail-aliases) (not (expand-abbrev))) bbdb-complete-name-hooks)
(message "No completion for `%s'" pattern) (icicle-ding))))
((and only-one-p (or exact-match bbdb-complete-name-allow-cycling))
(let* ((sym (if exact-match (intern-soft pattern ht) (car all-the-completions)))
(recs (symbol-value sym))
the-net match-recs lst primary matched)
(while recs
(when (bbdb-record-net (car recs))
(let ((b-r-name (or (bbdb-record-name (car recs)) "")))
(if (string= pattern (substring (downcase b-r-name) 0
(min (length b-r-name) (length pattern))))
(setq match-recs (cons (car recs) match-recs)
matched t)))
(unless matched
(setq lst (bbdb-record-aka (car recs)))
(while lst
(if (string= pattern (substring (downcase (car lst)) 0
(min (length (downcase (car lst)))
(length pattern))))
(setq match-recs (append match-recs (list (car recs)))
matched t
lst ())
(setq lst (cdr lst)))))
(unless matched
(setq lst (bbdb-record-net (car recs))
primary t)
(while lst
(if (string= pattern (substring (downcase (car lst)) 0
(min (length (downcase (car lst)))
(length pattern))))
(setq the-net (car lst)
lst ()
match-recs (if primary
(cons (car recs) match-recs)
(append match-recs (list (car recs))))))
(setq lst (cdr lst)
primary nil))))
(setq recs (cdr recs)
matched nil))
(unless match-recs (error "Only exact matching record has net field"))
(delete-region beg end)
(insert (bbdb-dwim-net-address (car match-recs) the-net))
(when (and (bbdb-auto-fill-function) (>= (current-column) fill-column))
(let ((p (point))
bol)
(save-excursion
(setq bol (line-beginning-position))
(goto-char p)
(when (search-backward "," bol t) (forward-char 1) (insert "\n ")))))
(when bbdb-completion-display-record
(let ((bbdb-gag-messages t))
(bbdb-pop-up-bbdb-buffer)
(bbdb-display-records-1 match-recs t)))
(bbdb-complete-name-cleanup)
(run-hooks 'bbdb-complete-name-hooks)))
((and (stringp completion) (not (string= typed completion)))
(delete-region beg end)
(insert completion)
(setq end (point))
(let ((last "")
(bbdb-complete-name-allow-cycling nil))
(while (and (stringp completion) (not (string= completion last))
(setq last completion
pattern (downcase orig)
completion (progn (all-completions pattern ht pred)
(try-completion pattern ht))))
(when (stringp completion) (delete-region beg end) (insert completion)))
(bbdb-complete-name beg)))
(t
(unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
(lexical-let (dwim-completions uniq nets net name akas)
(bbdb-mapc (lambda (sym)
(bbdb-mapc
(lambda (rec)
(unless (member rec uniq)
(setq uniq (cons rec uniq)
nets (bbdb-record-net rec)
name (downcase (or (bbdb-record-name rec) ""))
akas (mapcar 'downcase (bbdb-record-aka rec)))
(while nets
(setq net (car nets))
(when (cond
((and (member bbdb-completion-type
'(primary primary-or-name))
(member (intern-soft (downcase net) ht)
all-the-completions))
(setq nets ())
t)
((and name (member bbdb-completion-type
'(nil name primary-or-name))
(let ((cname (symbol-name sym)))
(or (string= cname name) (member cname akas))))
(setq name nil)
t)
((and (member bbdb-completion-type '(nil net))
(member (intern-soft (downcase net) ht) all-the-completions)))
((and (member bbdb-completion-type '(name-or-primary))
(let ((cname (symbol-name sym)))
(or (string= cname name) (member cname akas))))
(setq nets ())
t))
(setq dwim-completions
(cons (bbdb-dwim-net-address rec net)
dwim-completions))
(when exact-match (setq nets ())))
(setq nets (cdr nets)))))
(symbol-value sym)))
all-the-completions)
(cond ((and dwim-completions (null (cdr dwim-completions)))
(delete-region beg end) (insert (car dwim-completions)) (message ""))
(t
(icicle-condition-case-no-debug nil
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
(completion-ignore-case t)
(choice
(save-excursion
(completing-read "Complete: " (mapcar #'list dwim-completions)
nil t pattern nil pattern))))
(when choice
(delete-region beg end)
(insert choice)))
(error nil))
(unless (eq (selected-window) (minibuffer-window))
(message "Making completion list...done"))))))))))
(unless (fboundp 'icicle-ORIG-lisp-complete-symbol)
(defalias 'icicle-ORIG-lisp-complete-symbol (symbol-function 'lisp-complete-symbol)))
(defun icicle-lisp-complete-symbol (&optional predicate)
"Complete the Lisp symbol preceding point against known Lisp symbols.
If there is more than one completion, use the minibuffer to complete.
When called from a program, optional arg PREDICATE is a predicate
determining which symbols are considered, e.g. `commandp'.
If PREDICATE is nil, the context determines which symbols are
considered. If the symbol starts just after an open-parenthesis, only
symbols with function definitions are considered. Otherwise, all
symbols with function definitions, values or properties are
considered."
(interactive)
(let* ((end (point))
(buffer-syntax (syntax-table))
(beg (unwind-protect
(save-excursion
(set-syntax-table emacs-lisp-mode-syntax-table)
(backward-sexp 1)
(while (= (char-syntax (following-char)) ?\') (forward-char 1))
(point))
(set-syntax-table buffer-syntax)))
(pattern (buffer-substring beg end))
(new (try-completion pattern obarray)))
(unless (stringp new) (setq new pattern))
(delete-region beg end)
(insert new)
(setq end (+ beg (length new)))
(if (and (not (string= new "")) (not (string= (downcase new) (downcase pattern)))
(< (length (all-completions new obarray)) 2))
(message "Completed (no other completions)")
(let* ((enable-recursive-minibuffers (active-minibuffer-window))
(icicle-top-level-when-sole-completion-flag t)
(icicle-orig-window (selected-window))
(alt-fn nil)
(icicle-show-Completions-initially-flag t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "symbol"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn
(icicle-alt-act-fn-for-type "symbol")))
(predicate
(or predicate
(save-excursion
(goto-char beg)
(if (not (eq (char-before) ?\( ))
(lambda (sym)
(or (boundp sym) (fboundp sym) (symbol-plist sym)))
(and (not (condition-case nil
(progn (up-list -2) (forward-char 1) (eq (char-after) ?\( ))
(error nil)))
'fboundp))))))
(setq new (save-excursion (completing-read "Complete Lisp symbol: "
obarray predicate t new)))))
(delete-region beg end)
(insert new)))
(when (fboundp 'completion-at-point)
(unless (fboundp 'icicle-ORIG-lisp-completion-at-point)
(defalias 'icicle-ORIG-lisp-completion-at-point (symbol-function 'lisp-completion-at-point))
(defun icicle-lisp-completion-at-point () #'icicle-lisp-complete-symbol)))
(defun icicle-customize-icicles-group ()
"Customize Icicles options and faces. View their documentation."
(interactive)
(customize-group-other-window 'Icicles))
(defun icicle-send-bug-report ()
"Send a bug report about an Icicles problem."
(interactive)
(browse-url (format (concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
Icicles bug: \
&body=Describe bug below, using a precise recipe that starts with `emacs -Q' or `emacs -q'. \
Each Icicles file has a header `Update #' that you can use to identify it. \
Include at least the `Update #' from file `icicles-chg.el', if you have that file.\
%%0A%%0AEmacs version: %s.")
(emacs-version))))
(unless (fboundp 'icicle-ORIG-customize-face-other-window)
(defalias 'icicle-ORIG-customize-face-other-window (symbol-function 'customize-face-other-window)))
(defun icicle-customize-face-other-window (face)
"Customize face FACE in another window.
Same as `icicle-customize-face' except it uses a different window."
(interactive
(list (let* ((icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-action-fn
(lambda (x)
(icicle-ORIG-customize-face-other-window (intern (icicle-transform-multi-completion x)))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
(icicle-all-candidates-list-action-fn 'icicle-customize-faces)
(icicle-orig-window (selected-window))
(alt-fn nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "face"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
alt-fn
(icicle-alt-act-fn-for-type "face"))))
(if (and (> emacs-major-version 21) current-prefix-arg)
(read-face-name "Customize face: " "all faces" t)
(read-face-name "Customize face: ")))))
(icicle-ORIG-customize-face-other-window face))
(unless (fboundp 'icicle-ORIG-customize-face)
(defalias 'icicle-ORIG-customize-face (symbol-function 'customize-face)))
(defun icicle-customize-face (face &optional other-window)
"Customize face FACE. If OTHER-WINDOW is non-nil, use another window.
Input-candidate completion and cycling are available. While cycling,
these keys with prefix `C-' are active\\<minibuffer-local-completion-map>:
`C-mouse-2', `C-RET' - Act on current completion candidate only
`C-down' - Move to next completion candidate and act
`C-up' - Move to previous completion candidate and act
`C-next' - Move to next apropos-completion candidate and act
`C-prior' - Move to previous apropos-completion candidate and act
`C-end' - Move to next prefix-completion candidate and act
`C-home' - Move to previous prefix-completion candidate and act
`\\[icicle-all-candidates-list-action]' - Act on *all* candidates (or all that are saved):
Customize all in the same buffer.
`\\[icicle-all-candidates-action]' - Act on *all* candidates (or all that are saved):
Customize each in a separate buffer.
When candidate action and cycling are combined (e.g. `C-next'), option
`icicle-act-before-cycle-flag' determines which occurs first.
With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
`C-M-return', `C-M-down', and so on) provide help about candidates.
Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
or `C-g' to quit.
With a prefix argument, you can enter multiple faces at the same time
with a single `RET' (in Emacs 22 or later). This gives you more or
less the `crm' completion behavior of `customize-face' in vanilla
Emacs. Most Icicles completion features are still available, but
`TAB' performs `crm' completion, so it does not also cycle among
completion candidates. You can, as always, use `down' to do that.
A advantage of using a prefix argument is that the default value is
the list of all faces under the cursor. A disadvantage is that face
candidates are not WYSIWYG in buffer `*Completions*'.
This is an Icicles command - see command `icicle-mode'."
(interactive
(list (let* ((icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-action-fn
(lambda (x)
(icicle-ORIG-customize-face (intern (icicle-transform-multi-completion x)))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
(icicle-all-candidates-list-action-fn 'icicle-customize-faces)
(icicle-orig-window (selected-window))
(alt-fn nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "face"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
alt-fn
(icicle-alt-act-fn-for-type "face"))))
(if (and (> emacs-major-version 21) current-prefix-arg)
(read-face-name "Customize face: " "all faces" t)
(read-face-name "Customize face: ")))))
(if other-window
(if (> emacs-major-version 23)
(icicle-ORIG-customize-face face t)
(icicle-ORIG-customize-face-other-window face))
(icicle-ORIG-customize-face face)))
(defun icicle-customize-faces (faces)
"Open Customize buffer on all faces in list FACES."
(let ((icicle-list-nth-parts-join-string ": ")
(icicle-list-join-string ": ")
(icicle-list-use-nth-parts '(1)))
(custom-buffer-create
(custom-sort-items
(mapcar (lambda (f) (list (intern (icicle-transform-multi-completion f)) 'custom-face)) faces)
t custom-buffer-order-groups)
"*Customize Apropos*")))
(defun icicle-customize-apropos (pattern &optional type msgp)
"Customize all loaded user preferences matching PATTERN.
When prompted for the PATTERN, you can use completion against
preference names - e.g. `S-TAB'. Instead of entering a pattern you
can then just hit `RET' to accept the list of matching preferences.
This lets you see which preferences will be available in the customize
buffer and dynamically change that list.
Interactively:
With no prefix arg, customize all matching preferences: groups, faces,
and options. With a prefix arg, show those plus all matching
non-option variables in Customize (but you cannot actually customize
the latter).
Non-interactively:
If TYPE is `options', include only user options.
If TYPE is `faces', include only faces.
If TYPE is `groups', include only groups.
If TYPE is t, include variables that are not user options, as well as
faces and groups.
PATTERN is a regexp.
Starting with Emacs 22, if PATTERN includes no regexp special chars
then it can alternatively be a list of \"words\" separated by spaces.
Two or more of the words are matched in different orders against each
preference name. \"Word\" here really means a string of non-space
chars.
This handling of \"words\" is for compatibility with vanilla Emacs,
and is only approximative. It can include \"matches\" that you do not
expect. For better matching use Icicles progressive completion, i.e.,
separate the words (any strings, in fact, including regexps) using
`S-SPC', not just `SPC'."
(interactive
(let* ((pref-arg current-prefix-arg)
(pred `(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(or (get s 'custom-group)
(custom-facep s)
(and (boundp s)
(or (get s 'saved-value)
(custom-variable-p s)
(if (null ',pref-arg)
(user-variable-p s)
(get s 'variable-documentation)))))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (completing-read "Customize (pattern): " obarray (and icompletep pred) nil nil 'regexp-history)
pref-arg
t)))
(let ((found ()))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering apropos data for customize `%s'..." pattern))
(mapatoms `(lambda (symbol)
(when (string-match ,(if (> emacs-major-version 21) apropos-regexp pattern)
(symbol-name symbol))
(when (and (not (memq ,type '(faces options)))
(get symbol 'custom-group))
(push (list symbol 'custom-group) found))
(when (and (not (memq ,type '(options groups)))
(custom-facep symbol))
(push (list symbol 'custom-face) found))
(when (and (not (memq ,type '(groups faces)))
(boundp symbol)
(or (get symbol 'saved-value)
(custom-variable-p symbol)
(if (memq ,type '(nil options))
(user-variable-p symbol)
(get symbol 'variable-documentation))))
(push (list symbol 'custom-variable) found)))))
(unless found
(error "No %s matching %s" (if (eq type t)
"items"
(format "%s" (if (memq type '(options faces groups))
(symbol-name type)
"customizable items")))
pattern))
(custom-buffer-create (custom-sort-items found t custom-buffer-order-groups) "*Customize Apropos*")))
(unless (fboundp 'custom-variable-p)
(defun custom-variable-p (variable)
"Return non-nil if VARIABLE is a custom variable."
(and (symbolp variable)
(or (get variable 'standard-value) (get variable 'custom-autoload)))))
(defun icicle-customize-apropos-faces (pattern &optional msgp)
"Customize all loaded faces matching PATTERN.
See `icicle-customize-apropos'."
(interactive
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(custom-facep s)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (completing-read "Customize faces (pattern): " obarray (and icompletep pred)
nil nil 'regexp-history)
t)))
(when msgp (message "Gathering apropos data for customizing faces..."))
(customize-apropos pattern 'faces))
(defun icicle-customize-apropos-groups (pattern &optional msgp)
"Customize all loaded customize groups matching PATTERN.
See `icicle-customize-apropos'."
(interactive
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(get s 'custom-group)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (completing-read "Customize groups (pattern): " obarray (and icompletep pred)
nil nil 'regexp-history)
t)))
(when msgp (message "Gathering apropos data for customizing groups..."))
(customize-apropos pattern 'groups))
(defun icicle-customize-apropos-options (pattern &optional arg msgp)
"Customize all loaded user options matching PATTERN.
See `icicle-customize-apropos'.
With a prefix arg, include variables that are not user options as
completion candidates, and include also matching faces and groups in
the customize buffer."
(interactive
(let* ((pref-arg current-prefix-arg)
(pred `(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(and (boundp s)
(or (get s 'saved-value)
(custom-variable-p s)
(user-variable-p s)
(and ',pref-arg
(get s 'variable-documentation))))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (completing-read "Customize options (pattern): " obarray (and icompletep pred)
nil nil 'regexp-history)
pref-arg
t)))
(when msgp (message "Gathering apropos data for customizing options..."))
(customize-apropos pattern (or arg 'options)))
(icicle-define-command icicle-customize-apropos-options-of-type
"Customize all loaded user options of a given type.
Enter patterns for the OPTION name and TYPE definition in the
minibuffer, separated by `icicle-list-join-string', which is \"^G^J\",
by default. (`^G' here means the Control-g character, input using
`C-h C-g'. Likewise, for `^J'.)
OPTION is a regexp that is matched against option names.
See `icicle-describe-option-of-type', which handles input and
completion similarly, for a full description of TYPE, matching, and
the use of a prefix argument."
icicle-customize-apropos-opt-action
prompt
'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
((prompt "OPTION `C-M-j' TYPE: ")
(icicle-multi-completing-p t)
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-multi-comp-apropos-complete-match)
(icicle-candidate-help-fn 'icicle-describe-opt-action)
(icicle-pref-arg current-prefix-arg))
(progn (put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering user options and their types...")))
(defun icicle-customize-apropos-opt-action (opt+type)
"Action function for `icicle-customize-apropos-options-of-type'."
(let ((icicle-list-use-nth-parts '(1)))
(custom-buffer-create (custom-sort-items (mapcar (lambda (s) (list (intern s) 'custom-variable))
icicle-completion-candidates)
t "*Customize Apropos*"))))
(defun icicle-apropos (pattern &optional do-all msgp)
"Describe Lisp symbols whose names match PATTERN.
By default, show symbols only if they are defined as functions,
variables, or faces, or if they have nonempty property lists.
With a prefix argument, or if `apropos-do-all' is non-nil, describe all
matching symbols.
Return a list of the symbols and descriptions.
Like command `apropos', but you can preview the list of matches using
`S-TAB'. Function names are highlighted using face
`icicle-special-candidate'.
When prompted for the PATTERN, you can use completion against
preference names - e.g. `S-TAB'. Instead of entering a pattern you
can then just hit `RET' to accept the list of matching preferences.
This lets you see which preferences will be available in the customize
buffer and dynamically change that list.
PATTERN is a regexp.
Starting with Emacs 22, if PATTERN includes no regexp special chars
then it can alternatively be a list of \"words\" separated by spaces.
Two or more of the words are matched in different orders against each
preference name. \"Word\" here really means a string of non-space
chars.
This handling of \"words\" is for compatibility with vanilla Emacs,
and is only approximative. It can include \"matches\" that you do not
expect. For better matching use Icicles progressive completion, i.e.,
separate the words (any strings, in fact, including regexps) using
`S-SPC', not just `SPC'."
(interactive
(list
(unwind-protect
(progn
(mapatoms (lambda (symb) (when (fboundp symb) (put symb 'icicle-special-candidate t))))
(let ((icicle-fancy-candidates-p t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "symbol")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "symbol"))))
(completing-read "Apropos symbol (regexp or words): " obarray
nil nil nil 'regexp-history)))
(mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil))))
current-prefix-arg
t))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering apropos data..."))
(apropos pattern do-all))
(cond
((fboundp 'apropos-option)
(defun icicle-apropos-variable (pattern &optional msgp)
"Show variables that match PATTERN.
This includes variables that are not user options.
User options are highlighted using face `icicle-special-candidate'.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN."
(interactive
(list
(unwind-protect
(progn
(mapatoms (lambda (symb) (when (user-variable-p symb) (put symb 'icicle-special-candidate t))))
(let* ((icicle-fancy-candidates-p t)
(pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(and (boundp s)
(get s 'variable-documentation))))
(icompletep (and (boundp 'icomplete-mode)
icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "variable")))
(icicle-all-candidates-list-alt-action-fn (or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "variable"))))
(completing-read
(concat "Apropos variable (regexp" (and (>= emacs-major-version 22) " or words")
"): ")
obarray (and icompletep pred) nil nil 'regexp-history)))
(mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil))))
t))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering data apropos variables..."))
(apropos-variable pattern))
(defun icicle-apropos-option (pattern &optional msgp)
"Show user options (variables) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN."
(interactive
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(user-variable-p s)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (completing-read
(concat "Apropos user option (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray (and icompletep pred) nil nil 'regexp-history)
t)))
(let ((apropos-do-all nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "option")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "option"))))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering data apropos user options..."))
(apropos-option pattern)))
(defun icicle-apropos-function (pattern &optional msgp)
"Show functions that match PATTERN.
This includes functions that are not commands.
Command names are highlighted using face `icicle-special-candidate'.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN."
(interactive
(list
(unwind-protect
(progn
(mapatoms (lambda (symb) (when (commandp symb) (put symb 'icicle-special-candidate t))))
(let* ((icicle-fancy-candidates-p t)
(pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(fboundp s)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "function")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "function"))))
(completing-read
(concat "Apropos function (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray (and icompletep pred) nil nil 'regexp-history)))
(mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil))))
t))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering data apropos functions..."))
(apropos-function pattern))
(defun icicle-apropos-command (pattern &optional msgp)
"Show commands (interactively callable functions) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN."
(interactive
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(commandp s)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type "command")))
(icicle-all-candidates-list-alt-action-fn (or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "command"))))
(list (completing-read
(concat "Apropos command (regexp" (and (>= emacs-major-version 22) " or words")
"): ") obarray (and icompletep pred) nil nil 'regexp-history)
t)))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message "Gathering data apropos commands..."))
(let ((apropos-do-all nil)) (apropos-command pattern))))
(t
(defun icicle-apropos-variable (pattern &optional do-all msgp)
"Show variables that match PATTERN.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN.
By default, only user options are candidates. With optional prefix
DO-ALL, or if `apropos-do-all' is non-nil, all variables are
candidates. In that case, the user-option candidates are highlighted
using face `icicle-special-candidate'."
(interactive
(list
(unwind-protect
(progn
(unless (or (boundp 'apropos-do-all) (require 'apropos nil t))
(error "Library `apropos' not found"))
(when (or current-prefix-arg apropos-do-all)
(mapatoms (lambda (symb)
(when (user-variable-p symb) (put symb 'icicle-special-candidate t)))))
(let* ((icicle-fancy-candidates-p (or current-prefix-arg apropos-do-all))
(pred (if (or current-prefix-arg apropos-do-all)
(lambda (s)
(unless (symbolp s)
(setq s (intern s)))
(and (boundp s)
(get s 'variable-documentation)))
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(user-variable-p s))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type
(if icicle-fancy-candidates-p
"variable"
"option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"variable"
"option")))))
(completing-read
(concat "Apropos " (if (or current-prefix-arg apropos-do-all)
"variable" "user option")
" (regexp" (and (>= emacs-major-version 22) " or words") "): ")
obarray (and icompletep pred) nil nil 'regexp-history)))
(when (or current-prefix-arg apropos-do-all)
(mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil)))))
current-prefix-arg
t))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message (format "Gathering data apropos %s..." (if do-all "variables" "options"))))
(apropos-variable pattern do-all))
(defun icicle-apropos-command (pattern &optional do-all var-predicate msgp)
"Show commands (interactively callable functions) that match PATTERN.
You can see the list of matches with `S-TAB'.
See `icicle-apropos' for a description of PATTERN.
With \\[universal-argument] prefix, or if `apropos-do-all' is non-nil,
also show noninteractive functions. In that case, the command
candidates are highlighted using face `icicle-special-candidate'.
If VAR-PREDICATE is non-nil, show only variables, and only those that
satisfy the predicate VAR-PREDICATE.
Non-interactively, a string PATTERN is used as a regexp, while a list
of strings is used as a word list."
(interactive
(list
(unwind-protect
(progn
(unless (boundp 'apropos-do-all)
(unless (require 'apropos nil t) (error "Library `apropos' not found")))
(when (or current-prefix-arg apropos-do-all)
(mapatoms (lambda (symb) (when (commandp symb) (put symb 'icicle-special-candidate t)))))
(let* ((icicle-fancy-candidates-p (or current-prefix-arg apropos-do-all))
(pred (if current-prefix-arg
(lambda (s)
(unless (symbolp s)
(setq s (intern s)))
(fboundp s))
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(commandp s))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(icicle-alt-act-fn-for-type
(if icicle-fancy-candidates-p
"function"
"command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
"function"
"command")))))
(completing-read
(concat "Apropos " (if (or current-prefix-arg apropos-do-all)
"command or function" "command")
" (regexp" (and (>= emacs-major-version 22) " or words") "): ")
obarray (and icompletep pred) nil nil 'regexp-history)))
(when (or current-prefix-arg apropos-do-all)
(mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil)))))
current-prefix-arg
nil
t))
(when (and (> emacs-major-version 21) (require 'apropos nil t)
(string= (regexp-quote pattern) pattern)
(not (string= "" pattern)))
(setq pattern (split-string pattern "[ \t]+" 'OMIT-NULLS)))
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern))
(when msgp (message (format "Gathering data apropos %s..." (if do-all "functions" "commands"))))
(apropos-command pattern do-all var-predicate))))
(icicle-define-command icicle-apropos-options-of-type
"Show user options of a given type.
Enter patterns for the OPTION name and TYPE definition in the
minibuffer, separated by `icicle-list-join-string', which is \"^G^J\",
by default. (`^G' here means the Control-g character, input using
`C-h C-g'. Likewise, for `^J'.)
OPTION is a regexp that is matched against option names.
See also:
* `icicle-describe-option-of-type', which handles input and completion
similarly, for a full description of TYPE, matching, and the use of
a prefix argument
* `icicle-apropos-value', using `C-$' to filter to options only"
icicle-apropos-opt-action
prompt
'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
((prompt "OPTION `C-M-j' TYPE: ")
(icicle-multi-completing-p t)
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-multi-comp-apropos-complete-match)
(icicle-candidate-help-fn 'icicle-describe-opt-action)
(icicle-pref-arg current-prefix-arg))
(progn (put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering user options and their types...")))
(defun icicle-apropos-opt-action (opt+type)
"Action function for `icicle-apropos-options-of-type'."
(let ((icicle-list-use-nth-parts '(1)))
(apropos-option (icicle-transform-multi-completion opt+type))))
(defun icicle-apropos-zippy (regexp)
"Show all Zippy quotes matching the regular-expression REGEXP.
Return the list of matches."
(interactive (progn (unless (boundp 'yow-file)
(unless (require 'yow nil t) (error "Library `yow' not found")))
(cookie yow-file yow-load-message yow-after-load-message)
(let* ((case-fold-search t)
(cookie-table-symbol (intern yow-file cookie-cache))
(string-table (symbol-value cookie-table-symbol))
(table (nreverse (mapcar #'list string-table))))
(list (completing-read "Apropos Zippy (regexp): " table
nil nil nil 'regexp-history)))))
(let ((matches (apropos-zippy icicle-current-input)))
(when (interactive-p)
(with-output-to-temp-buffer "*Zippy Apropos*"
(while matches
(princ (car matches))
(setq matches (cdr matches))
(and matches (princ "\n\n")))))
matches))
(icicle-define-command icicle-apropos-value
"Choose a variable, function, or other symbol description.
This is similar to vanilla command `apropos-value', but you can match
against the variable name and its printed value at the same time.
By default, each completion candidate is multi-completion composed of
a variable name plus its value. They are separated by
`icicle-list-join-string' \(\"^G^J\", by default).
With a prefix arg, candidates are different kinds of symbols:
< 0: functions and their defs (but byte-compiled defs are skipped)
> 0: symbols and their plists
= 0: variables and their values, functions and their definitions, and
other symbols and their plists
plain (`C-u'): use the last-computed (cached) set of candidates
You can use `C-$' during completion to toggle filtering the domain of
initial candidates according to the prefix argument, as follows:
none: only user options (+ values)
< 0: only commands (+ definitions)
> 0: only faces (+ plists)
= 0: only options (+ values), commands (+ defs), faces (+ plists)
Remember that you can use \\<minibuffer-local-completion-map>\
`\\[icicle-cycle-incremental-completion]' to toggle incremental completion.
See also:
* `icicle-apropos-vars-w-val-satisfying',
`icicle-describe-vars-w-val-satisfying' - values satisfy a predicate
* `icicle-plist' - similar to this command with positive prefix arg
* `icicle-vardoc', `icicle-fundoc', `icicle-doc' - match name & doc
* `icicle-apropos-options-of-type', `icicle-describe-option-of-type' -
match name & defcustom type"
icicle-doc-action
prompt
(let ((cands (and (consp pref-arg) icicle-apropos-value-last-initial-cand-set))
cand)
(unless cands
(mapatoms (lambda (symb)
(setq cand (and (not (memq symb '(cands pref-arg num-arg prompt
icicle-toggle-transforming-message
icicle-candidate-properties-alist
icicle-multi-completing-p icicle-list-use-nth-parts
icicle-transform-before-sort-p icicle-transform-function
icicle-last-transform-function print-fn make-cand)))
(funcall make-cand symb)))
(when cand (push cand cands))))
(setq icicle-apropos-value-last-initial-cand-set cands))
cands)
nil nil nil nil nil nil
((pref-arg current-prefix-arg)
(num-arg (prefix-numeric-value pref-arg))
(prompt (format "SYMBOL `C-M-j' %s: " (if pref-arg "INFO" "VALUE")))
(icicle-toggle-transforming-message (cond ((or (consp pref-arg) (= num-arg 0))
"Filtering to OPTIONS, COMMANDS, & FACES is now %s")
((and pref-arg (> num-arg 0))
"Filtering to FACES (+ plists) is now %s")
((< num-arg 0)
"Filtering to COMMANDS (+ defs) is now %s")
(t "Filtering to user OPTIONS (+ values) is now %s")))
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-transform-before-sort-p t)
(icicle-transform-function nil)
(icicle-last-transform-function (lambda (cands)
(loop for cc in cands
with symb
do (setq symb (intern (icicle-transform-multi-completion cc)))
if (cond ((or (consp `,pref-arg) (= `,num-arg 0))
(or (user-variable-p symb)
(commandp symb)
(facep symb)))
((and `,pref-arg (> `,num-arg 0))
(facep symb))
((< `,num-arg 0)
(commandp symb))
(t
(user-variable-p symb)))
collect cc)))
(print-fn (lambda (obj)
(let ((print-circle t))
(prin1-to-string obj))))
(make-cand (cond ((< num-arg 0)
(lambda (symb)
(and (fboundp symb)
`((,(symbol-name symb)
,(if (byte-code-function-p (symbol-function symb))
""
(funcall print-fn (symbol-function symb))))))))
((= num-arg 0)
(lambda (symb)
(cond ((boundp symb)
`((,(symbol-name symb)
,(funcall print-fn (symbol-value symb)))))
((fboundp symb)
`((,(symbol-name symb)
,(if (byte-code-function-p (symbol-function symb))
""
(funcall print-fn (symbol-function symb))))))
((symbol-plist symb)
`((,(symbol-name symb)
,(funcall print-fn (symbol-plist symb))))))))
((and pref-arg (> num-arg 0))
(lambda (symb)
(and (symbol-plist symb)
`((,(symbol-name symb)
,(funcall print-fn (symbol-plist symb)))))))
(t
(lambda (symb)
(and (boundp symb)
`((,(symbol-name symb)
,(funcall print-fn (symbol-value symb))))))))))
(progn (put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering %s%s..." (cond ((consp pref-arg) 'SYMBOLS)
((and pref-arg (< num-arg 0)) 'FUNCTIONS)
((and pref-arg (= num-arg 0)) "all SYMBOLS")
((and pref-arg (> num-arg 0)) 'SYMBOLS)
(t 'VARIABLES))
(cond ((consp pref-arg) " from last invocation (cached)")
((and pref-arg (< num-arg 0)) " and their definitions")
((and pref-arg (= num-arg 0)) " and their info")
((and pref-arg (> num-arg 0)) " and their plists")
(t " and their values")))))
(icicle-define-command icicle-describe-option-of-type
"Describe a user option that was defined with a given `defcustom' type.
Enter patterns for the OPTION name and TYPE definition in the
minibuffer, separated by `icicle-list-join-string', which is \"^G^J\",
by default. (`^G' here means the Control-g character, input using
`C-h C-g'. Likewise, for `^J'.)
Remember that you can insert `icicle-list-join-string' using `C-M-j'.
This command binds option `icicle-dot-string' to the value of
`icicle-anychar-regexp' for the duration, which means that `.' in your
input to this command matches any character, including a newline char.
This is for convenience because `defcustom' type sexps are often
multiline. This is particularly important for progressive completion,
where your input definitely matches as a regexp (apropos completion).
If you do not want `.' to match newlines, use `C-M-.' during the
command.
Example use of progressive completion:
1. C-h C-o ici C-M-j choic S-TAB
That shows all options whose names are apropos-matched by `ici' and
whose types are matched by `choic'.
2. S-SPC om C-M-j sexp
That limits the matches to options whose names also match `om' and
whose types also match `sexp'.'
OPTION is a regexp that is matched against option names.
Depending on the prefix arg, TYPE is interpreted as either of these:
- a regexp to match against the option type
- a definition acceptable for `defcustom' :type, or its first symbol,
for example, (choice (integer) (regexp)) or `choice'
In the second case, depending on the prefix arg, TYPE can be matched
against the option type, or it can be matched against either the
option type or one of its subtypes.
In the second case also, depending on the prefix arg, if TYPE does not
match some option's type, that option might still be a candidate, if
its current value satisfies TYPE.
In sum, the prefix arg determines the type-matching behavior, as
follows:
- None: OPTION is defined with TYPE or a subtype of TYPE.
TYPE is a regexp.
- `C-u': OPTION is defined with TYPE or a subtype of TYPE,
or its current value is compatible with TYPE.
TYPE is a type definition or its first symbol.
- Negative: OPTION is defined with TYPE (exact match).
TYPE is a regexp.
- Positive: OPTION is defined with TYPE,
or its current value is compatible with TYPE.
TYPE is a type definition or its first symbol.
- Zero: OPTION is defined with TYPE or a subtype of TYPE.
TYPE is a type definition or its first symbol.
- `C-u C-u': OPTION is defined with TYPE (exact match).
TYPE is a type definition or its first symbol.
You can change these prefix-arg key sequences by customizing option
`icicle-option-type-prefix-arg-list'. For example, if you tend to use
the matching defined here for `C-u', you might want to make that the
default behavior (no prefix arg). You can assign any of the six
behaviors to any of the prefix-arg keys.
If TYPE is nil, then *all* options that match OPTION are candidates.
Note that options defined in libraries that have not been loaded can
be candidates, but their type will appear as nil, since it is not
known before loading the option definition.
You can match your input against the option name or the type
definition or both. Use `C-M-j' (equivalent here to `C-q C-g C-j') to
input the default separator.
For example, to match all Icicles options whose type matches `string'
\(according to the prefix arg), use `S-TAB' with this input:
icicle C-M-j string$
If you instead want all Icicles options whose type definition contains
`string', as in (repeat string), then use this:
icicle C-M-j string
Remember that you can use `\\<minibuffer-local-completion-map>\
\\[icicle-cycle-incremental-completion] to toggle incremental completion.
See also:
* `icicle-apropos-options-of-type', to show options of a given type
* `icicle-apropos-value', using `C-$' to filter to options only"
icicle-describe-opt-action
prompt
'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
((prompt "OPTION `C-M-j' TYPE: ")
(icicle-multi-completing-p t)
(icicle-candidate-properties-alist '((1 (face icicle-candidate-part))))
(icicle-dot-string icicle-anychar-regexp)
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-multi-comp-apropos-complete-match)
(icicle-candidate-help-fn 'icicle-describe-opt-action)
(icicle-pref-arg current-prefix-arg))
(progn (put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Gathering user options and their types...")))
(defun icicle-describe-opt-action (opt+type)
"Action function for `icicle-describe-option-of-type'."
(let ((icicle-list-use-nth-parts '(1)))
(describe-variable (intern (icicle-transform-multi-completion opt+type)))))
(defun icicle-describe-opt-of-type-complete (strg pred completion-mode)
"Completion function for `icicle-describe-option-of-type'.
This is used as the value of `minibuffer-completion-table'."
(setq strg icicle-current-input)
(lexical-let* ((num-prefix (prefix-numeric-value icicle-pref-arg))
(mode (cond ((not icicle-pref-arg)
(nth 4 icicle-option-type-prefix-arg-list))
((and (consp icicle-pref-arg) (= 16 num-prefix))
(nth 0 icicle-option-type-prefix-arg-list))
((consp icicle-pref-arg) (nth 2 icicle-option-type-prefix-arg-list))
((zerop num-prefix) (nth 1 icicle-option-type-prefix-arg-list))
((wholenump num-prefix)
(nth 3 icicle-option-type-prefix-arg-list))
(t (nth 5 icicle-option-type-prefix-arg-list))))
(ops (let ((icicle-list-use-nth-parts '(1)))
(icicle-transform-multi-completion strg)))
(tps (let ((icicle-list-use-nth-parts '(2)))
(icicle-transform-multi-completion strg)))
(tp (and (not (string= "" tps))
(if (memq mode '(inherit-or-regexp direct-or-regexp)) tps (read tps))))
(result ()))
(mapatoms
(lambda (symb)
(when (if (fboundp 'custom-variable-p) (custom-variable-p symb) (user-variable-p symb))
(condition-case nil
(push (list symb (get symb 'custom-type)) result)
(error nil)))))
(setq result
(lexical-let ((ops-re (if (memq icicle-current-completion-mode '(nil apropos))
ops
(concat "^" ops))))
(icicle-remove-if-not
(lambda (opt+typ)
(and (string-match ops-re (symbol-name (car opt+typ)))
(or (null tp)
(condition-case nil
(icicle-var-is-of-type-p (car opt+typ) (list tp)
(case mode
((inherit inherit-or-regexp) 'inherit)
((direct direct-or-regexp) 'direct)
(inherit-or-value 'inherit-or-value)
(direct-or-value 'direct-or-value)))
(error nil)))))
result)))
(setq result
(mapcar (lambda (entry)
(let* ((opt+typ-string
(mapconcat (lambda (e) (pp-to-string e)) entry icicle-list-join-string))
(doc
(and (or (> icicle-help-in-mode-line-delay 0)
(and (boundp 'tooltip-mode) tooltip-mode))
(documentation-property (car entry) 'variable-documentation t)))
(doc1 (and (stringp doc) (string-match ".+$" doc) (match-string 0 doc))))
(when doc1 (icicle-candidate-short-help doc1 opt+typ-string))
opt+typ-string))
result))
(if completion-mode
result
(try-completion
strg (mapcar #'list result) (and pred (lambda (ss) (funcall pred ss)))))))
(defun icicle-apropos-vars-w-val-satisfying (predicate pattern &optional optionp)
"Show variables whose values satisfy PREDICATE and names match PATTERN.
You are prompted for a predicate sexp and a pattern matching the
variable names. For the latter, before hitting `RET' you must use
completion (`S-TAB' or `TAB') to manifest the set of matching
variables. Apropos information is shown for those variables when you
hit `RET'.
The predicate sexp must be a function symbol or a lambda form that
accepts the value of the variable as its (first) argument.
Typically the predicate is a type predicate, such as `integerp', but
it could be anything. Instead of just `integerp', for example, it
could be `(lambda (val) (and (integerp val) (> val 5) (< val 15)))'.
With a prefix argument, candidates are limited to user options.
See also: `icicle-apropos-value', which matches names and values."
(interactive (icicle-read-args-w-val-satisfying "Apropos var (hit `S-TAB' or `TAB'): "
current-prefix-arg t))
(if optionp
(if (fboundp 'icicle-apropos-option)
(icicle-apropos-option pattern)
(icicle-apropos-variable pattern t))
(icicle-apropos-variable pattern)))
(defun icicle-customize-apropos-opts-w-val-satisfying (predicate pattern)
"Customize options whose values satisfy PREDICATE and names match PATTERN.
You are prompted for a predicate sexp and a pattern matching the
option names. For the latter, before hitting `RET' you must use
completion (`S-TAB' or `TAB') to manifest the set of matching options.
A Customize buffer is opened for those options when you hit `RET'.
The predicate sexp must be a function symbol or a lambda form that
accepts the value of the variable as its (first) argument.
Typically the predicate is a type predicate, such as `integerp', but
it could be anything. Instead of just `integerp', for example, it
could be `(lambda (val) (and (integerp val) (> val 5) (< val 15)))'."
(interactive (let ((xxx (icicle-read-args-w-val-satisfying "Customize vars (hit `S-TAB' or `TAB'): "
t t)))
(list (car xxx) (cadr xxx))))
(icicle-customize-apropos-options pattern))
(defun icicle-read-args-w-val-satisfying (prompt optionp patternp)
"Read args for `icicle-*-w-val-satisfying' commands.
Prompt for the variable names using PROMPT.
Non-nil OPTIONP means allow only variables that are user options. It
is used here during completion of the variable name, and it is
returned as the third arg for `icicle-describe-var-w-val-satisfying'.
Non-nil PATTERNP means return as the variable whatever input pattern
the user entered. Otherwise, assume the pattern names a variable, and
return the symbol with that name."
(let* ((enable-recursive-minibuffers t)
(valpred
(let ((string-read nil)
(read-result nil))
(condition-case err
(prog1 (setq read-result (read (setq string-read (completing-read
"Predicate to satify: "
icicle-predicate-types-alist
nil nil nil
(if (boundp 'function-name-history)
'function-name-history
'icicle-function-name-history)))))
(unless (functionp read-result) (error "")))
(error (error "Invalid function: `%s'" string-read)))))
(vardflt (or (and (fboundp 'symbol-nearest-point)
(symbol-nearest-point))
(and (symbolp (variable-at-point))
(variable-at-point))))
(symbpred (if optionp #'user-variable-p #'boundp))
(varpred `(lambda (sy)
(unless (symbolp sy) (setq sy (intern sy)))
(and
(funcall #',symbpred sy)
(funcall #',valpred (symbol-value sy)))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) varpred))
(varpat (completing-read
prompt obarray (and icompletep varpred) nil nil nil
(and vardflt (symbol-name vardflt)) t)))
(list valpred
(if patternp
(if icicle-completion-candidates
(regexp-opt icicle-completion-candidates)
(message "Predicate %s. You did not complete var names (`S-TAB' or `TAB')"
(icicle-propertize "IGNORED" 'face 'icicle-msg-emphasis))
(sit-for 3)
varpat)
(intern varpat))
optionp)))
(unless (fboundp 'icicle-ORIG-repeat-complex-command)
(defalias 'icicle-ORIG-repeat-complex-command (symbol-function 'repeat-complex-command)))
(defun icicle-repeat-complex-command (arg)
"Edit and re-evaluate the last complex command, or ARGth from last.
A complex command is one that used the minibuffer.
ARG is the prefix argument numeric value.
You can edit the past command you choose before executing it. The
Lisp form of the command is used. If the command you enter differs
from the previous complex command, then it is added to the front of
the command history.
Icicles completion is available for choosing a past command. You can
still use the vanilla Emacs bindings `\\<minibuffer-local-map>\\[next-history-element]' and \
`\\[previous-history-element]' to cycle inputs,
and `\\[repeat-matching-complex-command]' to match regexp input, but Icicles input cycling (`up',
`down', `next', `prior', `home', `end') and apropos completion
\(`S-TAB') are superior and more convenient."
(interactive "p")
(let ((elt (nth (1- arg) command-history))
newcmd)
(if elt
(progn
(setq newcmd
(let ((print-level nil)
(minibuffer-history-position arg)
(minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
(unwind-protect
(let ((icicle-transform-function 'icicle-remove-duplicates))
(read (completing-read
"Redo: " (mapcar (lambda (entry) (list (prin1-to-string entry)))
command-history)
nil nil (prin1-to-string elt) (cons 'command-history arg)
(prin1-to-string elt))))
(if (stringp (car command-history))
(setq command-history (cdr command-history))))))
(or (equal newcmd (car command-history))
(setq command-history (cons newcmd command-history)))
(eval newcmd))
(if command-history
(icicle-user-error "Argument %d is beyond length of command history" arg)
(icicle-user-error "There are no previous complex commands to repeat")))))
(defun icicle-add-entry-to-saved-completion-set (set-name entry type)
"Add ENTRY to saved completion-candidates set SET-NAME.
ENTRY is normally a single candidate (a string).
With a prefix arg, however, and if option
`icicle-filesets-as-saved-completion-sets-flag' is non-nil, then
ENTRY is the name of an Emacs fileset (Emacs 22 or later).
TYPE is the type of entry to add: `Fileset' or `Candidate'."
(interactive
(let ((typ (if (and current-prefix-arg icicle-filesets-as-saved-completion-sets-flag
(prog1 (or (require 'filesets nil t)
(error "Feature `filesets' not provided"))
(filesets-init))
filesets-data)
'Fileset
'Candidate)))
(list
(save-selected-window
(completing-read "Saved completion set: " icicle-saved-completion-sets nil t nil
'icicle-completion-set-history))
(if (eq typ 'Fileset)
(list ':fileset
(car (assoc (completing-read "Fileset to add: " filesets-data nil t)
filesets-data)))
(completing-read "Candidate to add: " (mapcar #'list icicle-saved-completion-candidates)))
typ)))
(let ((file-name (cdr (assoc set-name icicle-saved-completion-sets))))
(unless (icicle-file-readable-p file-name) (error "Cannot read cache file `%s'" file-name))
(let ((list-buf (find-file-noselect file-name 'NOWARN 'RAW))
candidates newcands entry-type)
(unwind-protect
(condition-case icicle-add-entry-to-saved-completion-set
(when (listp (setq newcands (setq candidates (read list-buf))))
(message "Set `%s' read from file `%s'" set-name file-name))
(error (error "Bad cache file. %s"
(error-message-string icicle-add-entry-to-saved-completion-set))))
(kill-buffer list-buf))
(unless (consp newcands) (error "Bad data in cache file `%s'" file-name))
(pushnew entry newcands :test #'equal)
(setq entry (if (eq type 'Fileset) (caar entry) entry))
(if (= (length candidates) (length newcands))
(message "%s `%s' is already in saved set `%s', file `%s'" type entry set-name file-name)
(with-temp-message (format "Writing entry to cache file `%s'..." file-name)
(with-temp-file file-name (prin1 newcands (current-buffer))))
(message "%s `%s' added to saved set `%s', file `%s'" type
(icicle-propertize entry 'face 'icicle-msg-emphasis)
(icicle-propertize set-name 'face 'icicle-msg-emphasis)
(icicle-propertize file-name 'face 'icicle-msg-emphasis))))))
(defun icicle-remove-entry-from-saved-completion-set (set-name)
"Remove an entry from saved completion-candidates set SET-NAME.
SET-NAME can be an Icicles saved completions set (cache file) or the
name of an Emacs fileset.
The entry to remove can be a single completion candidate (a string) or
an Emacs fileset. You can thus remove a file name from a fileset or
remove a fileset from an Icicles saved completion set. (You can also
remove a file name from a saved completion set.) If a saved set has
both a file and a fileset of the same name, then both are removed.
To use filesets here, use Emacs 22 or later, load library `filesets',
use `(filesets-init)', and ensure that option
`icicle-filesets-as-saved-completion-sets-flag' is non-nil."
(interactive
(list (completing-read "Saved completion set: "
(if (and icicle-filesets-as-saved-completion-sets-flag
(featurep 'filesets) filesets-data)
(append filesets-data icicle-saved-completion-sets)
icicle-saved-completion-sets)
nil t nil 'icicle-completion-set-history)))
(let* ((file-name (cdr (assoc set-name icicle-saved-completion-sets)))
(candidates (icicle-get-candidates-from-saved-set
set-name 'dont-expand))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-remove-icicles-props-p nil)
(entry
(funcall icicle-get-alist-candidate-function
(completing-read
"Candidate to remove: "
(mapcar (lambda (e)
(cond ((icicle-saved-fileset-p e)
`(,(cadr e) ,(car e) ,@(cddr e)))
((consp e) e)
(t (list e))))
candidates)
nil t))))
(when (and (consp entry) (eq (cadr entry) ':fileset))
(setq entry `(,(cadr entry) ,(car entry) ,@(cddr entry))))
(when (and (consp entry) (null (cdr entry))) (setq entry (car entry)))
(setq candidates (mapcar #'icicle-unpropertize-completion (delete entry candidates)))
(cond (file-name
(with-temp-message
(format "Writing remaining candidates to cache file `%s'..." file-name)
(with-temp-file file-name (prin1 candidates (current-buffer)))))
((icicle-saved-fileset-p (list ':fileset set-name))
(unless (require 'filesets nil t) (error "Feature `filesets' not provided"))
(filesets-init)
(let ((fst (and filesets-data (assoc set-name filesets-data))))
(unless fst (error "No such fileset: `%s'" set-name))
(let ((fst-files (filesets-entry-get-files fst)))
(if (car (filesets-member entry fst-files :test 'filesets-files-equalp))
(if fst-files
(let ((new-fst (list (cons ':files (delete entry fst-files)))))
(setcdr fst new-fst)
(filesets-set-config set-name 'filesets-data filesets-data))
(message "Cannot remove `%s' from fileset `%s'"
(icicle-propertize entry 'face 'icicle-msg-emphasis)
(icicle-propertize set-name 'face 'icicle-msg-emphasis)))
(message "`%s' not in fileset `%s'"
(icicle-propertize entry 'face 'icicle-msg-emphasis)
(icicle-propertize set-name 'face 'icicle-msg-emphasis)))))))
(when entry
(icicle-msg-maybe-in-minibuffer
"`%s' removed from %s `%s'%s"
(icicle-propertize (if (icicle-saved-fileset-p entry) (cadr entry) entry)
'face 'icicle-msg-emphasis)
(if (icicle-saved-fileset-p entry) "fileset" "saved set")
(icicle-propertize set-name 'face 'icicle-msg-emphasis)
(if file-name
(format ", file `%s'" (icicle-propertize file-name'face 'icicle-msg-emphasis))
"")))))
(icicle-define-command icicle-remove-saved-completion-set
"Remove an entry from `icicle-saved-completion-sets'.
Save the updated option.
You are prompted to also delete the associated cache file.
You can add entries to `icicle-saved-completion-sets' using command
`icicle-add/update-saved-completion-set'."
icicle-remove-saved-set-action
"Remove set of completion candidates named: "
icicle-saved-completion-sets nil t nil 'icicle-completion-set-history nil nil
((icicle-whole-candidate-as-text-prop-p t)
(icicle-use-candidates-only-once-flag t))
nil nil (icicle-remove-Completions-window))
(defun icicle-remove-saved-set-action (set-name)
"Remove saved set SET-NAME from `icicle-saved-completion-sets'."
(let ((enable-recursive-minibuffers t)
(sets icicle-saved-completion-sets)
set cache)
(save-selected-window
(select-window (minibuffer-window))
(while (setq set (assoc set-name sets)
cache (cdr set))
(when (file-exists-p cache)
(if (y-or-n-p (format "Delete cache file `%s'? "
(icicle-propertize cache 'face 'icicle-msg-emphasis)))
(when (condition-case err
(progn (delete-file cache) t)
(error (progn (message "%s" (error-message-string err)) nil)))
(message "%s `%s'" (icicle-propertize "DELETED" 'face 'icicle-msg-emphasis) cache)
(sit-for 1))
(message "OK, file NOT deleted") (sit-for 1)))
(setq sets (delete set sets)))))
(setq icicle-saved-completion-sets
(icicle-assoc-delete-all set-name icicle-saved-completion-sets))
(funcall icicle-customize-save-variable-function
'icicle-saved-completion-sets
icicle-saved-completion-sets)
(message "Candidate set `%s' removed" (icicle-propertize set-name 'face 'icicle-msg-emphasis)))
(defun icicle-bookmark-save-marked-files (&optional arg)
"Save file names of marked bookmarks as a set of completion candidates.
Saves file names in variable `icicle-saved-completion-candidates', by
default. Marked bookmarks that have no associated file are ignored.
With a plain prefix arg (`C-u'), save candidates in a cache file.
With a non-zero numeric prefix arg (`C-u N'), save candidates in a
variable for which you are prompted.
With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
or later). Use this only for file-name candidates, obviously.
To subsequently use a fileset for candidate retrieval, option
`icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
You can retrieve the saved set of file-name candidates during
completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a bookmark-list display buffer
\(`*Bookmark List*')."
(interactive "P")
(unless (fboundp 'bmkp-bmenu-get-marked-files)
(icicle-user-error "You need library `Bookmark+' for this command"))
(bmkp-bmenu-barf-if-not-in-menu-list)
(icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg))
(defun icicle-bookmark-save-marked-files-more (&optional arg)
"Add the file names of the marked bookmarks to the saved candidates set.
Marked bookmarks that have no associated file are ignored.
Add candidates to `icicle-saved-completion-candidates', by default.
A prefix argument acts the same as for `icicle-candidate-set-save'.
The existing saved candidates remain saved. The current candidates
are added to those already saved.
You can retrieve the saved set of candidates with `C-M-<'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a bookmark-list display buffer
\(`*Bookmark List*')."
(interactive "P")
(unless (fboundp 'bmkp-bmenu-get-marked-files)
(icicle-user-error "You need library `Bookmark+' for this command"))
(bmkp-bmenu-barf-if-not-in-menu-list)
(icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) arg t))
(defun icicle-bookmark-save-marked-files-to-variable ()
"Save the file names of the marked bookmarks to a variable.
Marked bookmarks that have no associated file are ignored.
You can retrieve the saved set of file-name candidates during
completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a bookmark-list display buffer
\(`*Bookmark List*')."
(interactive)
(unless (fboundp 'bmkp-bmenu-get-marked-files)
(icicle-user-error "You need library `Bookmark+' for this command"))
(bmkp-bmenu-barf-if-not-in-menu-list)
(icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) 99))
(defalias 'icicle-bookmark-save-marked-files-as-project
'icicle-bookmark-save-marked-files-persistently)
(defun icicle-bookmark-save-marked-files-persistently (filesetp)
"Save the file names of the marked bookmarks as a persistent set.
Marked bookmarks that have no associated file are ignored.
With no prefix arg, save in a cache file.
With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
You can retrieve the saved set of file-name candidates during
completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a bookmark-list display buffer
\(`*Bookmark List*')."
(interactive "P")
(unless (fboundp 'bmkp-bmenu-get-marked-files)
(icicle-user-error "You need library `Bookmark+' for this command"))
(bmkp-bmenu-barf-if-not-in-menu-list)
(icicle-candidate-set-save-1 (bmkp-bmenu-get-marked-files) (if filesetp 0 '(1))))
(defun icicle-dired-save-marked (&optional arg)
"Save the marked file names in Dired as a set of completion candidates.
Saves file names in variable `icicle-saved-completion-candidates', by
default.
With a plain prefix arg (`C-u'), save candidates in a cache file.
With a non-zero numeric prefix arg (`C-u N'), save candidates in a
variable for which you are prompted.
With a zero prefix arg (`C-0'), save candidates in a fileset (Emacs 22
or later). Use this only for file-name candidates, obviously.
To subsequently use a fileset for candidate retrieval, option
`icicle-filesets-as-saved-completion-sets-flag' must be non-nil.
You can retrieve the saved set of file-name candidates during
completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a Dired buffer."
(interactive "P")
(unless (eq major-mode 'dired-mode)
(icicle-user-error "You must be in a Dired buffer to use this command"))
(icicle-candidate-set-save-1 (dired-get-marked-files) arg))
(defun icicle-dired-save-marked-more (&optional arg)
"Add the marked file names in Dired to the saved candidates set.
Like `icicle-dired-save-marked', but add file names to those already
saved, if any. A prefix argument has the same effect as for
`icicle-dired-save-marked'."
(interactive "P")
(unless (eq major-mode 'dired-mode)
(icicle-user-error "You must be in a Dired buffer to use this command"))
(icicle-candidate-set-save-1 (dired-get-marked-files) arg t))
(defun icicle-dired-save-marked-to-variable ()
"Save the marked file names in Dired to a variable as a candidate set.
Same as using `icicle-dired-save-marked' with no prefix argument."
(interactive)
(unless (eq major-mode 'dired-mode)
(icicle-user-error "You must be in a Dired buffer to use this command"))
(icicle-candidate-set-save-1 (dired-get-marked-files) 99))
(defalias 'icicle-dired-save-marked-as-project
'icicle-dired-save-marked-persistently)
(defun icicle-dired-save-marked-persistently (filesetp)
"Save the marked file names in Dired as a persistent set.
With no prefix arg, save in a cache file.
With a prefix arg, save in an Emacs fileset (Emacs 22 or later).
You can retrieve the saved set of file-name candidates during
completion using `\\<minibuffer-local-completion-map>\\[icicle-candidate-set-retrieve]'.
You can use the saved set of candidates for operations such as
\\<minibuffer-local-completion-map>
`icicle-candidate-set-union' (`\\[icicle-candidate-set-union]'),
`icicle-candidate-set-intersection' (`\\[icicle-candidate-set-intersection]'), and
`icicle-candidate-set-difference' (`\\[icicle-candidate-set-difference]').
You can use this command only from a Dired buffer."
(interactive "P")
(unless (eq major-mode 'dired-mode)
(icicle-user-error "You must be in a Dired buffer to use this command"))
(icicle-candidate-set-save-1 (dired-get-marked-files) (if filesetp 0 '(1))))
(when (fboundp 'diredp-get-files)
(defun icicle-dired-save-marked-recursive (&optional ignore-marks-p arg)
"Save the marked file names in Dired, including those in marked subdirs.
Like `icicle-dired-save-marked', but act recursively on subdirs.
The files included are those that are marked in the current Dired
buffer, or all files in the directory if none are marked. Marked
subdirectories are handled recursively in the same way.
With a prefix argument, ignore all marks - include all files in this
Dired buffer and all subdirs, recursively.
You need library `Dired+' for this command."
(interactive (progn
(unless (fboundp 'diredp-get-confirmation-recursive)
(icicle-user-error "You need library `dired+.el' for this command"))
(diredp-get-confirmation-recursive)
(list current-prefix-arg 1)))
(icicle-candidate-set-save-1 (diredp-get-files ignore-marks-p) arg))
(defun icicle-dired-save-marked-more-recursive (&optional ignore-marks-p arg)
"Add marked files, including those in marked subdirs, to saved candidates.
Like `icicle-dired-save-marked-more', but act recursively on subdirs.
The files included are those that are marked in the current Dired
buffer, or all files in the directory if none are marked. Marked
subdirectories are handled recursively in the same way.
With a prefix argument, ignore all marks - include all files in this
Dired buffer and all subdirs, recursively.
You need library `Dired+' for this command."
(interactive (progn
(unless (fboundp 'diredp-get-confirmation-recursive)
(icicle-user-error "You need library `dired+.el' for this command"))
(diredp-get-confirmation-recursive)
(list current-prefix-arg 1)))
(icicle-candidate-set-save-1 (diredp-get-files ignore-marks-p) arg t))
(defun icicle-dired-save-marked-to-variable-recursive (&optional ignore-marks-p)
"Save marked files, including those in marked subdirs, to a variable.
Like `icicle-dired-save-marked-to-variable', but act recursively on subdirs.
The files included are those that are marked in the current Dired
buffer, or all files in the directory if none are marked. Marked
subdirectories are handled recursively in the same way.
With a prefix argument, ignore all marks - include all files in this
Dired buffer and all subdirs, recursively.
You need library `Dired+' for this command."
(interactive (progn
(unless (fboundp 'diredp-get-confirmation-recursive)
(icicle-user-error "You need library `dired+.el' for this command"))
(diredp-get-confirmation-recursive)
(list current-prefix-arg)))
(icicle-candidate-set-save-1 (diredp-get-files ignore-marks-p) 99))
(defun icicle-dired-save-marked-to-cache-file-recursive (&optional ignore-marks-p)
"Save marked files, including in marked subdirs, to an Icicles cache set.
Like `icicle-dired-save-marked-persistently' with no prefix arg, but
act recursively on subdirs.
The files included are those that are marked in the current Dired
buffer, or all files in the directory if none are marked. Marked
subdirectories are handled recursively in the same way.
With a prefix argument, ignore all marks - include all files in this
Dired buffer and all subdirs, recursively.
You need library `Dired+' for this command."
(interactive (progn
(unless (fboundp 'diredp-get-confirmation-recursive)
(icicle-user-error "You need library `dired+.el' for this command"))
(diredp-get-confirmation-recursive)
(list current-prefix-arg)))
(icicle-candidate-set-save-1 (diredp-get-files ignore-marks-p) '(1)))
(defun icicle-dired-save-marked-to-fileset-recursive (&optional ignore-marks-p)
"Save marked files, including those in marked subdirs, to an Emacs fileset.
Like `icicle-dired-save-marked-persistently' with no prefix arg, but
act recursively on subdirs.
The files included are those that are marked in the current Dired
buffer, or all files in the directory if none are marked. Marked
subdirectories are handled recursively in the same way.
With a prefix argument, ignore all marks - include all files in this
Dired buffer and all subdirs, recursively.
You need library `Dired+' for this command."
(interactive (progn
(unless (fboundp 'diredp-get-confirmation-recursive)
(icicle-user-error "You need library `dired+.el' for this command"))
(unless (require 'filesets nil t)
(error "Cannot save to a fileset - feature `filesets' not provided"))
(diredp-get-confirmation-recursive)
(list current-prefix-arg)))
(icicle-candidate-set-save-1 (diredp-get-files ignore-marks-p) 0)))
(when (and (> emacs-major-version 21)
(fboundp 'diredp-insert-as-subdir))
(icicle-define-file-command icicle-dired-insert-as-subdir
"Choose a directory. Insert it into a Dired ancestor listing.
If the directory you choose has a Dired buffer then its markings and
switches are preserved for the subdir listing in the ancestor Dired
buffer.
You need library `Dired+' for this command."
(lambda (dir) (diredp-insert-as-subdir dir ancestor-dir))
"Insert directory into ancestor Dired: "
default-directory nil t nil `(lambda (ff)
(and (file-directory-p (expand-file-name ff))
(dired-in-this-tree (expand-file-name ff) ',ancestor-dir)))
((ancestor-dir
(completing-read "Ancestor Dired dir to insert into: "
(cons (list default-directory)
(mapcar #'list (diredp-ancestor-dirs default-directory))))))))
(put 'icicle-dired-saved-file-candidates 'icicle-Completions-window-max-height 200)
(defalias 'icicle-dired-chosen-files 'icicle-dired-saved-file-candidates)
(defun icicle-dired-saved-file-candidates (prompt-for-dir-p)
"Open Dired on a set of files and directories of your choice.
If you have saved a set of file names using \\<minibuffer-local-completion-map>\
`\\[icicle-candidate-set-save]', then it is used.
If not, you are reminded to do so.
With a prefix argument, you are prompted for the default directory to use.
Otherwise, the current value of `default-directory' is used.
Names that do not correspond to existing files are ignored.
Existence of files with relative names is checked in the Dired
directory (default directory)."
(interactive "P")
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Directory: " nil default-directory nil)
default-directory))
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(file-names (icicle-remove-if
(lambda (fil)
(or (null fil)
(not (or (icicle-file-remote-p fil)
(file-exists-p fil)))))
(or (and icicle-saved-completion-candidates
(mapcar #'icicle-transform-multi-completion
icicle-saved-completion-candidates))
(icicle-file-list)))))
(unless file-names (error "No files or directories chosen"))
(dired (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
(put 'icicle-dired-saved-file-candidates-other-window 'icicle-Completions-window-max-height 200)
(defalias 'icicle-dired-chosen-files-other-window 'icicle-dired-saved-file-candidates-other-window)
(defun icicle-dired-saved-file-candidates-other-window (prompt-for-dir-p)
"Open Dired in other window on set of files & directories of your choice.
If you have saved a set of file names using \\<minibuffer-local-completion-map>\
`\\[icicle-candidate-set-save]', then it is used.
If not, you are reminded to do so.
With a prefix arg, you are prompted for the default directory to use.
Otherwise, the current value of `default-directory' is used.
Names that do not correspond to existing files are ignored.
Existence of files with relative names is checked in the Dired
directory (default directory)."
(interactive "P")
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Directory: " nil default-directory nil)
default-directory))
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(file-names (icicle-remove-if
(lambda (fil)
(or (null fil)
(not (or (icicle-file-remote-p fil)
(file-exists-p fil)))))
(or (and icicle-saved-completion-candidates
(mapcar #'icicle-transform-multi-completion
icicle-saved-completion-candidates))
(icicle-file-list)))))
(unless file-names (error "No files or directories chosen"))
(dired-other-window (cons (generate-new-buffer-name "Icy File Set") (nreverse file-names)))))
(put 'icicle-dired-project 'icicle-Completions-window-max-height 200)
(defun icicle-dired-project (prompt-for-dir-p)
"Open Dired on a saved project.
A project is either a persistent completion set or an Emacs fileset.
With a prefix argument, you are prompted for the directory.
Otherwise, the default directory is assumed.
Project file names that do not correspond to existing files are
ignored. Existence of files with relative names is checked in the
directory.
You can use `C-x m' during completion to access Dired bookmarks, if
you use library `Bookmark+'."
(interactive "P")
(when (require 'bookmark+ nil t)
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m")
'icicle-bookmark-dired-other-window))
(unwind-protect
(let ((set-name (completing-read "Project (saved file names): "
(if (and icicle-filesets-as-saved-completion-sets-flag
(featurep 'filesets) filesets-data)
(append filesets-data icicle-saved-completion-sets)
icicle-saved-completion-sets)
nil nil nil 'icicle-completion-set-history)))
(icicle-retrieve-candidates-from-set set-name)
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Dired directory: " nil default-directory nil)
default-directory))
(file-names ()))
(dolist (ff icicle-saved-completion-candidates)
(when (or (icicle-file-remote-p ff)
(file-exists-p ff))
(push ff file-names)))
(unless file-names (error "No files in project `%s' actually exist" set-name))
(dired (cons (generate-new-buffer-name set-name)
(nreverse (mapcar (lambda (file)
(if (file-name-absolute-p file)
(expand-file-name file)
file))
file-names))))))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m") nil)))
(put 'icicle-dired-project-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-dired-project-other-window (prompt-for-dir-p)
"Open Dired on a saved project in another window.
A project is either a persistent completion set or an Emacs fileset.
With a prefix argument, you are prompted for the directory.
Otherwise, the default directory is assumed.
Project file names that do not correspond to existing files are
ignored. Existence of files with relative names is checked in the
directory.
You can use `C-x m' during completion to access Dired bookmarks, if
you use library `Bookmark+'."
(interactive "P")
(when (require 'bookmark+ nil t)
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m")
'icicle-bookmark-dired-other-window))
(unwind-protect
(let ((set-name (completing-read "Project (saved file names): "
(if (and icicle-filesets-as-saved-completion-sets-flag
(featurep 'filesets) filesets-data)
(append filesets-data icicle-saved-completion-sets)
icicle-saved-completion-sets)
nil nil nil 'icicle-completion-set-history)))
(icicle-retrieve-candidates-from-set set-name)
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Dired directory: " nil default-directory nil)
default-directory))
(file-names ()))
(dolist (ff icicle-saved-completion-candidates)
(when (or (icicle-file-remote-p ff)
(file-exists-p ff))
(push ff file-names)))
(unless file-names (error "No files in project `%s' actually exist" set-name))
(dired-other-window (cons (generate-new-buffer-name set-name)
(nreverse (mapcar (lambda (file)
(if (file-name-absolute-p file)
(expand-file-name file)
file))
file-names))))))
(define-key minibuffer-local-completion-map (icicle-kbd "C-x m") nil)))
(defun icicle-grep-saved-file-candidates (command-args)
"Run `grep' on the set of completion candidates saved with \\<minibuffer-local-completion-map>\
`\\[icicle-candidate-set-save]'.
Saved names that do not correspond to existing files are ignored.
Existence of files with relative names is checked in the default
directory."
(interactive
(list
(let ((file-names ()))
(unless icicle-saved-completion-candidates
(icicle-user-error "%s" (substitute-command-keys "No saved completion candidates. \
Use \\<minibuffer-local-completion-map>`\\[icicle-candidate-set-save]' to save candidates")))
(unless grep-command (grep-compute-defaults))
(dolist (ff icicle-saved-completion-candidates)
(when (or (icicle-file-remote-p ff)
(file-exists-p ff))
(push ff file-names)))
(let ((default (and (fboundp 'grep-default-command) (grep-default-command))))
(read-from-minibuffer
"grep <pattern> <files> : "
(let ((up-to-files (concat grep-command " ")))
(cons (concat up-to-files (mapconcat #'identity icicle-saved-completion-candidates " "))
(- (length up-to-files) 2)))
nil nil 'grep-history default)))))
(grep command-args))
(defun icicle-explore (define-candidates-fn final-action-fn quit-fn error-fn cleanup-fn prompt
&rest compl-read-args)
"Icicle explorer: explore complex completion candidates.
Navigate among locations or other entities represented by a set of
completion candidates. See `icicle-search' for a typical example.
Arguments:
DEFINE-CANDIDATES-FN:
Function of no args called to fill `icicle-candidates-alist' with
the candidates.
FINAL-ACTION-FN:
Function of no args called after the final choice of candidate
(after both `icicle-explore-final-choice' and
`icicle-explore-final-choice-full' have been set). Typically uses
`icicle-explore-final-choice-full', the full candidate.
QUIT-FN: Function of no args called if user uses `C-g'.
ERROR-FN: Function of no args called if an error is raised.
CLEANUP-FN: Function of no args called after exploring.
PROMPT: Prompt string for `completing-read'.
COMPL-READ-ARGS: `completing-read' args other than PROMPT and
COLLECTION.
If there is only one candidate, then FINAL-ACTION-FN is called
immediately. The candidate is not available to act on (e.g. using
\\<minibuffer-local-completion-map>`\\[icicle-candidate-alt-action]').
Returns:
The result of executing FINAL-ACTION-FN, if that arg is non-nil.
Otherwise, `icicle-explore-final-choice-full'.
To use `icicle-explore' to define a multi-command, you must also bind
`icicle-candidate-action-fn'.
Though `icicle-explore' is typically used to define navigation
commands, it need not be. It can be useful anytime you need to use
`completing-read' and also provide specific behavior for quitting
\(`C-g'), completion errors, and final actions."
(let ((icicle-incremental-completion 'always)
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-function (if (interactive-p) nil icicle-transform-function))
(icicle-act-before-cycle-flag icicle-act-before-cycle-flag)
(icicle-orig-pt-explore (point-marker))
(icicle-orig-win-explore (selected-window))
result)
(setq icicle-act-before-cycle-flag nil
icicle-candidates-alist ()
icicle-explore-final-choice nil
icicle-explore-final-choice-full nil)
(icicle-highlight-lighter)
(message "Finding candidates...")
(when define-candidates-fn (funcall define-candidates-fn))
(unless icicle-candidates-alist (error "No candidates defined"))
(when (= (length icicle-candidates-alist) 1)
(setq icicle-explore-final-choice (icicle-display-cand-from-full-cand (car icicle-candidates-alist))))
(unwind-protect
(icicle-condition-case-no-debug failure
(progn
(unless icicle-explore-final-choice
(setq icicle-explore-final-choice
(let ((icicle-remove-icicles-props-p nil))
(apply #'completing-read prompt icicle-candidates-alist compl-read-args))))
(setq icicle-explore-final-choice-full
(funcall icicle-get-alist-candidate-function icicle-explore-final-choice 'no-error-p))
(unless icicle-explore-final-choice-full (error "No such occurrence"))
(setq result (if final-action-fn
(funcall final-action-fn)
icicle-explore-final-choice-full)))
(quit (if quit-fn (funcall quit-fn) (keyboard-quit)))
(error (when error-fn (funcall error-fn))
(error "%s" (error-message-string failure))))
(setq result (icicle-unpropertize-completion result))
(when cleanup-fn (funcall cleanup-fn)))
result))
(icicle-define-command icicle-execute-extended-command
"Read command name, then read its arguments and call it.
This is `execute-extended-command', turned into a multi-command.
You can use `\\<minibuffer-local-completion-map>\\[icicle-toggle-transforming]' \
to toggle filtering of candidates to those that are
bound to keys.
You can use `\\[icicle-toggle-annotation]' to toggle showing key bindings as annotations.
\(Menu bindings are not shown.)
By default, Icicle mode remaps all key sequences that are normally
bound to `execute-extended-command' to
`icicle-execute-extended-command'. If you do not want this remapping,
then customize option `icicle-top-level-key-bindings'."
icicle-execute-extended-command-1
(format "Execute command%s: "
(if current-prefix-arg
(format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
""))
obarray (and icompletep pred) t nil 'extended-command-history nil nil
(
(last-command last-command)
(use-file-dialog nil)
(alt-fn nil)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (lambda (c)
(unless (symbolp c) (setq c (intern-soft c)))
(commandp c)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
(icicle--last-toggle-transforming-msg icicle-toggle-transforming-message)
(icicle-toggle-transforming-message "Filtering to commands bound to keys is now %s")
(icicle-last-transform-function (lambda (cands)
(with-current-buffer icicle-pre-minibuffer-buffer
(loop for cand in cands
for symb = (intern-soft cand)
if (and (symbolp symb)
(where-is-internal symb nil 'non-ascii))
collect cand))))
(icicle-transform-function nil)
(completion-annotate-function (lambda (cand)
(with-current-buffer icicle-pre-minibuffer-buffer
(and (setq cand (intern-soft cand)) (symbolp cand)
(let ((key (where-is-internal cand nil t)))
(and key
(format " %s" (icicle-key-description key))))))))
icicle-new-last-cmd)
nil nil
(setq this-command icicle-new-last-cmd))
(defun icicle-execute-extended-command-1 (cmd-name)
"Action function to execute command or named keyboard macro CMD-NAME."
(when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
(when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
(when (string= "" cmd-name) (error "No command name"))
(let* ((cmd (intern cmd-name))
(fn (and (fboundp cmd) (symbol-function cmd)))
(count (prefix-numeric-value current-prefix-arg))
(completion-annotate-function nil)
(icicle-toggle-transforming-message icicle--last-toggle-transforming-msg)
(icicle-candidate-alt-action-fn nil)
(icicle-all-candidates-list-alt-action-fn nil)
(icicle-candidate-action-fn
(and icicle-candidate-action-fn
`(lambda (arg)
(setq arg (icicle-transform-multi-completion arg))
(condition-case nil
(funcall ',cmd arg)
(wrong-type-argument (funcall ',cmd (car (read-from-string arg))))
(wrong-number-of-arguments (funcall #'icicle-help-on-candidate)))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))))
(cond ((arrayp fn)
(let ((this-command cmd)) (execute-kbd-macro fn count))
(when (> count 1) (message "(%d times)" count)))
((commandp cmd)
(run-hooks 'post-command-hook)
(run-hooks 'pre-command-hook)
(let ((enable-recursive-minibuffers t)
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred)
(this-command cmd))
(call-interactively cmd 'record-it)))
(t (error "Not a command: `%s'" cmd-name)))
(when (and suggest-key-bindings (not executing-kbd-macro)
(not (or (icicle-get-safe this-command 'icicle-action-command)
(icicle-get-safe this-command 'icicle-cycling-command))))
(let* ((binding (if (> emacs-major-version 21)
(where-is-internal cmd overriding-local-map t 'NOINDIRECT)
(where-is-internal cmd overriding-local-map t)))
(curr-msg (current-message))
(wait-time (or (and (numberp suggest-key-bindings) suggest-key-bindings) 2)))
(when (and binding (not (and (vectorp binding) (eq (aref binding 0) 'mouse-movement))))
(let ((message-log-max nil)
(waited (sit-for (if (current-message) wait-time 0))))
(when (and waited (atom unread-command-events))
(unwind-protect
(progn (message "You can invoke command `%s' using `%s'"
(icicle-propertize (symbol-name cmd) 'face 'icicle-msg-emphasis)
(icicle-propertize (key-description binding) 'face 'icicle-msg-emphasis))
(sit-for wait-time))
(message "%s" curr-msg)))))))
(setq icicle-new-last-cmd cmd)))
(icicle-define-command icicle-command-abbrev
"Read command name or its abbreviation, read command args, call command.
Read input, then call `icicle-command-abbrev-action' to act on it.
If `icicle-add-proxy-candidates-flag' is non-nil, then command
abbreviations, as well as commands, are available as completion
candidates. Otherwise, only commands are available. You can toggle
`icicle-add-proxy-candidates-flag' using `\\<minibuffer-local-completion-map>\
\\[icicle-toggle-proxy-candidates]'in the minibuffer.
When an abbreviation is available, you can treat it just like a
command. The rest of this description covers the behavior of choosing
an abbreviation.
Completion for an abbreviation is lax. If you enter a new
abbreviation then it is added to option `icicle-command-abbrev-alist',
which is the list of your known abbreviations. You can also customize
this list.
If an abbreviation that you enter matches a single command name then
that command is invoked. If it matches more than one, then you can
use (strict) completion to choose one.
Hyphens (`-') in command names divide them into parts. For example,
`find-file' has two parts: `find' and `file'. Each character of a
command abbreviation corresponds to one part of each of the commands
that match the abbreviation. For example, abbreviation `ff' matches
commands `find-file' and `focus-frame', and abbreviation `fg' matches
`find-grep'.
If user option `icicle-command-abbrev-match-all-parts-flag' is nil
then an abbreviation need not match all parts of a command name; it
need match only a prefix. For example, if nil then abbreviation `ff'
also matches `find-file-other-window' and `fg' also matches
`find-grep-dired'.
You can use `\\<minibuffer-local-completion-map>\\[icicle-toggle-transforming]' \
to toggle filtering of candidates to those that are
bound to keys.
You can use `\\[icicle-toggle-annotation]' to toggle showing key bindings as annotations.
\(Menu bindings are not shown.)"
icicle-command-abbrev-action
prompt obarray (and icompletep pred) nil nil
'icicle-command-abbrev-history nil nil
((prompt "Command or abbrev: ")
(last-command last-command)
(icicle-sort-comparer 'icicle-proxy-candidate-first-p)
(first-sort-entries '(("proxy candidates first" . icicle-proxy-candidate-first-p)
("by abbrev frequency" . icicle-command-abbrev-used-more-p)))
(icicle-sort-orders-alist (append
first-sort-entries
(delete (car first-sort-entries)
(delete (cadr first-sort-entries)
(copy-sequence icicle-sort-orders-alist)))))
(icicle-allowed-sort-predicate 'icicle-command-abbrev-used-more-p)
(icicle-proxy-candidates (let ((ipc ())
abv)
(dolist (entry icicle-command-abbrev-alist ipc)
(setq abv (symbol-name (cadr entry)))
(unless (member abv ipc) (push abv ipc)))
ipc))
(use-file-dialog nil)
(alt-fn nil)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (lambda (c)
(unless (symbolp c) (setq c (intern-soft c)))
(commandp c)))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
(icicle-toggle-transforming-message "Filtering to commands bound to keys is now %s")
(icicle-last-transform-function (lambda (cands)
(with-current-buffer icicle-pre-minibuffer-buffer
(loop for cand in cands
for symb = (intern-soft cand)
if (and (symbolp symb)
(where-is-internal symb nil 'non-ascii))
collect cand))))
(icicle-transform-function nil)
(completion-annotate-function (lambda (cand)
(with-current-buffer icicle-pre-minibuffer-buffer
(and (setq cand (intern-soft cand)) (symbolp cand)
(let ((key (where-is-internal cand nil t)))
(and key
(format " %s" (icicle-key-description key)))))))))
(when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt))
nil (setq icicle-proxy-candidates ()))
(defun icicle-command-abbrev-action (abbrev-or-cmd)
"Action function for `icicle-command-abbrev'.
If ABBREV-OR-CMD is a command, call it.
If ABBREV-OR-CMD is an abbreviation for a single command, invoke it.
If ABBREV-OR-CMD is an abbreviation for multiple commands, call
`icicle-command-abbrev-command', to let user choose commands.
If ABBREV-OR-CMD is not an abbreviation or a command, raise an error."
(setq abbrev-or-cmd (intern abbrev-or-cmd))
(let* ((completion-annotate-function nil)
(icicle-add-proxy-candidates-flag icicle-add-proxy-candidates-flag)
(icicle-proxy-candidates icicle-proxy-candidates)
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred)
(icicle-candidate-alt-action-fn nil)
(icicle-all-candidates-list-alt-action-fn nil)
(not-cmdp (not (commandp abbrev-or-cmd)))
(regexp (and (or not-cmdp icicle-command-abbrev-priority-flag)
(icicle-command-abbrev-regexp abbrev-or-cmd)))
(icicle-commands-for-abbrev
(and (or not-cmdp icicle-command-abbrev-priority-flag)
(nconc (let ((result ()))
(dolist (abrv icicle-command-abbrev-alist)
(when (string= (symbol-name (cadr abrv)) (symbol-name abbrev-or-cmd))
(push (list (symbol-name (car abrv))) result)))
result)
(icicle-command-abbrev-matching-commands regexp)))))
(cond ((and not-cmdp (null icicle-commands-for-abbrev))
(error "No such command or abbreviation `%s'" abbrev-or-cmd))
(icicle-commands-for-abbrev
(let ((cmd (if (null (cdr icicle-commands-for-abbrev))
(prog1 (intern (caar icicle-commands-for-abbrev))
(push (caar icicle-commands-for-abbrev) extended-command-history)
(call-interactively (intern (caar icicle-commands-for-abbrev)) t))
(let ((enable-recursive-minibuffers t)
(icicle-current-input abbrev-or-cmd))
(icicle-remove-Completions-window)
(icicle-command-abbrev-command)))))
(icicle-command-abbrev-record abbrev-or-cmd cmd)))
((not not-cmdp) (call-interactively abbrev-or-cmd)))))
(defun icicle-command-abbrev-regexp (abbrev)
"Return the command-matching regexp for ABBREV."
(let ((char-list (append (symbol-name abbrev) ()))
(str "^"))
(dolist (c char-list) (setq str (concat str (list c) "[^-]*-")))
(concat (substring str 0 (1- (length str)))
(if icicle-command-abbrev-match-all-parts-flag "$" ".*$"))))
(defun icicle-command-abbrev-matching-commands (regexp)
"Return a completion alist of commands that match REGEXP."
(mapcar #'list (icicle-remove-if-not
`(lambda (strg) (string-match ',regexp strg))
(lexical-let ((cmds ()))
(mapatoms
(lambda (symb) (when (commandp symb) (push (symbol-name symb) cmds))))
cmds))))
(icicle-define-command icicle-command-abbrev-command
"Read command name, then read its arguments and call command."
icicle-execute-extended-command-1
(format "Command abbreviated%s%s: "
(cond ((and icicle-current-input (not (string= "" icicle-current-input)))
(format " `%s'" icicle-current-input))
(icicle-candidate-nb
(format " `%s'" (elt icicle-completion-candidates icicle-candidate-nb)))
(t ""))
(if current-prefix-arg
(format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
""))
icicle-commands-for-abbrev nil t nil 'extended-command-history nil nil
(
(use-file-dialog nil)
(alt-fn nil)
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
(icicle-add-proxy-candidates-flag nil)
(last-command last-command)
icicle-new-last-cmd)
nil nil
(setq this-command icicle-new-last-cmd)
'NON-INTERACTIVE)
(defun icicle-command-abbrev-record (abbrev command)
"Record ABBREV and COMMAND in `icicle-command-abbrev-alist'."
(let ((entry (assq command icicle-command-abbrev-alist)))
(when (and abbrev command)
(if entry
(setq icicle-command-abbrev-alist (cons (list command abbrev (1+ (car (cddr entry))))
(delete entry icicle-command-abbrev-alist)))
(push (list command abbrev 1) icicle-command-abbrev-alist)))))
(icicle-define-command icicle-execute-named-keyboard-macro
"Read the name of a keyboard macro, then execute it."
icicle-execute-extended-command-1
(format "Execute keyboard macro%s: "
(if current-prefix-arg
(format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
""))
obarray (and icompletep pred) t nil 'icicle-kmacro-history nil nil
((last-command last-command)
(alt-fn nil)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (lambda (fn)
(unless (symbolp fn) (setq fn (intern fn)))
(and (commandp fn) (arrayp (symbol-function fn)))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "command"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))))
(when (locate-library "kmacro")
(icicle-define-command icicle-kmacro
"Execute a keyboard macro according to its position in `kmacro-ring'.
Macros in the keyboard macro ring are given names `1', `2', and so on,
for use as completion candidates.
With prefix argument, repeat macro that many times (but see below).
If a macro is still being defined, end it first, then execute it.
Since this is a multi-command, you can execute any number of macros
any number of times in a single invocation. In particular, you can
execute a given macro repeatedly using `C-RET' (be sure you use `TAB'
first, to make it the current candidate).
If you use a prefix arg for `icicle-kmacro', then each multi-command
action (e.g. `C-RET') repeats the macro that number of times. However
if you use a prefix arg for an individual action, then the action
repeats the macro that number of times. Without its own prefix arg,
an action uses the base prefix arg you used for `icicle-kmacro'."
icicle-kmacro-action
(format "Execute keyboard macro%s: "
(if current-prefix-arg
(format " (prefix %s)" (prefix-numeric-value current-prefix-arg))
""))
(lexical-let ((count 0))
(setq icicle-kmacro-alist
(mapcar (lambda (x) (cons (format "%d" (setq count (1+ count))) x))
(reverse (if nil kmacro-ring (cons (kmacro-ring-head) kmacro-ring))))))
nil 'NO-EXIT-WO-MATCH nil 'icicle-kmacro-history
(and (kmacro-ring-head) (null kmacro-ring) "1") nil
((icicle-pref-arg current-prefix-arg))
(progn
(unless (require 'kmacro nil t) (icicle-user-error "You need library `kmacro.el' for this command"))
(when defining-kbd-macro (kmacro-end-or-call-macro current-prefix-arg) (icicle-user-error "Done"))
(unless (or (kmacro-ring-head) kmacro-ring) (icicle-user-error "No keyboard macro defined"))))
(defun icicle-kmacro-action (cand)
"Action function for `icicle-kmacro'."
(when (get-buffer icicle-orig-buff) (set-buffer icicle-orig-buff))
(when (window-live-p icicle-orig-window) (select-window icicle-orig-window))
(let* ((count (if current-prefix-arg (prefix-numeric-value current-prefix-arg) icicle-pref-arg))
(macro (cadr (assoc cand icicle-kmacro-alist))))
(unless macro (error "No such macro: `%s'" cand))
(execute-kbd-macro macro count #'kmacro-loop-setup-function)
(when (> count 1)
(message "(%s times)" (icicle-propertize count 'face 'icicle-msg-emphasis))))))
(icicle-define-command icicle-set-option-to-t
"Set option to t. This makes sense for binary (toggle) options.
By default, completion candidates are limited to user options that
have `boolean' custom types. However, there are many \"binary\" options
that allow other non-nil values than t.
You can use a prefix argument to change the set of completion
candidates, as follows:
- With a non-negative prefix arg, all user options are candidates.
- With a negative prefix arg, all variables are candidates."
(lambda (opt) (set (intern opt) t) (message "`%s' is now `t'" opt))
"Set option to t: " obarray (and icompletep pred) 'must-confirm nil
(if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
((enable-recursive-minibuffers t)
(icicle-use-candidates-only-once-flag t)
(alt-fn nil)
(pred
(cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
(lambda (x)
(unless (symbolp x) (setq x (intern x)))
(and (boundp x) (user-variable-p x) (eq nil (symbol-value x)))))
(current-prefix-arg
(lambda (x)
(unless (symbolp x) (setq x (intern x)))
(and (boundp x) (eq nil (symbol-value x)))))
(t
(lambda (x)
(unless (symbolp x) (setq x (intern x)))
(and (boundp x) (icicle-binary-option-p x) (eq nil (symbol-value x)))))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(icicle-define-command icicle-clear-history
"Clear a minibuffer history of selected entries.
You are prompted for the history to clear, then you are prompted for
the entries to delete from it. You can use multi-command completion
for both inputs. That is, you can act on multiple histories and
delete multiple entries from each.
For convenience, you can use \\<minibuffer-local-completion-map>\
`\\[icicle-delete-candidate-object]' the same way as `C-RET': Each
of them deletes the current entry candidate from the history.
With a prefix argument, empty the chosen history completely
\(you are not prompted to choose history entries to delete).
`icicle-act-before-cycle-flag' is bound to t here during completion of
history entries, so `C-next' and so on act on the current candidate."
icicle-clear-history-1
"History to clear: " icicle-clear-history-hist-vars
nil t nil nil (symbol-name minibuffer-history-variable) nil
((icicle-pref-arg current-prefix-arg)
(enable-recursive-minibuffers t)
(icicle-transform-function 'icicle-remove-duplicates)
(icicle-clear-history-hist-vars `((,(symbol-name minibuffer-history-variable))
(,(symbol-name 'icicle-previous-raw-file-name-inputs))
(,(symbol-name 'icicle-previous-raw-non-file-name-inputs))))
(icicle-delete-candidate-object 'icicle-clear-history-entry))
(mapatoms (lambda (x) (when (and (boundp x) (consp (symbol-value x))
(stringp (car (symbol-value x)))
(string-match "-\\(history\\|ring\\)\\'" (symbol-name x)))
(push (list (symbol-name x))
icicle-clear-history-hist-vars)))))
(defun icicle-clear-history-1 (hist)
"Action function for `icicle-clear-history' history-variable candidates."
(setq hist (intern hist))
(if (not icicle-pref-arg)
(let* ((icicle-candidate-action-fn 'icicle-clear-history-entry)
(icicle-transform-function 'icicle-remove-duplicates)
(icicle-clear-history-hist hist)
(icicle-use-candidates-only-once-flag t)
(icicle-show-Completions-initially-flag t)
(icicle-act-before-cycle-flag t))
(when hist
(funcall icicle-candidate-action-fn
(completing-read "Clear input: " (mapcar #'list (symbol-value hist)) nil t))))
(set hist nil))
(unless hist (message "History `%s' is now empty" hist))
nil)
(defun icicle-clear-history-entry (cand)
"Action function for history entry candidates in `icicle-clear-history'."
(unless (string= "" cand)
(set icicle-clear-history-hist
(icicle-remove-if
`(lambda (x)
(string= (icicle-substring-no-properties ',cand) (icicle-substring-no-properties x)))
(symbol-value icicle-clear-history-hist)))
(message "`%s' deleted from history `%s'" cand icicle-clear-history-hist))
nil)
(icicle-define-command icicle-clear-current-history
"Clear current minibuffer history of selected entries.
You are prompted for the history entries to delete.
With a prefix argument, however, empty the history completely
\(you are not prompted to choose history entries to delete).
`icicle-act-before-cycle-flag' is bound to t here during completion of
history entries, so `C-next' and so on act on the current candidate."
icicle-clear-history-entry
"Clear input: " (mapcar #'list (symbol-value icicle-clear-history-hist))
nil t nil nil nil nil
((icicle-pref-arg current-prefix-arg)
(enable-recursive-minibuffers t)
(icicle-transform-function 'icicle-remove-duplicates)
(icicle-use-candidates-only-once-flag t)
(icicle-show-Completions-initially-flag t)
(icicle-clear-history-hist minibuffer-history-variable))
(when icicle-pref-arg
(icicle-ding)
(if (not (yes-or-no-p (format "Are you sure you want to empty `%s' completely? "
minibuffer-history-variable)))
(icicle-user-error "")
(set minibuffer-history-variable nil)
(icicle-user-error "History `%s' is now empty" minibuffer-history-variable))))
(when (and icicle-define-alias-commands-flag (not (fboundp 'clear-option)))
(defalias 'clear-option 'icicle-reset-option-to-nil))
(icicle-define-command icicle-reset-option-to-nil
"Set option to nil. This makes sense for binary and list options.
By default, the set of completion candidates is limited to user
options. Note: it is *not* limited to binary and list options.
With a prefix arg, all variables are candidates."
(lambda (opt) (set (intern opt) nil) (message "`%s' is now `nil'" opt))
"Clear option (set it to nil): " obarray (and icompletep pred) t nil
(if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history)
nil nil
((enable-recursive-minibuffers t)
(icicle-use-candidates-only-once-flag t)
(alt-fn nil)
(pred (if current-prefix-arg
(lambda (x)
(unless (symbolp x) (setq x (intern x)))
(and (boundp x) (symbol-value x)))
(lambda (x)
(unless (symbolp x) (setq x (intern x)))
(and (boundp x) (user-variable-p x) (symbol-value x)))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(when (and icicle-define-alias-commands-flag (not (fboundp 'toggle)))
(defalias 'toggle 'icicle-toggle-option))
(icicle-define-command icicle-toggle-option
"Toggle option's value. This makes sense for binary (toggle) options.
By default, completion candidates are limited to user options that
have `boolean' custom types. However, there are many \"binary\" options
that allow other non-nil values than t.
You can use a prefix argument to change the set of completion
candidates, as follows:
- With a non-negative prefix arg, all user options are candidates.
- With a negative prefix arg, all variables are candidates."
(lambda (opt)
(let ((sym (intern opt)))
(set sym (not (eval sym)))
(message "`%s' is now `%s'" opt (icicle-propertize (eval sym) 'face 'icicle-msg-emphasis))))
"Toggle value of option: " obarray (and icompletep pred) 'must-confirm nil
(if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
((enable-recursive-minibuffers t)
(alt-fn nil)
(pred
(cond ((and current-prefix-arg (wholenump (prefix-numeric-value current-prefix-arg)))
(lambda (c) (unless (symbolp c) (setq c (intern c))) (user-variable-p c)))
(current-prefix-arg (lambda (c) (unless (symbolp c) (setq c (intern c))) (boundp c)))
(t (lambda (c)
(unless (symbolp c) (setq c (intern c))) (icicle-binary-option-p c)))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(defun icicle-binary-option-p (symbol)
"Non-nil if SYMBOL is a user option that has custom-type `boolean'."
(eq (icicle-get-safe symbol 'custom-type) 'boolean))
(icicle-define-command icicle-increment-option
"Increment option's value using the arrow keys (`up', `down').
Completion candidates are limited to options that have `integer',
`float', and `number' custom types.
This command needs library `doremi.el'."
(lambda (opt)
(let ((sym (intern opt))
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred))
(icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") t)
(message "`%s' is now `%s'" opt (icicle-propertize (eval sym) 'face 'icicle-msg-emphasis))))
"Increment value of option: " obarray (and icompletep pred) 'must-confirm nil
(if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
((enable-recursive-minibuffers t)
(alt-fn nil)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (lambda (symb)
(unless (symbolp symb) (setq symb (intern-soft symb)))
(memq (get symb 'custom-type) '(number integer float))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "option"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option"))))
(unless (require 'doremi nil t)
(icicle-user-error "You need library `doremi.el' for this command")))
(icicle-define-command icicle-increment-variable
"Increment variable's value using the arrow keys (`up', `down').
With a prefix arg, only numeric user options are candidates.
With no prefix arg, all variables are candidates, even those that are
not numeric.
This command needs library `doremi.el'."
(lambda (var)
(let ((sym (intern var))
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred))
(icicle-doremi-increment-variable+ sym (icicle-read-number "Increment (amount): ") prefix-arg)
(message "`%s' is now `%s'" var (icicle-propertize (eval sym) 'face 'icicle-msg-emphasis))))
"Increment value of variable: " obarray (and icompletep pred) 'must-confirm nil
(if (boundp 'variable-name-history) 'variable-name-history 'icicle-variable-name-history) nil nil
((enable-recursive-minibuffers t)
(prefix-arg current-prefix-arg)
(alt-fn nil)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (if prefix-arg
(lambda (symb)
(unless (symbolp symb) (setq symb (intern-soft symb)))
(memq (get symb 'custom-type) '(number integer float)))
(lambda (symb)
(unless (symbolp symb) (setq symb (intern symb)))
(boundp symb))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn
(icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
(unless (require 'doremi nil t)
(icicle-user-error "You need library `doremi.el' for this command")))
(defun icicle-doremi-increment-variable+ (variable &optional increment optionp)
"Increment VARIABLE by INCREMENT (default 1).
Use arrow key `up' or `down' or mouse wheel to increase or decrease.
You can use the `Meta' key (e.g. `M-up') to increment in larger steps.
Interactively, you can choose VARIABLE using completion.
With a prefix arg, only user options are available to choose from.
Raises an error if VARIABLE's value is not a number."
(interactive
(let* ((symb (or (and (fboundp 'symbol-nearest-point)
(symbol-nearest-point))
(and (symbolp (variable-at-point))
(variable-at-point))))
(enable-recursive-minibuffers t)
(icicle-orig-must-pass-after-match-pred icicle-must-pass-after-match-predicate)
(pred (if current-prefix-arg
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(user-variable-p s))
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(boundp s))))
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) pred)))
(list (intern (completing-read "Increment variable: " obarray (and icompletep pred) t nil nil
(and symb (symbol-name symb)) t))
(let ((icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred))
(icicle-read-number "Increment (amount): "))
current-prefix-arg)))
(unless (require 'doremi nil t) (icicle-user-error "You need library `doremi.el' for this command"))
(unless increment (setq increment 1))
(unless (numberp (symbol-value variable))
(icicle-user-error "Variable's value is not a number: %S" (symbol-value variable)))
(doremi (lambda (new-val)
(set variable new-val)
new-val)
(symbol-value variable)
increment))
(defun icicle-bookmark-cmd (&optional parg)
"Set bookmark or visit bookmark(s).
With a negative prefix arg, visit bookmark(s), using
`icicle-bookmark-other-window' (see that command for more info).
Otherwise, set a bookmark, as follows:
* No prefix arg: Prompt for the bookmark name.
If feature `bookmark+' is present:
. You can use (lax) completion for the bookmark name.
The candidates are bookmarks in the current buffer (or all
bookmarks if there are none in this buffer).
. You can narrow the current completion candidates to bookmarks of a
given type. The keys for this are the same as for
`icicle-bookmark' and for the bookmark-jumping keys at the top
level.
. See the `Bookmark+' doc string of redefined command `bookmark-set'
for info about the available default values for the bookmark name.
If feature `bookmark+' is not present, then completion is not
available, and the default bookmark name is the last one used in
the current buffer.
Note: You can use command `icicle-bookmark-set' with a numeric
prefix arg if you want to complete against all bookmark names,
instead of those for the current buffer.
* Plain prefix arg (`C-u'): Same as no prefix arg, but do not
overwrite any existing bookmark that has the same name.
* Non-negative numeric prefix arg: Do not prompt for bookmark name.
If feature `bookmark+' is present and the region is active and
nonempty, then use the buffer name followed by a prefix of the
region text as the bookmark name.
Otherwise, use the buffer name followed by the text of the current
line, starting at point.
Use at most `icicle-bookmark-name-length-max' chars, in either case.
If the prefix arg is 0, then do not overwrite any existing bookmark
that has the same name.
By default, Icicle mode remaps all key sequences that are normally
bound to `bookmark-set' to `icicle-bookmark-cmd'. If you do not want
this remapping, then customize option `icicle-top-level-key-bindings'.
In particular, you might prefer to remap `bookmark-set' to
`icicle-bookmark-set' (see Note, above)."
(interactive "P")
(if (and parg (< (prefix-numeric-value parg) 0))
(icicle-bookmark-other-window)
(if (or (not parg) (consp parg))
(icicle-bookmark-set nil parg 'PSEUDO-INTERACTIVEP)
(let* ((regionp (and (featurep 'bookmark+) transient-mark-mode mark-active
(not (eq (region-beginning) (region-end)))))
(name-beg (if regionp (region-beginning) (point)))
(name-end (if regionp (region-end) (line-end-position)))
(def-name (concat (buffer-name) ": " (buffer-substring name-beg name-end)))
(trim-name (replace-regexp-in-string
"\n" " " (substring def-name 0 (min icicle-bookmark-name-length-max
(length def-name))))))
(message "Setting bookmark `%s'" trim-name) (sit-for 2)
(bookmark-set trim-name (and parg (or (consp parg) (zerop (prefix-numeric-value parg)))))))))
(defun icicle-bookmark-set (&optional name parg interactivep)
"With `Bookmark+', this is `bookmark-set' with Icicles multi-completions.
In particular, you can use (lax) completion for the bookmark name.
Without `Bookmark+', this is the same as vanilla Emacs `bookmark-set'.
With `Bookmark+':
. You can use (lax) completion for the bookmark name.
The candidates are bookmarks in the current buffer (or all
bookmarks if there are none in this buffer).
. You can narrow the current completion candidates to bookmarks of a
given type. The keys for this are the same as for
`icicle-bookmark' and for the bookmark-jumping keys at the top
level.
. See the `Bookmark+' doc string of redefined command `bookmark-set'
for info about the available default values for the bookmark name.
If feature `bookmark+' is not present, then completion is not
available, and the default bookmark name is the last one used in
the current buffer.
Note: You can use command `icicle-bookmark-set' with a numeric
prefix arg if you want to complete against all bookmark names,
instead of those for the current buffer."
(interactive (list nil current-prefix-arg t))
(if (not (featurep 'bookmark+))
(bookmark-set name parg)
(unwind-protect
(let ((enable-recursive-minibuffers t)
(completion-ignore-case bookmark-completion-ignore-case)
(prompt "Bookmark: ")
(icicle-multi-completing-p icicle-show-multi-completion-flag)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-properties-alist (if (not icicle-show-multi-completion-flag)
()
(if (facep 'file-name-shadow)
'((2 (face file-name-shadow))
(3 (face bookmark-menu-heading)))
'((3 (face bookmark-menu-heading))))))
(icicle-transform-function (if (interactive-p) nil icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
(icicle-candidates-alist
(if (not (featurep 'bookmark+))
(mapcar (lambda (cand)
(list (icicle-candidate-short-help
(icicle-bookmark-help-string cand)
(icicle-bookmark-propertize-candidate cand))))
(bookmark-all-names))
(bookmark-maybe-load-default-file)
(mapcar #'icicle-make-bookmark-candidate
(bmkp-sort-omit
(and (or (not parg) (consp parg))
(or (bmkp-specific-buffers-alist-only) bookmark-alist))))))
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order")
("by bookmark name" . icicle-alpha-p))
(and (featurep 'bookmark+)
'(("by last bookmark access" (bmkp-bookmark-last-access-cp)
icicle-alpha-p)
("by bookmark visit frequency" (bmkp-visited-more-cp)
icicle-alpha-p)
("by last buffer or file access"
(bmkp-buffer-last-access-cp
bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
icicle-alpha-p)
("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
("by last local file access"
(bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("by last local file update"
(bmkp-local-file-updated-more-recently-cp)
icicle-alpha-p)
("by Info location" (bmkp-info-cp) icicle-alpha-p)
("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
("by URL" (bmkp-url-cp) icicle-alpha-p)
("by bookmark type"
(bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
bmkp-local-file-type-cp bmkp-handler-cp)
icicle-alpha-p)))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
(icicle-candidate-help-fn
(lambda (cand)
(when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
(setq cand (funcall icicle-get-alist-candidate-function cand))
(setq cand (cons (caar cand) (cdr cand))))
(if (featurep 'bookmark+)
(if current-prefix-arg
(bmkp-describe-bookmark-internals cand)
(bmkp-describe-bookmark cand))
(icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand))))))
(require 'bookmark)
(when (featurep 'bookmark+)
(dolist (map '(minibuffer-local-must-match-map minibuffer-local-completion-map))
(icicle-bookmark-bind-narrow-commands map)))
(setq bookmark-current-point (point)
bookmark-current-buffer (current-buffer))
(save-excursion (skip-chars-forward " ") (setq bookmark-yank-point (point)))
(let* ((record (bookmark-make-record))
(defname (or (and (stringp (car record)) (car record))
(cond ((eq major-mode 'w3m-mode) w3m-current-title)
((eq major-mode 'gnus-summary-mode)
(elt (gnus-summary-article-header) 1))
((memq major-mode '(Man-mode woman-mode))
(buffer-substring (point-min) (save-excursion
(goto-char (point-min))
(skip-syntax-forward "^ ")
(point))))
(t nil))))
(defname (and defname (bmkp-replace-regexp-in-string "\n" " " defname)))
(bname (or name (icicle-transform-multi-completion
(bmkp-completing-read-lax "Set bookmark "
(bmkp-new-bookmark-default-names defname)
icicle-candidates-alist
nil (if (boundp 'bookmark-history)
'bookmark-history
'icicle-bookmark-history))))))
(when (string-equal bname "") (setq bname defname))
(bookmark-store bname (cdr record) (consp parg))
(when (and interactivep bmkp-prompt-for-tags-flag)
(bmkp-add-tags bname (bmkp-read-tags-completing)))
(case (and (boundp 'bmkp-auto-light-when-set) bmkp-auto-light-when-set)
(autonamed-bookmark (when (bmkp-autonamed-bookmark-p bname)
(bmkp-light-bookmark bname)))
(non-autonamed-bookmark (unless (bmkp-autonamed-bookmark-p bname)
(bmkp-light-bookmark bname)))
(any-bookmark (bmkp-light-bookmark bname))
(autonamed-in-buffer (bmkp-light-bookmarks
(bmkp-remove-if-not
#'bmkp-autonamed-bookmark-p
(bmkp-this-buffer-alist-only)) nil interactivep))
(non-autonamed-in-buffer (bmkp-light-bookmarks
(bmkp-remove-if
#'bmkp-autonamed-bookmark-p
(bmkp-this-buffer-alist-only)) nil interactivep))
(all-in-buffer (bmkp-light-this-buffer nil interactivep)))
(if bmkp-autotemp-all-when-set-p
(bmkp-make-bookmark-temporary bname)
(catch 'icicle-bookmark-set
(dolist (pred bmkp-autotemp-bookmark-predicates)
(when (and (functionp pred) (funcall pred bname))
(bmkp-make-bookmark-temporary bname)
(throw 'icicle-bookmark-set t)))))
(run-hooks 'bmkp-after-set-hook)
(if bookmark-use-annotations
(bookmark-edit-annotation bname)
(goto-char bookmark-current-point)))
(setq bookmark-yank-point nil
bookmark-current-buffer nil))
(icicle-bookmark-cleanup))))
(defun icicle-make-bookmark-candidate (bookmark)
"Return a propertized full bookmark candidate for BOOKMARK.
BOOKMARK is a bookmark name or a bookmark record.
The return value is of the form (DISPLAY . RECORD), where:
DISPLAY is the display candidate, propertized with
`icicle-bookmark-help-string' and `icicle-bookmark-propertize-candidate'.
RECORD is the full BOOKMARK record.
If option `icicle-show-multi-completion-flag' is non-nil then DISPLAY
is a multi-completion with three parts:
bookmark name
target file for the bookmark
tags in the bookmark
If the option value is nil then DISPLAY is just the bookmark name."
(setq bookmark (bookmark-get-bookmark bookmark))
(icicle-condition-case-no-debug nil
(if icicle-show-multi-completion-flag
(let* ((bname (bookmark-name-from-full-record bookmark))
(guts (bookmark-get-bookmark-record bookmark))
(file (bookmark-get-filename bookmark))
(buf (bmkp-get-buffer-name bookmark))
(file/buf (if (and buf (equal file bmkp-non-file-filename))
buf
file))
(tags (bmkp-get-tags bookmark)))
(cons `(,(icicle-candidate-short-help
(icicle-bookmark-help-string bname)
(icicle-bookmark-propertize-candidate bname))
,file/buf
,@(and tags (list (format "%S" tags))))
guts))
(let ((bname (bookmark-name-from-full-record bookmark))
(guts (bookmark-get-bookmark-record bookmark)))
(cons (icicle-candidate-short-help
(icicle-bookmark-help-string bname)
(icicle-bookmark-propertize-candidate bname))
guts)))
(error nil)))
(icicle-define-command icicle-bookmark
"Jump to a bookmark.
With a plain prefix argument (`C-u'), reverse the effect of option
`icicle-bookmark-refresh-cache-flag'. See the doc for that option.
In particular, if the option value is nil and you try to jump to a
bookmark that is not up to date or does not exist, then try using a
prefix arg to refresh the cache.
During completion, you can use \\<minibuffer-local-completion-map>\
`\\[icicle-delete-candidate-object]' on a bookmark to delete it.
If you also use library `Bookmark+', then:
* `C-M-return' shows detailed info about the current bookmark candidate.
`C-u C-M-return' shows the complete, internal info for the bookmark.
Likewise, for the other candidate help keys: `C-M-down' etc.
(And the mode line always shows summary info about the bookmark.)
* You can use `C-,' to sort bookmarks in many different ways,
according to their properties.
* In `*Completions*', the candidate bookmarks are highlighted
according to their type. You can customize the highlighting faces:
`bmkp-bad-bookmark' - possibly bad bookmark
`bmkp-bookmark-list' - bookmark list
`bmkp-buffer' - buffer
`bmkp-desktop' - desktop
`bmkp-function' - function bookmark
`bmkp-gnus' - Gnus article
`bmkp-info' - Info node
`bmkp-local-directory' - local directory
`bmkp-local-file-with-region' - local file with a region
`bmkp-local-file-without-region' - local file without a region
`bmkp-man' - `man' page
`bmkp-non-file' - non-file (no current buffer)
`bmkp-remote-file' - remote-file
`bmkp-sequence' - sequence bookmark
`bmkp-url' - URL
* In `*Completions*', if option `icicle-show-multi-completion-flag'
is non-nil, then each completion candidate is a multi-completion:
a. the bookmark name
b. the bookmark file or buffer name
c. any tags
You can match any parts of the multi-completion. You can toggle
the option (for the next command) using `M-m' during completion.
For example, you can match all bookmarks that have tags by typing:
C-M-j . * C-M-j S-TAB
(Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string'.)
* You can narrow the current completion candidates to bookmarks of a
given type. The keys for this are the same as the bookmark-jumping
keys at the top level.
`C-x j a' - autofile bookmarks
`C-x j b' - non-file (buffer) bookmarks
`C-x j B' - bookmark-list bookmarks
`C-x j d' - Dired bookmarks
`C-x j f' - file bookmarks
`C-x j . f' - bookmarks to files in the current directory
`C-x j g' - Gnus bookmarks
`C-x j i' - Info bookmarks
`C-x j M-i' - image bookmarks
`C-x j K' - desktop bookmarks
`C-x j l' - local-file bookmarks
`C-x j m' - `man' pages
`C-x j n' - remote-file bookmarks
`C-x j r' - bookmarks with regions
`C-x j u' - URL bookmarks
`C-x j w' - W3M (URL) bookmarks
`C-x j x' - temporary bookmarks
`C-x j y' - bookmark-file bookmarks
`C-x j #' - autonamed bookmarks
`C-x j , #' - autonamed bookmarks for the current buffer
`C-x j , ,' - bookmarks for the current buffer
`C-x j = b' - bookmarks for specific buffers
`C-x j = f' - bookmarks for specific files
See also the individual multi-commands for different bookmark
types: `icicle-bookmark-info-other-window' etc.
If you also use library `crosshairs.el', then the visited bookmark
position is highlighted."
(lambda (cand) (icicle-bookmark-jump (icicle-transform-multi-completion cand)))
prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag)
nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
(and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
((enable-recursive-minibuffers t)
(completion-ignore-case bookmark-completion-ignore-case)
(prompt "Bookmark: ")
(icicle-multi-completing-p icicle-show-multi-completion-flag)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-properties-alist (if (not icicle-show-multi-completion-flag)
()
(if (facep 'file-name-shadow)
'((2 (face file-name-shadow))
(3 (face bookmark-menu-heading)))
'((3 (face bookmark-menu-heading))))))
(icicle-transform-function (if (interactive-p) nil icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
(icicle-delete-candidate-object 'icicle-bookmark-delete-action)
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order")
("by bookmark name" . icicle-alpha-p))
(and (featurep 'bookmark+)
'(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
("by last buffer or file access" (bmkp-buffer-last-access-cp
bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
icicle-alpha-p)
("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("by last local file update" (bmkp-local-file-updated-more-recently-cp)
icicle-alpha-p)
("by Info location" (bmkp-info-cp) icicle-alpha-p)
("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
("by URL" (bmkp-url-cp) icicle-alpha-p)
("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
bmkp-local-file-type-cp bmkp-handler-cp)
icicle-alpha-p)))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
(icicle-candidate-help-fn
(lambda (cand)
(when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
(setq cand (funcall icicle-get-alist-candidate-function cand)
cand (cons (caar cand) (cdr cand))))
(if (featurep 'bookmark+)
(if current-prefix-arg (bmkp-describe-bookmark-internals cand) (bmkp-describe-bookmark cand))
(icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
(icicle-candidates-alist
(if (not (featurep 'bookmark+))
(mapcar (lambda (cand)
(list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
(icicle-bookmark-propertize-candidate cand))))
(bookmark-all-names))
(bookmark-maybe-load-default-file)
(mapcar #'icicle-make-bookmark-candidate
(or (and (or (and (not icicle-bookmark-refresh-cache-flag)
(not (consp current-prefix-arg)))
(and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
bmkp-sorted-alist)
(setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist)))))))
(progn
(require 'bookmark)
(when (featurep 'bookmark+)
(dolist (map '(minibuffer-local-must-match-map minibuffer-local-completion-map))
(icicle-bookmark-bind-narrow-commands map))))
(icicle-bookmark-cleanup-on-quit)
(icicle-bookmark-cleanup))
(icicle-define-command icicle-bookmark-other-window
"Jump to a bookmark in another window.
Same as `icicle-bookmark', but uses another window."
(lambda (cand) (icicle-bookmark-jump-other-window (icicle-transform-multi-completion cand)))
prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag)
nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
(and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
((enable-recursive-minibuffers t)
(completion-ignore-case bookmark-completion-ignore-case)
(prompt "Bookmark: ")
(icicle-multi-completing-p icicle-show-multi-completion-flag)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-properties-alist (if (not icicle-show-multi-completion-flag)
()
(if (facep 'file-name-shadow)
'((2 (face file-name-shadow))
(3 (face bookmark-menu-heading)))
'((3 (face bookmark-menu-heading))))))
(icicle-transform-function (if (interactive-p) nil icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
(icicle-delete-candidate-object 'icicle-bookmark-delete-action)
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order")
("by bookmark name" . icicle-alpha-p))
(and (featurep 'bookmark+)
'(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p)
("by last buffer or file access" (bmkp-buffer-last-access-cp
bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
icicle-alpha-p)
("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)
("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
("by last local file access" (bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("by last local file update" (bmkp-local-file-updated-more-recently-cp)
icicle-alpha-p)
("by Info location" (bmkp-info-cp) icicle-alpha-p)
("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)
("by URL" (bmkp-url-cp) icicle-alpha-p)
("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
bmkp-local-file-type-cp bmkp-handler-cp)
icicle-alpha-p)))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
(icicle-candidate-help-fn
(lambda (cand)
(when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
(setq cand (funcall icicle-get-alist-candidate-function cand))
(setq cand (cons (caar cand) (cdr cand))))
(if (featurep 'bookmark+)
(if current-prefix-arg
(bmkp-describe-bookmark-internals cand)
(bmkp-describe-bookmark cand))
(icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand)))))
(icicle-candidates-alist
(if (not (featurep 'bookmark+))
(mapcar (lambda (cand)
(list (icicle-candidate-short-help (icicle-bookmark-help-string cand)
(icicle-bookmark-propertize-candidate cand))))
(bookmark-all-names))
(bookmark-maybe-load-default-file)
(mapcar #'icicle-make-bookmark-candidate
(or (and (or (and (not icicle-bookmark-refresh-cache-flag)
(not (consp current-prefix-arg)))
(and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
bmkp-sorted-alist)
(setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist)))))))
(progn
(require 'bookmark)
(when (featurep 'bookmark+)
(dolist (map '(minibuffer-local-must-match-map minibuffer-local-completion-map))
(icicle-bookmark-bind-narrow-commands map))))
(icicle-bookmark-cleanup-on-quit)
(icicle-bookmark-cleanup))
(defun icicle-bookmark-bind-narrow-commands (map)
"Bind keys to narrow bookmark candidates by type."
(when (featurep 'bookmark+)
(dolist (map '(minibuffer-local-must-match-map minibuffer-local-completion-map))
(define-key (symbol-value map) (icicle-kbd "C-x j #")
'icicle-bookmark-autonamed-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j , #")
'icicle-bookmark-autonamed-this-buffer-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j a")
'icicle-bookmark-autofile-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j b")
'icicle-bookmark-non-file-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j B")
'icicle-bookmark-bookmark-list-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j d")
'icicle-bookmark-dired-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j f")
'icicle-bookmark-file-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j . f")
'icicle-bookmark-file-this-dir-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j g")
'icicle-bookmark-gnus-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j i")
'icicle-bookmark-info-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j M-i")
'icicle-bookmark-image-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j K")
'icicle-bookmark-desktop-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j l")
'icicle-bookmark-local-file-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j m")
'icicle-bookmark-man-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j n")
'icicle-bookmark-remote-file-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j r")
'icicle-bookmark-region-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j u")
'icicle-bookmark-url-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j w")
'icicle-bookmark-w3m-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j x")
'icicle-bookmark-temporary-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j y")
'icicle-bookmark-bookmark-file-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j , ,")
'icicle-bookmark-this-buffer-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j = b")
'icicle-bookmark-specific-buffers-narrow)
(define-key (symbol-value map) (icicle-kbd "C-x j = f")
'icicle-bookmark-specific-files-narrow))))
(defun icicle-bookmark-delete-action (cand)
"Delete bookmark candidate CAND, then update `bmkp-sorted-alist'."
(bookmark-delete (icicle-transform-multi-completion cand))
(when (or (and (not icicle-bookmark-refresh-cache-flag)
(not (consp current-prefix-arg)))
(and icicle-bookmark-refresh-cache-flag (consp current-prefix-arg)))
(setq bmkp-sorted-alist (bmkp-sort-omit bookmark-alist))))
(defun icicle-bookmark-propertize-candidate (cand)
"Return bookmark name CAND, with a face indicating its type."
(when (featurep 'bookmark+)
(put-text-property
0 (length cand) 'face
(cond ((bmkp-sequence-bookmark-p cand) 'bmkp-sequence)
((bmkp-function-bookmark-p cand) 'bmkp-function)
((bmkp-bookmark-list-bookmark-p cand) 'bmkp-bookmark-list)
((bmkp-desktop-bookmark-p cand) 'bmkp-desktop)
((bmkp-info-bookmark-p cand) 'bmkp-info)
((bmkp-man-bookmark-p cand) 'bmkp-man)
((bmkp-gnus-bookmark-p cand) 'bmkp-gnus)
((bmkp-url-bookmark-p cand) 'bmkp-url)
((bmkp-remote-file-bookmark-p cand) 'bmkp-remote-file)
((and (bmkp-file-bookmark-p cand)
(file-directory-p
(bookmark-get-filename cand))) 'bmkp-local-directory)
((and (bmkp-local-file-bookmark-p cand)
(bmkp-region-bookmark-p cand)) 'bmkp-local-file-with-region)
((bmkp-local-file-bookmark-p cand) 'bmkp-local-file-without-region)
((and (bmkp-get-buffer-name cand)
(get-buffer (bmkp-get-buffer-name cand))
(equal (bookmark-get-filename cand)
bmkp-non-file-filename)) 'bmkp-buffer)
((not (bmkp-file-bookmark-p cand)) 'bmkp-non-file)
(t 'bmkp-bad-bookmark))
cand))
cand)
(defun icicle-bookmark-jump (bookmark)
"Jump to BOOKMARK.
If `crosshairs.el' is loaded, then highlight the target position.
You probably don't want to use this. Use `icicle-bookmark' instead."
(interactive (list (bookmark-completing-read "Jump to bookmark" bookmark-current-bookmark)))
(icicle-bookmark-jump-1 bookmark))
(defun icicle-bookmark-jump-other-window (bookmark)
"Jump to BOOKMARK in another window.
If `crosshairs.el' is loaded, then highlight the target position.
You probably don't want to use this. Use
`icicle-bookmark-other-window' instead."
(interactive (list (bookmark-completing-read "Jump to bookmark (other window)"
bookmark-current-bookmark)))
(icicle-bookmark-jump-1 bookmark 'other-window))
(defun icicle-bookmark-jump-1 (bookmark &optional other-window-p)
"Helper function for `icicle-bookmark-jump(-other-window)'."
(unless bookmark (error "No bookmark specified"))
(bookmark-maybe-historicize-string bookmark)
(setq bookmark (bookmark-get-bookmark bookmark 'NOERROR))
(if (fboundp 'bookmark--jump-via)
(bookmark--jump-via bookmark (if other-window-p 'pop-to-buffer 'switch-to-buffer))
(let ((cell (bookmark-jump-noselect bookmark)))
(when cell
(if other-window-p
(pop-to-buffer (car cell) 'other-window)
(switch-to-buffer (car cell)))
(goto-char (cdr cell))
(unless (pos-visible-in-window-p) (recenter icicle-recenter))
(progn (run-hooks 'bookmark-after-jump-hook) t)
(when bookmark-automatically-show-annotations (bookmark-show-annotation bookmark)))))
(unless (and (boundp 'bmkp-use-region) bmkp-use-region
(fboundp 'bmkp-get-end-position) (bmkp-get-end-position bookmark)
(/= (bookmark-get-position bookmark) (bmkp-get-end-position bookmark)))
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight))))
(defun icicle-bookmark-help-string (bookmark-name)
"Return a help string for BOOKMARK-NAME."
(let* ((bmk (bookmark-get-bookmark bookmark-name))
(buf (and (fboundp 'bmkp-get-buffer-name) (bmkp-get-buffer-name bmk)))
(file (bookmark-get-filename bookmark-name))
(start (bookmark-get-position bookmark-name))
(no-position-p (not start))
(end (and (fboundp 'bmkp-get-end-position) (bmkp-get-end-position bmk)))
(annot (bookmark-get-annotation bookmark-name))
(sequence-p (and (fboundp 'bmkp-sequence-bookmark-p)
(bmkp-sequence-bookmark-p bmk)))
(function-p (and (fboundp 'bmkp-function-bookmark-p)
(bmkp-function-bookmark-p bmk)))
(blist-p (and (fboundp 'bmkp-bookmark-list-bookmark-p)
(bmkp-bookmark-list-bookmark-p bmk)))
(desktop-p (and (fboundp 'bmkp-desktop-bookmark-p)
(bmkp-desktop-bookmark-p bmk)))
(dired-p (and (fboundp 'bmkp-dired-bookmark-p) (bmkp-dired-bookmark-p bmk)))
(gnus-p (and (fboundp 'bmkp-gnus-bookmark-p) (bmkp-gnus-bookmark-p bmk)))
(info-p (and (fboundp 'bmkp-info-bookmark-p) (bmkp-info-bookmark-p bmk)))
(man-p (and (fboundp 'bmkp-man-bookmark-p) (bmkp-man-bookmark-p bmk)))
(url-p (and (fboundp 'bmkp-url-bookmark-p) (bmkp-url-bookmark-p bmk)))
type-info-p)
(when (or sequence-p function-p) (setq no-position-p t))
(concat (setq type-info-p
(cond (sequence-p (format "Sequence: %S" (bookmark-prop-get bmk 'sequence)))
(function-p (let ((fn (bookmark-prop-get bmk 'function)))
(if (symbolp fn) (format "Function: `%s'" fn) "Function")))
(desktop-p "Desktop, ")
(dired-p (format "Dired %s, " file))
(gnus-p "Gnus, ")
(info-p "Info, ")
(man-p (let ((man-args (bookmark-prop-get bmk 'man-args)))
(if man-args
(format "`man %s', " man-args)
(format "%s, " (bookmark-prop-get bmk 'buffer-name)))))
(url-p "URL, ")
(t nil)))
(and (not dired-p)
(or (and file (or (not (boundp 'bmkp-non-file-filename))
(not (equal file bmkp-non-file-filename)))
(format (if type-info-p "file `%s', " "File `%s', ") file))
(and buf (format (if type-info-p "buffer `%s', " "Buffer `%s', ") buf))))
(and (not no-position-p)
(if (and end (> (- end start) 0))
(format "from %d to %d (%d chars)" start end (- end start))
(format "position %d" start)))
(and annot (format ", %s" annot)))))
(defun icicle-bookmark-cleanup ()
"Cleanup code for `icicle-bookmark'.
Remove crosshairs highlighting and unbind filtering keys."
(when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))
(when (featurep 'bookmark+)
(dolist (map '(minibuffer-local-must-match-map minibuffer-local-completion-map))
(define-key (symbol-value map) (icicle-kbd "C-M-b") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-B") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-d") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-f") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-F") nil)
(dolist (key icicle-read+insert-file-name-keys)
(define-key (symbol-value map) key 'icicle-read+insert-file-name))
(define-key (symbol-value map) (icicle-kbd "C-M-g") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-I") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-K") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-m") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-r") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-w") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-@") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-.")
'icicle-toggle-dot)
(define-key (symbol-value map) (icicle-kbd "C-M-= b") nil)
(define-key (symbol-value map) (icicle-kbd "C-M-= f") nil))))
(defun icicle-bookmark-cleanup-on-quit ()
"Do `icicle-bookmark-cleanup', then return to original window."
(icicle-bookmark-cleanup)
(when (window-live-p icicle-orig-window)
(select-window icicle-orig-window)
(select-frame-set-input-focus (selected-frame))))
(defun icicle-bookmark-autofile-narrow ()
"Narrow the bookmark candidates to autofile bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-autofile-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-autonamed-narrow ()
"Narrow the bookmark candidates to autonamed bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x)
(bmkp-autonamed-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-autonamed-this-buffer-narrow ()
"Narrow bookmark candidates to autonamed bookmarks in current buffer."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x)
(with-current-buffer icicle-orig-buff
(bmkp-autonamed-this-buffer-bookmark-p (icicle-transform-multi-completion (car x))))))))
(defun icicle-bookmark-bookmark-file-narrow ()
"Narrow the bookmark candidates to bookmark-file bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-bookmark-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-bookmark-list-narrow ()
"Narrow the bookmark candidates to bookmark-list bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-bookmark-list-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-desktop-narrow ()
"Narrow the bookmark candidates to desktop bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-desktop-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-dired-narrow ()
"Narrow the bookmark candidates to Dired bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-dired-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-file-narrow ()
"Narrow the bookmark candidates to file bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-file-this-dir-narrow ()
"Narrow the bookmark candidates to bookmarked files in `default-directory'."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-file-this-dir-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-gnus-narrow ()
"Narrow the bookmark candidates to Gnus bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-gnus-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-image-narrow ()
"Narrow the bookmark candidates to image bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-image-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-info-narrow ()
"Narrow the bookmark candidates to Info bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-info-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-local-file-narrow ()
"Narrow the bookmark candidates to local-file bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-local-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-man-narrow ()
"Narrow the bookmark candidates to `man'-page bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-man-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-non-file-narrow ()
"Narrow the bookmark candidates to non-file (buffer-only) bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-non-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-region-narrow ()
"Narrow the bookmark candidates to bookmarks with regions."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-region-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-remote-file-narrow ()
"Narrow the bookmark candidates to remote-file bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-remote-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-specific-buffers-narrow (buffers)
"Narrow the bookmark candidates to bookmarks for specific BUFFERS.
You are prompted for the BUFFERS."
(interactive (let ((icicle-completion-candidates icicle-completion-candidates))
(list (icicle-bookmarked-buffer-list))))
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
`(lambda (x)
(member (bmkp-get-buffer-name (icicle-transform-multi-completion (car x))) ',buffers)))))
(defun icicle-bookmark-specific-files-narrow (files)
"Narrow the bookmark candidates to bookmarks for specific FILES.
You are prompted for the FILES."
(interactive (list (icicle-bookmarked-file-list)))
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
`(lambda (x)
(member (bookmark-get-filename (icicle-transform-multi-completion (car x))) ',files)))))
(defun icicle-bookmark-temporary-narrow ()
"Narrow the bookmark candidates to temporary bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-temporary-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-this-buffer-narrow ()
"Narrow the bookmark candidates to bookmarks for the current buffer."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x)
(with-current-buffer icicle-orig-buff
(bmkp-this-buffer-p (icicle-transform-multi-completion (car x))))))))
(defun icicle-bookmark-url-narrow ()
"Narrow the bookmark candidates to URL bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-url-bookmark-p (icicle-transform-multi-completion (car x)))))))
(defun icicle-bookmark-w3m-narrow ()
"Narrow the bookmark candidates to W3M (URL) bookmarks."
(interactive)
(when (featurep 'bookmark+)
(icicle-narrow-candidates-with-predicate
(lambda (x) (bmkp-w3m-bookmark-p (icicle-transform-multi-completion (car x)))))))
(icicle-define-bookmark-command "this-buffer")
(icicle-define-bookmark-other-window-command "this-buffer")
(icicle-define-bookmark-command "specific-buffers" nil
(icicle-bookmarked-buffer-list))
(icicle-define-bookmark-other-window-command "specific-buffers" nil
(icicle-bookmarked-buffer-list))
(icicle-define-bookmark-command "specific-files" nil
(icicle-bookmarked-file-list))
(icicle-define-bookmark-other-window-command "specific-files" nil
(icicle-bookmarked-file-list))
(icicle-define-bookmark-command "autofile")
(icicle-define-bookmark-other-window-command "autofile")
(icicle-define-bookmark-command "autofile-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "autofile-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "autofile-all-tags-regexp" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "autofile-all-tags-regexp" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "autofile-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "autofile-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "autofile-some-tags-regexp" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "autofile-some-tags-regexp" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "autonamed")
(icicle-define-bookmark-other-window-command "autonamed")
(icicle-define-bookmark-command "autonamed-this-buffer")
(icicle-define-bookmark-other-window-command "autonamed-this-buffer")
(icicle-define-bookmark-command "non-file")
(icicle-define-bookmark-other-window-command "non-file")
(icicle-define-bookmark-command "bookmark-list")
(icicle-define-bookmark-command "dired")
(icicle-define-bookmark-other-window-command "dired")
(icicle-define-bookmark-command "file")
(icicle-define-bookmark-other-window-command "file")
(icicle-define-bookmark-command "file-this-dir")
(icicle-define-bookmark-other-window-command "file-this-dir")
(icicle-define-bookmark-command "gnus")
(icicle-define-bookmark-other-window-command "gnus")
(icicle-define-bookmark-command "image")
(icicle-define-bookmark-other-window-command "image")
(icicle-define-bookmark-command "info")
(icicle-define-bookmark-other-window-command "info")
(icicle-define-bookmark-command "desktop")
(icicle-define-bookmark-command "local-file")
(icicle-define-bookmark-other-window-command "local-file")
(icicle-define-bookmark-command "man")
(icicle-define-bookmark-other-window-command "man")
(icicle-define-bookmark-command "remote-file")
(icicle-define-bookmark-other-window-command "remote-file")
(icicle-define-bookmark-command "region" "Select region: ")
(icicle-define-bookmark-other-window-command "region" "Select region: ")
(icicle-define-bookmark-command "all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "file-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "file-some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "file-this-dir-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-this-dir-all-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-this-dir-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-this-dir-some-tags" nil
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-this-dir-all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-this-dir-all-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "file-this-dir-some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-this-dir-some-tags-regexp" nil
(read-string "Regexp for tags: "))
(icicle-define-bookmark-command "url")
(icicle-define-bookmark-other-window-command "url")
(icicle-define-bookmark-command "w3m")
(icicle-define-bookmark-other-window-command "w3m")
(icicle-define-bookmark-command "temporary")
(icicle-define-bookmark-other-window-command "temporary")
(icicle-define-bookmark-command "bookmark-file")
(defalias 'icicle-select-bookmarked-region 'icicle-bookmark-region-other-window)
(defun icicle-bookmarked-buffer-list ()
"`icicle-buffer-list', but only for bookmarked buffers."
(interactive)
(let ((icicle-buffer-predicate (lambda (buf) (member buf (bmkp-buffer-names))))
(icicle-prompt "Choose bookmarked buffer (`RET' when done): "))
(icicle-buffer-list)))
(defun icicle-bookmarked-file-list ()
"`icicle-file-list', but only for bookmarked files."
(interactive)
(bookmark-maybe-load-default-file)
(let ((use-file-dialog nil)
(icicle-file-predicate (lambda (file) (member (expand-file-name file) (bmkp-file-names))))
(icicle-prompt "Choose bookmarked file (`RET' when done): "))
(icicle-file-list)))
(icicle-define-command icicle-find-first-tag
"Find first tag in current tags table whose name matches your input.
This is similar to standard command `find-tag', with these
differences:
* This is a multi-command, so you can visit any number of tags.
* Only the first tag of several identical tags is a candidate, so you
cannot visit the others. That is, there is no equivalent to using
`M-,' (`tags-loop-continue') after `find-tag' to find additional,
identical tags.
* If `crosshairs.el' is loaded, the target position is highlighted.
To browse all tags (including duplicates) in all tags tables, use the
more powerful Icicles multi-command `icicle-find-tag'.
By default, Icicle mode remaps all key sequences that are normally
bound to `find-tag-other-window' to `icicle-find-first-tag'. If you
do not want this remapping, then customize option
`icicle-top-level-key-bindings'."
icicle-find-first-tag-action
"Find tag: "
(if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
'find-tag-default))
nil
((completion-ignore-case (progn (require 'etags)
(if (and (boundp 'tags-case-fold-search)
(memq tags-case-fold-search '(t nil)))
tags-case-fold-search
case-fold-search)))
(case-fold-search completion-ignore-case))
nil nil
(when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch)))
(defun icicle-find-first-tag-action (cand)
"Action function for `icicle-find-first-tag'."
(find-tag cand)
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
(icicle-define-command icicle-find-first-tag-other-window
"Find first tag in current tags table whose name matches your input.
Same as `icicle-find-first-tag' except it uses a different window."
icicle-find-first-tag-other-window-action
"Find tag other window: "
(if (fboundp 'tags-lazy-completion-table) (tags-lazy-completion-table) 'tags-complete-tag)
nil nil nil nil (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function)
'find-tag-default))
nil
((completion-ignore-case (progn (require 'etags)
(if (and (boundp 'tags-case-fold-search)
(memq tags-case-fold-search '(t nil)))
tags-case-fold-search
case-fold-search)))
(case-fold-search completion-ignore-case))
nil nil
(when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch)))
(defun icicle-find-first-tag-other-window-action (cand)
"Action function for `icicle-find-first-tag-other-window'."
(find-tag-other-window cand)
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight)))
(defun icicle-find-tag (regexp &optional arg)
"Navigate among all tags that match REGEXP.
You are prompted for the REGEXP to match. Enter REGEXP with `RET'.
You can use completion to choose a tag in the current tags table as
REGEXP. You can use `\\[icicle-pop-tag-mark]' to return to your starting point.
All matching tags are shown, including duplicate tags from the same or
different source files. This means that you do not need `M-,' - you
see all tags as candidates to visit.
By default:
* Tags from all tags files are candidates.
* In `*Completions*', the source file name is shown after each tag.
A prefix argument changes this default behavior, as follows:
* ARG = 0 or ARG > 0: only the current tag table is used
* ARG = 0 or ARG < 0: source file names are not shown
By default, Icicle mode remaps all key sequences that are normally
bound to `find-tag' to `icicle-find-tag'. If you do not want this
remapping, then customize option `icicle-top-level-key-bindings'.
If `crosshairs.el' is loaded, then the target position is highlighted."
(interactive
(let* ((completion-ignore-case (if (and (boundp 'tags-case-fold-search)
(memq tags-case-fold-search '(t nil)))
tags-case-fold-search
case-fold-search))
(case-fold-search completion-ignore-case))
(require 'etags)
(list (completing-read "Find tag matching regexp: "
(if (fboundp 'tags-lazy-completion-table)
(tags-lazy-completion-table)
'tags-complete-tag)
nil nil nil 'find-tag-history
(funcall (or find-tag-default-function
(get major-mode 'find-tag-default-function)
'find-tag-default)))
current-prefix-arg)))
(unwind-protect
(let* ((icicle-whole-candidate-as-text-prop-p t)
(icicle-sort-comparer nil)
(icicle-inhibit-sort-p t)
(icicle-candidate-action-fn 'icicle-find-tag-action)
(icicle-candidate-help-fn 'icicle-find-tag-help)
(completion-ignore-case (if (and (boundp 'tags-case-fold-search)
(memq tags-case-fold-search '(t nil)))
tags-case-fold-search
case-fold-search))
(case-fold-search completion-ignore-case)
(orig-pt-find-tag (point-marker)))
(ring-insert find-tag-marker-ring orig-pt-find-tag)
(icicle-explore `(lambda () (icicle-find-tag-define-candidates ',regexp ',arg))
#'icicle-find-tag-final-act #'icicle-find-tag-quit-or-error
#'icicle-find-tag-quit-or-error nil
"Choose a tag: " nil nil nil 'find-tag-history))
(when (fboundp 'crosshairs-unhighlight) (crosshairs-unhighlight 'even-if-frame-switch))))
(defun icicle-pop-tag-mark ()
"Like `pop-tag-mark', but uses `pop-to-buffer', not `switch-to-buffer'.
By default, Icicle mode remaps all key sequences that are normally
bound to `pop-tag-mark' to `icicle-pop-tag-mark'. If you do not want
this remapping, then customize option
`icicle-top-level-key-bindings'."
(interactive)
(require 'etags)
(when (ring-empty-p find-tag-marker-ring) (error "No previous locations for find-tag invocation"))
(let ((marker (ring-remove find-tag-marker-ring 0)))
(pop-to-buffer (or (marker-buffer marker) (error "The marked buffer has been deleted")))
(goto-char (marker-position marker))
(unless (pos-visible-in-window-p) (recenter icicle-recenter))
(set-marker marker nil nil)))
(defun icicle-find-tag-define-candidates (regexp arg)
"Define candidates for `icicle-find-tag'.
See `icicle-explore', argument DEFINE-CANDIDATES-FN."
(save-excursion
(let ((first-time t)
(morep t))
(setq icicle-candidates-alist ())
(while (and morep (visit-tags-table-buffer (not first-time)))
(when (and arg (wholenump (prefix-numeric-value arg))) (setq morep nil))
(setq first-time nil
icicle-candidates-alist (append icicle-candidates-alist
(nreverse (icicle-find-tag-define-candidates-1
regexp (> (prefix-numeric-value arg) 0)))))))))
(defun icicle-find-tag-define-candidates-1 (regexp show-file-p)
"Helper function for `icicle-find-tag-define-candidates'.
Returns completion alist of tag information for tags matching REGEXP.
Include file name (label) if SHOW-FILE-P is non-nil.
If SHOW-FILE-P is nil, then alist items look like this:
(TAG TAG-INFO FILE-PATH GOTO-FUNC)
If SHOW-FILE-P is non-nil, then alist items look like this:
((TAG FILE-LABEL) TAG-INFO FILE-PATH GOTO-FUNC) or
(FILE-LABEL TAG-INFO FILE-PATH GOTO-FUNC) if no matching TAG.
TAG-INFO is what `snarf-tag-function' (e.g. `etags-snarf-tag')
returns. It is a cons (TEXT LINE . POSITION).
TEXT is the initial part of a line containing the tag.
LINE is the line number.
POSITION is the (one-based) char position of TEXT within the file.
If TEXT is t, it means the tag refers to exactly LINE or POSITION,
whichever is present, LINE having preference, no searching.
Either LINE or POSITION can be nil. POSITION is used if present."
(icicle-highlight-lighter)
(message "Gathering tags for `%s'..." regexp)
(goto-char (point-min))
(let ((temp-list ()))
(while (re-search-forward (concat regexp ".*\177*") nil t)
(beginning-of-line)
(let* ((goto-func goto-tag-location-function)
(tag-info (save-excursion (funcall snarf-tag-function)))
(tag (if (eq t (car tag-info)) nil (car tag-info)))
(file-path (save-excursion
(if tag (file-of-tag) (save-excursion (next-line 1) (file-of-tag)))))
(file-label (expand-file-name file-path (file-truename default-directory))))
(when (and tag (not (string= "" tag)) (= (aref tag 0) ?\( ))
(setq tag (concat tag " ...)")))
(when (file-readable-p file-path)
(cond (tag
(push `(,(if show-file-p
(list tag
(progn (put-text-property 0 (length file-label) 'face
'icicle-candidate-part file-label)
file-label))
tag)
,tag-info ,file-path ,goto-func)
temp-list))
(show-file-p
(push `((,(progn (put-text-property 0 (length file-label) 'face
'icicle-candidate-part file-label)
file-label))
,tag-info ,file-path ,goto-func)
temp-list)))))
(forward-line))
temp-list))
(defun icicle-find-tag-action (ignored-string)
"Action function for `icicle-find-tag'."
(let* ((cand (cdr (elt (icicle-filter-alist icicle-candidates-alist icicle-completion-candidates)
icicle-candidate-nb)))
(tag-info (nth 0 cand))
(goto-func (nth 2 cand)))
(switch-to-buffer-other-window
(if (fboundp 'tag-find-file-of-tag-noselect)
(tag-find-file-of-tag-noselect (nth 1 cand))
(find-file-noselect (nth 1 cand))))
(widen)
(icicle-condition-case-no-debug err
(funcall goto-func tag-info)
(error (message "%s" (error-message-string err)) (sit-for 2) nil)))
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame)))
(defun icicle-find-tag-help (cand)
"Use as `icicle-candidate-help-fn' for `icicle-find-tag'."
(let* ((cand (cdr (elt (icicle-filter-alist icicle-candidates-alist icicle-completion-candidates)
icicle-candidate-nb)))
(tag-info (nth 0 cand)))
(message (if (eq t (car tag-info))
"No tag - file name itself matches"
(format "Line: %s, Position: %s, File: %s"
(icicle-propertize (cadr tag-info) 'face 'icicle-msg-emphasis)
(icicle-propertize (cddr tag-info) 'face 'icicle-msg-emphasis)
(icicle-propertize (nth 1 cand) 'face 'icicle-msg-emphasis))))
(sit-for 4)))
(defun icicle-find-tag-final-act ()
"Go to the final tag choice."
(let ((cand (cdr icicle-explore-final-choice-full)))
(unless cand (error "No such occurrence: %s" cand))
(switch-to-buffer-other-window
(if (fboundp 'tag-find-file-of-tag-noselect)
(tag-find-file-of-tag-noselect (nth 1 cand))
(find-file-noselect (nth 1 cand))))
(widen)
(funcall (nth 2 cand) (nth 0 cand))))
(defun icicle-find-tag-quit-or-error ()
"Pop back to the last tag visited."
(icicle-pop-tag-mark)
(raise-frame))
(defun icicle-other-window-or-frame (arg)
"Select a window or frame, by name or by order.
This command combines Emacs commands `other-window' and `other-frame',
together with Icicles multi-commands `icicle-select-window', and
`icicle-select-frame'. Use the prefix argument to choose, as follows:
With no prefix arg or a non-zero numeric prefix arg:
If the selected frame has multiple windows, then this is
`other-window'. Otherwise, it is `other-frame'.
With a zero prefix arg (e.g. `C-0'):
If the selected frame has multiple windows, then this is
`icicle-select-window' with windows in the frame as candidates.
Otherwise (single-window frame), this is `icicle-select-frame'.
With plain `C-u':
If the selected frame has multiple windows, then this is
`icicle-select-window' with windows from all visible frames as
candidates. Otherwise, this is `icicle-select-frame'.
If you use library `oneonone.el' with a standalone minibuffer frame,
and if option `1on1-remap-other-frame-command-flag' is non-nil, then
frame selection can include the standalone minibuffer frame.
By default, Icicle mode remaps all key sequences that are normally
bound to `other-window' to `icicle-other-window-or-frame'. If you do
not want this remapping, then customize option
`icicle-top-level-key-bindings'."
(interactive "P")
(let ((numarg (prefix-numeric-value arg)))
(cond ((consp arg)
(if (one-window-p) (icicle-select-frame) (icicle-select-window)))
((zerop numarg)
(if (one-window-p)
(icicle-select-frame)
(let ((current-prefix-arg nil)) (icicle-select-window))))
(t
(if (one-window-p)
(if (and (fboundp '1on1-other-frame)
1on1-minibuffer-frame
1on1-remap-other-frame-command-flag)
(1on1-other-frame numarg)
(other-frame numarg))
(other-window numarg))))))
(icicle-define-command icicle-select-frame
"Select frame by its name and raise it.
A frame name in this context is suffixed as needed by [NUMBER], to
make it unique. For example, in a context where frames are named for
their buffers and you have two frames showing buffer *Help*, one of
the frames will be called `*Help*[2]' for use with this command."
icicle-select-frame-by-name
"Select frame: "
icicle-frame-alist nil t nil
(if (boundp 'frame-name-history) 'frame-name-history 'icicle-frame-name-history)
(cdr (assq 'name (frame-parameters (next-frame (selected-frame))))) nil
((icicle-frame-alist (icicle-make-frame-alist))
(alt-fn nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "frame"))))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "frame")))))
(defun icicle-select-frame-by-name (name &optional frame-alist)
"Select the frame named NAME, and raise it.
Optional argument FRAME-ALIST is an alist of frames to choose from.
Each element has the form (FNAME . FRAME), where FNAME names FRAME.
See `icicle-make-frame-alist' for more about FNAME."
(interactive (let* ((alist (icicle-make-frame-alist))
(default (car (rassoc (selected-frame) alist)))
(input (completing-read "Select Frame: " alist nil t nil
'frame-name-history default)))
(list (if (= (length input) 0) default input)
alist)))
(unless frame-alist (setq frame-alist (or (and (boundp 'icicle-frame-alist) icicle-frame-alist)
(icicle-make-frame-alist))))
(let ((frame (cdr (assoc name frame-alist))))
(unless frame (icicle-user-error "No such frame: `%s'" name))
(make-frame-visible frame)
(select-frame-set-input-focus frame)))
(defun icicle-make-frame-alist ()
"Return an alist of entries (FNAME . FRAME), where FNAME names FRAME.
Frame parameter `name' is used as FNAME, unless there is more than one
frame with the same name. In that case, FNAME includes a suffix
\[NUMBER], to make it a unique name. The NUMBER order among frame
names that differ only by their [NUMBER] is arbitrary."
(let ((fr-alist ())
(count 2)
fname new-name)
(dolist (fr (frame-list))
(setq fname (frame-parameter fr 'name))
(if (not (assoc fname fr-alist))
(push (cons fname fr) fr-alist)
(setq new-name fname)
(while (assoc new-name fr-alist)
(setq new-name (format "%s[%d]" fname count)
count (1+ count)))
(push (cons new-name fr) fr-alist))
(setq count 2))
fr-alist))
(icicle-define-command icicle-select-window
"Select window by its name.
With no prefix arg, candidate windows are those of the selected frame.
With a prefix arg, windows of all visible frames are candidates.
A window name is the name of its displayed buffer, but suffixed as
needed by [NUMBER], to make the name unique. For example, if you have
two windows showing buffer *Help*, one of the windows will be called
`*Help*[2]' for use with this command."
icicle-select-window-by-name
"Select window: " icicle-window-alist nil t nil nil
(buffer-name (window-buffer (other-window 1))) nil
((icicle-window-alist (icicle-make-window-alist current-prefix-arg))))
(defun icicle-select-window-by-name (name &optional window-alist)
"Select the window named NAME.
Optional argument WINDOW-ALIST is an alist of windows to choose from.
Interactively:
A prefix arg means windows from all visible frames are candidates.
No prefix arg means windows from the selected frame are candidates.
Each alist element has the form (WNAME . WINDOW), where WNAME names
WINDOW. See `icicle-make-window-alist' for more about WNAME.
If `crosshairs.el' is loaded, then the target position is highlighted."
(interactive (let* ((alist (icicle-make-window-alist current-prefix-arg))
(default (car (rassoc (selected-window) alist)))
(input (completing-read "Select Window: " alist nil t nil nil default)))
(list (if (= (length input) 0) default input) alist)))
(unless window-alist
(setq window-alist (or (and (boundp 'icicle-window-alist) icicle-window-alist)
(icicle-make-window-alist))))
(let ((window (cdr (assoc name window-alist))))
(unless window (icicle-user-error "No such window: `%s'" name))
(select-window window)
(when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
(select-frame-set-input-focus (selected-frame))))
(defun icicle-make-window-alist (&optional all-p)
"Return an alist of entries (WNAME . WINDOW), where WNAME names WINDOW.
The name of the buffer in a window is used as its name, unless there
is more than one window displaying the same buffer. In that case,
WNAME includes a suffix [NUMBER], to make it a unique name. The
NUMBER order among window names that differ only by their [NUMBER] is
arbitrary.
Non-nil argument ALL-P means use windows from all visible frames.
Otherwise, use only windows from the selected frame."
(lexical-let ((win-alist ())
(count 2)
wname new-name)
(walk-windows (lambda (w)
(setq wname (buffer-name (window-buffer w)))
(if (not (assoc wname win-alist))
(push (cons wname w) win-alist)
(setq new-name wname)
(while (assoc new-name win-alist)
(setq new-name (format "%s[%d]" wname count)
count (1+ count)))
(push (cons new-name w) win-alist))
(setq count 2))
'no-mini
(if all-p 'visible 'this-frame))
win-alist))
(icicle-define-command icicle-delete-windows
"Delete windows showing a buffer, anywhere."
delete-windows-on
"Delete windows on buffer: "
(let ((cand-bufs ()))
(dolist (buf (buffer-list))
(when (get-buffer-window buf 0) (push (list (buffer-name buf)) cand-bufs)))
cand-bufs)
nil t nil 'buffer-name-history (buffer-name (current-buffer)) nil
((icicle-use-candidates-only-once-flag t)
(icicle-inhibit-try-switch-buffer t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))))
(defun icicle-delete-window (bufferp)
"`delete-window' or prompt for buffer and delete all its windows.
When called from the minibuffer, remove the `*Completions*' window.
Otherwise:
With no prefix argument, delete the selected window.
With a prefix argument, prompt for a buffer and delete all windows,
on any frame, that show that buffer.
With a prefix argument, this is an Icicles multi-command - see
command `icicle-mode'. Input-candidate completion and cycling are
available. While cycling, these keys with prefix `C-' are active\\<minibuffer-local-completion-map>:
`C-RET' - Act on current completion candidate only
`C-down' - Move to next completion candidate and act
`C-up' - Move to previous completion candidate and act
`C-next' - Move to next apropos-completion candidate and act
`C-prior' - Move to previous apropos-completion candidate and act
`C-end' - Move to next prefix-completion candidate and act
`C-home' - Move to previous prefix-completion candidate and act
`\\[icicle-all-candidates-action]' - Act on *all* candidates (or all that are saved),
successively (careful!)
With prefix `C-M-' instead of `C-', the same keys (`C-M-mouse-2',
`C-M-return', `C-M-down', and so on) provide help about candidates.
Use `mouse-2', `RET', or `S-RET' to finally choose a candidate,
or `C-g' to quit.
By default, Icicle mode remaps all key sequences that are normally
bound to `delete-window' to `icicle-delete-window'. If you do not
want this remapping, then customize option
`icicle-top-level-key-bindings'."
(interactive "P")
(if (window-minibuffer-p (selected-window))
(icicle-remove-Completions-window)
(if bufferp (icicle-delete-windows) (delete-window))))
(icicle-define-command icicle-kill-buffer
"Kill a buffer.
See `icicle-buffer' for more information, including about buffer-name
completion candidates, default values, and additional key bindings.
By default, Icicle mode remaps all key sequences that are normally
bound to `kill-buffer' to `icicle-kill-buffer'. If you do not want
this remapping, then customize option
`icicle-top-level-key-bindings'."
icicle-kill-a-buffer-and-update-completions
(icicle-buffer-name-prompt "Kill")
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (if (< emacs-major-version 23)
(buffer-name (current-buffer))
(cons (buffer-name (current-buffer))
(icicle-default-buffer-names current-prefix-arg)))
nil
(icicle-buffer-bindings)
(icicle-bind-buffer-candidate-keys)
nil
(icicle-unbind-buffer-candidate-keys))
(defun icicle-buffer-name-prompt (action &optional other-window-p)
"Return prompt for buffer-name completion.
ACTION is the command action, a string. It starts the prompt.
Non-nil OTHER-WINDOW-P appends \" in other window\" to the prompt."
(concat (cond ((null current-prefix-arg)
(format "%s buffer" action))
((and (consp current-prefix-arg) (> (prefix-numeric-value current-prefix-arg) 16))
(format "%s invisible buffer" action))
((and (consp current-prefix-arg) (> (prefix-numeric-value current-prefix-arg) 4))
(format "%s visible buffer" action))
((and (consp current-prefix-arg) (fboundp 'derived-mode-p))
(format "%s buffer with same or ancestor mode" action))
((zerop (prefix-numeric-value current-prefix-arg))
(format "%s buffer with same mode" action))
((< (prefix-numeric-value current-prefix-arg) 0)
(format "%s buffer for same frame" action))
(t
(format "%s file buffer" action)))
(and other-window-p " in other window")
": "))
(defun icicle-kill-a-buffer-and-update-completions (buf)
"Kill buffer BUF and update the set of completions."
(setq buf (get-buffer buf))
(if buf
(icicle-condition-case-no-debug err
(if (not (buffer-live-p buf))
(message "Buffer already deleted: `%s'" buf)
(if (fboundp 'kill-buffer-and-its-windows)
(kill-buffer-and-its-windows buf)
(kill-buffer buf))
(setq minibuffer-completion-table (mapcar (lambda (buf) (list (buffer-name buf))) (buffer-list)))
(icicle-complete-again-update))
(error nil))
(message "No such live buffer: `%s'" buf)))
(put 'icicle-buffer 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-buffer
"Switch to a different buffer, whose content contains a regexp match.
By default, Icicle mode remaps all key sequences that are normally
bound to `switch-to-buffer' to `icicle-buffer'. If you do not want
this remapping, then customize option `icicle-top-level-key-bindings'.
Completion candidates are two-part multi-completions, with the second
part optional. If both parts are present they are separated by
`icicle-list-join-string' (\"^G^J\", by default).
The first part is matched as a regexp against a buffer name.
The second part is matched as a regexp against buffer content.
Candidates that do not match are filtered out.
When matching buffer content, Icicles just looks for a single match.
Visiting the buffer does not move to that match or to any other match.
Matching is used only to filter candidate buffers.
However, if your input includes a content-matching part and it
matches, that part is automatically added to the Isearch regexp
history, `regexp-search-ring' whenever you hit `S-TAB' to complete.
This means that when you visit the buffer you can immediately search
for matches using `C-M-s' or `C-M-r'.
Your minibuffer input can match a buffer name or buffer content, or
both. Use \\<minibuffer-local-completion-map>`C-M-j' (equivalent here to `C-q C-g C-j') to input the
default separator.
For example:
To match `foo' against buffer names, use input `foo'.
To match `bar' against buffer contents, use input `C-M-j bar'.
To match both, use input `foo C-M-j bar'.
Only the matching buffer names are shown in `*Completions*', and only
the chosen buffer name is returned. The actual content matches are
unimportant anyway: content matching is used only to filter
candidates.
This is a buffer-switching command. If you instead want to navigate
to text searched for in buffers then use `icicle-search'.
The buffer-name portion of completion candidates is as follows,
depending on the prefix arg:
* No prefix arg: all buffers
* Numeric arg > 0: buffers visiting files or directories (Dired)
* Numeric arg < 0: buffers associated with the selected frame
* Numeric arg = 0: buffers with the same mode as the current buffer
* Plain prefix arg (`C-u'): buffers with the same mode as current,
or with a mode that the current mode is derived from
* Double plain (`C-u C-u'): visible buffers (possibly iconified)
* Triple plain (`C-u C-u C-u'): invisible buffers
Those are the default prefix-argument behaviors, but you can change
them using option `icicle-buffer-prefix-arg-filtering'.
For Emacs 23 and later, the default values (via `M-n') are the
\(buffer-name components of the) first four completion candidates
\(respecting the prefix argument).
You can use these additional keys during completion:
* `C-x F' Toggle including cached file names as candidates (option
`icicle-buffer-include-cached-files-nflag').
* `C-x R' Toggle including recent file names as candidates (option
`icicle-buffer-include-recent-files-nflag').
* `C-x m' Visit a bookmarked buffer (only if you use Bookmark+).
* `C-x M -' Remove buffers in a given mode. Repeatable.
* `C-x M +' Keep only buffers in a given mode.
* `C-x C-m -' Remove candidate buffers whose mode is derived from a
given mode. Repeatable. (`C-m' = `RET'.)
* `C-x C-m +' Keep only buffers in a mode derived from a given mode.
* `C-x v -' Remove buffers that are visible (maybe iconified).
* `C-x v +' Keep only buffers that are visible (maybe iconified).
* `\\[icicle-delete-candidate-object]' Kill the buffer named by a completion candidate.
Those are default key bindings, but you can change them using option
`icicle-buffer-candidate-key-bindings'.
These options, when non-nil, control candidate matching and filtering:
`icicle-buffer-extras' - Extra buffers to display
`icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
`icicle-buffer-include-cached-files-nflag' - Include cached files
`icicle-buffer-include-recent-files-nflag' - Include recent files
`icicle-buffer-match-regexp' - Regexp that buffers must match
`icicle-buffer-no-match-regexp' - Regexp buffers must not match
`icicle-buffer-predicate' - Predicate buffer names satisfy
`icicle-buffer-sort' - Sort function for candidates
`icicle-buffer-skip-hook' - Exclude from content searching
`icicle-find-file-of-content-skip-hook' - Same, cached/recent files
For example, to change the default behavior to show only buffers that
are associated with files, set `icicle-buffer-predicate' to this:
(lambda (buf) (buffer-file-name buf))
Option `icicle-buffer-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-buffers-ido-like' non-nil gives this command a more
Ido-like behavior.
See also command `icicle-buffer-no-search', which is `icicle-buffer'
without the multi-completion behavior that searches buffer content.
See also command `icicle-buffer-config', which lets you choose a
configuration of user options for commands such as `icicle-buffer'.
Note: The prefix arg is tested, even when this is called
noninteractively. Lisp code can bind `current-prefix-arg' to control
the behavior."
(lambda (buf)
(when (and (not (get-buffer buf)) (member buf icicle-buffer-easy-files))
(setq buf (find-file-noselect buf)))
(switch-to-buffer buf))
prompt 'icicle-buffer-multi-complete nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
(icicle-buffer-bindings
((prompt (icicle-buffer-name-prompt "Switch to"))
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-help-fn 'icicle-buffer-cand-help)
(icicle-buffer-easy-files ()))
((icicle-buffer-complete-fn 'icicle-buffer-multi-complete)
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-buffer-apropos-complete-match)
(icicle-bufflist (setq icicle-bufflist
(delete icicle-orig-buff icicle-bufflist)))))
(progn (icicle-bind-buffer-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Matching buffer contents..."))
nil
(icicle-unbind-buffer-candidate-keys))
(defun icicle-default-buffer-names (&optional arg)
"Default buffer names (Emacs 23+) or name (< Emacs 23).
For Emacs 23+, up to six names are returned.
Optional ARG is used only for Emacs 23+. Its meaning is the same as
the prefix argument in Icicles buffer commands, except that it
determines which kinds of buffers to include as default values, not as
completion candidates:
* nil : all buffers, and the first default is `other-buffer'
* Number > 0: buffers visiting files or directories (Dired)
* Number < 0: buffers associated with the selected frame
* Number = 0: buffers with the same mode as the current buffer
* (4) : buffers with the same mode as current, or with
a mode that the current mode is derived from
* (16) : visible buffers
* (64) : invisible buffers
In any case, the current buffer is always excluded."
(if (< emacs-major-version 23)
(let ((bname (buffer-name (if (fboundp 'another-buffer)
(another-buffer nil t)
(other-buffer (current-buffer))))))
(if (and icicle-bufflist (not (member bname icicle-bufflist)))
(car icicle-bufflist)
bname))
(let ((bfnames (mapcar #'buffer-name (delete (current-buffer) (or icicle-bufflist (buffer-list))))))
(when icicle-buffer-ignore-space-prefix-flag
(setq bfnames (icicle-remove-if (lambda (bfname) (icicle-string-match-p "^ " bfname)) bfnames)))
(let ((six (icicle-first-N 6 bfnames)))
(if arg six (let ((other (buffer-name (other-buffer (current-buffer)))))
(cons other (delete other six))))))))
(defun icicle-buffer-cand-help (cand)
"Help function for multi-completion buffer-name candidate CAND."
(setq cand (icicle-transform-multi-completion cand))
(when (and (bufferp (get-buffer cand))
(with-current-buffer cand
(if (fboundp 'describe-buffer) (describe-buffer) (describe-mode)) t))))
(put 'icicle-buffer-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-buffer-other-window
"Switch to a buffer whose content matches a regexp, in another window.
Same as `icicle-buffer' except it uses a different window."
(lambda (buf)
(when (and (not (get-buffer buf)) (member buf icicle-buffer-easy-files))
(setq buf (find-file-noselect buf)))
(switch-to-buffer-other-window buf))
prompt 'icicle-buffer-multi-complete nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
(icicle-buffer-bindings
((prompt (icicle-buffer-name-prompt "Switch to" 'OTHER-WIN))
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-help-fn 'icicle-buffer-cand-help)
(icicle-buffer-easy-files ()))
((icicle-buffer-complete-fn 'icicle-buffer-multi-complete)
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-buffer-apropos-complete-match)
(icicle-bufflist (setq icicle-bufflist
(delete icicle-orig-buff icicle-bufflist)))))
(progn (icicle-bind-buffer-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Matching buffer contents..."))
nil
(icicle-unbind-buffer-candidate-keys))
(defun icicle-buffer-multi-complete (strg pred completion-mode)
"Completion function for `icicle-buffer'.
Used as the value of `icicle-buffer-complete-fn' and hence as
`minibuffer-completion-table'."
(setq strg icicle-current-input)
(lexical-let* ((name-pat (let ((icicle-list-use-nth-parts '(1)))
(icicle-transform-multi-completion strg)))
(name-pat (if (memq icicle-current-completion-mode '(nil apropos))
name-pat
(concat "^" name-pat)))
(content-pat (let ((icicle-list-use-nth-parts '(2)))
(icicle-transform-multi-completion strg)))
(bufs (mapcar (lambda (buf) (buffer-name buf)) icicle-bufflist))
(bufs (if icicle-buffer-ignore-space-prefix-flag
(icicle-remove-if (lambda (buf) (icicle-string-match-p "^ " buf)) bufs)
bufs))
(bufs (icicle-remove-if (lambda (buf)
(or (not (icicle-string-match-p name-pat buf))
(run-hook-with-args-until-success
'icicle-buffer-skip-hook buf)))
bufs))
(bufs (cond ((equal "" content-pat)
(dolist (buf bufs)
(when (and (boundp 'existing-bufs) (boundp 'new-bufs--to-kill)
(not (memq (setq buf (get-buffer buf)) existing-bufs)))
(add-to-list 'new-bufs--to-kill buf)))
bufs)
(t
(icicle-remove-if-not
(lambda (buf)
(let ((found (with-current-buffer buf
(save-excursion
(goto-char (point-min))
(re-search-forward content-pat nil t)))))
(when (and (boundp 'existing-bufs) (boundp 'new-bufs--to-kill)
(not (memq (setq buf (get-buffer buf)) existing-bufs)))
(add-to-list 'new-bufs--to-kill buf))
(when (and found
(or (icicle-get-safe this-command
'icicle-apropos-completing-command)
(icicle-get-safe this-command
'icicle-cycling-command)
(memq this-command
'(icicle-retrieve-next-input
icicle-retrieve-previous-input))))
(isearch-update-ring content-pat 'REGEXP))
found))
bufs))))
(filnames (and (> icicle-buffer-include-recent-files-nflag 0)
(require 'recentf nil t)
(or recentf-list (recentf-load-list))
(icicle-recent-files-without-buffers bufs)))
(filnames (append filnames (and (> icicle-buffer-include-cached-files-nflag 0)
(icicle-cached-files-without-buffers bufs))))
(filnames (icicle-remove-if (lambda (fil)
(or (not (icicle-string-match-p name-pat fil))
(run-hook-with-args-until-success
'icicle-find-file-of-content-skip-hook fil)))
filnames))
(filnames (if (equal "" content-pat)
filnames
(icicle-remove-if-not
(lambda (filname)
(and (or find-file-run-dired (not (file-directory-p filname)))
(let* ((buf (find-file-noselect filname))
(found (with-current-buffer buf
(message "Matching buffer contents...")
(save-excursion
(goto-char (point-min))
(re-search-forward content-pat nil t)))))
(when (and (boundp 'existing-bufs) (boundp 'new-bufs--to-kill)
(not (memq buf existing-bufs)))
(add-to-list 'new-bufs--to-kill buf))
(when (and found
(or (icicle-get-safe this-command
'icicle-apropos-completing-command)
(icicle-get-safe this-command
'icicle-cycling-command)
(memq this-command
'(icicle-retrieve-next-input
icicle-retrieve-previous-input))))
(isearch-update-ring content-pat 'REGEXP))
found)))
filnames))))
(setq bufs (append bufs (setq icicle-buffer-easy-files filnames)))
(cond ((and (eq 'metadata completion-mode) (> emacs-major-version 23))
'(metadata (category . buffer)))
(completion-mode
bufs)
(t
(try-completion
strg (mapcar #'list bufs) (and pred (lambda (ss) (funcall pred ss))))))))
(defun icicle-buffer-apropos-complete-match (input buffer)
"Match function for progressive completion with `icicle-buffer'.
Return non-nil if the current multi-completion INPUT matches BUFFER.
BUFFER is a buffer name."
(lexical-let* ((name-pat (let ((icicle-list-use-nth-parts '(1)))
(icicle-transform-multi-completion input)))
(content-pat (let ((icicle-list-use-nth-parts '(2)))
(icicle-transform-multi-completion input))))
(and (icicle-string-match-p name-pat buffer)
(or (equal "" content-pat)
(let ((found (with-current-buffer buffer
(save-excursion (goto-char (point-min))
(re-search-forward content-pat nil t)))))
(when (and found
(or (icicle-get-safe this-command 'icicle-apropos-completing-command)
(icicle-get-safe this-command 'icicle-cycling-command)
(memq this-command '(icicle-retrieve-next-input
icicle-retrieve-previous-input))))
(isearch-update-ring content-pat 'REGEXP))
found)))))
(defun icicle-cached-files-without-buffers (buffers)
"Return absolute file-name list represented by `file-cache-alist'.
Do not include any files that are already visited in BUFFERS, which is
a list of buffer names. Return only the first
`icicle-buffer-include-cached-files-nflag' names."
(and (boundp 'file-cache-alist)
file-cache-alist
(catch 'icicle-cached-files-without-buffers
(let ((result ())
(buf-files (mapcar #'buffer-file-name (mapcar #'get-buffer buffers)))
file)
(dolist (file+dirs file-cache-alist)
(setq file (car file+dirs))
(dolist (dir (cdr file+dirs))
(setq file (concat (or dir default-directory) file))
(unless (member file buf-files) (push file result))
(when (>= (length result) icicle-buffer-include-cached-files-nflag)
(throw 'icicle-cached-files-without-buffers result))))
result))))
(defun icicle-recent-files-without-buffers (buffers)
"Return absolute file-name list represented by `recentf-list'.
Do not include any files that are already visited in BUFFERS, which is
a list of buffer names. Return only the first
`icicle-buffer-include-recent-files-nflag' names."
(and (boundp 'recentf-list)
recentf-list
(catch 'icicle-recent-files-without-buffers
(let ((result ())
(buf-files (mapcar #'buffer-file-name (mapcar #'get-buffer buffers)))
file)
(dolist (file recentf-list)
(unless (member file buf-files) (push file result))
(when (>= (length result) icicle-buffer-include-recent-files-nflag)
(throw 'icicle-recent-files-without-buffers result)))
result))))
(put 'icicle-buffer-no-search 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-buffer-no-search
"Switch to a different buffer.
This is like command `icicle-buffer', but without the possibility of
searching buffer contents. That is, completion candidates are just
buffer names, not multi-completions - they contain no buffer-content
part."
switch-to-buffer
(icicle-buffer-name-prompt "Switch to")
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
(icicle-buffer-bindings
()
((icicle-bufflist (setq icicle-bufflist (delete icicle-orig-buff icicle-bufflist)))))
(icicle-bind-buffer-candidate-keys)
nil
(icicle-unbind-buffer-candidate-keys))
(put 'icicle-buffer-no-search-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-buffer-no-search-other-window
"Switch to a different buffer in another window.
Same as `icicle-buffer' except it uses a different window."
switch-to-buffer-other-window
(icicle-buffer-name-prompt "Switch to" 'OTHER-WIN)
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
(icicle-buffer-bindings
()
((icicle-bufflist (setq icicle-bufflist (delete icicle-orig-buff icicle-bufflist)))))
(icicle-bind-buffer-candidate-keys)
nil
(icicle-unbind-buffer-candidate-keys))
(icicle-define-command icicle-visit-marked-file-of-content
"Visit a marked file whose content matches a regexp.
The marked files are examined, and those whose file names and/or
contents match your multi-completion input are available as candidate
buffers to visit. This command is like `icicle-buffer' and
`icicle-find-file-of-content' - see those commands for more
information. You must be in Dired mode to use this command.
When this command is finished, any unused buffers that were created
for content matching are killed, if option
`icicle-kill-visited-buffers-flag' is non-nil. But a prefix argument
flips the behavior specified by that option."
(lambda (buf)
(push (switch-to-buffer (icicle-transform-multi-completion buf))
new-bufs--to-keep))
prompt 'icicle-buffer-multi-complete nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names) nil
(icicle-buffer-bindings
((prompt (icicle-buffer-name-prompt "Visit file"))
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(init-pref-arg current-prefix-arg)
(existing-bufs (buffer-list))
(new-bufs--to-kill ())
(new-bufs--to-keep ())
(icicle-candidate-help-fn 'icicle-buffer-cand-help))
((icicle-buffer-complete-fn 'icicle-buffer-multi-complete)
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-buffer-apropos-complete-match)
(icicle-bufflist (save-excursion
(let* ((files (dired-get-marked-files
nil nil
(lambda (file) (not (file-directory-p file)))))
(bufs ()))
(dolist (file files) (push (find-file-noselect file) bufs))
bufs)))))
(progn (unless (eq major-mode 'dired-mode) (icicle-user-error "Use this command only in Dired mode"))
(icicle-bind-buffer-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Matching file contents..."))
nil
(progn (icicle-unbind-buffer-candidate-keys)
(when (or (and init-pref-arg (not icicle-kill-visited-buffers-flag))
(and (not init-pref-arg) icicle-kill-visited-buffers-flag))
(dolist (buf new-bufs--to-kill)
(unless (memq buf new-bufs--to-keep) (kill-buffer buf))))))
(icicle-define-command icicle-visit-marked-file-of-content-other-window
"Visit a marked file whose content matches a regexp, in another window.
Same as `icicle-visit-marked-file-of-content' except it uses a
different window. You must be in Dired to use this command."
(lambda (buf)
(push (switch-to-buffer-other-window (icicle-transform-multi-completion buf))
new-bufs--to-keep))
prompt 'icicle-buffer-multi-complete nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names) nil
(icicle-buffer-bindings
((prompt (icicle-buffer-name-prompt "Visit file" 'OTHER-WIN))
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(init-pref-arg current-prefix-arg)
(existing-bufs (buffer-list))
(new-bufs--to-kill ())
(new-bufs--to-keep ())
(icicle-candidate-help-fn 'icicle-buffer-cand-help))
((icicle-buffer-complete-fn 'icicle-buffer-multi-complete)
(icicle-apropos-complete-match-fn nil)
(icicle-last-apropos-complete-match-fn 'icicle-buffer-apropos-complete-match)
(icicle-bufflist (save-excursion
(let* ((files (dired-get-marked-files
nil nil
(lambda (file) (not (file-directory-p file)))))
(bufs ()))
(dolist (file files) (push (find-file-noselect file) bufs))
bufs)))))
(progn (unless (eq major-mode 'dired-mode) (icicle-user-error "Use this command only in Dired mode"))
(icicle-bind-buffer-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)
(message "Matching file contents..."))
nil
(progn (icicle-unbind-buffer-candidate-keys)
(when (or (and init-pref-arg (not icicle-kill-visited-buffers-flag))
(and (not init-pref-arg) icicle-kill-visited-buffers-flag))
(dolist (buf new-bufs--to-kill)
(unless (memq buf new-bufs--to-keep) (kill-buffer buf))))))
(icicle-define-command icicle-insert-buffer
"Multi-command version of `insert-buffer'.
See `icicle-buffer' for more information, including about buffer-name
completion candidates, default values, and additional key bindings."
insert-buffer
(icicle-buffer-name-prompt "Insert")
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
(icicle-buffer-bindings)
(icicle-bind-buffer-candidate-keys)
nil
(icicle-unbind-buffer-candidate-keys))
(icicle-define-command icicle-add-buffer-candidate
"Add buffer as an always-show completion candidate.
Add the buffer to `icicle-buffer-extras'. Save the updated option.
See `icicle-buffer' for more information, including about buffer-name
completion candidates, default values, and additional key bindings."
(lambda (buf)
(add-to-list 'icicle-buffer-extras buf)
(funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
(message "Buffer `%s' added to always-show buffers"
(icicle-propertize buf 'face 'icicle-msg-emphasis)))
(icicle-buffer-name-prompt "Show always")
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history (if (< emacs-major-version 23)
(buffer-name (current-buffer))
(cons (buffer-name (current-buffer))
(icicle-default-buffer-names current-prefix-arg)))
nil
(icicle-buffer-bindings
((icicle-delete-candidate-object 'icicle-remove-buffer-candidate-action)
(icicle-use-candidates-only-once-flag t)))
(icicle-bind-buffer-candidate-keys)
nil
(icicle-unbind-buffer-candidate-keys))
(icicle-define-command icicle-remove-buffer-candidate
"Remove buffer as an always-show completion candidate.
Remove the buffer from `icicle-buffer-extras'.
Save the updated option."
icicle-remove-buffer-candidate-action
"Remove buffer from always-show list: "
(mapcar #'list icicle-buffer-extras) nil t nil 'buffer-name-history (car icicle-buffer-extras) nil
((icicle-use-candidates-only-once-flag t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer"))))
(unless icicle-buffer-extras (icicle-user-error "`icicle-extra-buffers' is empty")))
(defun icicle-remove-buffer-candidate-action (buf)
"Action function for command `icicle-remove-buffer-candidate'."
(setq icicle-buffer-extras (delete buf icicle-buffer-extras))
(funcall icicle-customize-save-variable-function 'icicle-buffer-extras icicle-buffer-extras)
(message "Buffer `%s' removed from always-show buffers"
(icicle-propertize buf 'face 'icicle-msg-emphasis)))
(icicle-define-command icicle-buffer-config
"Choose a configuration of user options for `icicle-buffer'.
You can use \\<minibuffer-local-completion-map>\
`\\[icicle-delete-candidate-object]' on any configuration during completion to
remove it. See user option `icicle-buffer-configs'.
See also commands `icicle-add-buffer-config' and
`icicle-remove-buffer-config'."
(lambda (config-name)
(let ((config (assoc config-name icicle-buffer-configs)))
(setq icicle-buffer-match-regexp (elt config 1)
icicle-buffer-no-match-regexp (elt config 2)
icicle-buffer-predicate (elt config 3)
icicle-buffer-extras (elt config 4)
icicle-buffer-sort (elt config 5))))
"Configuration: " icicle-buffer-configs nil t nil
'icicle-buffer-config-history nil nil
((icicle-delete-candidate-object 'icicle-remove-buffer-config-action)))
(icicle-define-add-to-alist-command icicle-add-buffer-config
"Add buffer configuration to `icicle-buffer-configs'.
You are prompted for the buffer configuration components.
For the list of extra buffers to always display, you can choose them
using `C-mouse-2', `C-RET', and so on, just as you would make any
Icicles multiple choice."
(lambda ()
(let ((name (read-from-minibuffer "Add buffer configuration. Name: "))
(match-regexp (icicle-read-from-minibuf-nil-default
"Regexp to match: " nil nil nil 'regexp-history
icicle-buffer-match-regexp))
(nomatch-regexp (icicle-read-from-minibuf-nil-default
"Regexp not to match: " nil nil nil 'regexp-history
icicle-buffer-no-match-regexp))
(pred (icicle-read-from-minibuf-nil-default
"Predicate to satify: " nil nil nil
(if (boundp 'function-name-history)
'function-name-history
'icicle-function-name-history)
icicle-buffer-predicate))
(sort-fn (icicle-read-from-minibuf-nil-default
"Sort function: " nil nil t
(if (boundp 'function-name-history)
'function-name-history
'icicle-function-name-history)
(and icicle-buffer-sort (symbol-name icicle-buffer-sort))))
(extras (let ((icicle-prompt "Choose extra buffers to show (`RET' when done): "))
(icicle-buffer-list))))
(list name match-regexp nomatch-regexp pred extras sort-fn)))
icicle-buffer-configs)
(icicle-define-command icicle-remove-buffer-config
"Remove buffer configuration from `icicle-buffer-configs'.
Save the updated option."
icicle-remove-buffer-config-action
"Remove buffer configuration: "
(mapcar (lambda (config) (list (car config))) icicle-buffer-configs)
nil t nil 'icicle-buffer-config-history (caar icicle-buffer-configs) nil
((icicle-use-candidates-only-once-flag t)))
(defun icicle-remove-buffer-config-action (config-name)
"Action function for command `icicle-remove-buffer-config'."
(setq icicle-buffer-configs (icicle-assoc-delete-all config-name icicle-buffer-configs))
(funcall icicle-customize-save-variable-function 'icicle-buffer-configs icicle-buffer-configs)
(message "Buffer configuration `%s' removed"
(icicle-propertize config-name 'face 'icicle-msg-emphasis)))
(icicle-define-command icicle-color-theme
"Change color theme.
You can use \\<minibuffer-local-completion-map>\
`\\[icicle-delete-candidate-object]' during completion to remove the current
candidate from the list of color themes.
If you use `C-g' during this command, the previous color-theme
snapshot is used to restore that color theme.
Remember too that you can use the pseudo-theme [Reset] to restore the
last theme: `M-x color-theme-select [Reset]'.
By default, each time you invoke this command, a snapshot is first
made of the current color theme (or current colors, if no theme is
used). Thus, by default, if you use `C-g', the colors restored are
those used before you changed themes using this command.
However, if you use a prefix arg, then this command takes no new
snapshot, unless no snapshot has ever been taken during this Emacs
session. This can be useful when experimenting, to restore not to the
state just before this command invocation, but to some previous
snapshot.
To use this command, you must have loaded library `color-theme.el',
available from http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme."
(lambda (theme)
(when (string= "" theme) (icicle-user-error "No theme name entered (empty input)"))
(funcall (intern theme)))
"Theme: " icicle-color-themes nil t nil
(if (boundp 'color-theme-history) 'color-theme-history 'icicle-color-theme-history)
nil nil
((icicle-delete-candidate-object 'icicle-color-themes)
(prefix-arg current-prefix-arg))
(progn (unless (prog1 (require 'color-theme nil t)
(when (and (fboundp 'color-theme-initialize) (not color-theme-initialized))
(icicle-condition-case-no-debug nil
(let ((color-theme-load-all-themes t))
(color-theme-initialize)
(setq color-theme-initialized t))
(error nil))))
(icicle-user-error "You need library `color-theme.el' for this command"))
(unless icicle-color-themes
(setq icicle-color-themes
(delete '("bury-buffer")
(mapcar (lambda (entry) (list (symbol-name (car entry))))
color-themes))))
(when (or (not prefix-arg)
(not (assq 'color-theme-snapshot color-themes))
(not (commandp 'color-theme-snapshot)))
(fset 'color-theme-snapshot (color-theme-make-snapshot))
(setq color-themes (delq (assq 'color-theme-snapshot color-themes) color-themes)
color-themes (delq (assq 'bury-buffer color-themes) color-themes)
color-themes (append '((color-theme-snapshot
"[Reset]" "Undo changes, if possible.")
(bury-buffer "[Quit]" "Bury this buffer."))
color-themes))))
(color-theme-snapshot))
(put 'icicle-yank-pop-commands 'delete-selection 'yank)
(defun icicle-yank-pop-commands (&optional arg)
"`yank-pop', `yank-pop-secondary', or `icicle-completing-yank'.
Which of these is used depends on the previous command, as follows:
* If the previous command was a yank-secondary command, then
`yank-pop-secondary'.
* Else if the previous command was a yank command (i.e. using the
kill ring), then `yank-pop'.
* Else `icicle-completing-yank'.
In the last case (`icicle-completing-yank'), during completion you can
use:
* \\<minibuffer-local-completion-map>`\\[icicle-change-sort-order]' to sort the \
candidates to yank in different ways (repeat)
* `\\[icicle-delete-candidate-object]' to remove a candidate entry from the selection ring
* `\\[icicle-candidate-alt-action]' to copy a candidate to the other selection ring
You need library `second-sel.el' for this command."
(interactive "p")
(unless (featurep 'second-sel) (icicle-user-error "You need library `second-sel.el' for this command"))
(when (fboundp 'browse-kill-ring)
(condition-case nil
(ad-disable-advice 'yank-pop 'around 'kill-ring-browse-maybe)
(error nil)))
(cond ((memq last-command secondary-selection-yank-secondary-commands)
(when buffer-read-only (icicle-user-error "Buffer is read-only: %S" (current-buffer)))
(yank-pop-secondary arg))
((memq last-command secondary-selection-yank-commands)
(when buffer-read-only (icicle-user-error "Buffer is read-only: %S" (current-buffer)))
(yank-pop arg))
(t
(icicle-completing-yank)
(setq this-command 'icicle-yank-pop-commands))))
(put 'icicle-completing-yank 'delete-selection 'yank)
(icicle-define-command icicle-completing-yank
"Yank an entry from a selection ring, choosing it using completion.
By default, the selection ring used is the kill ring.
If you also use library `browse-kill-ring+.el' or library
`second-sel.el' then an alternative selection ring is used if you
provide a prefix argument: `browse-kill-ring-alternative-ring' or
`secondary-selection-ring'. This gives you a way to yank chosen items
from two different sets of selections.
When the kill ring is used, this is similar to `yank', but this does
not rotate the ring. The mark is pushed first, so the yanked text
becomes the region.
During completion, you can use:
* \\<minibuffer-local-completion-map>`\\[icicle-change-sort-order]' to sort the \
candidates to yank in different ways (repeat)
* `\\[icicle-delete-candidate-object]' to remove a candidate entry from the selection ring
* `\\[icicle-candidate-alt-action]' to copy a candidate to the other selection ring
(requires `second-sel.el' or `browse-kill-ring+.el')"
icicle-insert-for-yank
"Insert: " (mapcar #'list kills-in-order) nil t nil 'icicle-kill-history
(car kills-in-order) nil
((icicle-transform-function 'icicle-remove-duplicates)
(icicle-sort-comparer nil)
(selection-ring (if (not current-prefix-arg)
'kill-ring
(if (boundp 'browse-kill-ring-alternative-ring)
browse-kill-ring-alternative-ring
(if (boundp 'secondary-selection-ring)
'secondary-selection-ring)
'kill-ring)))
(icicle-candidate-alt-action-fn `(lambda (seln)
(let ((other-ring (if (eq 'kill-ring ',selection-ring)
(if (fboundp 'browse-kill-ring)
browse-kill-ring-alternative-ring
(if (boundp 'secondary-selection-ring)
'secondary-selection-ring
nil))
'kill-ring)))
(if (eq 'kill-ring ',selection-ring)
(if (fboundp 'browse-kill-ring-alternative-push-function)
(funcall browse-kill-ring-alternative-push-function
seln)
(when (boundp 'secondary-selection-ring)
(add-secondary-to-ring seln)))
(kill-new seln))
(icicle-msg-maybe-in-minibuffer
(if (null other-ring)
"No other selection ring"
(format "Copied to `%s'" other-ring))))))
(icicle-delete-candidate-object selection-ring)
(kills-in-order (if (eq selection-ring 'kill-ring)
(append kill-ring-yank-pointer kill-ring ())
(copy-sequence (symbol-value selection-ring))))))
(defun icicle-insert-for-yank (string)
"`insert-for-yank', if defined; else, `insert' with `read-only' removed.
Pushes the mark first, so the inserted text becomes the region."
(setq this-command 'yank)
(push-mark)
(if (fboundp 'insert-for-yank)
(insert-for-yank string)
(let ((opoint (point)))
(insert string)
(let ((inhibit-read-only t)) (remove-text-properties opoint (point) '(read-only nil))))))
(put 'icicle-yank-maybe-completing 'delete-selection 'yank)
(defun icicle-yank-maybe-completing (&optional arg)
"`icicle-completing-yank', `icicle-yank', or `icicle-yank-function'.
If called from the minibuffer, call `icicle-yank'.
Otherwise:
With a negative prefix argument, call `icicle-completing-yank'.
Otherwise, call the value of user option `icicle-yank-function' (by
default, `yank')."
(interactive "*P")
(if (window-minibuffer-p (selected-window))
(icicle-yank arg)
(if (wholenump (prefix-numeric-value arg))
(funcall icicle-yank-function arg)
(let ((current-prefix-arg nil)) (icicle-completing-yank)))))
(when (locate-library "proced")
(icicle-define-command icicle-send-signal-to-process
"Send a signal to a system process.
Each candidate is a multi-completion with parts COMMAND, USER, and
PID, separated by `icicle-list-join-string' (\"^G^J\", by default).
COMMAND is the system command associated with the process.
USER is the user who issued COMMAND.
PID is the process identifier.
You can match an input regexp against any combination of the parts.
You can use `C-M-j' (equivalent here to `C-q C-g C-j') to input the
default separator."
(lambda (cand)
(let* ((process (funcall get-pid cand))
(process-name (funcall get-attr cand 'comm))
(sigcode (let ((enable-recursive-minibuffers t))
(completing-read
(format "Send signal to process %s: " process-name)
proced-signal-list nil nil nil nil "TERM"))))
(setq sigcode (and (stringp sigcode) (if (string-match "\\`[0-9]+\\'" sigcode)
(string-to-number sigcode)
(make-symbol sigcode))))
(when sigcode (signal-process process sigcode))))
prompt (mapcar (lambda (pid)
(let ((ats (process-attributes pid)))
`((,(cdr (assoc 'comm ats)) ,(cdr (assoc 'user ats)) ,(number-to-string pid)))))
(list-system-processes))
nil 'FORCE-MATCH-TO-PREVENT-ACCIDENTS nil nil nil nil
((prompt "COMMAND `C-M-j' USER `C-M-j' PID: ")
(completion-ignore-case t)
(icicle-candidate-properties-alist ())
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(3))
(get-pid (lambda (cand) (string-to-number cand)))
(get-attr (lambda (cand attr)
(cdr-safe (assoc attr (process-attributes
(funcall get-pid cand))))))
(get-user (lambda (cand)
(funcall get-attr cand 'user)))
(icicle-candidate-help-fn (lambda (cand)
(icicle-describe-process (funcall get-pid cand))))
(icicle-transform-before-sort-p t)
(icicle-last-transform-function nil)
(icicle-transform-function (lambda (cands)
(let ((user-name (user-login-name)))
(loop for cand in cands
for user = (funcall
get-user
(icicle-transform-multi-completion cand))
if (equal user-name user)
collect cand))))
(icicle-sort-orders-alist '(("by pid" .
(lambda (s1 s2)
(< (funcall get-pid s1) (funcall get-pid s2))))
("by command name" .
(lambda (s1 s2)
(string-lessp (upcase (funcall get-attr s1 'comm))
(upcase (funcall get-attr s2 'comm)))))
("by age" .
(lambda (s1 s2)
(> (float-time (funcall get-attr s1 'start))
(float-time (funcall get-attr s2 'start)))))))
(icicle-sort-comparer (cdar icicle-sort-orders-alist)))
(progn (unless (require 'proced nil t)
(icicle-user-error "You need library `proced.el' for this command"))
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter)))
(defun icicle-describe-process (pid)
"Describe the system process that has process id PID."
(interactive "nPID: ")
(with-output-to-temp-buffer "*Help*"
(let* ((attributes (process-attributes pid))
(comm (cdr-safe (assoc 'comm attributes)))
(args (cdr-safe (assoc 'args attributes)))
(start (cdr-safe (assoc 'start attributes)))
(user (cdr-safe (assoc 'user attributes)))
(state (cdr-safe (assoc 'state attributes))))
(princ (format "PID:\t\t%s\n" pid))
(when comm (princ (format "Command name:\t%s\n" comm)))
(when args (princ (format "Command line:\t%s\n" args)))
(when user (princ (format "User:\t\t%s\n" user)))
(when state (princ (format "State:\t%s\n" state)))
(when start (princ (format-time-string "Started:\t%a %b %e %T %Y (%z)\n" start)))))))
(icicle-define-file-command icicle-delete-file
"Delete a file or directory.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)"
(lambda (file)
(icicle-delete-file-or-directory file)
(icicle-remove-candidate-display-others 'ALL))
"Delete file or directory: " default-directory nil t nil nil
(icicle-file-bindings)
(icicle-bind-file-candidate-keys)
nil
(icicle-unbind-file-candidate-keys))
(defun icicle-delete-file-or-directory (file)
"Delete file or (empty) directory FILE."
(icicle-condition-case-no-debug i-delete-file
(if (eq t (car (file-attributes file)))
(delete-directory file)
(delete-file file))
(error (message "%s" (error-message-string i-delete-file))
(error "%s" (error-message-string i-delete-file)))))
(icicle-define-file-command icicle-dired
"Multi-command version of `dired'.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)"
(lambda (dir) (dired dir switches))
"Dired (directory): " nil default-directory nil nil nil
(icicle-file-bindings
((switches (and current-prefix-arg
(read-string "Dired listing switches: " dired-listing-switches)))
(icicle-file-sort (or icicle-file-sort 'icicle-dirs-first-p))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys)
nil
(icicle-unbind-file-candidate-keys))
(icicle-define-file-command icicle-dired-other-window
"Same as `icicle-dired', except uses another window."
(lambda (dir) (dired-other-window dir switches))
"Dired in other window (directory): " nil default-directory nil nil nil
(icicle-file-bindings
((switches (and current-prefix-arg
(read-string "Dired listing switches: " dired-listing-switches)))
(icicle-file-sort (or icicle-file-sort 'icicle-dirs-first-p))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys)
nil
(icicle-unbind-file-candidate-keys))
(put 'icicle-file 'icicle-Completions-window-max-height 200)
(defun icicle-file (arg)
"Visit a file or directory.
With no prefix argument, use relative file names
(`icicle-find-file').
With a prefix argument, use absolute file names
(`icicle-find-file-absolute').
With a negative prefix arg, you can choose also by date:
Completion candidates include the last modification date.
Note that when you use a prefix arg, completion matches candidates as
ordinary strings. It knows nothing of file names per se. In
particular, you cannot use remote file-name syntax if you use a prefix
argument.
If you use a prefix arg when you act on a completion candidate, then
you visit the file or dir in read-only mode. This includes when you
act on all candidates using \\<minibuffer-local-completion-map>\
`\\[icicle-all-candidates-action]': precede the `\\[icicle-all-candidates-action]' with a prefix
arg. This does not apply to the final candidate chosen (using `RET'
or `mouse-2') - a prefix arg has no effect for that.
See `icicle-find-file' and `icicle-find-file-absolute' for more
information. Note that for Emacs 23 and later, `icicle-find-file'
lets you search file content, as well as file names.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
By default, Icicle mode remaps all key sequences that are normally bound
to `find-file' to `icicle-file'. If you do not want this remapping,
then customize option `icicle-top-level-key-bindings'."
(interactive "P")
(if arg
(let ((current-prefix-arg (not (wholenump (prefix-numeric-value arg)))))
(icicle-find-file-absolute))
(icicle-find-file)))
(put 'icicle-file-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-file-other-window (arg)
"Same as `icicle-file', except uses another window."
(interactive "P")
(if arg
(let ((current-prefix-arg (not (wholenump (prefix-numeric-value arg)))))
(icicle-find-file-absolute-other-window))
(icicle-find-file-other-window)))
(put 'icicle-find-file-absolute 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-find-file-absolute
"Visit a file or directory, given its absolute name.
Unlike `icicle-find-file', the completion candidates are absolute, not
relative, file names.
Also, this is like `icicle-find-file-no-search', and not like
`icicle-find-file', in that there is no file-content search:
candidates are only file names, not multi-completions with content
patterns after `C-M-j'.
By default, the completion candidates are files in the current
directory, but you can substitute other candidates by retrieving a
saved candidate set.
Note that completion here matches candidates as ordinary strings. It
knows nothing of file names per se. In particular, you cannot use
remote file-name syntax.
Also, you cannot move up and down the file hierarchy the same way you
can for ordinary (non-absolute) file-name completion. To change to a
different directory, with its files as candidates, use \\<minibuffer-local-completion-map>`C-c C-d' from
the minibuffer - it prompts you for the new directory.
Remember that you can use `C-x .' to hide the common match portion of
each candidate. That can be particularly helpful for files that are
in a common directory.
With a prefix argument, you can choose also by date: Completion
candidates include the last modification date.
If you use a prefix argument when you act on a completion candidate,
then you visit the file or dir in read-only mode. This includes when
you act on all candidates using \\<minibuffer-local-completion-map>\
`\\[icicle-all-candidates-action]': precede the `\\[icicle-all-candidates-action]' with a prefix
arg. This does not apply to the final candidate chosen (using `RET'
or `mouse-2') - a prefix arg has no effect for that.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c C-d - change the `default-directory' (a la `cd')
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, set
`icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (file)
(let ((r-o (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
current-prefix-arg))
(fil (icicle-transform-multi-completion file)))
(if r-o
(find-file-read-only fil 'WILDCARDS)
(find-file fil 'WILDCARDS))))
prompt icicle-abs-file-candidates nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history default-directory nil
(icicle-file-bindings
((prompt "File or dir (absolute): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-abs-file-candidates (mapcar icicle-full-cand-fn
(directory-files default-directory 'FULL nil 'NOSORT)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))
(icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))))
(progn
(when current-prefix-arg
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(setq current-prefix-arg nil))
(icicle-highlight-lighter)
(message "Gathering files...")
(icicle-bind-file-candidate-keys)
(define-key minibuffer-local-completion-map "\C-c\C-d" 'icicle-cd-for-abs-files)
(define-key minibuffer-local-must-match-map "\C-c\C-d" 'icicle-cd-for-abs-files))
nil
(progn (icicle-unbind-file-candidate-keys)
(define-key minibuffer-local-completion-map "\C-c\C-d" nil)
(define-key minibuffer-local-must-match-map "\C-c\C-d" nil)))
(put 'icicle-find-file-absolute-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-find-file-absolute-other-window
"Same as `icicle-find-file-absolute' except uses another window."
(lambda (file)
(let ((r-o (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
current-prefix-arg))
(fil (icicle-transform-multi-completion file)))
(if r-o
(find-file-read-only-other-window fil 'WILDCARDS)
(find-file-other-window fil 'WILDCARDS))))
prompt icicle-abs-file-candidates nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history default-directory nil
(icicle-file-bindings
((prompt "File or dir (absolute): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-abs-file-candidates (mapcar icicle-full-cand-fn
(directory-files default-directory 'FULL nil 'NOSORT)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))
(icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))))
(progn
(when current-prefix-arg
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(setq current-prefix-arg nil))
(icicle-highlight-lighter)
(message "Gathering files...")
(icicle-bind-file-candidate-keys)
(define-key minibuffer-local-completion-map "\C-c\C-d" 'icicle-cd-for-abs-files)
(define-key minibuffer-local-must-match-map "\C-c\C-d" 'icicle-cd-for-abs-files))
nil
(progn (icicle-unbind-file-candidate-keys)
(define-key minibuffer-local-completion-map "\C-c\C-d" nil)
(define-key minibuffer-local-must-match-map "\C-c\C-d" nil)))
(defun icicle-cd-for-abs-files (dir)
"Change `default-directory' during `icicle-find-file-absolute'."
(interactive
(let ((enable-recursive-minibuffers t)
(minibuffer-completion-predicate minibuffer-completion-predicate))
(list (funcall (if (fboundp 'read-directory-name)
#'read-directory-name
#'read-file-name)
"Change default directory: " default-directory (icicle-file-name-directory-w-default
(icicle-input-from-minibuffer))
(and (member cd-path '(nil ("./"))) (null (getenv "CDPATH")))))))
(cd dir)
(let ((icicle-abs-file-candidates
(mapcar (lambda (file)
(setq file (if (file-directory-p file) (file-name-as-directory file) file))
(if icicle-multi-completing-p (icicle-make-file+date-candidate file) (list file)))
(directory-files default-directory 'full nil 'nosort))))
(setq minibuffer-completion-table
(car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
(put 'icicle-find-file-no-search 'icicle-Completions-window-max-height 200)
(icicle-define-file-command icicle-find-file-no-search
"Visit a file or directory.
\(Option `find-file-run-dired' determines whether you can actually
visit a directory candidate that you choose.)
For Emacs 23 and later, this is like command
`icicle-find-file-of-content', but without the possibility of
searching file contents. That is, completion candidates are just file
names, not multi-completions - they contain no file-content part
following `C-M-j'.
If you use a prefix argument when you act on a completion candidate
\(see below for the use of a prefix arg for the command itself.), then
you visit the file or dir in read-only mode. This includes when you
act on all candidates using \\<minibuffer-local-completion-map>\
`\\[icicle-all-candidates-action]': precede the `\\[icicle-all-candidates-action]' with a prefix
arg. This does not apply to the final candidate chosen (using `RET'
or `mouse-2') - a prefix arg has no effect for that.
If you use a prefix arg for the command itself, this reverses the
effect of using a prefix arg on individual candidates. That is, with
a prefix arg for the command, files are visited in read-only mode by
default and a prefix arg for an individual file visits it without
read-only mode.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra absolute file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, set
`icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (file)
(let* ((r-o (if (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(funcall fn file 'WILDCARDS)))
(concat "File or directory" (and init-pref-arg " (read-only)") ": ")
nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit))
(condition-case nil
(abbreviate-file-name (dired-get-file-for-visit))
(error nil))
default-directory)
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil nil
(icicle-file-bindings
((init-pref-arg current-prefix-arg)
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys)
nil
(icicle-unbind-file-candidate-keys))
(put 'icicle-find-file-no-search-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-file-command icicle-find-file-no-search-other-window
"Same as `icicle-find-file-no-search', except uses another window."
(lambda (file)
(let* ((r-o (if (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
(or (and init-pref-arg (not current-prefix-arg))
(and (not init-pref-arg) current-prefix-arg))
init-pref-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(funcall fn file 'WILDCARDS)))
(concat "File or directory" (and init-pref-arg " (read-only)") ": ")
nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit))
(condition-case nil
(abbreviate-file-name (dired-get-file-for-visit))
(error nil))
default-directory)
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil nil
(icicle-file-bindings
((init-pref-arg current-prefix-arg)
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys)
nil
(icicle-unbind-file-candidate-keys))
(put 'icicle-find-file-read-only 'icicle-Completions-window-max-height 200)
(defun icicle-find-file-read-only ()
"Visit a file or directory in read-only mode.
This is `icicle-find-file-no-search' with prefix-arg behavior flipped.
If you use a prefix arg when you act on a candidate file name then
visit the file without read-only mode.
If you use a prefix arg for the command itself, this reverses the
effect of using a prefix arg on individual candidates. That is, with
a prefix arg for the command, files are not visited in read-only mode
by default and a prefix arg for an individual file visits it in
read-only mode.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>:
*You can use `C-x a +' or `C-x a -' to add or remove tags from the
current-candidate file. You are prompted for the tags.
*You can use `C-x m' to access file bookmarks (not just autofiles).
You can use `C-c +' to create a new directory.
You can use `\\[icicle-all-candidates-list-alt-action]' to open Dired on currently matching file names.
You can use `\\[icicle-delete-candidate-object]' to delete a candidate file or (empty) dir."
(interactive)
(let ((current-prefix-arg (not current-prefix-arg)))
(icicle-find-file-no-search)))
(put 'icicle-find-file-read-only-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-find-file-read-only-other-window ()
"Same as `icicle-find-file-read-only' except uses another window."
(interactive)
(let ((current-prefix-arg (not current-prefix-arg)))
(icicle-find-file-no-search-other-window)))
(when (> emacs-major-version 22)
(put 'icicle-find-file-of-content 'icicle-Completions-window-max-height 200)
(icicle-define-file-command icicle-find-file-of-content
"Visit a file or dir whose name and/or content matches.
Candidate files and directories for completion are examined, and those
whose names and/or contents match your multi-completion input are
available to visit.
\(Option `find-file-run-dired' determines whether you can actually
visit a directory candidate that you choose.)
If you use a prefix argument when you act on a completion candidate
\(see below for the use of a prefix arg for the command itself.), then
you visit the file or dir in read-only mode. This includes when you
act on all candidates using \\<minibuffer-local-completion-map>\
`\\[icicle-all-candidates-action]': precede the `\\[icicle-all-candidates-action]' with a prefix
arg. This does not apply to the final candidate chosen (using `RET'
or `mouse-2') - a prefix arg has no effect for that.
Completion candidates are two-part multi-completions, with the second
part optional. If both parts are present they are separated by
`icicle-list-join-string' (\"^G^J\", by default).
The first part is matched as a regexp against a file or directory
name. The second part is matched as a regexp against the file or
directory content. Candidates that do not match are filtered out.
When matching file content, Icicles just looks for a single match.
Visiting the file does not move to that match or to any other match.
Matching is used only to filter candidate files.
However, if your input includes a content-matching part and it
matches, that part is automatically added to the Isearch regexp
history, `regexp-search-ring' whenever you hit `S-TAB' to complete.
This means that when you visit the file you can immediately search for
matches using `C-M-s' or `C-M-r'.
Your minibuffer input can match a name or content, or both. Use
`C-M-j' (equivalent here to `C-q C-g C-j') to input the default
separator.
For example:
To match `foo' against file and dir names, use input `foo'.
To match `bar' against file and dir contents, use input `C-M-j bar'.
To match both names and content, use input `foo C-M-j bar'.
Only the matching file and directory names are shown in buffer
`*Completions*', and only the chosen name is returned. The actual
content matches are unimportant anyway: content matching is used only
to filter the candidates.
If your input does not include a content-matching part then this
command acts similar to `icicle-find-file-no-search' (but with a
different use of the prefix argument).
If your input includes a content-matching part then all files and
directories matching the name part of your input (or all, if no name
part) are visited. This creates buffers visiting each matching
candidate.
For a directory, a Dired buffer is used - that is the content that is
searched. (Actually, this is determined by option
`find-directory-functions'.)
As you would expect, content matching can be costly in time, even
though it can be quite helpful. Use name matching to narrow the set
of files that must be visited to search their contents.
When this command is finished, any unused buffers that were created
for content matching are killed, if option
`icicle-kill-visited-buffers-flag' is non-nil. But a prefix argument
flips the behavior specified by that option.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)"
(lambda (file)
(let* ((r-o (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
current-prefix-arg))
(fn (if r-o 'find-file-read-only 'find-file)))
(setq file (icicle-transform-multi-completion file))
(funcall fn file 'WILDCARDS)
(when (and (file-readable-p file) (buffer-file-name)) (normal-mode))
(let ((fil2 (if (string= "" (file-name-nondirectory file)) (directory-file-name file) file)))
(dolist (fil (file-expand-wildcards fil2))
(when (setq fil (if (file-directory-p fil)
(get-buffer (file-name-nondirectory fil))
(get-file-buffer fil)))
(push fil new-bufs--to-keep))))))
prompt nil (if (eq major-mode 'dired-mode)
(condition-case nil
(abbreviate-file-name (dired-get-file-for-visit))
(error nil))
default-directory)
(confirm-nonexistent-file-or-buffer) nil nil
(icicle-file-bindings
((init-pref-arg current-prefix-arg)
(prompt "File or directory: ")
(icicle-compute-narrowing-regexp-p t)
(icicle-apropos-complete-match-fn 'icicle-file-of-content-apropos-complete-match)
(icicle-last-apropos-complete-match-fn 'icicle-file-of-content-apropos-complete-match)
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-transform-before-sort-p t)
(existing-bufs (buffer-list))
(new-bufs--to-kill ())
(new-bufs--to-keep ())
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(progn (icicle-bind-file-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter))
nil
(progn (icicle-unbind-file-candidate-keys)
(when (or (and init-pref-arg (not icicle-kill-visited-buffers-flag))
(and (not init-pref-arg) icicle-kill-visited-buffers-flag))
(dolist (buf new-bufs--to-kill)
(unless (memq buf new-bufs--to-keep)
(with-current-buffer buf
(restore-buffer-modified-p nil)
(kill-buffer buf)))))))
(put 'icicle-find-file-of-content-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-file-command icicle-find-file-of-content-other-window
"Visit a file or dir whose name and/or content matches, in another window.
Same as `icicle-find-file-of-content' except it uses a different window."
(lambda (file)
(let* ((r-o (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
icicle-all-candidates-action))
current-prefix-arg))
(fn (if r-o 'find-file-read-only-other-window 'find-file-other-window)))
(setq file (icicle-transform-multi-completion file))
(funcall fn file 'WILDCARDS)
(when (and (file-readable-p file) (buffer-file-name)) (normal-mode))
(let ((fil2 (if (string= "" (file-name-nondirectory file)) (directory-file-name file) file)))
(dolist (fil (file-expand-wildcards fil2))
(when (setq fil (if (file-directory-p fil)
(get-buffer (file-name-nondirectory fil))
(get-file-buffer fil)))
(push fil new-bufs--to-keep))))))
prompt nil (if (eq major-mode 'dired-mode)
(condition-case nil
(abbreviate-file-name (dired-get-file-for-visit))
(error nil))
default-directory)
(confirm-nonexistent-file-or-buffer) nil nil
(icicle-file-bindings
((init-pref-arg current-prefix-arg)
(prompt "File or directory: ")
(icicle-compute-narrowing-regexp-p t)
(icicle-apropos-complete-match-fn 'icicle-file-of-content-apropos-complete-match)
(icicle-last-apropos-complete-match-fn 'icicle-file-of-content-apropos-complete-match)
(icicle-show-multi-completion-flag t)
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-transform-before-sort-p t)
(existing-bufs (buffer-list))
(new-bufs--to-kill ())
(new-bufs--to-keep ())
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(progn (icicle-bind-file-candidate-keys)
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
(icicle-highlight-lighter))
nil
(progn (icicle-unbind-file-candidate-keys)
(when (or (and init-pref-arg (not icicle-kill-visited-buffers-flag))
(and (not init-pref-arg) icicle-kill-visited-buffers-flag))
(dolist (buf new-bufs--to-kill)
(unless (memq buf new-bufs--to-keep)
(with-current-buffer buf
(restore-buffer-modified-p nil)
(kill-buffer buf)))))))
(defun icicle-file-of-content-apropos-complete-match (input file-name)
"Match function for progressive completion with `icicle-find-file-of-content'.
Return non-nil if the current multi-completion INPUT matches FILE-NAME."
(lexical-let* ((name-pat (let ((icicle-list-use-nth-parts '(1)))
(icicle-transform-multi-completion input)))
(content-pat (let ((icicle-list-use-nth-parts '(2)))
(icicle-transform-multi-completion input))))
(and (icicle-string-match-p name-pat file-name)
(or (not icicle-narrow-regexp) (icicle-string-match-p icicle-narrow-regexp file-name))
(or find-file-run-dired (not (file-directory-p file-name)))
(or (equal "" content-pat)
(and (not (run-hook-with-args-until-success 'icicle-find-file-of-content-skip-hook file-name))
(let* ((dir-p (file-directory-p file-name))
(exists nil)
(buf (if dir-p
(find-file-noselect file-name)
(or (setq exists (find-buffer-visiting file-name))
(create-file-buffer file-name))))
(found (with-current-buffer buf
(message "Matching file contents...")
(unless (or dir-p exists)
(insert-file-contents file-name 'VISIT))
(save-excursion (goto-char (point-min))
(re-search-forward content-pat nil t)))))
(when (and (boundp 'existing-bufs) (boundp 'new-bufs--to-kill)
(not (memq buf existing-bufs)))
(add-to-list 'new-bufs--to-kill buf))
(when (and found
(or (icicle-get-safe this-command 'icicle-apropos-completing-command)
(icicle-get-safe this-command 'icicle-cycling-command)
(memq this-command '(icicle-retrieve-next-input
icicle-retrieve-previous-input))))
(isearch-update-ring content-pat 'REGEXP))
found)))))))
(defalias 'icicle-find-file (if (fboundp 'icicle-find-file-of-content)
'icicle-find-file-of-content
'icicle-find-file-no-search))
(defalias 'icicle-find-file-other-window (if (fboundp 'icicle-find-file-of-content)
'icicle-find-file-of-content-other-window
'icicle-find-file-no-search-other-window))
(put 'icicle-recent-file 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-recent-file
"Open a recently used file.
With a prefix argument, you can choose also by date: Completion
candidates include the last modification date.
Note that completion here matches candidates as ordinary strings. It
knows nothing of file names per se. In particular, you cannot use
remote file-name syntax.
Remember that you can use \\<minibuffer-local-completion-map>`C-x .' to hide the common match portion of
each candidate. That can be particularly helpful for files that are
in a common directory.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
You can use any of the alternative-action keys, such as `\\[icicle-candidate-alt-action]', to
remove a candidate file from the recent files list, `recentf-list'.
\(The file itself is not deleted.)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra absolute file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, set
`icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (f) (find-file (icicle-transform-multi-completion f) 'WILDCARDS))
prompt icicle-abs-file-candidates nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history (car recentf-list) nil
(icicle-file-bindings
((prompt "Recent file (absolute): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-transform-before-sort-p t)
(icicle-sort-comparer 'icicle-last-accessed-first-p)
(icicle-abs-file-candidates
(progn (unless (boundp 'recentf-list) (require 'recentf))
(when (fboundp 'recentf-mode) (recentf-mode 99))
(unless (consp recentf-list) (icicle-user-error "Recent-files list is empty"))
(mapcar (lambda (file)
(if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
recentf-list)))
(icicle-candidate-alt-action-fn 'icicle-remove-from-recentf-candidate-action)
(icicle-use-candidates-only-once-alt-p t)
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ")
(mapcar #'icicle-transform-multi-completion files))))))))
(progn
(when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
(icicle-highlight-lighter)
(message "Gathering files...")
(icicle-bind-file-candidate-keys))
nil
(icicle-unbind-file-candidate-keys))
(put 'icicle-recent-file-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-recent-file-other-window
"Same as `icicle-recent-file' except uses another window."
(lambda (f) (find-file-other-window (icicle-transform-multi-completion f) 'WILDCARDS))
prompt icicle-abs-file-candidates nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history (car recentf-list) nil
(icicle-file-bindings
((prompt "Recent file (absolute): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-transform-before-sort-p t)
(icicle-sort-comparer 'icicle-last-accessed-first-p)
(icicle-abs-file-candidates
(progn (unless (boundp 'recentf-list) (require 'recentf))
(when (fboundp 'recentf-mode) (recentf-mode 99))
(unless (consp recentf-list) (icicle-user-error "Recent-files list is empty"))
(mapcar (lambda (file)
(if current-prefix-arg (icicle-make-file+date-candidate file) (list file)))
recentf-list)))
(icicle-candidate-alt-action-fn 'icicle-remove-from-recentf-candidate-action)
(icicle-use-candidates-only-once-alt-p t)
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ")
(mapcar #'icicle-transform-multi-completion files))))))))
(progn
(when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
(icicle-highlight-lighter)
(message "Gathering files...")
(icicle-bind-file-candidate-keys))
nil
(icicle-unbind-file-candidate-keys))
(icicle-define-command icicle-remove-file-from-recentf-list
"Remove file from `recentf-list' - the list of recently used files."
icicle-remove-from-recentf-candidate-action
"Remove from recent files list, `recentf-list': "
(mapcar #'list (progn (unless (boundp 'recentf-list) (require 'recentf))
(when (fboundp 'recentf-mode) (recentf-mode 99))
(unless (consp recentf-list) (icicle-user-error "Recent-files list is empty"))
recentf-list))
nil (and (fboundp 'confirm-nonexistent-file-or-buffer)
(confirm-nonexistent-file-or-buffer))
nil 'file-name-history (car recentf-list) nil
((icicle-use-candidates-only-once-flag t)))
(defun icicle-remove-from-recentf-candidate-action (file)
"Action function for command `icicle-remove-file-from-recentf-list'."
(setq recentf-list (delete file recentf-list))
(message "`%s' removed from `recentf-list'" (icicle-propertize file 'face 'icicle-msg-emphasis)))
(defvar icicle-locate-file-action-fn nil
"Action function used in `icicle-locate-file-1'.")
(defvar icicle-locate-file-no-symlinks-p nil
"Flag bound in `icicle-locate-file* for use by `icicle-files-within'.")
(defvar icicle-locate-file-use-locate-p nil
"Flag bound to non-nil in `icicle-locate(-other-window)'.
Non-nil means `icicle-locate-file-1' uses external command `locate'.")
(put 'icicle-locate-file 'icicle-Completions-window-max-height 200)
(defun icicle-locate-file ()
"Visit a file within one or more directories or their subdirectories.
A prefix argument determines the behavior, as follows:
* None: The default (i.e., current) directory is used.
* Plain (`C-u'): You are prompted for the directories, using
multi-command `icicle-directory-list'.
* Non-negative (>= 0): You are prompted for the directory.
* Non-positive (<= 0): You can choose files also by date: A completion
candidate includes the last modification date of the file.
* Double plain (`C-u C-u'): You are prompted for the directories and
candidates include last-modification dates.
The absolute names of all files within a directory and all of its
subdirectories are targets for completion. Regexp input is matched
against all parts of the absolute name, not just the file-name part.
Remember that you can use `C-x .' to hide the common match portion of
each candidate. That can be particularly helpful for files that are
in a common directory.
You can use this command to find all files within your file system
that match a regexp, but be aware that gathering and matching the file
names will take some time.
See also command `icicle-locate-file-no-symlinks', which does the same
thing but without following symbolic links.
If you use Emacs on a platform that has an external program `locate',
then consider using `icicle-locate' instead of `icicle-locate-file'.
Remember that you can save the set of files matching your input using
\\<minibuffer-local-completion-map>\
`\\[icicle-candidate-set-save]' or \
`\\[icicle-candidate-set-save-persistently]'. You can then retrieve quickly them later using
`\\[icicle-candidate-set-retrieve]' or \
`\\[icicle-candidate-set-retrieve-persistent]'.
Note that completion here matches candidates as ordinary strings. It
knows nothing of file names per se. In particular, you cannot use
remote file-name syntax.
You cannot move up and down the file hierarchy the same way you can
for ordinary (non-absolute) file-name completion. To change to a
different directory, with its files as candidates, use \\<minibuffer-local-completion-map>`C-c C-d' from
the minibuffer - it prompts you for the new directory.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c C-d - change the `default-directory' (a la `cd')
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
Directories in `icicle-ignored-directories' are ignored (skipped). In
addition, these options control candidate matching and filtering:
`icicle-file-extras' - Extra file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-require-match-flag' - See `icicle-require-match-flag'
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, set
`icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))"
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-action)
(icicle-locate-file-no-symlinks-p nil))
(icicle-locate-file-1)))
(put 'icicle-locate-file-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-locate-file-other-window ()
"Same as `icicle-locate-file' except uses another window.
See also command `icicle-locate-file-no-symlinks-other-window', which
does not follow symbolic links."
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-other-window-action)
(icicle-locate-file-no-symlinks-p nil))
(icicle-locate-file-1)))
(put 'icicle-locate 'icicle-Completions-window-max-height 200)
(defun icicle-locate ()
"Run the external program `locate', then visit files.
Unlike `icicle-locate-file' this is a wrapper for the external program
`locate', which searches an index of files in your file system, which
is normally created by external program `updatedb'. Because of this
indexing, this command can be much faster than `icicle-locate-file'.
`icicle-locate' first prompts for a search pattern for program
`locate', which it passes to that program. The absolute file names
that match this pattern are targets for Icicles completion.
`icicle-locate' uses settings from library `locate.el' where
appropriate. In particular, you can customize
`locate-make-command-line' to use either regexp matching or file-name
globbing. Here is an example of a setup to use regexp matching:
\(setq locate-make-command-line
(lambda (ss) (list locate-command \"--regex\" ss)))
Which particular options the external program `locate' accepts, and
how matching is performed, depend on your operating system and its
implementation of that program.
A prefix argument has the same meaning as for vanilla Emacs command
`locate': prompt for a shell command to run instead of program
`locate'. A prefix arg has the effect of flipping the value of user
option `locate-prompt-for-command' for the duration of the command
invocation.
After you input the search pattern for program `locate', normal
Icicles input pattern matching is available for completion. This is
absolute file-name completion, so your input can match any parts of
the name, including directory components.
Remember that you can use \\<minibuffer-local-completion-map>`C-x .' to hide the common match portion of
each candidate. That can be particularly helpful for files that are
in a common directory.
Remember that you can save the set of files matching your input using
\\<minibuffer-local-completion-map>\
`\\[icicle-candidate-set-save]' or \
`\\[icicle-candidate-set-save-persistently]'. You can then retrieve quickly them later using
`\\[icicle-candidate-set-retrieve]' or \
`\\[icicle-candidate-set-retrieve-persistent]'.
Note that completion here matches candidates as ordinary strings. It
knows nothing of file names per se. In particular, you cannot use
remote file-name syntax.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These Icicles options control candidate matching and filtering:
`icicle-file-extras' - Extra file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-require-match-flag' - See `icicle-require-match-flag'
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, you
could temporarily set `icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))"
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-action)
(icicle-locate-file-use-locate-p t))
(icicle-locate-file-1)))
(put 'icicle-locate-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-locate-other-window ()
"Same as `icicle-locate' except uses another window."
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-other-window-action)
(icicle-locate-file-use-locate-p t))
(icicle-locate-file-1)))
(put 'icicle-locate-file-no-symlinks 'icicle-Completions-window-max-height 200)
(defun icicle-locate-file-no-symlinks ()
"Same as `icicle-locate-file', except do not follow symlinks."
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-other-window-action)
(icicle-locate-file-no-symlinks-p t))
(icicle-locate-file-1)))
(put 'icicle-locate-file-no-symlinks-other-window 'icicle-Completions-window-max-height 200)
(defun icicle-locate-file-no-symlinks-other-window ()
"Same as `icicle-locate-file-no-symlinks', except uses another window."
(interactive)
(let ((icicle-locate-file-action-fn 'icicle-locate-file-other-window-action)
(icicle-locate-file-no-symlinks-p t))
(icicle-locate-file-1)))
(defun icicle-locate-file-action (file)
"Action function for `icicle-locate-file'."
(find-file (icicle-transform-multi-completion file) 'WILDCARDS))
(defun icicle-locate-file-other-window-action (file)
"Action function for `icicle-locate-file-other-window'."
(find-file-other-window (icicle-transform-multi-completion file) 'WILDCARDS))
(icicle-define-command icicle-locate-file-1
"Helper for `icicle-locate(-file(-no-symlinks))(-other-window)'."
(lambda (f) (funcall icicle-locate-file-action-fn f))
prompt icicle-abs-file-candidates nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history nil nil
(icicle-file-bindings
((prompt "File (absolute): ")
(dirs (and (not icicle-locate-file-use-locate-p)
(cond ((and current-prefix-arg (consp current-prefix-arg))
(icicle-directory-list))
((and current-prefix-arg
(wholenump (prefix-numeric-value current-prefix-arg)))
(read-file-name "Locate under which directory: "
nil default-directory nil))
(t default-directory))))
(icicle-multi-completing-p (and (not icicle-locate-file-use-locate-p)
(or (<= (prefix-numeric-value current-prefix-arg) 0)
(and current-prefix-arg (consp current-prefix-arg)
(= (car current-prefix-arg) 16)))))
(icicle-full-cand-fn (if icicle-multi-completing-p
(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
(icicle-make-file+date-candidate file))
(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
(list file))))
(use-dialog-box nil)
(icicle-candidate-properties-alist (and icicle-multi-completing-p '((1 (face icicle-candidate-part)))))
(icicle-list-use-nth-parts (and icicle-multi-completing-p '(1)))
(IGNORED--FOR-SIDE-EFFECT
(progn (icicle-highlight-lighter)
(if icicle-locate-file-use-locate-p
(require 'locate)
(message "Gathering files %s (this could take a while)..."
(if (or (symbolp dirs) (consp dirs))
(format "in `%s'" (icicle-propertize dirs 'face 'icicle-msg-emphasis))
(format "within `%s'" (icicle-propertize dirs 'face 'icicle-msg-emphasis)))))))
(icicle-abs-file-candidates
(mapcar (if icicle-multi-completing-p #'icicle-make-file+date-candidate #'list)
(if icicle-locate-file-use-locate-p
(let* ((locate-buffer-name " *Icicles Locate*")
(temp-locate-buffer (get-buffer-create locate-buffer-name)))
(unwind-protect
(with-current-buffer temp-locate-buffer
(let ((cands ()))
(call-interactively #'locate)
(dired-repeat-over-lines
(count-lines (point-min) (point-max))
(lambda () (push (dired-get-filename nil t) cands)))
(nreverse cands)))
(kill-buffer temp-locate-buffer)))
(if (not (or (symbolp dirs) (consp dirs)))
(icicle-files-within (directory-files dirs 'full icicle-re-no-dot)
nil icicle-locate-file-no-symlinks-p)
(apply #'append
(mapcar (if icicle-locate-file-no-symlinks-p
(lambda (dir)
(icicle-remove-if #'file-symlink-p
(directory-files dir 'full icicle-re-no-dot 'NOSORT)))
(lambda (dir) (directory-files dir 'full icicle-re-no-dot 'NOSORT)))
dirs))))))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ")
(mapcar #'icicle-transform-multi-completion files))))))))
(progn
(when icicle-multi-completing-p (put-text-property 0 1 'icicle-fancy-candidates t prompt))
(icicle-bind-file-candidate-keys)
(unless icicle-locate-file-use-locate-p
(define-key minibuffer-local-completion-map "\C-c\C-d" 'icicle-cd-for-loc-files)
(define-key minibuffer-local-must-match-map "\C-c\C-d" 'icicle-cd-for-loc-files)))
nil
(progn (icicle-unbind-file-candidate-keys)
(unless icicle-locate-file-use-locate-p
(define-key minibuffer-local-completion-map "\C-c\C-d" nil)
(define-key minibuffer-local-must-match-map "\C-c\C-d" nil)))
'NON-INTERACTIVE)
(defun icicle-cd-for-loc-files (dir &optional no-symlinks-p)
"Change `default-directory' during `icicle-locate-file'.
Optional arg NO-SYMLINKS-P non-nil means do not follow symbolic links."
(interactive
(save-selected-window
(let ((minibuffer-completion-predicate minibuffer-completion-predicate))
(list (funcall (if (fboundp 'read-directory-name)
#'read-directory-name
#'read-file-name)
"Change default directory: " default-directory (icicle-file-name-directory-w-default
(icicle-input-from-minibuffer))
(and (member cd-path '(nil ("./"))) (null (getenv "CDPATH"))))))))
(cd dir)
(let ((icicle-abs-file-candidates
(mapcar (lambda (file)
(if icicle-multi-completing-p (icicle-make-file+date-candidate file) (list file)))
(icicle-files-within (directory-files dir 'full icicle-re-no-dot) nil no-symlinks-p))))
(setq minibuffer-completion-table
(car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
(put 'icicle-find-file-in-tags-table 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-find-file-in-tags-table
"Visit a file listed in a tags table.
By default, the completion candidates are the file names listed in the
current tags table, but you can substitute other candidates by
retrieving a saved candidate set. The default candidates appear as
they did in the `etags' command that created the tags table, which
typically means without directory names.
Completion here matches candidates as ordinary strings. It knows
nothing of file names per se. In particular, you cannot use remote
file-name syntax. If a candidate is an absolute file name then you
can complete against any and all parts of the name (including
directory components).
`find-file' is called for the candidate(s) you choose, with the
directory of the tags file as `default-directory'.
Remember that you can use \\<minibuffer-local-completion-map>`C-x .' to hide the common match portion of
each candidate. That can be particularly helpful for files that are
in a common directory.
With a prefix argument, you can choose also by date: Completion
candidates include the last modification date.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, you
could temporarily set `icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (ff)
(visit-tags-table-buffer 'same)
(find-file (icicle-transform-multi-completion ff) 'WILDCARDS))
prompt
(mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
(save-excursion (let ((enable-recursive-minibuffers t)) (visit-tags-table-buffer))
(tags-table-files)))
nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history nil nil
(icicle-file-bindings
((prompt "File (in tags table): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(progn
(when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
(unless (require 'etags nil t) (error "`etags.el' is required"))
(icicle-bind-file-candidate-keys))
nil
(icicle-unbind-file-candidate-keys))
(put 'icicle-find-file-in-tags-table-other-window 'icicle-Completions-window-max-height 200)
(icicle-define-command icicle-find-file-in-tags-table-other-window
"Same as `icicle-find-file-in-tags-table', but uses another window."
(lambda (ff)
(visit-tags-table-buffer 'same)
(find-file (icicle-transform-multi-completion ff) 'WILDCARDS))
prompt
(mapcar (if current-prefix-arg #'icicle-make-file+date-candidate #'list)
(save-excursion (let ((enable-recursive-minibuffers t)) (visit-tags-table-buffer))
(tags-table-files)))
nil
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'file-name-history nil nil
(icicle-file-bindings
((prompt "File (in tags table): ")
(icicle-full-cand-fn `(lambda (file)
(setq file (if (file-directory-p file)
(file-name-as-directory file)
file))
,(if current-prefix-arg
'(icicle-make-file+date-candidate file)
'(list file))))
(icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
(icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
(icicle-multi-completing-p current-prefix-arg)
(icicle-list-use-nth-parts (and current-prefix-arg '(1)))
(icicle-all-candidates-list-alt-action-fn
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(progn
(when current-prefix-arg (put-text-property 0 1 'icicle-fancy-candidates t prompt))
(unless (require 'etags nil t) (error "`etags.el' is required"))
(icicle-bind-file-candidate-keys))
nil
(icicle-unbind-file-candidate-keys))
(defun icicle-make-file+date-candidate (file)
"Return a multi-completion candidate: FILE + last modification date."
(list (list file (format-time-string "%Y %m %d %T " (nth 5 (file-attributes file))))))
(icicle-define-command icicle-string-list
"Choose a list of strings. The list is returned.
You can choose from strings used previously or enter new strings.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
If option `icicle-add-proxy-candidates-flag' is non-nil (toggle using
`\\<minibuffer-local-completion-map>\\[icicle-toggle-proxy-candidates]'), you can also choose the \
name of a string variable - its value
is returned. A string variable is a variable whose value or whose
custom type is compatible with type `string'."
(lambda (string)
(let (temp)
(push (if (setq temp (member string icicle-proxy-candidates))
(setq temp (symbol-value (intern (car temp))))
(setq temp string))
strings)
(when (interactive-p)
(message "Added string \"%s\"" (icicle-propertize temp 'face 'icicle-msg-emphasis))
(sit-for 1))))
prompt (mapcar #'list (icicle-remove-duplicates comp-strings))
nil nil nil 'regexp-history nil nil
((icicle-proxy-candidates
(and icicle-add-proxy-candidates-flag
(let ((ipc ()))
(mapatoms (lambda (cand)
(when (and (user-variable-p cand)
(condition-case nil
(icicle-var-is-of-type-p cand '(string color regexp))
(error nil)))
(push (symbol-name cand) ipc))))
ipc)))
(comp-strings (append regexp-history regexp-search-ring search-ring
icicle-search-history kill-ring))
(strings ())
(icicle-use-candidates-only-once-flag t)
(prompt (or icicle-prompt "Choose string (`RET' when done): ")))
(when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt))
nil
(prog1 (setq strings (nreverse (delete "" strings)))
(setq icicle-proxy-candidates ())
(when (interactive-p) (message "Strings: %S" strings))))
(when (fboundp 'read-char-by-name)
(defun icicle-zap-to-char (arg char &optional names)
"Kill up to and including ARGth occurrence of CHAR.
Case is ignored if `case-fold-search' is non-nil in the current buffer.
Go backward if ARG is negative. Raise an error if CHAR is not found.
This is the same as `zap-to-char', except if you hit a completing key
such as `TAB' then you can complete against the char names in NAMES.
If you need to zap up to a completing-key char such as `TAB', escape
the char with `C-q'. E.g., use `C-q TAB' instead of `TAB'.
NAMES has the same form as `ucs-names'. Interactively, NAMES is
determined by option `icicle-zap-to-char-candidates'. By default, it
is the subset of `ucs-names' that corresponds to the characters that
have been read previously (`icicle-read-char-history'), that is, the
Unicode names you entered. If you want to complete against all
Unicode chars, then customize option `icicle-zap-to-char-candidates'."
(interactive
(list (prefix-numeric-value current-prefix-arg)
(icicle-read-char-maybe-completing "Zap to char: "
(and (functionp icicle-zap-to-char-candidates)
(funcall icicle-zap-to-char-candidates)))))
(unless names (setq names (or (icicle-char-cands-from-charlist) (icicle-ucs-names))))
(with-no-warnings
(when (char-table-p translation-table-for-input)
(setq char (or (aref translation-table-for-input char) char))))
(kill-region (point) (progn (search-forward (string char) nil nil arg)
(point)))))
(icicle-define-command icicle-sexp-list
"Choose a list of sexps. The list is returned.
The list entries are Lisp objects, not strings (unless you use \"...\").
You can choose from sexps entered previously or enter new sexps.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one."
(lambda (sexp)
(push sexp sexps)
(when (interactive-p)
(message "Added sexp `%s'" (icicle-propertize sexp 'face 'icicle-msg-emphasis)) (sit-for 1)))
prompt
(mapcar #'list (icicle-remove-duplicates (symbol-value history)))
nil nil nil history nil nil
((sexps ())
(icicle-use-candidates-only-once-flag t)
(prompt (or icicle-prompt "Choose sexp (`RET' when done): "))
(history (or icicle-hist-var 'read-expression-history)))
nil nil
(prog1 (setq sexps (nreverse (delete "" sexps))
sexps (mapcar (lambda (sx) (car (read-from-string sx))) sexps))
(when (interactive-p) (message "Sexps: %S" sexps))))
(defalias 'icicle-regexp-list 'icicle-keyword-list)
(icicle-define-command icicle-keyword-list
"Choose a list of keywords. The list of keywords (strings) is returned.
Each keyword is a regexp. The regexps are OR'd, and the resulting
regexp is usable for `icicle-search'.
You can choose from keywords entered previously or enter new keywords.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one."
(lambda (name)
(push name keywords)
(when (interactive-p)
(message "Added keyword `%s'" (icicle-propertize name 'face 'icicle-msg-emphasis)) (sit-for 1)))
prompt (mapcar #'list (icicle-remove-duplicates regexp-history))
nil nil nil 'regexp-history nil nil
((keywords ())
(icicle-use-candidates-only-once-flag t)
(prompt (or icicle-prompt
"Choose keyword (regexp) (`RET' when done): ")))
nil nil
(prog1 (setq keywords (nreverse (delete "" keywords)))
(when (interactive-p) (message "Keywords (regexps): %S" keywords))))
(icicle-define-command icicle-face-list
"Choose a list of face names. The list of names (strings) is returned.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one."
(lambda (name)
(let ((temp (icicle-transform-multi-completion name)))
(push temp face-names)
(when (interactive-p)
(message "Added face `%s'" (icicle-propertize temp 'face 'icicle-msg-emphasis)) (sit-for 1))))
prompt (mapcar #'icicle-make-face-candidate (face-list))
nil (not (stringp icicle-WYSIWYG-Completions-flag)) nil
(if (boundp 'face-name-history) 'face-name-history 'icicle-face-name-history)
nil nil
((prompt (or icicle-prompt
"Choose face (`RET' when done): "))
(icicle-list-nth-parts-join-string ": ")
(icicle-list-join-string ": ")
(icicle-multi-completing-p t)
(icicle-list-use-nth-parts '(1))
(icicle-use-candidates-only-once-flag t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "face")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "face")))
(face-names ()))
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
nil
(prog1 (setq face-names (nreverse (delete "" face-names)))
(when (interactive-p) (message "Faces: %S" face-names))))
(icicle-define-command icicle-buffer-list
"Choose a list of buffer names.
With a positive prefix arg, only buffers visiting files or directories
\(Dired) are candidates.
With a negative prefix arg, only buffers associated with the selected
frame are candidates.
Use multi-command action keys (e.g. \\<minibuffer-local-completion-map>`C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
You can use `\\[icicle-delete-candidate-object]' during completion to kill a candidate buffer.
The list of names (strings) is returned.
These options, when non-nil, control candidate matching and filtering:
`icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
`icicle-buffer-extras' - Extra buffers to display
`icicle-buffer-match-regexp' - Regexp that buffers must match
`icicle-buffer-no-match-regexp' - Regexp buffers must not match
`icicle-buffer-predicate' - Predicate buffer names satisfy
`icicle-buffer-sort' - Sort function for candidates
Note: The prefix arg is tested, even when this is called
noninteractively. Lisp code can bind `current-prefix-arg' to control
the behavior."
(lambda (name)
(push name buf-names)
(when (interactive-p)
(message "Added buffer name `%s'" (icicle-propertize name 'face 'icicle-msg-emphasis))
(sit-for 1)))
prompt (mapcar (lambda (buf) (list (buffer-name buf)))
(if current-prefix-arg
(if (wholenump (prefix-numeric-value current-prefix-arg))
(icicle-remove-if-not (lambda (bf)
(or (buffer-file-name bf)
(with-current-buffer bf (eq major-mode 'dired-mode))))
(buffer-list))
(cdr (assq 'buffer-list (frame-parameters))))
(buffer-list)))
(and icompletep icicle-buffer-predicate
(lambda (buf) (funcall icicle-buffer-predicate (car buf))))
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer))
nil 'buffer-name-history nil nil
((buf-names ())
(prompt (or icicle-prompt
"Choose buffer name (`RET' when done): "))
(completion-ignore-case (or (and (boundp 'read-buffer-completion-ignore-case)
read-buffer-completion-ignore-case)
completion-ignore-case))
(icicle-must-match-regexp icicle-buffer-match-regexp)
(icicle-must-not-match-regexp icicle-buffer-no-match-regexp)
(icompletep (and (boundp 'icomplete-mode) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) icicle-buffer-predicate))
(icicle-require-match-flag icicle-buffer-require-match-flag)
(icicle-extra-candidates icicle-buffer-extras)
(icicle-delete-candidate-object 'icicle-kill-a-buffer)
(icicle-transform-function 'icicle-remove-dups-if-extras)
(icicle-sort-comparer (or icicle-buffer-sort icicle-sort-comparer))
(icicle-sort-orders-alist
(append (list '("by last access")
'("*...* last" . icicle-buffer-sort-*...*-last)
'("by buffer size" . icicle-buffer-smaller-p)
'("by major mode name" . icicle-major-mode-name-less-p)
(and (fboundp 'icicle-mode-line-name-less-p)
'("by mode-line mode name" . icicle-mode-line-name-less-p))
'("by file/process name" . icicle-buffer-file/process-name-less-p))
(delete '("turned OFF") icicle-sort-orders-alist)))
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
(icicle-all-candidates-list-alt-action-fn
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
(icicle-use-candidates-only-once-flag t))
nil nil
(prog1 (setq buf-names (nreverse (delete "" buf-names)))
(when (interactive-p) (message "Buffer names: %S" buf-names))))
(icicle-define-command icicle-bookmark-list
"Choose a list of bookmarks.
This is an alist whose entries are bookmark entries. The entries have
the bookmark names as their key. You can use the return value as a
bookmark alist or as a COLLECTION argument for `completing-read'.
With a prefix argument, this is a list of the bookmark names, not an
alist of the full bookmarks.
If `icicle-show-multi-completion-flag' is non-nil, then completion
candidates are multi-completions, with the first part being the
bookmark name and the second part being the bookmark's file or buffer
name. Otherwise, the candidates are just the bookmark names.
If you also use library Bookmark+ (`bookmark+.el') then\\<minibuffer-local-completion-map>:
* Candidates displayed in `*Completions*' are color-coded by type.
* You can sort the candidates (e.g. `C-,') in many more ways.
* When you ask for help on a candidate (e.g. `C-M-return'), detailed
information about the bookmark is shown in `*Help*'. If you use a
prefix arg for this (e.g. `C-u C-M-return') then the full, internal
form of the bookmark is shown.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
You can use `\\[icicle-delete-candidate-object]' during completion to delete a candidate bookmark.
The list of bookmark names (strings) is returned.
Non-interactively:
* If `icicle-bookmark-list-names-only-p' is non-nil, then return a
list of the bookmark names (just as if a prefix arg were used).
* If `icicle-bookmark-types' is non-nil, and you use Bookmark+,
then only bookmarks of those types are used. You can thus bind
this variable around the function call to specialize the behavior
to only certain types."
(lambda (name)
(let ((temp (icicle-transform-multi-completion name)))
(push (if names-only-p
(icicle-unpropertize-completion temp)
(bookmark-get-bookmark (icicle-unpropertize-completion temp)))
chosen-bmks)
(when (interactive-p)
(message "Added bookmark `%s'" (icicle-propertize temp 'face 'icicle-msg-emphasis))
(sit-for 1))))
prompt icicle-candidates-alist nil (not icicle-show-multi-completion-flag)
nil (if (boundp 'bookmark-history) 'bookmark-history 'icicle-bookmark-history)
(and (boundp 'bookmark-current-bookmark) bookmark-current-bookmark) nil
((prompt (or icicle-prompt
"Choose bookmark (`RET' when done): "))
(enable-recursive-minibuffers t)
(completion-ignore-case bookmark-completion-ignore-case)
(icicle-multi-completing-p icicle-show-multi-completion-flag)
(icicle-list-use-nth-parts '(1))
(icicle-candidate-properties-alist (if (not icicle-show-multi-completion-flag)
()
(if (facep 'file-name-shadow)
'((2 (face file-name-shadow))
(3 (face bookmark-menu-heading)))
'((3 (face bookmark-menu-heading))))))
(icicle-transform-function (if (interactive-p) nil icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
(icicle-delete-candidate-object 'icicle-bookmark-delete-action)
(types icicle-bookmark-types)
(names-only-p (if (interactive-p)
current-prefix-arg
icicle-bookmark-list-names-only-p))
(icicle-candidates-alist ())
(chosen-bmks ())
(icicle-unpropertize-completion-result-flag nil)
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order")
("by bookmark name" . icicle-alpha-p))
(and (featurep 'bookmark+)
(append
'(("by last bookmark access" (bmkp-bookmark-last-access-cp) icicle-alpha-p)
("by bookmark visit frequency" (bmkp-visited-more-cp) icicle-alpha-p))
(and (icicle-set-intersection types '("info" "region"))
'(("by Info location" (bmkp-info-cp) icicle-alpha-p)))
(and (icicle-set-intersection types '("gnus" "region"))
'(("by Gnus thread" (bmkp-gnus-cp) icicle-alpha-p)))
(and (icicle-set-intersection types '("url" "region"))
'(("by URL" (bmkp-url-cp) icicle-alpha-p)))
(and (icicle-set-difference types
'("bookmark-list" "desktop" "gnus" "info" "man" "url"))
'(("by bookmark type" (bmkp-info-cp bmkp-url-cp bmkp-gnus-cp
bmkp-local-file-type-cp bmkp-handler-cp)
icicle-alpha-p)))
(and (icicle-set-difference
types '("bookmark-list" "desktop" "dired" "non-file"))
'(("by file name" (bmkp-file-alpha-cp) icicle-alpha-p)))
(and (icicle-set-intersection types
'("local-file" "file" "dired" "region"))
'(("by local file type" (bmkp-local-file-type-cp) icicle-alpha-p)
("by local file size" (bmkp-local-file-size-cp) icicle-alpha-p)
("by last local file access"
(bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)
("by last local file update" (bmkp-local-file-updated-more-recently-cp)
icicle-alpha-p)))
(and (not (equal types '("desktop")))
'(("by last buffer or file access"
(bmkp-buffer-last-access-cp
bmkp-local-file-accessed-more-recently-cp)
icicle-alpha-p)))
(and (get-buffer "*Bookmark List*")
'(("marked before unmarked (in *Bookmark List*)" (bmkp-marked-cp)
icicle-alpha-p)))))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
(icicle-candidate-help-fn
(lambda (cand)
(when (and (featurep 'bookmark+) icicle-show-multi-completion-flag)
(setq cand (funcall icicle-get-alist-candidate-function cand))
(setq cand (cons (caar cand) (cdr cand))))
(if (featurep 'bookmark+)
(if current-prefix-arg
(bmkp-describe-bookmark-internals cand)
(bmkp-describe-bookmark cand))
(icicle-msg-maybe-in-minibuffer (icicle-bookmark-help-string cand))))))
(progn
(message "Gathering bookmarks...")
(bookmark-maybe-load-default-file)
(if (not (featurep 'bookmark+))
(mapcar (lambda (cand) (list (icicle-candidate-short-help
(icicle-bookmark-help-string cand)
(icicle-bookmark-propertize-candidate cand))))
bookmark-alist)
(unless types (setq types '(all)))
(dolist (type types)
(setq icicle-candidates-alist (nconc icicle-candidates-alist
(mapcar #'icicle-make-bookmark-candidate
(bmkp-sort-omit
(if (eq type 'all)
bookmark-alist
(funcall (intern (format "bmkp-%s-alist-only"
type)))))))))))
(icicle-bookmark-cleanup-on-quit)
(prog1 (setq chosen-bmks (nreverse (delete "" chosen-bmks)))
(icicle-bookmark-cleanup)
(when (interactive-p)
(message "Bookmarks: %S" (if names-only-p chosen-bmks (mapcar #'car chosen-bmks))))))
(icicle-define-file-command icicle-file-list
"Choose a list of file and directory names (strings), and return it.
Use multi-command action keys (e.g. \\<minibuffer-local-completion-map>`C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
You can navigate the directory tree, picking files and directories
anywhere in the tree.
Remember too that you can use `\\[icicle-all-candidates-action]' to gather all of the file names
matching your current input. For example, apropos-completing with
input `foo.*bar' and hitting `\\[icicle-all-candidates-action]' adds all file names matching that
regexp.
You can use either `RET' or `C-g' to finish adding file names to the
list.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra file names to display
`icicle-file-match-regexp' - Regexp that file names must match
`icicle-file-no-match-regexp' - Regexp file names must not match
`icicle-file-predicate' - Predicate file names must satisfy
`icicle-file-sort' - Sort function for candidates
For example, to show only names of files larger than 5000 bytes, set
`icicle-file-predicate' to:
(lambda (file) (and (numberp (nth 7 (file-attributes file)))
(> (nth 7 (file-attributes file)) 5000)))
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (name)
(push name file-names)
(when (interactive-p)
(message "Added file name `%s'" (icicle-propertize name 'face 'icicle-msg-emphasis)) (sit-for 1)))
prompt nil nil t nil nil
(icicle-file-bindings
((prompt (or icicle-prompt
"Choose file (`RET' when done): "))
(file-names ())
(icicle-comp-base-is-default-dir-p t)
))
(icicle-bind-file-candidate-keys)
nil
(prog1 (setq file-names (nreverse (delete "" file-names)))
(icicle-unbind-file-candidate-keys)
(when (interactive-p) (message "Files: %S" file-names))))
(icicle-define-file-command icicle-directory-list
"Choose a list of directory names (strings), and return it.
You must include a slash (`/') at the end of each directory name.
Use multi-command action keys (e.g. `C-RET', `C-mouse-2') to choose,
and a final-choice key (e.g. `RET', `mouse-2') to choose the last one.
You can navigate the directory tree, picking directories anywhere in
the tree.
If `icicle-add-proxy-candidates-flag' is non-nil, then certain Emacs
variables whose values are lists of directories are available as proxy
candidates. This includes variables such as `load-path' and
`exec-path'. You can toggle `icicle-add-proxy-candidates-flag' using
\\<minibuffer-local-completion-map>\
`\\[icicle-toggle-proxy-candidates]'in the minibuffer.
When you choose a proxy candidate all of its directories are added to
the result list. Non-directory elements in the variable value are
ignored - only string elements are retained. And none of the string
elements are checked to see whether they actually correspond to an
existing directory.
Keep in mind that only those proxy candidates that match your current
input are available. In particular, if `insert-default-directory' is
non-nil then you will want to use `\\[icicle-erase-minibuffer-or-history-element]' to remove the default
directory from the minibuffer when you want to match proxy candidates.
During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
can use the following keys:
C-c + - create a new directory
\\[icicle-all-candidates-list-alt-action] - open Dired on the currently matching file names
\\[icicle-delete-candidate-object] - delete candidate file or (empty) dir
* C-x C-t * - narrow to files with all of the tags you specify
* C-x C-t + - narrow to files with some of the tags you specify
* C-x C-t % * - narrow to files with all tags matching a regexp
* C-x C-t % + - narrow to files with some tags matching a regexp
* C-x a + - add tags to current candidate
* C-x a - - remove tags from current candidate
* C-x m - access file bookmarks (not just autofiles)
These options, when non-nil, control candidate matching and filtering:
`icicle-file-extras' - Extra directory names to display
`icicle-file-match-regexp' - Regexp directory names must match
`icicle-file-no-match-regexp' - Regexp dir names must not match
`icicle-file-predicate' - Predicate the dir names must satisfy
`icicle-file-sort' - Sort function for candidates
Option `icicle-file-require-match-flag' can be used to override
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
Ido-like behavior."
(lambda (name)
(if (member (file-name-nondirectory name)
keep-proxy-cands)
(setq name (symbol-value (intern (file-name-nondirectory name)))
dir-names (append (icicle-remove-if-not #'stringp name) dir-names))
(push name dir-names))
(when (interactive-p)
(message "Added directory name `%s'" (icicle-propertize name 'face 'icicle-msg-emphasis))
(sit-for 1)))
prompt nil nil t nil nil
(icicle-file-bindings
((prompt (or icicle-prompt
"Choose directory (`RET' when done): "))
(dir-names ())
(icicle-exclude-default-proxies t)
(icicle-proxy-candidates
(let ((ipc ()))
(when icicle-add-proxy-candidates-flag
(setq ipc (mapcar #'symbol-name
(icicle-remove-if-not
(lambda (symb)
(and (boundp symb) (consp (symbol-value symb))
(let ((dirs (symbol-value symb)))
(catch 'icicle-directory-list
(dolist (dir dirs)
(when (stringp dir) (throw 'icicle-directory-list t)))
nil))))
icicle-path-variables))))
ipc))
(keep-proxy-cands icicle-proxy-candidates)
(user-file-pred icicle-file-predicate)
(icicle-file-predicate (if user-file-pred
(lambda (f)
(and (file-directory-p f) (funcall user-file-pred f)))
#'file-directory-p))
(icicle-comp-base-is-default-dir-p t)
))
(progn (icicle-bind-file-candidate-keys)
(when icicle-proxy-candidates (put-text-property 0 1 'icicle-fancy-candidates t prompt)))
nil
(prog1 (setq dir-names (nreverse (delete "" dir-names)))
(icicle-unbind-file-candidate-keys)
(setq icicle-proxy-candidates ())
(when (interactive-p) (message "Directories: %S" dir-names))))
(provide 'icicles-cmd1)