;; Filename: icicles-cmd1.el
;; Description: Top-level commands for Icicles
;; Author: Drew Adams
-;; Maintainer: Drew Adams
-;; Copyright (C) 1996-2013, Drew Adams, all rights reserved.
+;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
+;; Copyright (C) 1996-2014, Drew Adams, all rights reserved.
;; Created: Mon Feb 27 09:25:04 2006
-;; Version: 22.0
-;; Last-Updated: Sat Apr 6 21:42:22 2013 (-0700)
+;; Last-Updated: Sun Mar 9 09:59:48 2014 (-0700)
;; By: dradams
-;; Update #: 25681
+;; Update #: 26878
;; URL: http://www.emacswiki.org/icicles-cmd1.el
;; Doc URL: http://www.emacswiki.org/Icicles
;; Keywords: extensions, help, abbrev, local, minibuffer,
;; Features that might be required by this library:
;;
;; `apropos', `apropos-fn+var', `avoid', `cl', `cus-edit',
-;; `cus-face', `cus-load', `cus-start', `doremi', `easymenu',
-;; `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds', `frame-fns',
-;; `fuzzy', `fuzzy-match', `hexrgb', `icicles-fn', `icicles-mcmd',
-;; `icicles-opt', `icicles-var', `image-dired', `kmacro',
-;; `levenshtein', `misc-fns', `mouse3', `mwheel', `naked',
-;; `regexp-opt', `ring', `ring+', `second-sel', `strings',
+;; `cus-face', `cus-load', `cus-start', `cus-theme', `doremi',
+;; `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
+;; `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-fn',
+;; `icicles-mcmd', `icicles-opt', `icicles-var', `image-dired',
+;; `kmacro', `levenshtein', `misc-fns', `mouse3', `mwheel',
+;; `naked', `regexp-opt', `ring', `second-sel', `strings',
;; `thingatpt', `thingatpt+', `wid-edit', `wid-edit+', `widget'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; using Emacs 23. Otherwise, Icicles key completion (and perhaps
;; other things?) will not work correctly.
;;
+;; Macros defined here:
+;;
+;; `icicle-find-file-abs-no-search-action-1',
+;; `icicle-find-file-abs-of-content-action-1',
+;; `icicle-find-file-no-search-action-1',
+;; `icicle-find-file-of-content-action-1'.
+;;
;; Widgets defined here:
;;
;; `icicle-file', `icicle-ORIG-file'.
;; (+)`icicle-customize-apropos-opts-w-val-satisfying',
;; (+)`icicle-customize-face',
;; (+)`icicle-customize-face-other-window',
-;; `icicle-customize-icicles-group', `icicle-dabbrev-completion',
-;; (+)`icicle-delete-file', (+)`icicle-delete-window',
-;; (+)`icicle-describe-option-of-type', `icicle-describe-process',
+;; `icicle-customize-icicles-group', (+)`icicle-custom-theme',
+;; `icicle-dabbrev-completion', (+)`icicle-delete-file',
+;; (+)`icicle-delete-window', (+)`icicle-describe-option-of-type',
+;; `icicle-describe-process',
;; (+)`icicle-describe-var-w-val-satisfying',
;; (+)`icicle-delete-windows', (+)`icicle-directory-list',
;; (+)`icicle-dired', `icicle-dired-chosen-files',
;; (+)`icicle-execute-named-keyboard-macro', (+)`icicle-face-list',
;; (+)`icicle-file', (+)`icicle-file-list',
;; (+)`icicle-file-other-window', (+)`icicle-find-file',
+;; (+)`icicle-find-file-abs-no-search',
+;; (+)`icicle-find-file-abs-no-search-other-window',
+;; (+)`icicle-find-file-abs-of-content',
+;; (+)`icicle-find-file-abs-of-content-other-window',
;; (+)`icicle-find-file-absolute',
;; (+)`icicle-find-file-absolute-other-window',
+;; (+)`icicle-find-file-abs-read-only',
+;; (+)`icicle-find-file-abs-read-only-other-window',
;; (+)`icicle-find-file-in-tags-table',
;; (+)`icicle-find-file-in-tags-table-other-window',
;; (+)`icicle-find-file-of-content',
+;; (+)`icicle-find-file-of-content-in-tags-table',
+;; (+)`icicle-find-file-of-content-in-tags-table-other-window',
;; (+)`icicle-find-file-of-content-other-window',
;; (+)`icicle-find-file-other-window',
;; (+)`icicle-find-file-no-search',
+;; (+)`icicle-find-file-no-search-in-tags-table',
+;; (+)`icicle-find-file-no-search-in-tags-table-other-window',
;; (+)`icicle-find-file-no-search-other-window',
;; (+)`icicle-find-file-read-only',
;; (+)`icicle-find-file-read-only-other-window',
;; (+)`icicle-keyword-list', (+)`icicle-kill-buffer',
;; (+)`icicle-kmacro', `icicle-lisp-complete-symbol',
;; (+)`icicle-locate', (+)`icicle-locate-file',
+;; (+)`icicle-locate-file-no-search',
+;; (+)`icicle-locate-file-no-search-no-symlinks',
+;; (+)`icicle-locate-file-no-search-no-symlinks-other-window',
+;; (+)`icicle-locate-file-no-search-other-window',
;; (+)`icicle-locate-file-no-symlinks',
;; (+)`icicle-locate-file-no-symlinks-other-window',
+;; (+)`icicle-locate-file-of-content',
+;; (+)`icicle-locate-file-of-content-no-symlinks',
+;; (+)`icicle-locate-file-of-content-no-symlinks-other-window',
+;; (+)`icicle-locate-file-of-content-other-window',
;; (+)`icicle-locate-file-other-window',
-;; (+)`icicle-locate-other-window', `icicle-ORIG-customize-face',
+;; (+)`icicle-locate-other-window', (+)`icicle-locate-no-search',
+;; (+)`icicle-locate-no-search-other-window',
+;; (+)`icicle-locate-of-content',
+;; (+)`icicle-locate-of-content-other-window',
+;; `icicle-ORIG-customize-face',
;; `icicle-ORIG-customize-face-other-window',
;; `icicle-ORIG-dabbrev-completion',
;; `icicle-ORIG-lisp-complete-symbol',
;; `icicle-ORIG-repeat-complex-command',
;; (+)`icicle-other-window-or-frame', `icicle-pop-tag-mark',
;; `icicle-pp-eval-expression', (+)`icicle-recent-file',
+;; (+)`icicle-recent-file-no-search',
+;; (+)`icicle-recent-file-no-search-other-window',
+;; (+)`icicle-recent-file-of-content',
+;; (+)`icicle-recent-file-of-content-other-window',
;; (+)`icicle-recent-file-other-window',
;; `icicle-recompute-shell-command-candidates',
;; (+)`icicle-regexp-list', (+)`icicle-remove-buffer-candidate',
;; (+)`icicle-string-list', (+)`icicle-toggle-option',
;; (+)`icicle-visit-marked-file-of-content',
;; (+)`icicle-visit-marked-file-of-content-other-window',
+;; (+)`icicle-visit-marked-file-of-content-recursive',
+;; (+)`icicle-visit-marked-file-of-content-recursive-other-window',
;; `icicle-widget-file-complete',
;; (+)`icicle-yank-maybe-completing',
;; (+)`icicle-yank-pop-commands', `icicle-zap-to-char',
;; Non-interactive functions defined here:
;;
;; `custom-variable-p', `icicle-apropos-opt-action',
-;; `icicle-binary-option-p',
+;; `icicle-binary-option-p', `icicle-bookmark-act-on-prop',
;; `icicle-bookmark-bind-narrow-commands',
;; `icicle-bookmark-cleanup', `icicle-bookmark-cleanup-on-quit',
-;; `icicle-bookmark-delete-action', `icicle-bookmark-help-string',
-;; `icicle-bookmark-jump-1',
+;; `icicle-bookmark-delete-action', `icicle-bookmark-help',
+;; `icicle-bookmark-help-string', `icicle-bookmark-jump-1',
;; `icicle-buffer-apropos-complete-match',
;; `icicle-buffer-cand-help', `icicle-buffer-multi-complete',
;; `icicle-buffer-name-prompt',
;; `icicle-describe-opt-of-type-complete',
;; `icicle-execute-extended-command-1', `icicle-explore',
;; `icicle-file-of-content-apropos-complete-match',
+;; (+)`icicle-find-file-abs-no-search-1',
+;; `icicle-find-file-abs-no-search-action',
+;; `icicle-find-file-abs-no-search-other-window-action',
+;; `icicle-find-file-abs-no-search-ro-action',
+;; `icicle-find-file-abs-no-search-ro-ow-action',
+;; (+)`icicle-find-file-abs-of-content-1',
+;; `icicle-find-file-abs-of-content-action',
+;; `icicle-find-file-abs-of-content-other-window-action',
+;; `icicle-find-file-abs-of-content-ro-action',
+;; `icicle-find-file-abs-of-content-ro-ow-action',
+;; `icicle-find-file-no-search-action',
+;; `icicle-find-file-no-search-other-window-action',
+;; (+)`icicle-find-file-no-search-in-tags-table-1',
+;; (+)`icicle-find-file-of-content-in-tags-table-1',
+;; `icicle-find-file-of-content-ro-action',
+;; `icicle-find-file-of-content-ro-ow-action',
+;; `icicle-find-file-or-expand-dir',
;; `icicle-find-first-tag-action',
;; `icicle-find-first-tag-other-window-action',
;; `icicle-find-tag-action', `icicle-find-tag-define-candidates',
;; `icicle-find-tag-quit-or-error', `icicle-insert-for-yank',
;; `icicle-kill-a-buffer-and-update-completions',
;; `icicle-kmacro-action', `icicle-lisp-completion-at-point',
-;; (+)`icicle-locate-file-1', `icicle-locate-file-action',
-;; `icicle-locate-file-other-window-action',
+;; (+)`icicle-locate-file-no-search-1',
+;; (+)`icicle-locate-file-of-content-1',
;; `icicle-make-bookmark-candidate',
;; `icicle-make-file+date-candidate', `icicle-make-frame-alist',
;; `icicle-make-window-alist',
;; `icicle-bookmark-propertize-candidate',
;; `icicle-pp-display-expression',
;; `icicle-read-args-w-val-satisfying',
+;; (+)`icicle-recent-file-of-content-1',
;; `icicle-recent-files-without-buffers.',
;; `icicle-remove-buffer-candidate-action',
;; `icicle-remove-buffer-config-action',
;; `icicle-remove-saved-set-action',
;; `icicle-shell-command-on-file',
;; `icicle-shell-dynamic-complete-as-command',
-;; `icicle-shell-dynamic-complete-as-environment-variable'.
+;; `icicle-shell-dynamic-complete-as-environment-variable',
+;; (+)`icicle-visit-marked-file-of-content-1'.
;;
;; Internal variables defined here:
;;
-;; `icicle-locate-file-action-fn',
+;; `icicle-dabbrev--last-completion-buffer',
+;; `icicle-dabbrev--last-obarray', `icicle-existing-bufs',
+;; `icicle-find-file-abs-action-fn', `icicle-find-file-action-fn',
;; `icicle-locate-file-no-symlinks-p',
-;; `icicle-locate-file-use-locate-p'.
+;; `icicle-locate-file-use-locate-p', `icicle-new-bufs-to-keep',
+;; `icicle-new-bufs-to-kill', `icicle-vmfoc-other-win-p',
+;; `icicle-vmfoc-recursive-p'.
;;
;;
;; ***** NOTE: The following functions defined in `dabbrev.el' have
;; been REDEFINED HERE:
;; (BBDB is available here: http://bbdb.sourceforge.net/.)
;;
-;; `bbdb-complete-name' - Use Icicles minibuffer completion when there
+;; `icicle-bbdb-complete-mail', `bbdb-complete-name' -
+;; Use Icicles minibuffer completion when there
;; are multiple candidates.
;;
;;
;; headings throughout this file. You can get `linkd.el' here:
;; http://dto.freeshell.org/notebook/Linkd.html.
;;
+;; (@> "Internal Variables (alphabetical)")
+;; (@> "Macros")
;; (@> "Icicles Top-Level Commands, Part 1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(eval-when-compile
(when (< emacs-major-version 24) ; $$$$$$$$ TODO: Update it for Emacs 24+
(require 'dabbrev)))
- ;; dabbrev-case-fold-search, dabbrev-upcase-means-case-search, dabbrev--last-obarray,
- ;; dabbrev--last-completion-buffer, dabbrev--last-abbreviation, dabbrev--check-other-buffers,
- ;; dabbrev-case-replace, dabbrev--reset-global-variables, dabbrev--minibuffer-origin,
+ ;; dabbrev-case-fold-search, dabbrev-upcase-means-case-search, dabbrev--last-abbreviation,
+ ;; dabbrev--check-other-buffers, dabbrev-case-replace, dabbrev--reset-global-variables,
;; dabbrev--find-all-expansions, dabbrev--substitute-expansion
(eval-when-compile (require 'bookmark))
;; bookmark-all-names, bookmark-buffer-name, bookmark-current-bookmark
;; icicle-candidates-alist, icicle-color-theme-history, icicle-command-abbrev-history,
;; icicle-commands-for-abbrev, icicle-comp-base-is-default-dir-p, icicle-completion-candidates,
;; icicle-completion-set-history, icicle-current-input, icicle-delete-candidate-object,
- ;; icicle-explore-final-choice, icicle-explore-final-choice-full, icicle-extra-candidates,
- ;; icicle-face-name-history, icicle-frame-alist, icicle-frame-name-history, icicle-full-cand-fn,
- ;; icicle-function-name-history, icicle-get-alist-candidate-function, icicle-hist-var,
+ ;; icicle-explore-final-choice, icicle-explore-final-choice-full,
+ ;; icicle-extra-candidates, icicle-face-name-history, icicle-frame-alist, icicle-frame-name-history,
+ ;; icicle-full-cand-fn, icicle-function-name-history, icicle-get-alist-candidate-function, icicle-hist-var,
;; icicle-incremental-completion-p, icicle-inhibit-sort-p, icicle-inhibit-try-switch-buffer,
;; icicle-kill-history, icicle-kmacro-alist, icicle-kmacro-history,icicle-list-use-nth-parts,
;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate,
- ;; icicle-new-last-cmd, icicle-orig-buff, icicle-orig-must-pass-after-match-pred,
- ;; icicle-orig-pt-explore, icicle-orig-window, icicle-orig-win-explore, icicle-pref-arg,
- ;; icicle-previous-raw-file-name-inputs, icicle-previous-raw-non-file-name-inputs, icicle-prompt,
- ;; icicle-proxy-candidates, icicle-read-expression-map, icicle-remove-icicles-props-p,
- ;; icicle-re-no-dot, icicle-saved-completion-candidates, icicle-search-history,
- ;; icicle-transform-before-sort-p, icicle-use-candidates-only-once-alt-p,
- ;; icicle-whole-candidate-as-text-prop-p, icicle-variable-name-history
+ ;; icicle-new-last-cmd, icicle-orig-buff, icicle-orig-must-pass-after-match-pred, icicle-orig-pt-explore,
+ ;; icicle-orig-window, icicle-orig-win-explore, icicle-pref-arg, icicle-previous-raw-file-name-inputs,
+ ;; icicle-previous-raw-non-file-name-inputs, icicle-prompt, icicle-proxy-candidates,
+ ;; icicle-read-expression-map, icicle-remove-icicles-props-p, icicle-re-no-dot,
+ ;; icicle-saved-completion-candidates, icicle-search-history, icicle-transform-before-sort-p,
+ ;; icicle-use-candidates-only-once-alt-p, icicle-whole-candidate-as-text-prop-p,
+ ;; icicle-variable-name-history
(require 'icicles-fn) ; (This is required anyway by `icicles-mcmd.el'.)
;; icicle-delete-dups, icicle-highlight-lighter, icicle-multi-comp-apropos-complete-match,
- ;; icicle-read-from-minibuf-nil-default, icicle-string-match-p
+ ;; icicle-read-from-minibuf-nil-default, icicle-read-regexp, icicle-string-match-p
;; Byte-compiling this file, you will likely get some byte-compiler warning messages.
(defvar icicle-kmacro-alist) ; In `icicles-var.el'
(defvar kmacro-ring) ; In `kmacro.el'
(defvar read-file-name-completion-ignore-case) ; In `minibuffer.el'
- (defvar recentf-list) ; In `recentf.el'
(defvar tags-case-fold-search) ; In `etags.el'
(defvar tooltip-mode)) ; In `tooltip.el'
(defvar apropos-do-all) ; In `apropos.el'
(defvar bbdb-complete-mail-allow-cycling) ; In `bbdb-com.el'
-(defvar bbdb-complete-name-allow-cycling) ; In `bbdb-com.el'
+(defvar bbdb-complete-name-allow-cycling) ; In `bbdb-com.el', older BBDB versions
(defvar bbdb-completion-list) ; In `bbdb-come.el'
(defvar bbdb-extract-address-components-func) ; In `bbdb-com.el'
(defvar bbdb-expand-mail-aliases) ; In `bbdb-com.el'
-(defvar bbdb-complete-name-hooks) ; In `bbdb-com.el'
+(defvar bbdb-complete-name-hooks) ; In `bbdb-com.el', older BBDB versions
(defvar bbdb-completion-display-record) ; In `bbdb.el'
(defvar bbdb-completion-type) ; In `bbdb.el'
(defvar bbdb-hashtable) ; In `bbdb.el'
(defvar bmkp-non-file-filename) ; In `bookmark+-1.el'
(defvar bmkp-prompt-for-tags-flag) ; In `bookmark+-1.el'
(defvar bmkp-sorted-alist) ; In `bookmark+-1.el'
-(defvar bookmark-current-point) ; In `bookmark.el' for Emacs <
+(defvar bookmark-current-point) ; In `bookmark.el' (Emacs < 23)
(defvar color-theme) ; In `color-theme.el'
(defvar color-themes) ; In `color-theme.el'
(defvar color-theme-initialized) ; In `color-theme.el'
(defvar cookie-cache)
-(defvar dabbrev--last-obarray) ; In `dabbrev.el' for Emacs < 24
-(defvar dabbrev--last-completion-buffer) ; In `dabbrev.el' for Emacs < 24
+(defvar custom-enabled-themes) ; In `custom.el' (Emacs 24+)
+(defvar dabbrev-case-fold-search) ; In `dabbrev.el'
+(defvar dabbrev-case-replace) ; In `dabbrev.el'
+(defvar dabbrev-abbrev-char-regexp) ; In `dabbrev.el'
+(defvar dabbrev--check-other-buffers) ; In `dabbrev.el'
+(defvar dabbrev--last-abbreviation) ; In `dabbrev.el'
+(defvar dabbrev--last-abbrev-location) ; In `dabbrev.el'
+(defvar dabbrev-upcase-means-case-search) ; In `dabbrev.el'
(defvar ess-current-process-name) ; In `ess-inf.el'
(defvar ess-mode-syntax-table) ; In `ess-cust.el'
(defvar ess-use-R-completion) ; In `ess-cust.el'
-(defvar existing-bufs) ; `icicle-visit-marked-file-of-content', `icicle-find-file-of-content'
(defvar file-cache-alist) ; In `filecache.el'
(defvar filesets-data) ; In `filesets.el'
(defvar find-tag-default-function) ; In `etags.el'
(defvar goto-tag-location-function) ; In `etags.el'
(defvar icicle-buffer-easy-files) ; Here
(defvar icicle-clear-history-hist) ; In `icicle-clear-history-1',`icicle-clear-current-history'
+(defvar icicle-custom-themes) ; In `icicles-opt.el' (Emacs 24+)
+(defvar icicle-custom-themes-accumulate-flag) ; In `icicles-opt.el' (Emacs 24+)
+(defvar icicle-custom-themes-update-flag) ; In `icicles-opt.el' (Emacs 24+)
(defvar icicle--last-toggle-transforming-msg) ; Here
(defvar icicle-window-alist) ; In `icicle-select-window'
(defvar locate-make-command-line) ; In `locate.el'
(defvar proced-signal-list) ; In `proced.el' (Emacs 23+)
+(defvar recentf-list) ; In `recentf.el'
(defvar shell-completion-execonly) ; In `shell.el'
(defvar snarf-tag-function) ; In `etags.el'
(defvar translation-table-for-input) ; Built-in, Emacs 21+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;(@* "Internal Variables (alphabetical)")
+
+;;; Internal variables (alphabetical) --------------------------------
+
+(defvar icicle-existing-bufs ()
+ "List of existing buffers before a content-searching command.")
+
+(defvar icicle-find-file-abs-action-fn nil
+ "Action function used in commands that find an absolute file name.")
+
+(defvar icicle-find-file-action-fn nil
+ "Action function used in commands that use `read-file-name'.")
+
+(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*' uses external command `locate'.")
+
+(defvar icicle-new-bufs-to-keep ()
+ "List of temporary buffers for content-searching commands.")
+
+(defvar icicle-new-bufs-to-kill ()
+ "List of temporary buffers for content-searching commands.")
+
+;;(@* "Macros")
+
+;;; Macros -----------------------------------------------------------
+
+(defmacro icicle-find-file-abs-no-search-action-1 (other-window-p read-only-p)
+ "Action function for commands reading absolute file names without searching.
+Non-nil OTHER-WINDOW-P means use other window.
+Non-nil READ-ONLY-P means visit file in read-only mode."
+ `(lambda (file)
+ (let ((r-o (or ,read-only-p
+ (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
+ (if ,other-window-p
+ (find-file-read-only-other-window fil 'WILDCARDS)
+ (find-file-read-only fil 'WILDCARDS))
+ (if ,other-window-p
+ (find-file-other-window fil 'WILDCARDS)
+ (find-file fil 'WILDCARDS))))))
+
+(defmacro icicle-find-file-no-search-action-1 (other-window-p)
+ "Action function for commands using `read-file-name' without searching.
+Non-nil OTHER-WINDOW-P means use other window."
+ ;; FREE VARS here: CURRENT-PREFIX-ARG, THIS-COMMAND, `icicle-pref-arg'.
+ `(lambda (file)
+ (let ((r-o (if (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
+ icicle-all-candidates-action))
+ (or (and ,icicle-pref-arg (not current-prefix-arg))
+ (and (not ,icicle-pref-arg) current-prefix-arg))
+ ,icicle-pref-arg)))
+ (icicle-find-file-or-expand-dir file #'icicle-find-file-no-search-1 r-o ,other-window-p))))
+
+(defmacro icicle-find-file-abs-of-content-action-1 (other-window-p read-only-p)
+ "File-visiting action function for commands reading absolute file names.
+Non-nil OTHER-WINDOW-P means use other window.
+Non-nil READ-ONLY-P means visit file in read-only mode."
+ `(lambda (file)
+ (setq file (icicle-transform-multi-completion file)
+ file (if (string= "" (file-name-nondirectory file)) (directory-file-name file) file))
+ (let* ((r-o (or ,read-only-p
+ (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
+ icicle-all-candidates-action))
+ current-prefix-arg))) ; Use this, not `icicle-pref-arg': for this candidate.
+ ;; If FILE uses wildcards there are multiple files to visit.
+ (wildfiles (file-expand-wildcards file)))
+
+ ;; For each matching file name, kill any buffers created for content-searching it, so that
+ ;; `find-file*' DTRT wrt file-local variable declarations, file handlers, find-file hooks etc.
+ (dolist (fil wildfiles)
+ (let ((created-buf (car (memq (find-buffer-visiting fil) icicle-new-bufs-to-kill))))
+ (when (and (buffer-live-p created-buf) (not (memq created-buf icicle-new-bufs-to-keep)))
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (with-current-buffer created-buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (setq icicle-new-bufs-to-kill (delete created-buf icicle-new-bufs-to-kill))
+;;; (kill-buffer created-buf)))))
+ (setq icicle-new-bufs-to-kill (delete created-buf icicle-new-bufs-to-kill))
+ (kill-buffer created-buf))))
+
+ ;; Visit properly (mode, vars, handlers, hooks).
+ (let ((fn (if r-o
+ (if ,other-window-p #'find-file-read-only-other-window #'find-file-read-only)
+ (if ,other-window-p #'find-file-other-window #'find-file))))
+ (funcall fn file 'WILDCARDS))
+
+ ;; Add the visited buffers to those we will keep (not kill).
+ ;; For a directory, get the Dired buffer instead of using `get-file-buffer'.
+ (dolist (fil wildfiles)
+ (when (setq fil (if (file-directory-p fil)
+ (get-buffer (file-name-nondirectory fil))
+ (get-file-buffer fil)))
+ (push fil icicle-new-bufs-to-keep))))))
+
+(defmacro icicle-find-file-of-content-action-1 (other-window-p read-only-p)
+ "Action function for commands using `read-file-name' with content searching.
+Non-nil OTHER-WINDOW-P means use other window.
+Non-nil READ-ONLY-P means visit file in read-only mode."
+ ;; FREE VARS here: CURRENT-PREFIX-ARG, THIS-COMMAND, `icicle-new-bufs-to-kill', `icicle-new-bufs-to-keep'.
+ `(lambda (file) ; Action function
+ (setq file (icicle-transform-multi-completion file))
+ (setq file (if (string= "" (file-name-nondirectory file)) (directory-file-name file) file))
+ (let* ((r-o (or ,read-only-p
+ (and (memq this-command '(icicle-candidate-action icicle-mouse-candidate-action
+ icicle-all-candidates-action))
+ current-prefix-arg))) ; Use this, not `icicle-pref-arg': for this candidate.
+ ;; If FILE uses wildcards then there are multiple files to visit.
+ (wildfiles (file-expand-wildcards file)))
+
+ ;; For each matching file name, kill any buffers created for content-searching it, so that
+ ;; `find-file*' DTRT wrt file-local variable declarations, file handlers, find-file hooks etc.
+ (dolist (fil wildfiles)
+ (let ((created-buf (car (memq (find-buffer-visiting fil) icicle-new-bufs-to-kill))))
+ (when (and (buffer-live-p created-buf) (not (memq created-buf icicle-new-bufs-to-keep)))
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (with-current-buffer created-buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (setq icicle-new-bufs-to-kill (delete created-buf icicle-new-bufs-to-kill))
+;;; (kill-buffer created-buf)))))
+ (setq icicle-new-bufs-to-kill (delete created-buf icicle-new-bufs-to-kill))
+ (kill-buffer created-buf))))
+
+ ;; Visit properly (mode, vars, handlers, hooks).
+ (icicle-find-file-or-expand-dir file #'icicle-find-file-of-content-1 r-o ,other-window-p)
+
+ ;; Add the visited buffers to those we will keep (not kill).
+ ;; For a directory, get the Dired buffer instead of using `get-file-buffer'.
+ (dolist (fil wildfiles)
+ (when (setq fil (if (file-directory-p fil)
+ (get-buffer (file-name-nondirectory fil))
+ (get-file-buffer fil)))
+ (push fil icicle-new-bufs-to-keep))))))
+
;;(@* "Icicles Top-Level Commands, Part 1")
-;;; Icicles Top-Level Commands, Part 1 . . . . . . . . .
+
+;;; Icicles Top-Level Commands, Part 1 -------------------------------
;; REPLACE ORIGINAL `pp-eval-expression' defined in `pp.el',
(setq values (cons (eval expression) values))
(let ((old-value (make-symbol "t"))
new-value)
- ;; Bind debug-on-error to something unique so that we can
- ;; detect when evaled code changes it.
+ ;; Bind `debug-on-error' to something unique so that we can detect when evaled code changes it.
(let ((debug-on-error old-value))
(setq values (cons (eval expression) values)
new-value debug-on-error))
- ;; If evaled code has changed the value of debug-on-error,
- ;; propagate that change to the global binding.
+ ;; If evaled code has changed the value of `debug-on-error', propagate that change to the global binding.
(unless (eq old-value new-value)
(setq debug-on-error new-value))))
(let ((print-length icicle-pp-eval-expression-print-length)
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
+ (enable-recursive-minibuffers t)
(choice
(save-excursion
(save-window-excursion (read-file-name "Complete: " directory nil t)))))
;; Insert completion. The completion string might have a different case from
;; what's in the prompt, if `read-file-name-completion-ignore-case' is non-nil.
(delete-region filename-beg filename-end)
- (if filedir (insert (comint-quote-filename filedir)))
+ (when filedir (insert (comint-quote-filename filedir)))
(insert (comint-quote-filename (directory-file-name completion)))
(cond ((symbolp (file-name-completion completion directory))
;; We inserted a unique completion. Add suffix.
(let* ((icicle-show-Completions-initially-flag t)
(icicle-incremental-completion-p 'display)
(icicle-top-level-when-sole-completion-flag t)
+ (enable-recursive-minibuffers t)
(choice
(save-excursion
(save-window-excursion
plus those that effect file completion.
See `icicle-shell-dynamic-complete-as-command'.
-Returns t if successful.
+Return 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)))))
+ (when (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.
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.
+Return nil if no completion was inserted.
+Return `sole' if completed with the only completion match.
+Return `shortest' if completed with the shortest match.
+Return `partial' if completed as far as possible.
+Return `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)))
(insert suffix)
'sole))
(t ; There's no unique completion.
- (let ((completion (try-completion stub candidates)))
+ (let ((completion (try-completion stub candidates))
+ (enable-recursive-minibuffers t))
;; Insert the longest substring.
(insert (substring completion (length stub)))
(cond ((and comint-completion-recexact comint-completion-addsuffix
(string-equal stub completion)
(member completion completions))
- (insert suffix) ; User wants shortest match.
+ (insert suffix) ; Not unique but user wants shortest match.
(unless minibuffer-p (message "Completed shortest"))
'shortest)
((or comint-completion-autolist (string-equal stub 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)))))
+ (when (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."
(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)))
+ (when (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))
(icicle-comint-dynamic-simple-complete command-word complete-list)))
+(defvar icicle-dabbrev--last-obarray nil
+ "Last obarray of completions used by `icicle-dabbrev-completion'.")
+
+(defvar icicle-dabbrev--last-completion-buffer nil
+ "Buffer last completed in by `icicle-dabbrev-completion'.")
+
+
;; REPLACE ORIGINAL `dabbrev-completion' defined in `dabbrev.el',
;; saving it for restoration when you toggle `icicle-mode'.
;;
;; You can complete from an empty abbrev also.
;; Uses Icicles completion when there are multiple candidates.
;;
-(when (< emacs-major-version 24) ; $$$$$$$$ TODO: Update this for Emacs 24+.
+(when (and (fboundp 'dabbrev-completion) (not (fboundp 'icicle-ORIG-dabbrev-completion)))
+ (defalias 'icicle-ORIG-dabbrev-completion (symbol-function 'dabbrev-completion)))
- (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) ; Bound to `C-M-/' globally.
- "Completion on current word.
+(defun icicle-dabbrev-completion (&optional arg) ; Bound to `C-M-/' globally.
+ "Complete current word in buffer.
Like \\[dabbrev-expand], but finds all expansions in the current buffer
and presents suggestions for completion.
With no prefix argument, it reuses an old completion list
if there is a suitable one already."
- (interactive "*P")
- (unless (featurep 'dabbrev)
- (unless (require 'dabbrev nil t) (error "Library `dabbrev' not found"))
- (icicle-mode 1)) ; Redefine `dabbrev-completion' to Icicles version.
- (dabbrev--reset-global-variables)
- (let* ((dabbrev-check-other-buffers (and arg t)) ; Must be t
- (dabbrev-check-all-buffers (and arg (= (prefix-numeric-value arg) 16)))
- (abbrev (icicle-dabbrev--abbrev-at-point))
- (ignore-case-p (and (if (eq dabbrev-case-fold-search 'case-fold-search)
- case-fold-search
- dabbrev-case-fold-search)
- (or (not dabbrev-upcase-means-case-search)
- (string= abbrev (downcase abbrev)))))
- (my-obarray dabbrev--last-obarray)
- init)
- ;; If new abbreviation to expand, then expand it.
- (save-excursion
- (unless (and (null arg)
- my-obarray
- (or (eq dabbrev--last-completion-buffer (current-buffer))
- (and (window-minibuffer-p (selected-window))
- (eq dabbrev--last-completion-buffer (dabbrev--minibuffer-origin))))
- dabbrev--last-abbreviation
- (>= (length abbrev) (length dabbrev--last-abbreviation))
- (string= dabbrev--last-abbreviation
- (substring abbrev 0 (length dabbrev--last-abbreviation)))
- (setq init (try-completion abbrev my-obarray)))
- (setq dabbrev--last-abbreviation abbrev)
- (let ((completion-list (dabbrev--find-all-expansions abbrev ignore-case-p))
- (completion-ignore-case ignore-case-p))
- ;; Make an obarray with all expansions
- (setq my-obarray (make-vector (length completion-list) 0))
- (unless (> (length my-obarray) 0)
- (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)
- ;; Find the expanded common string.
- init (try-completion abbrev my-obarray)))))
- ;; Let the user choose between the expansions
- (unless (stringp init) (setq init abbrev))
- (cond
- ((and (not (string-equal init ""))
- (not (string-equal (downcase init) (downcase abbrev)))
- (<= (length (all-completions init my-obarray)) 1))
- (message "Completed (no other completions)")
- (if (< emacs-major-version 21)
- (dabbrev--substitute-expansion nil abbrev init)
- (dabbrev--substitute-expansion nil abbrev init nil))
- (when (window-minibuffer-p (selected-window)) (message nil)))
- ;;$$ ;; Complete text only up through the common root. NOT USED.
- ;; ((and icicle-dabbrev-stop-at-common-root-p
- ;; (not (string-equal init ""))
- ;; (not (string-equal (downcase init) (downcase abbrev))))
- ;; (message "Use `%s' again to complete further"
- ;; (icicle-key-description (this-command-keys) nil icicle-key-descriptions-use-<>-flag))
- ;; (if (< emacs-major-version 21)
- ;; (dabbrev--substitute-expansion nil abbrev init)
- ;; (dabbrev--substitute-expansion nil abbrev init nil))
- ;; (when (window-minibuffer-p (selected-window)) (message nil))) ; $$ NEEDED?
- (t
- ;; String is a common root already. Use Icicles completion.
- (icicle-highlight-lighter)
- (message "Making completion list...")
- (search-backward abbrev)
- (replace-match "")
- (condition-case nil
- (let* ((icicle-show-Completions-initially-flag t)
- (icicle-incremental-completion-p 'display)
- (minibuffer-completion-table my-obarray)
- (choice
- (completing-read "Complete: " my-obarray nil nil init nil init)))
- (when choice (insert choice)))
- (quit (insert abbrev)))))))
+ (interactive "*P")
+ (unless (featurep 'dabbrev)
+ (unless (require 'dabbrev nil t) (error "Library `dabbrev' not found"))
+ (icicle-mode 1)) ; Redefine `dabbrev-completion' to Icicles version.
+ (dabbrev--reset-global-variables)
+ (let* ((dabbrev-check-other-buffers (and arg t)) ; Must be t
+ (dabbrev-check-all-buffers (and arg (= (prefix-numeric-value arg) 16)))
+ (abbrev (icicle-dabbrev--abbrev-at-point))
+ (ignore-case-p (and (if (eq dabbrev-case-fold-search 'case-fold-search)
+ case-fold-search
+ dabbrev-case-fold-search)
+ (or (not dabbrev-upcase-means-case-search)
+ (string= abbrev (downcase abbrev)))))
+ (my-obarray icicle-dabbrev--last-obarray)
+ init)
+ (save-excursion ; If new abbreviation to expand then expand it.
+ (unless (and (null arg) ; Reuse existing completions, if appropriate.
+ my-obarray
+ (or (eq icicle-dabbrev--last-completion-buffer (current-buffer))
+ (and (window-minibuffer-p (selected-window))
+ (eq icicle-dabbrev--last-completion-buffer
+ (window-buffer (minibuffer-selected-window)))))
+ dabbrev--last-abbreviation
+ (>= (length abbrev) (length dabbrev--last-abbreviation))
+ (string= dabbrev--last-abbreviation
+ (substring abbrev 0 (length dabbrev--last-abbreviation)))
+ (setq init (try-completion abbrev my-obarray)))
+ (setq dabbrev--last-abbreviation abbrev)
+ (let ((completion-list (dabbrev--find-all-expansions abbrev ignore-case-p))
+ (completion-ignore-case ignore-case-p))
+ ;; Make an obarray with all expansions
+ (setq my-obarray (make-vector (length completion-list) 0))
+ (unless (> (length my-obarray) 0)
+ (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 icicle-dabbrev--last-obarray my-obarray
+ icicle-dabbrev--last-completion-buffer (current-buffer)
+ ;; Find the expanded common string.
+ init (try-completion abbrev my-obarray)))))
+ ;; Let the user choose between the expansions
+ (unless (stringp init) (setq init abbrev))
+ (cond
+ ((and (not (string-equal init ""))
+ (not (string-equal (downcase init) (downcase abbrev)))
+ (<= (length (all-completions init my-obarray)) 1))
+ (message "Completed (no other completions)")
+ (if (< emacs-major-version 21)
+ (dabbrev--substitute-expansion nil abbrev init)
+ (dabbrev--substitute-expansion nil abbrev init nil))
+ (when (window-minibuffer-p (selected-window)) (message nil)))
+ ;;$$ ;; Complete text only up through the common root. NOT USED.
+ ;; ((and icicle-dabbrev-stop-at-common-root-p
+ ;; (not (string-equal init ""))
+ ;; (not (string-equal (downcase init) (downcase abbrev))))
+ ;; (message "Use `%s' again to complete further"
+ ;; (icicle-key-description (this-command-keys) nil
+ ;; icicle-key-descriptions-use-<>-flag))
+ ;; (if (< emacs-major-version 21)
+ ;; (dabbrev--substitute-expansion nil abbrev init)
+ ;; (dabbrev--substitute-expansion nil abbrev init nil))
+ ;; (when (window-minibuffer-p (selected-window)) (message nil))) ; $$ NEEDED?
+ (t
+ ;; String is a common root already. Use Icicles completion.
+ (icicle-highlight-lighter)
+ (message "Making completion list...")
+ (search-backward abbrev)
+ (replace-match "")
+ (condition-case nil
+ (let* ((icicle-show-Completions-initially-flag t)
+ (icicle-incremental-completion-p 'display)
+ (minibuffer-completion-table my-obarray)
+ (choice
+ (completing-read "Complete: " my-obarray nil nil init nil init)))
+ (when choice (insert choice)))
+ (quit (insert abbrev)))))))
(defun icicle-dabbrev--abbrev-at-point ()
"Like `dabbrev--abbrev-at-point', but returns \"\" if there is no match.
(forward-char 1)))
(dabbrev--goto-start-of-abbrev) ; Now find the beginning of that one.
(setq abv (buffer-substring-no-properties dabbrev--last-abbrev-location (point)))))
- abv)))
+ abv))
;; REPLACE ORIGINAL `bbdb-complete-mail' defined in `bbdb-com.el', version 3.02
"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.
+Return 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).
(unless mails (error "Matching record has no `mail' field"))
;; (1) If PATTERN matches name, AKA, or organization of ONE-RECORD,
;; then ADDRESS is the first mail address of ONE-RECORD.
- (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)))
+ (when (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)))
;; (2) If PATTERN matches one or multiple mail addresses of ONE-RECORD,
;; then we take the first one matching PATTERN.
(unless mail (while (setq elt (pop mails))
;;
;; Avoid a byte-compile error if user has already loaded BBDB version 3+.
;; The error has to do with `bbdb-records' being a defsubst that takes no args.
-(unless (eval-when-compile (and (featurep 'bbdb) (not (string-lessp bbdb-version "3"))))
+(unless (eval-when-compile (and (featurep 'bbdb) (or (not (zerop (string-to-number bbdb-version)))
+ (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
(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)))))))
+ (and (not (memq sym all-the-completions))
+ (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)))
(when (bbdb-record-net (car recs))
;; Did we match on name?
(let ((b-r-name (or (bbdb-record-name (car recs)) "")))
- (if (string= pattern (substring (downcase b-r-name) 0
- (min (length b-r-name) (length pattern))))
- (setq match-recs (cons (car recs) match-recs)
- matched t)))
+ (when (string= pattern (substring (downcase b-r-name) 0
+ (min (length b-r-name) (length pattern))))
+ (setq match-recs (cons (car recs) match-recs)
+ matched t)))
;; Did we match on aka?
(unless matched
(setq lst (bbdb-record-aka (car recs)))
(setq lst (bbdb-record-net (car recs))
primary t) ; primary wins over secondary...
(while lst
- (if (string= pattern (substring (downcase (car lst)) 0
- (min (length (downcase (car lst)))
- (length pattern))))
- (setq the-net (car lst)
- lst ()
- match-recs (if primary
- (cons (car recs) match-recs)
- (append match-recs (list (car recs))))))
+ (when (string= pattern (substring (downcase (car lst)) 0
+ (min (length (downcase (car lst)))
+ (length pattern))))
+ (setq the-net (car lst)
+ lst ()
+ match-recs (if primary
+ (cons (car recs) match-recs)
+ (append match-recs (list (car recs))))))
(setq lst (cdr lst)
primary nil))))
(setq recs (cdr recs) ; Next rec for loop.
symbols with function definitions, values or properties are
considered."
(interactive)
- (let* ((end (point))
+ (let* ((pos (point))
(buffer-syntax (syntax-table))
+ ;; $$$$$$ FIXME: In minibuffer with no input, `backward-sexp' moves into the prompt, which is
+ ;; read-only. What we do currently is just let that happen and let the pattern be "".
+ ;; Better would be to stop movement into the prompt etc. See also Emacs bug #16453.
(beg (unwind-protect
- (save-excursion
+ (progn
(set-syntax-table emacs-lisp-mode-syntax-table)
- (backward-sexp 1)
- (while (= (char-syntax (following-char)) ?\') (forward-char 1))
- (point))
+ (condition-case nil
+ (save-excursion
+ (backward-sexp 1)
+ (skip-syntax-forward "'")
+ (point))
+ (scan-error pos)))
(set-syntax-table buffer-syntax)))
- (pattern (buffer-substring beg end))
+ (end (unless (or (eq beg (point-max))
+ (member (char-syntax (char-after beg)) '(?\" ?\( ?\))))
+ (unwind-protect
+ (progn
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (condition-case nil
+ (save-excursion
+ (goto-char beg)
+ (forward-sexp 1)
+ (max (point) beg))
+ (scan-error pos)))
+ (set-syntax-table buffer-syntax))))
+ (pattern (buffer-substring beg (or end beg)))
(new (try-completion pattern obarray)))
(unless (stringp new) (setq new pattern))
- (delete-region beg end)
+ (condition-case nil (delete-region beg end) (error nil)) ; E.g. read-only text of a prompt.
+ (goto-char beg)
(insert new)
(setq end (+ beg (length new)))
(if (and (not (string= new "")) (not (string= (downcase new) (downcase pattern)))
(icicle-show-Completions-initially-flag t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "symbol"))))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
- (or icicle-all-candidates-list-alt-action-fn alt-fn
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (or icicle-all-candidates-list-alt-action-fn
+ alt-fn
(icicle-alt-act-fn-for-type "symbol")))
(predicate
(or predicate
(save-excursion
(goto-char beg)
(if (not (eq (char-before) ?\( ))
- (lambda (sym) ;why not just nil ? -sm
+ (lambda (sym) ;why not just nil ? -sm
(or (boundp sym) (fboundp sym) (symbol-plist sym)))
;; If first element of parent list is not an open paren, assume that this is a
;; funcall position: use `fboundp'. If not, then maybe this is a variable in
;; candidate and pass nil as PRED to `completing-read'. Don't bother for now.
(setq new (save-excursion (completing-read "Complete Lisp symbol: "
obarray predicate t new)))))
- (delete-region beg end)
+ (condition-case nil (delete-region beg end) (error nil)) ; E.g. read-only text of a prompt.
(insert new)))
(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)))
+ (lambda (fc)
+ (let ((proxy (car (member fc icicle-proxy-candidates))))
+ (setq fc (icicle-transform-multi-completion fc)
+ fc (if proxy
+ (symbol-value (intern (substring proxy 1 (1- (length proxy)))))
+ (intern fc)))
+ (icicle-ORIG-customize-face fc))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
(icicle-all-candidates-list-action-fn 'icicle-customize-faces)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "face"))))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn
alt-fn
(icicle-alt-act-fn-for-type "face"))))
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.
+With no prefix argument:
-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*'.
+* Candidates are shown according to option
+ `icicle-WYSIWYG-Completions-flag'.
+
+* If `icicle-add-proxy-candidates-flag' is non-nil then proxy
+ candidates are included. These are the names of face-name options,
+ that is, options with custom-type `face'. The face that is option
+ value is used.
+
+With a prefix argument:
+
+* You get no WYSIWYG display and no proxy candidates.
+
+* 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.
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)))
+ (lambda (fc)
+ (let ((proxy (car (member fc icicle-proxy-candidates))))
+ (setq fc (icicle-transform-multi-completion fc)
+ fc (if proxy
+ (symbol-value (intern (substring proxy 1 (1- (length proxy)))))
+ (intern fc)))
+ (icicle-ORIG-customize-face fc))
(select-window (minibuffer-window))
(select-frame-set-input-focus (selected-frame))))
(icicle-all-candidates-list-action-fn 'icicle-customize-faces)
(alt-fn nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "face"))))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn
alt-fn
(icicle-alt-act-fn-for-type "face"))))
(if (null ',pref-arg)
(user-variable-p s)
(get s 'variable-documentation)))))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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
(when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+
(when msgp (message "Gathering apropos data for customize `%s'..." pattern))
(mapatoms `(lambda (symbol) ; FREE here: APROPOS-REGEXP.
- (when (string-match ,(if (> emacs-major-version 21) apropos-regexp pattern)
+ (when (string-match ,(and (> emacs-major-version 21) apropos-regexp pattern)
(symbol-name symbol))
(when (and (not (memq ,type '(faces options))) ; groups or t
(get symbol 'custom-group))
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(custom-facep s)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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)
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(get s 'custom-group)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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)
(user-variable-p s)
(and ',pref-arg
(get s 'variable-documentation))))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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)
(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"))))
+ (or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "symbol")))
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (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))))
(unless (symbolp s) (setq s (intern s)))
(and (boundp s)
(get s 'variable-documentation))))
- (icompletep (and (boundp 'icomplete-mode)
- icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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"))))
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (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")
"): ")
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(user-variable-p s)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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")
(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
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(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)
(pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(fboundp s)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn
(icicle-alt-act-fn-for-type "function"))))
(completing-read
(let* ((pred (lambda (s)
(unless (symbolp s) (setq s (intern s)))
(commandp s)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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-all-candidates-list-alt-action-fn (or icicle-all-candidates-list-alt-action-fn ; `M-|'
(icicle-alt-act-fn-for-type "command"))))
(list (completing-read
(concat "Apropos command (regexp" (and (>= emacs-major-version 22) " or words")
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(user-variable-p s))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn
- (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
- "variable"
- "option")))))
+ (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")
+ (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)
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(commandp s))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn
- (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p
- "function"
- "command")))))
+ (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")
+ "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)
(and matches (princ "\n\n")))))
matches)) ; Return matching Zippyisms.
+
+(put 'icicle-apropos-value 'icicle-turn-off-icomplete-mode t)
+(put 'icicle-apropos-value 'icicle-turn-off-incremental-completion t)
(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
> 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"
+ match name & defcustom type
+
+Because you will often use this command in contexts that result in
+many, many completion candidates, the following are turned off by
+default for this command:
+
+ * Icomplete mode. You can toggle this using \\<minibuffer-local-completion-map>\
+`\\[icicle-toggle-icomplete-mode]'.
+ * Icicles incremental completion. You can cycle this using `\\[icicle-cycle-incremental-completion]'."
icicle-doc-action ; Action function
prompt ; `completing-read' args
(let ((cands (and (consp pref-arg) icicle-apropos-value-last-initial-cand-set))
(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"))) ; Bindings
- (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) ; No transformation: all symbols.
- (icicle-last-transform-function (lambda (cands) ; `C-$': only user options, commands, or faces.
- (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))
+ ((pref-arg current-prefix-arg) ; Bindings
+ (num-arg (prefix-numeric-value pref-arg))
+ (prompt (format "SYMBOL `C-M-j' %s: " (if pref-arg "INFO" "VALUE")))
+ (icicle--last-toggle-transforming-msg icicle-toggle-transforming-message)
+ (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) ; No transformation: all symbols.
+ (icicle-last-transform-function (lambda (cands) ; `C-$': only user options, commands, or faces.
+ (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))
;;; $$$$$$ (condition-case nil
;;; (prin1-to-string obj)
;;; (error "`icicle-apropos-value' printing error")))))
- (prin1-to-string obj))))
- (make-cand (cond ((< num-arg 0) ; Function
- (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) ; Do ALL
- (lambda (symb) ; Favor the var, then the fn, then the plist.
- (cond ((boundp symb)
- `((,(symbol-name symb)
- ,(funcall print-fn (symbol-value symb)))))
- ((fboundp symb)
+ (prin1-to-string obj))))
+ (make-cand (cond ((< num-arg 0) ; Function
+ (lambda (symb)
+ (and (fboundp symb)
`((,(symbol-name symb)
,(if (byte-code-function-p (symbol-function symb))
""
- (funcall print-fn (symbol-function symb))))))
- ((symbol-plist symb)
+ (funcall print-fn (symbol-function symb))))))))
+ ((= num-arg 0) ; Do ALL
+ (lambda (symb) ; Favor the var, then the fn, then the plist.
+ (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)) ; Plist
+ (lambda (symb)
+ (and (symbol-plist symb)
`((,(symbol-name symb)
- ,(funcall print-fn (symbol-plist symb))))))))
- ((and pref-arg (> num-arg 0)) ; Plist
- (lambda (symb)
- (and (symbol-plist symb)
- `((,(symbol-name symb)
- ,(funcall print-fn (symbol-plist symb)))))))
- (t ; Variable
- (lambda (symb)
- (and (boundp symb)
- `((,(symbol-name symb)
- ,(funcall print-fn (symbol-value symb))))))))))
+ ,(funcall print-fn (symbol-plist symb)))))))
+ (t ; Variable
+ (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) ; First code.
(icicle-highlight-lighter)
(message "Gathering %s%s..." (cond ((consp pref-arg) 'SYMBOLS)
((and pref-arg (> num-arg 0)) " and their plists")
(t " and their values")))))
+
+(put 'icicle-describe-option-of-type 'icicle-turn-off-icomplete-mode t)
+(put 'icicle-describe-option-of-type 'icicle-turn-off-incremental-completion t)
(icicle-define-command icicle-describe-option-of-type ; Bound to `C-h C-o'. Command name
"Describe a user option that was defined with a given `defcustom' type.
Enter patterns for the OPTION name and TYPE definition in the
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" ; Doc string
+ * `icicle-apropos-options-of-type', to show options of a given type
+ * `icicle-apropos-value', using `C-$' to filter to options only
+
+Because you will often use this command in contexts that result in
+many, many completion candidates, the following are turned off by
+default for this command:
+
+ * Icomplete mode. You can toggle this using \\<minibuffer-local-completion-map>\
+`\\[icicle-toggle-icomplete-mode]'.
+ * Icicles incremental completion. You can cycle this using `\\[icicle-cycle-incremental-completion]'."
icicle-describe-opt-action ; Action function
prompt ; `completing-read' args
'icicle-describe-opt-of-type-complete nil nil nil nil nil nil
(setq result
(lexical-let ((ops-re (if (memq icicle-current-completion-mode '(nil apropos))
ops
- (concat "^" ops))))
+ (concat "^" (regexp-quote ops)))))
(icicle-remove-if-not
(lambda (opt+typ) ; FREE here: OPS-RE, MODE, TP.
(and (string-match ops-re (symbol-name (car opt+typ)))
(and
(funcall #',symbpred sy)
(funcall #',valpred (symbol-value sy)))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) icomplete-mode))
(icicle-must-pass-after-match-predicate (and (not icompletep) varpred))
(varpat (completing-read
prompt obarray (and icompletep varpred) nil nil nil
(prin1-to-string elt))))
;; If command was added to command-history as a string, get rid of that.
;; We want only evaluable expressions there.
- (if (stringp (car command-history))
- (setq command-history (cdr command-history))))))
+ (and (stringp (car command-history))
+ (setq command-history (cdr command-history))))))
;; If command to be redone does not match front of history, add it to the history.
(or (equal newcmd (car command-history))
(setq command-history (cons newcmd command-history)))
directory (default directory)."
(interactive "P")
;; $$$$$$$ Maybe filter sets to get only file-name candidate sets?
- (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")))
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Directory: " nil default-directory nil)
default-directory))
- (icicle-multi-completing-p t)
+ (icicle-multi-completing-p t) ; Could have multi-completion saved candidates, from `C-- C-x C-f'.
(icicle-list-use-nth-parts '(1))
(file-names (icicle-remove-if
(lambda (fil)
(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) ; Bound `C-M-<' in Dired.
(let* ((default-directory (if prompt-for-dir-p
(read-file-name "Directory: " nil default-directory nil)
default-directory))
- (icicle-multi-completing-p t)
+ (icicle-multi-completing-p t) ; Could have multi-completion saved candidates, from `C-- C-x C-f'.
(icicle-list-use-nth-parts '(1))
(file-names (icicle-remove-if
(lambda (fil)
(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.
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) ; Bound to `C-{' in Dired.
"Open Dired on a saved project in another window.
immediately. The candidate is not available to act on (e.g. using
\\<minibuffer-local-completion-map>`\\[icicle-candidate-alt-action]').
-Returns:
+Return:
The result of executing FINAL-ACTION-FN, if that arg is non-nil.
Otherwise, `icicle-explore-final-choice-full'.
\(`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-transform-function (and (not (interactive-p)) 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))
(pred (lambda (c)
(unless (symbolp c) (setq c (intern-soft c)))
(commandp c)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
(icicle--last-toggle-transforming-msg icicle-toggle-transforming-message)
(icicle-toggle-transforming-message "Filtering to commands bound to keys is now %s")
(and key
(format " %s" (icicle-key-description key))))))))
icicle-new-last-cmd) ; Set in `icicle-execute-extended-command-1'.
- nil nil ; First code, undo code
- (setq this-command icicle-new-last-cmd)) ; Last code: this will update `last-command'
+ (define-key minibuffer-local-must-match-map " " 'minibuffer-complete-word) ; First code
+ nil ; Undo code
+ (progn ; Last code. Restore `SPC'. CMD might turn off Icicle mode...
+ (define-key minibuffer-local-must-match-map
+ " " (if icicle-mode 'icicle-self-insert 'minibuffer-complete-word))
+ (setq this-command icicle-new-last-cmd))) ; This will update `last-command'.
;; Free vars here: `icicle-orig-buff' and `icicle-orig-window' are bound by `icicle-define-command'.
;; `icicle-new-last-cmd' and `icicle-orig-must-pass-after-match-pred' are bound in
(icicle-toggle-transforming-message icicle--last-toggle-transforming-msg) ; Restore - FREE HERE
;; Rebind alternative action functions to nil, so we don't override the command we call.
(icicle-candidate-alt-action-fn nil)
- (icicle-all-candidates-list-alt-action-fn nil)
+ (icicle-all-candidates-list-alt-action-fn nil) ; `M-|'
;; Rebind `icicle-candidate-action-fn' to a function that calls the candidate command on a single
;; argument that it reads. This is used only if the command itself reads an input argument with
;; completion. When that is the case, you can use completion on that input, and if you do that,
(when (> count 1) (message "(%d times)" count)))
((commandp cmd)
(run-hooks 'post-command-hook)
- (run-hooks 'pre-command-hook)
(let ((enable-recursive-minibuffers t)
;; Restore this before we invoke command, since it might use completion.
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred)
;; to be `cmd' during the `C-RET' part, but `last-command' must not be `cmd'
;; during the `next' part.
(this-command cmd))
+ (run-hooks 'pre-command-hook)
+ (define-key minibuffer-local-must-match-map ; Restore `SPC'. CMD might turn off Icicle mode...
+ " " (if icicle-mode 'icicle-self-insert 'minibuffer-complete-word))
(call-interactively cmd 'record-it)))
;; Should not happen, since `icicle-e*-e*-command' calls `completing-read' with non-nil REQUIRE arg.
(t (error "Not a command: `%s'" cmd-name)))
(when (and binding (not (and (vectorp binding) (eq (aref binding 0) 'mouse-movement))))
(let ((message-log-max nil) ; Do not log this message.
;; If CMD showed a msg in echo area, wait a bit, before showing the key-reminder msg.
- (waited (sit-for (if (current-message) wait-time 0))))
+ (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'"
(pred (lambda (c)
(unless (symbolp c) (setq c (intern-soft c)))
(commandp c)))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
+ (icicle--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) ; Because we bind `icicle-transform-function'.
(with-current-buffer icicle-pre-minibuffer-buffer
(icicle-must-pass-after-match-predicate icicle-orig-must-pass-after-match-pred)
;; Rebind alternative action functions to nil, so we don't override command we call.
(icicle-candidate-alt-action-fn nil)
- (icicle-all-candidates-list-alt-action-fn nil)
+ (icicle-all-candidates-list-alt-action-fn nil) ; `M-|'
(not-cmdp (not (commandp abbrev-or-cmd)))
(regexp (and (or not-cmdp icicle-command-abbrev-priority-flag)
(icicle-command-abbrev-regexp abbrev-or-cmd)))
(let ((enable-recursive-minibuffers t)
(icicle-current-input abbrev-or-cmd))
(icicle-remove-Completions-window)
- (icicle-command-abbrev-command)))))
+ (icicle-command-abbrev-command)
+ (caar command-history))))) ; CMD read and invoked, to be recorded.
(icicle-command-abbrev-record abbrev-or-cmd cmd)))
((not not-cmdp) (call-interactively abbrev-or-cmd)))))
(alt-fn nil)
(icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
(setq alt-fn (icicle-alt-act-fn-for-type "command"))))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))
(icicle-add-proxy-candidates-flag nil) ; No abbrevs - just commands here.
(last-command last-command) ; Save and restore the last command.
icicle-new-last-cmd) ; Set in `icicle-execute-extended-command-1'.
nil nil ; First code, undo code
(setq this-command icicle-new-last-cmd) ; Last code: this will update `last-command'.
- 'NON-INTERACTIVE) ; This is not a real command.
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
(defun icicle-command-abbrev-record (abbrev command)
"Record ABBREV and COMMAND in `icicle-command-abbrev-alist'."
(format " (prefix %d)" (prefix-numeric-value current-prefix-arg))
""))
obarray (and icompletep pred) t nil 'icicle-kmacro-history nil nil
- ((last-command last-command) ; Save and restore the last command.
+ ((last-command last-command) ; Save and restore the last command. (Bindings.)
(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))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "command")))))
(when (locate-library "kmacro")
(lexical-let ((count 0))
(setq icicle-kmacro-alist
(mapcar (lambda (x) (cons (format "%d" (setq count (1+ count))) x)) ; FREE here: COUNT.
+ ;; @@@@@@@ Why the (if nil...) here?
(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
"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))
+ (let* ((count (prefix-numeric-value (or 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)
(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))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(icicle-define-command icicle-clear-history
(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))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(when (and icicle-define-alias-commands-flag (not (fboundp 'toggle)))
(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))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option")))))
(defun icicle-binary-option-p (symbol)
(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))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "option"))))
(unless (require 'doremi nil t) ; First code
(icicle-user-error "You need library `doremi.el' for this command")))
(lambda (symb)
(unless (symbolp symb) (setq symb (intern symb)))
(boundp symb))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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 ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn
(icicle-alt-act-fn-for-type (if prefix-arg "option" "variable")))))
(unless (require 'doremi nil t) ; First code
(lambda (s)
(unless (symbolp s) (setq s (intern s)))
(boundp s))))
- (icompletep (and (boundp 'icomplete-mode) icomplete-mode))
+ (icompletep (and (featurep 'icomplete) 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))
(symbol-value variable)
increment))
-(defun icicle-bookmark-cmd (&optional parg) ; Bound to what `bookmark-set' is bound to (`C-x r m').
+(defun icicle-bookmark-cmd (&optional parg) ; Bound to what `bookmark-set' and
+ ; `bmkp-bookmark-set-confirm-overwrite' are bound to (`C-x r m').
"Set bookmark or visit bookmark(s).
With a negative prefix arg, visit bookmark(s), using
`icicle-bookmark-other-window' (see that command for more info).
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)."
+bound to `bookmark-set' (and `bmkp-bookmark-set-confirm-overwrite', if
+defined) 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)
"\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)))))))))
+ (funcall (if (fboundp 'bmkp-bookmark-set-confirm-overwrite) ; Defined in `bookmark+-1.el'.
+ #'bmkp-bookmark-set-confirm-overwrite
+ #'bookmark-set)
+ (and parg (or (consp parg) (zerop (prefix-numeric-value parg)))))))))
(defun icicle-bookmark-set (&optional name parg interactivep) ; `C-x r m'
- "With `Bookmark+', this is `bookmark-set' with Icicles multi-completions.
-In particular, you can use (lax) completion for the bookmark name.
-Without `Bookmark+', this is the same as vanilla Emacs `bookmark-set'.
+ "Without `Bookmark+', this is the same as vanilla Emacs `bookmark-set'.
+With `Bookmark+', this is `bmkp-bookmark-set-confirm-overwrite' with
+Icicles multi-completions. In particular, you can use (lax)
+completion for the bookmark name.
With `Bookmark+':
(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)
+ (icicle-candidate-properties-alist (if (not icicle-multi-completing-p)
()
(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-transform-function (and (not (interactive-p)) icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
+ (icicle-candidate-help-fn 'icicle-bookmark-help)
(icicle-candidates-alist
(if (not (featurep 'bookmark+))
(mapcar (lambda (cand)
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
- ;; FREE here: CURRENT-PREFIX-ARG, ICICLE-GET-ALIST-CANDIDATE-FUNCTION,
- ;; ICICLE-SHOW-MULTI-COMPLETION-FLAG.
- (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))))))
+ ("case insensitive" . icicle-case-insensitive-string-less-p)))))
(require 'bookmark)
(when (featurep 'bookmark+)
;; Bind keys to narrow bookmark candidates by type. Lax is for multi-completion case.
'bookmark-history
'icicle-bookmark-history))))))
(when (string-equal bname "") (setq bname defname))
+ (when (and interactivep (boundp 'bmkp-bookmark-set-confirms-overwrite-p)
+ bmkp-bookmark-set-confirms-overwrite-p (atom parg)
+ (bmkp-get-bookmark-in-alist bname 'NOERROR)
+ (not (y-or-n-p (format "Overwirte bookmark `%s'? " bname))))
+ (error "OK, canceled"))
(bookmark-store bname (cdr record) (consp parg))
(when (and interactivep bmkp-prompt-for-tags-flag)
(bmkp-add-tags bname (bmkp-read-tags-completing))) ; Don't bother to refresh tags. (?)
(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))
+ (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)
guts)))
(error nil)))
+(defun icicle-bookmark-help-string (bookmark-name)
+ "Return a help string for BOOKMARK-NAME." ; `bmkp-*' functions are defined in `Bookmark+'.
+ ;; Use BOOKMARK-NAME, not full bookmark BMK, as arg to vanilla bookmark functions, for Emacs < 23.
+ (let* ((bmk (bookmark-get-bookmark bookmark-name))
+ (buf (and (fboundp 'bmkp-get-buffer-name) (bmkp-get-buffer-name bmk)))
+ (file (bookmark-get-filename bookmark-name))
+ (start (bookmark-get-position bookmark-name))
+ (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)
+ ;; WoMan has no variable for the cmd name.
+ (format "%s, " (bookmark-prop-get bmk 'buffer-name)))))
+ (url-p "URL, ")
+ (t nil)))
+ (and (not dired-p)
+ (or (and file (or (not (boundp 'bmkp-non-file-filename))
+ (not (equal file bmkp-non-file-filename)))
+ (format (if type-info-p "file `%s', " "File `%s', ") file))
+ (and buf (format (if type-info-p "buffer `%s', " "Buffer `%s', ") buf))))
+ (and (not no-position-p)
+ (if (and end (> (- end start) 0))
+ (format "from %d to %d (%d chars)" start end (- end start))
+ (format "position %d" start)))
+ (and annot (format ", %s" annot)))))
+
+(defun icicle-bookmark-help (cand)
+ "Icicles help function for a bookmark candidate."
+ ;; FREE here: CURRENT-PREFIX-ARG, ICICLE-GET-ALIST-CANDIDATE-FUNCTION, ICICLE-MULTI-COMPLETING-P.
+ (when (and (featurep 'bookmark+) icicle-multi-completing-p)
+ (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))))
+
+(defun icicle-bookmark-act-on-prop (cand)
+ "Apply a function to a bookmark property. You choose both.
+The argument is a bookmark name or a multi-completion with 3 parts:
+
+ a. the bookmark name
+ b. the bookmark file or buffer name
+ c. any tags"
+ (when (and (featurep 'bookmark+) icicle-multi-completing-p)
+ (setq cand (funcall icicle-get-alist-candidate-function cand))
+ (setq cand (cons (caar cand) (cdr cand))))
+ (let* ((enable-recursive-minibuffers t)
+ (full-bmk (bookmark-get-bookmark cand))
+ (props `("bookmark-name"
+ ,@(mapcar (lambda (data) (symbol-name (car data)))
+ (bmkp-bookmark-data-from-record full-bmk))))
+ (property (intern (completing-read "Bookmark property to act on: "
+ (mapcar #'list props) nil t)))
+ (result (condition-case err
+ (funcall (read (completing-read "Function to apply to property: "
+ obarray 'functionp))
+ (if (eq 'bookmark-name property)
+ (bmkp-bookmark-name-from-record full-bmk)
+ (bookmark-prop-get full-bmk property)))
+ (error (concat "ERROR: " (message (error-message-string err)))))))
+ (pp-eval-expression `',result)
+ result))
+
(icicle-define-command icicle-bookmark ; Bound to `C-x j j', `C-x p b', `C-x r b'.
"Jump to a bookmark.
With a plain prefix argument (`C-u'), reverse the effect of option
See also the individual multi-commands for different bookmark
types: `icicle-bookmark-info-other-window' etc.
+ * `C-S-RET', the alternative candidate action, prompts you for a
+ property of the candidate bookmark and a function, then applies the
+ function to the property. Completion is available for the
+ properties (and symbol functions). You can also use a lambda sexp
+ as the function.
+
If you also use library `crosshairs.el', then the visited bookmark
position is highlighted." ; Doc string
(lambda (cand) (icicle-bookmark-jump (icicle-transform-multi-completion cand))) ; Action
(prompt "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)
+ (icicle-candidate-properties-alist (if (not icicle-multi-completing-p)
()
(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-transform-function (and (not (interactive-p)) icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
+ (icicle-candidate-help-fn 'icicle-bookmark-help)
+ (icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn 'icicle-bookmark-act-on-prop))
(icicle-delete-candidate-object 'icicle-bookmark-delete-action)
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
icicle-alpha-p)))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
- (icicle-candidate-help-fn
- ;; FREE here: CURRENT-PREFIX-ARG, ICICLE-GET-ALIST-CANDIDATE-FUNCTION,
- ;; ICICLE-SHOW-MULTI-COMPLETION-FLAG.
- (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)
(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)
+ (icicle-candidate-properties-alist (if (not icicle-multi-completing-p)
()
(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-transform-function (and (not (interactive-p)) icicle-transform-function))
(icicle-whole-candidate-as-text-prop-p t)
(icicle-transform-before-sort-p t)
+ (icicle-candidate-help-fn 'icicle-bookmark-help)
+ (icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn 'icicle-bookmark-act-on-prop))
(icicle-delete-candidate-object 'icicle-bookmark-delete-action)
(icicle-sort-orders-alist
(append '(("in *Bookmark List* order") ; Renamed from "turned OFF'.
icicle-alpha-p)))
'(("by previous use alphabetically" . icicle-historical-alphabetic-p)
("case insensitive" . icicle-case-insensitive-string-less-p))))
- (icicle-candidate-help-fn
- ;; FREE here: CURRENT-PREFIX-ARG, ICICLE-GET-ALIST-CANDIDATE-FUNCTION,
- ;; ICICLE-SHOW-MULTI-COMPLETION-FLAG.
- (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)
(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)))
+You probably do not want to use this. Use `icicle-bookmark' instead.
+
+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.)
+
+ * `C-S-RET', the alternative candidate action, prompts you for a
+ property of the candidate bookmark and a function, then applies the
+ function to the property. Completion is available for the
+ properties (and symbol functions). You can also use a lambda sexp
+ as the function."
+ (interactive
+ (list (let ((icicle-candidate-help-fn 'icicle-bookmark-help)
+ (icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
+ 'icicle-bookmark-act-on-prop)))
+ (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
+Same as `icicle-bookmark-jump', but uses another window.
+You probably do not want to use this. Use
`icicle-bookmark-other-window' instead."
- (interactive (list (bookmark-completing-read "Jump to bookmark (other window)"
- bookmark-current-bookmark)))
+ (interactive
+ (list (let ((icicle-candidate-help-fn 'icicle-bookmark-help)
+ (icicle-candidate-alt-action-fn (or icicle-candidate-alt-action-fn
+ 'icicle-bookmark-act-on-prop)))
+ (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)
;; $$$$$$ (select-window (minibuffer-window))
;; $$$$$$ (select-frame-set-input-focus (selected-frame)))
-(defun icicle-bookmark-help-string (bookmark-name)
- "Return a help string for BOOKMARK-NAME." ; `bmkp-*' functions are defined in `Bookmark+'.
- ;; Use BOOKMARK-NAME, not full bookmark BMK, as arg to vanilla bookmark functions, for Emacs < 23.
- (let* ((bmk (bookmark-get-bookmark bookmark-name))
- (buf (and (fboundp 'bmkp-get-buffer-name) (bmkp-get-buffer-name bmk)))
- (file (bookmark-get-filename bookmark-name))
- (start (bookmark-get-position bookmark-name))
- (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)
- ;; WoMan has no variable for the cmd name.
- (format "%s, " (bookmark-prop-get bmk 'buffer-name)))))
- (url-p "URL, ")
- (t nil)))
- (and (not dired-p)
- (or (and file (or (not (boundp 'bmkp-non-file-filename))
- (not (equal file bmkp-non-file-filename)))
- (format (if type-info-p "file `%s', " "File `%s', ") file))
- (and buf (format (if type-info-p "buffer `%s', " "Buffer `%s', ") buf))))
- (and (not no-position-p)
- (if (and end (> (- end start) 0))
- (format "from %d to %d (%d chars)" start end (- end start))
- (format "position %d" start)))
- (and annot (format ", %s" annot)))))
-
;;; MUST keep this synchronized with any general Icicle-mode `C-M-' bindings in `icicles-mode.el'.
;; That includes things like `icicle-read+insert-file-name-keys'.
(defun icicle-bookmark-cleanup ()
(icicle-define-bookmark-other-window-command "some-tags" nil ; `C-x 4 j t +'
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "all-tags-regexp" nil ; `C-x j t % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "all-tags-regexp" nil ; `C-x 4 j t % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "some-tags-regexp" nil ; `C-x j t % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "some-tags-regexp" nil ; `C-x 4 j t % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "file-all-tags" nil ; `C-x j t f *'
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-all-tags" nil ; `C-x 4 j t f *'
(icicle-define-bookmark-other-window-command "file-some-tags" nil ; `C-x 4 j t f +'
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-all-tags-regexp" nil ; `C-x j t f % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-all-tags-regexp" nil ; `C-x 4 j t f % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "file-some-tags-regexp" nil ; `C-x j t f % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-some-tags-regexp" nil ; `C-x 4 j t f % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "file-this-dir-all-tags" nil ; `C-x j t . f *'
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-other-window-command "file-this-dir-all-tags" nil ; `C-x 4 j t . f *'
(icicle-define-bookmark-other-window-command "file-this-dir-some-tags" nil ; `C-x 4 j t . f +'
(bmkp-read-tags-completing nil nil current-prefix-arg))
(icicle-define-bookmark-command "file-this-dir-all-tags-regexp" nil ; `C-x j t . f % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-this-dir-all-tags-regexp" nil ; `C-x 4 j t . f % *'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "file-this-dir-some-tags-regexp" nil ; `C-x j t . f % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-other-window-command "file-this-dir-some-tags-regexp" nil ; `C-x 4 j t . f % +'
- (read-string "Regexp for tags: "))
+ (icicle-read-regexp "Regexp for tags: "))
(icicle-define-bookmark-command "url") ; `C-x j u'
(icicle-define-bookmark-other-window-command "url") ; `C-x 4 j u'
(icicle-define-bookmark-command "w3m") ; `C-x j w'
(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.
+Return 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-INFO: If no specific tag, (t nil (point-min)). Else, (TEXT LINE . STARTPOS).
;; e.g. TEXT = "(defun foo ()" or just "foo" (if explicit),
;; LINE = "148", STARTPOS = "1723"
- (tag-info (save-excursion (funcall snarf-tag-function))) ; e.g. `etags-snarf-tag'.
- (tag (if (eq t (car tag-info)) nil (car tag-info)))
+ (tag-info (save-excursion (funcall snarf-tag-function))) ; e.g. `etags-snarf-tag'.
+ (tag (and (not (eq t (car tag-info))) (car tag-info)))
;; FILE-PATH is absolute. FILE-LABEL is relative to `default-directory'.
- (file-path (save-excursion
- (if tag (file-of-tag) (save-excursion (next-line 1) (file-of-tag)))))
+ (file-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 " ...)")))
(alt-fn nil)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (setq alt-fn (icicle-alt-act-fn-for-type "frame"))))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn alt-fn (icicle-alt-act-fn-for-type "frame")))))
(defun icicle-select-frame-by-name (name &optional frame-alist)
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
+ (input (completing-read "Select frame: " alist nil t nil
'frame-name-history default)))
(list (if (= (length input) 0) default input)
alist)))
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)))
+ (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-inhibit-try-switch-buffer t)
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))))
(defun icicle-delete-window (bufferp) ; Bound to `C-x 0' in Icicle mode.
`icicle-top-level-key-bindings'." ; Doc string
icicle-kill-a-buffer-and-update-completions ; Action function
(icicle-buffer-name-prompt "Kill") ; `completing-read' args
- (mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
+ (mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free here.
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs 23.
- nil 'buffer-name-history (buffer-name (current-buffer)) nil
- (icicle-buffer-bindings) ; Bindings
- ;; Actually, there is no reason to bind `C-x m' to `icicle-bookmark-non-file-other-window' here,
- ;; but to keep things simple we do it anyway.
+ 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 ; Bindings
+ ((icicle-use-candidates-only-once-flag t)))
(icicle-bind-buffer-candidate-keys) ; First code
nil ; Undo code
(icicle-unbind-buffer-candidate-keys)) ; Last code
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)) ; 3 `C-u'
+ (format "%s invisible buffer" action))
((and (consp current-prefix-arg) (> (prefix-numeric-value current-prefix-arg) 4)) ; `C-u C-u'
(format "%s visible buffer" action))
((and (consp current-prefix-arg) (fboundp 'derived-mode-p)) ; `C-u'
(if (fboundp 'kill-buffer-and-its-windows)
(kill-buffer-and-its-windows buf) ; Defined in `misc-cmds.el'.
(kill-buffer buf))
- ;; Update the set of completions, then update `*Completions*'.
- (setq minibuffer-completion-table (mapcar (lambda (buf) (list (buffer-name buf))) (buffer-list)))
(icicle-complete-again-update))
(error nil))
(message "No such live buffer: `%s'" buf)))
* 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
* `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-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
+ `icicle-buffer-skip-functions' - Exclude from content searching
+ `icicle-file-skip-functions' - Same, but 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:
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 - it determines what
-kinds of buffers to include:
- * nil : all buffers
+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
- * Cons : buffers with the same mode as current, or with
+ * (4) : buffers with the same mode as current, or with
a mode that the current mode is derived from
-When ARG is nil, the first buffer is `other-buffer'."
+ * (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) ; In `misc-fns.el'.
(another-buffer nil t)
(car icicle-bufflist)
bname))
;; Emacs 23 accepts a list of default values. ; Just keep the first 4. (This could be an option.)
- (let* ((bfnames (mapcar #'buffer-name (delete (current-buffer) (or icicle-bufflist (buffer-list))))))
+ (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)))
(icicle-transform-multi-completion strg)))
(name-pat (if (memq icicle-current-completion-mode '(nil apropos))
name-pat
- (concat "^" name-pat)))
+ (concat "^" (regexp-quote 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 (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)))
+ 'icicle-buffer-skip-functions buf)))
bufs))
(bufs (cond ((equal "" content-pat)
(dolist (buf bufs)
- ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL.
- ;; Bound in `icicle-visit-marked-file-of-content(-other-window)'.
- (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)))
+ ;; Bound in `icicle-visit-marked-file-of-content-1'.
+ (unless (memq (setq buf (get-buffer buf)) icicle-existing-bufs)
+ (add-to-list 'icicle-new-bufs-to-kill buf)))
bufs)
(t
(icicle-remove-if-not
(save-excursion
(goto-char (point-min))
(re-search-forward content-pat nil t)))))
- ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL.
- ;; Bound in `icicle-visit-marked-file-of-content(-other-window)'.
- (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))
+ ;; Bound in `icicle-visit-marked-file-of-content-1'.
+ (unless (memq (setq buf (get-buffer buf)) icicle-existing-bufs)
+ (add-to-list 'icicle-new-bufs-to-kill buf))
(when (and found ; Don't do it just because incrementally complete.
(or (icicle-get-safe this-command
'icicle-apropos-completing-command)
(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 (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)))
+ 'icicle-file-skip-functions fil)))
filnames))
(filnames (if (equal "" content-pat)
filnames
(save-excursion
(goto-char (point-min))
(re-search-forward content-pat nil t)))))
- ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL
- (when (and (boundp 'existing-bufs) (boundp 'new-bufs--to-kill)
- (not (memq buf existing-bufs)))
- (add-to-list 'new-bufs--to-kill buf))
+ ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL.
+ ;; Bound in `icicle-visit-marked-file-of-content-1'.
+ (unless (memq buf icicle-existing-bufs)
+ (add-to-list 'icicle-new-bufs-to-kill buf))
(when (and found ; Don't do it just because incrementally complete.
(or (icicle-get-safe this-command
'icicle-apropos-completing-command)
nil ; Undo code
(icicle-unbind-buffer-candidate-keys)) ; Last code
-(icicle-define-command icicle-visit-marked-file-of-content ; Command name
+(defvar icicle-vmfoc-other-win-p nil
+ "Flag bound in `icicle-visit-marked-file-of-content*'.
+Non-nil means use other window.")
+
+(defvar icicle-vmfoc-recursive-p nil
+ "Flag bound in `icicle-visit-marked-file-of-content*'.
+Non-nil means act on files marked in subdirs, defined recursively.")
+
+(defun icicle-visit-marked-file-of-content () ; Bound to `C-S-f', aka `C-F', in Dired.
"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
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." ; Doc string
- (lambda (buf) ; Action function. Free var here: NEW-BUFS--TO-KEEP.
- (push (switch-to-buffer (icicle-transform-multi-completion buf))
- new-bufs--to-keep)) ; Add the visited buffer to those we will keep (not kill).
- prompt 'icicle-buffer-multi-complete nil ; `completing-read' args
- (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs 23.
- nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
- (icicle-buffer-bindings ; Bindings
- ((prompt (icicle-buffer-name-prompt "Visit file"))
- (icicle-show-multi-completion-flag t) ; Override user setting.
- (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)
- ;; Bind `icicle-apropos-complete-match-fn' to nil to prevent automatic input matching in
- ;; `icicle-unsorted-apropos-candidates' etc., because `icicle-buffer-multi-complete' does everything.
- (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) ; First code
- (icicle-highlight-lighter)
- (message "Matching file contents..."))
- nil ; Undo code
- (progn (icicle-unbind-buffer-candidate-keys) ; Last code
- (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))))))
+flips the behavior specified by that option."
+ (interactive)
+ (let ((icicle-vmfoc-other-win-p nil)
+ (icicle-vmfoc-recursive-p nil))
+ (icicle-visit-marked-file-of-content-1)))
-(icicle-define-command icicle-visit-marked-file-of-content-other-window ; Command name
+(defun icicle-visit-marked-file-of-content-other-window () ; Bound to `C-M-S-f', aka `C-M-F', in Dired.
"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." ; Doc string
+different window. You must be in Dired mode to use this command."
+ (interactive)
+ (let ((icicle-vmfoc-other-win-p t)
+ (icicle-vmfoc-recursive-p nil))
+ (icicle-visit-marked-file-of-content-1)))
+
+(defun icicle-visit-marked-file-of-content-recursive () ; Bound to `M-+ C-S-f', aka `M-+ C-F', in Dired.
+ "Visit a marked file whose content matches a regexp.
+Like `icicle-visit-marked-file-of-content', but include also the files
+marked in marked subdirs, recursively.
+
+You need library `dired+.el' for this command, and you must be in
+Dired mode to use it."
+ (interactive)
+ (let ((icicle-vmfoc-other-win-p nil)
+ (icicle-vmfoc-recursive-p t))
+ (icicle-visit-marked-file-of-content-1)))
+
+(defun icicle-visit-marked-file-of-content-recursive-other-window ()
+ ; Bound to `M-+ C-M-S-f', aka `M-+ C-M-F', in Dired.
+ "Visit a marked file whose content matches a regexp, in another window.
+Like `icicle-visit-marked-file-of-content-other-window', but include
+also the files marked in marked subdirs, recursively.
+
+You need library `dired+.el' for this command, and you must be in
+Dired mode to use it."
+ (interactive)
+ (let ((icicle-vmfoc-other-win-p t)
+ (icicle-vmfoc-recursive-p t))
+ (icicle-visit-marked-file-of-content-1)))
+
+(icicle-define-command icicle-visit-marked-file-of-content-1
+ "Helper for `icicle-visit-marked-file-of-content*'." ; Doc string
(lambda (buf) ; Action function. Free var here: NEW-BUFS--TO-KEEP.
- (push (switch-to-buffer-other-window (icicle-transform-multi-completion buf))
- new-bufs--to-keep)) ; Add the visited buffer to those we will keep (not kill).
+ (push (funcall act-fn (icicle-transform-multi-completion buf))
+ icicle-new-bufs-to-keep)) ; Add the visited buffer to those we will keep (not kill).
prompt 'icicle-buffer-multi-complete nil ; `completing-read' args
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs 23.
- nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
+ nil 'buffer-name-history (icicle-default-buffer-names) nil
(icicle-buffer-bindings ; Bindings
((prompt (icicle-buffer-name-prompt "Visit file" 'OTHER-WIN))
(icicle-show-multi-completion-flag t) ; Override user setting.
(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-existing-bufs (buffer-list))
+ (icicle-new-bufs-to-kill ())
+ (icicle-new-bufs-to-keep ())
+ (act-fn (if icicle-vmfoc-other-win-p
+ 'switch-to-buffer-other-window
+ 'switch-to-buffer))
(icicle-candidate-help-fn 'icicle-buffer-cand-help))
((icicle-buffer-complete-fn 'icicle-buffer-multi-complete)
;; Bind `icicle-apropos-complete-match-fn' to nil to prevent automatic input matching in
(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)))))
+ (let* ((files (if (and icicle-vmfoc-recursive-p
+ (fboundp 'diredp-get-files))
+ (diredp-get-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"))
+ (progn (when (and icicle-vmfoc-recursive-p (not (fboundp 'diredp-get-files)))
+ (icicle-user-error "You need library `dired+.el' for this command"))
+ (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) ; First code
(icicle-highlight-lighter)
(progn (icicle-unbind-buffer-candidate-keys) ; Last code
(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))))))
+ (dolist (buf icicle-new-bufs-to-kill)
+ (unless (memq buf icicle-new-bufs-to-keep) (kill-buffer buf)))))
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
(icicle-define-command icicle-insert-buffer
"Multi-command version of `insert-buffer'.
(icicle-buffer-name-prompt "Show always") ; `completing-read' args
(mapcar (lambda (buf) (list (buffer-name buf))) icicle-bufflist) nil ; `icicle-bufflist' is free.
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ; Emacs 23.
- nil 'buffer-name-history (icicle-default-buffer-names current-prefix-arg) nil
+ 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 ; Bindings
((icicle-delete-candidate-object 'icicle-remove-buffer-candidate-action) ; Override default (kill).
(icicle-use-candidates-only-once-flag t)))
((icicle-use-candidates-only-once-flag t) ; Bindings
(icicle-candidate-alt-action-fn
(or icicle-candidate-alt-action-fn (icicle-alt-act-fn-for-type "buffer")))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(or icicle-all-candidates-list-alt-action-fn (icicle-alt-act-fn-for-type "buffer"))))
(unless icicle-buffer-extras (icicle-user-error "`icicle-extra-buffers' is empty"))) ; First code
snapshot.
To use this command, you must have loaded library `color-theme.el',
-available from http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme." ; Doc string
+available from http://www.nongnu.org/color-theme. See also:
+http://www.emacswiki.org/ColorTheme." ; Doc string
(lambda (theme)
- (when (string= "" theme) (icicle-user-error "No theme name entered (empty input)"))
+ (when (string= "" theme) (icicle-user-error "No color theme name entered (empty input)"))
(funcall (intern theme))) ; Action function: just call the theme.
- "Theme: " icicle-color-themes nil t nil ; `completing-read' args
+ "Color theme: " icicle-color-themes nil t nil ; `completing-read' args
(if (boundp 'color-theme-history) 'color-theme-history 'icicle-color-theme-history)
nil nil
((icicle-delete-candidate-object 'icicle-color-themes) ; Bindings
(color-theme-snapshot)) ; Undo code
+;; Emacs 22-23 `cus-themes.el' has no `provide', and only Emacs 24 version
+;; has `custom-available-themes'.
+(when (condition-case nil (require 'cus-theme nil t) (error nil)) ; Emacs 24+
+
+ (icicle-define-command icicle-custom-theme ; Command name
+ "Change custom theme.
+The themes used as candidates are those in option `icicle-custom-themes'.
+
+You can use \\<minibuffer-local-completion-map>\
+`\\[icicle-delete-candidate-object]' during completion to remove the current
+candidate from the list of Icicles custom themes.
+
+You can use `C-g' to quit and cancel changes by the command. Note,
+however, that some things might not be restored. `C-g' can only
+disable any themes that you applied. It cannot restore other
+customizations that enabling a theme might have overruled. This is a
+limitation of Emacs custom themes: you can disable them, but you
+cannot restore non-theme settings in effect before enabling a theme.
+Color themes (and command `icicle-color-theme') do not have this
+limitation.
+
+Note: Having a lot of frames present can slow down this command
+considerably.
+
+Option `icicle-custom-themes-accumulate-flag' determines whether
+cycling accumulates themes or disables all themes other than the
+current one. Note: A non-nil value (accumulating) can considerably
+slow down cycling.
+
+Option `icicle-custom-themes-update-flag' determines whether the
+updated value of `icicle-custom-themes' is saved. A prefix arg to
+this command flips the option value for the current invocation of the
+command." ; Doc string
+ (lambda (theme) ; Action function: enable theme.
+ (when (string= "" theme) (icicle-user-error "No theme name entered (empty input)"))
+ (setq theme (intern theme))
+ (condition-case nil
+ (progn (unless icicle-custom-themes-accumulate-flag
+ (mapc #'disable-theme (delete theme custom-enabled-themes)))
+ (unless (memq theme custom-enabled-themes) ; Don't enable if already enabled.
+ (if (custom-theme-p theme) (enable-theme theme) (load-theme theme t)))
+ (run-hooks 'icicle-custom-theme-hook))
+ (error (condition-case nil (disable-theme theme) (error nil))))
+ theme) ; Return it (but not necessary).
+ "Custom theme: " ; `completing-read' args
+ (mapcar (lambda (thm) (list (symbol-name thm))) icicle-custom-themes) nil t nil
+ (if (boundp 'custom-theme-history) 'custom-theme-history 'icicle-custom-theme-history)
+ nil nil
+ ((flip current-prefix-arg) ; Bindings
+ (orig-themes (delq nil (copy-sequence custom-enabled-themes)))
+ (icicle-delete-candidate-object
+ (lambda (thm) (setq icicle-custom-themes (delq (intern thm) icicle-custom-themes)))))
+ (unless icicle-custom-themes ; First code
+ (setq icicle-custom-themes (custom-available-themes)))
+ (condition-case nil ; Undo code
+ (progn (mapc #'disable-theme custom-enabled-themes)
+ (mapc #'enable-theme orig-themes))
+ (error nil))
+ (when custom-enabled-themes ; Last code
+ ;; `enable-theme' -> `custom-reevaluate-setting' adds `nil'.
+ (setq icicle-custom-themes (delq nil icicle-custom-themes))
+ ;; Move chosen theme to the front.
+ (setq icicle-custom-themes (delete (car custom-enabled-themes) icicle-custom-themes))
+ (setq icicle-custom-themes (cons (car custom-enabled-themes) icicle-custom-themes))
+ (message "Theme: `%s'" (car icicle-custom-themes))
+ (when (or (and flip (not icicle-custom-themes-update-flag))
+ (and (not flip) icicle-custom-themes-update-flag))
+ (customize-save-variable 'icicle-custom-themes icicle-custom-themes)))))
+
+
;; Make delete-selection mode recognize yanking, so it replaces region text.
(put 'icicle-yank-pop-commands 'delete-selection 'yank)
(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)
- ;; Need to do this because `icicle-completing-yank' sets it to `yank'.
- (setq this-command 'icicle-yank-pop-commands))))
+ (let ((enable-recursive-minibuffers t))
+ (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)
+ ;; Need to do this because `icicle-completing-yank' sets it to `yank'.
+ (setq this-command 'icicle-yank-pop-commands)))))
;; Make delete-selection mode recognize yanking, so it replaces region text.
icicle-insert-for-yank ; Action function
"Insert: " (mapcar #'list kills-in-order) nil t nil 'icicle-kill-history ; `completing-read' args
(car kills-in-order) nil
- ((icicle-transform-function 'icicle-remove-duplicates) ; Bindings
+ ((enable-recursive-minibuffers t)
+ (icicle-transform-function 'icicle-remove-duplicates) ; Bindings
(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)))
+ 'secondary-selection-ring
+ 'kill-ring))))
(icicle-candidate-alt-action-fn `(lambda (seln) ; Add selection to the front of the other ring.
;; FREE here: BROWSE-KILL-RING-ALTERNATIVE-PUSH-FUNCTION,
;; BROWSE-KILL-RING-ALTERNATIVE-RING.
(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))
+ (and (boundp 'secondary-selection-ring)
+ 'secondary-selection-ring))
'kill-ring)))
(if (eq 'kill-ring ',selection-ring)
(if (fboundp 'browse-kill-ring-alternative-push-function)
- (funcall browse-kill-ring-alternative-push-function
- seln)
+ (funcall browse-kill-ring-alternative-push-function seln)
(when (boundp 'secondary-selection-ring)
(add-secondary-to-ring seln)))
(kill-new seln))
((switches (and current-prefix-arg
(read-string "Dired listing switches: " dired-listing-switches)))
(icicle-file-sort (or icicle-file-sort 'icicle-dirs-first-p))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys) ; First code
((switches (and current-prefix-arg
(read-string "Dired listing switches: " dired-listing-switches)))
(icicle-file-sort (or icicle-file-sort 'icicle-dirs-first-p))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
(dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
(icicle-bind-file-candidate-keys) ; First code
With a negative prefix arg, you can choose also by date:
Completion candidates include the last modification date.
+all of these commands let you search file content, as well as file
+names (unless you use an Emacs version prior to 23). See
+`icicle-find-file' and `icicle-find-file-absolute' for more
+information.
+
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
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
(interactive "P")
(if arg
(let ((current-prefix-arg (not (wholenump (prefix-numeric-value arg)))))
+ (setq this-command 'icicle-find-file-absolute) ; So user sees msgs appropriate to the command.
(icicle-find-file-absolute))
+ (setq this-command 'icicle-find-file) ; So user sees msgs appropriate to the command.
(icicle-find-file)))
(interactive "P")
(if arg
(let ((current-prefix-arg (not (wholenump (prefix-numeric-value arg)))))
+ (setq this-command 'icicle-find-file-absolute-other-window) ; So user sees appropriate msgs.
(icicle-find-file-absolute-other-window))
+ (setq this-command 'icicle-find-file-other-window) ; So user sees msgs appropriate to the command.
(icicle-find-file-other-window)))
+(defun icicle-find-file-abs-no-search-action (file)
+ "Action function for commands reading absolute file names without searching."
+ (funcall (icicle-find-file-abs-no-search-action-1 nil nil) file))
-(put 'icicle-find-file-absolute 'icicle-Completions-window-max-height 200)
-(icicle-define-command icicle-find-file-absolute ; Bound to `C-u C-x f' in Icicle mode.
+(defun icicle-find-file-abs-no-search-other-window-action (file)
+ "Action function for commands reading absolute file names without searching."
+ (funcall (icicle-find-file-abs-no-search-action-1 'OTHER-WINDOW-P nil) file))
+
+(defun icicle-find-file-abs-no-search-ro-action (file)
+ "Action function for commands reading absolute file names without searching."
+ (funcall (icicle-find-file-abs-no-search-action-1 nil 'READ-ONLY-P) file))
+
+(defun icicle-find-file-abs-no-search-ro-ow-action (file)
+ "Action function for commands reading absolute file names without searching."
+ (funcall (icicle-find-file-abs-no-search-action-1 'OTHER-WINDOW-P 'READ-ONLY-P) file))
+
+
+(put 'icicle-find-file-abs-no-search 'icicle-hide-common-match t)
+(put 'icicle-find-file-abs-no-search 'icicle-Completions-window-max-height 200)
+(defun icicle-find-file-abs-no-search () ; Bound to `C-u C-x f' in Icicle mode.
"Visit a file or directory, given its absolute name.
Unlike `icicle-find-file', the completion candidates are absolute, not
relative, file names.
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.
These options, when non-nil, control candidate matching and filtering:
- `icicle-file-extras' - Extra file names to display
+ `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
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
-Ido-like behavior." ; Doc string
- (lambda (file) ; FREE here: CURRENT-PREFIX-ARG, THIS-COMMAND.
- (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 ; `completing-read' args
- (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs 23.
- nil 'file-name-history default-directory nil
- (icicle-file-bindings ; Bindings
- ((prompt "File or dir (absolute): ")
- (icicle-full-cand-fn `(lambda (file)
- (setq file (if (file-directory-p file)
- (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 ; M-|'
- (lambda (files) (let ((enable-recursive-minibuffers t))
- (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
- (icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
- (icicle-candidate-properties-alist (and current-prefix-arg '((1 (face icicle-candidate-part)))))
- (icicle-multi-completing-p current-prefix-arg)
- (icicle-list-use-nth-parts (and current-prefix-arg '(1)))))
- (progn ; First code
- (when current-prefix-arg
- (put-text-property 0 1 'icicle-fancy-candidates t prompt)
- (setq current-prefix-arg nil)) ; Reset so can use it in action function.
- (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 ; Undo code
- (progn (icicle-unbind-file-candidate-keys) ; Last code
- (define-key minibuffer-local-completion-map "\C-c\C-d" nil)
- (define-key minibuffer-local-must-match-map "\C-c\C-d" nil)))
+Ido-like behavior.
+Because absolute file names can be long, with common prefixes, the
+common match portion of each candidate is hidden by default. You can
+toggle this hiding using `\\[icicle-dispatch-C-x.]'."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-no-search-action))
+ (icicle-find-file-abs-no-search-1)))
-(put 'icicle-find-file-absolute-other-window 'icicle-Completions-window-max-height 200)
-(icicle-define-command icicle-find-file-absolute-other-window ; Bound to `C-u C-x 4 f'
- "Same as `icicle-find-file-absolute' except uses another window." ; Doc string
- (lambda (file) ; FREE here: CURRENT-PREFIX-ARG, THIS-COMMAND.
- (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))))
+
+(put 'icicle-find-file-abs-no-search-other-window 'icicle-hide-common-match t)
+(put 'icicle-find-file-abs-no-search-other-window 'icicle-Completions-window-max-height 200)
+(defun icicle-find-file-abs-no-search-other-window () ; Bound to `C-u C-x 4 f'
+ "Same as `icicle-find-file-abs-no-search' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-no-search-other-window-action))
+ (icicle-find-file-abs-no-search-1)))
+
+(icicle-define-command icicle-find-file-abs-no-search-1
+ "Helper for `icicle-find-file-abs-no-search(-other-window)'." ; Doc string
+ (lambda (fil) (funcall icicle-find-file-abs-action-fn fil)) ; FREE here: `icicle-find-file-abs-action-fn'.
prompt icicle-abs-file-candidates nil ; `completing-read' args
(and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs 23.
nil 'file-name-history default-directory nil
'(list file))))
(icicle-abs-file-candidates (mapcar icicle-full-cand-fn
(directory-files default-directory 'FULL nil 'NOSORT)))
- (icicle-all-candidates-list-alt-action-fn ; M-|'
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
- (dired-other-window (cons (read-string "Dired buffer name: ") files)))))
+ (dired-other-window (cons (read-string "Dired buffer name: ")
+ (mapcar #'icicle-transform-multi-completion 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)
(progn ; First code
(when current-prefix-arg
(put-text-property 0 1 'icicle-fancy-candidates t prompt)
- (setq current-prefix-arg nil)) ; Reset so can use it in action function.
+ (setq current-prefix-arg nil)) ; Reset, so can use it in action function.
(icicle-highlight-lighter)
(message "Gathering files...")
(icicle-bind-file-candidate-keys)
nil ; Undo code
(progn (icicle-unbind-file-candidate-keys) ; Last code
(define-key minibuffer-local-completion-map "\C-c\C-d" nil)
- (define-key minibuffer-local-must-match-map "\C-c\C-d" nil)))
+ (define-key minibuffer-local-must-match-map "\C-c\C-d" nil))
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
;; This is a minibuffer command. It is in this file because it is used only here.
;;
(setq minibuffer-completion-table
(car (icicle-mctize-all icicle-abs-file-candidates minibuffer-completion-predicate)))))
+(defun icicle-find-file-no-search-action (file)
+ "Action function for commands using `read-file-name' without searching."
+ (funcall (icicle-find-file-no-search-action-1 nil) file))
+
+(defun icicle-find-file-no-search-other-window-action (file)
+ "Action function for commands using `read-file-name' without searching."
+ (funcall (icicle-find-file-no-search-action-1 'OTHER-WINDOW-P) file))
+
+
+(icicle-define-file-command icicle-find-file-no-search-1
+ "Helper for `icicle-find-file-no-search(-other-window)'." ; Doc string
+ (lambda (fil) (funcall icicle-find-file-action-fn fil)) ; FREE here: `icicle-find-file-action-fn'.
+ prompt nil ; `read-file-name' args
+ (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
+ (condition-case nil ; E.g. error because not on file line (ignore)
+ (abbreviate-file-name (dired-get-file-for-visit))
+ (error nil))
+ default-directory)
+ (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs 23.
+ nil nil
+ (icicle-file-bindings ; Bindings
+ ((prompt (concat "File or directory" (and icicle-pref-arg
+ " (read-only)") ": "))
+ (icicle-pref-arg current-prefix-arg)
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (lambda (files) (let ((enable-recursive-minibuffers t))
+ (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
+ (progn ; First code
+ (icicle-bind-file-candidate-keys)
+ (setq current-prefix-arg nil)) ; Reset, so can use it in action function.
+ (icicle-unbind-file-candidate-keys) ; Undo code
+ (icicle-unbind-file-candidate-keys) ; Last code
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
+
(put 'icicle-find-file-no-search 'icicle-Completions-window-max-height 200)
-(icicle-define-file-command icicle-find-file-no-search
+(defun 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.)
option `icicle-require-match-flag'.
Option `icicle-files-ido-like' non-nil gives this command a more
-Ido-like behavior." ; Doc string
- (lambda (file) ; FREE here: CURRENT-PREFIX-ARG, INIT-PREF-ARG, THIS-COMMAND.
- (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)") ": ") ; `read-file-name' args
- nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
- (condition-case nil ; E.g. error because not on file line (ignore)
- (abbreviate-file-name (dired-get-file-for-visit))
- (error nil))
- default-directory)
- (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs 23.
- nil nil
- (icicle-file-bindings ; Bindings
- ((init-pref-arg current-prefix-arg)
- (icicle-all-candidates-list-alt-action-fn ; `M-|'
- (lambda (files) (let ((enable-recursive-minibuffers t))
- (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
- (icicle-bind-file-candidate-keys) ; First code
- nil ; Undo code
- (icicle-unbind-file-candidate-keys)) ; Last code
+Ido-like behavior."
+ (interactive)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-no-search-action))
+ (icicle-find-file-no-search-1)))
(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." ; Doc string
- (lambda (file) ; FREE here: CURRENT-PREFIX-ARG, INIT-PREF-ARG, THIS-COMMAND.
- (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)") ": ") ; `read-file-name' args
- nil (if (and (eq major-mode 'dired-mode) (fboundp 'dired-get-file-for-visit)) ; Emacs 22+.
- (condition-case nil ; E.g. error because not on file line (ignore)
- (abbreviate-file-name (dired-get-file-for-visit))
- (error nil))
- default-directory)
- (and (fboundp 'confirm-nonexistent-file-or-buffer) (confirm-nonexistent-file-or-buffer)) ;Emacs 23.
- nil nil
- (icicle-file-bindings ; Bindings
- ((init-pref-arg current-prefix-arg)
- (icicle-all-candidates-list-alt-action-fn ; `M-|'
- (lambda (files) (let ((enable-recursive-minibuffers t))
- (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
- (icicle-bind-file-candidate-keys) ; First code
- nil ; Undo code
- (icicle-unbind-file-candidate-keys)) ; Last code
+(defun icicle-find-file-no-search-other-window ()
+ "Same as `icicle-find-file-no-search' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-no-search-other-window-action))
+ (icicle-find-file-no-search-1)))
+
+(defun icicle-find-file-or-expand-dir (file-or-dir command read-only-p other-window-p)
+ "Helper for Icicles commands that find files using `read-file-name'.
+FILE-OR-DIR is the target file or directory name.
+COMMAND is the original Icicles file-finding command (a symbol).
+Non-nil READ-ONLY-P means visit the file in read-only mode.
+Non-nil OTHER-WINDOW-P means visit the file in another window.
+
+If `icicle-find-file-expand-directory-flag' is non-nil, FILE-OR-DIR is
+a directory name, and you have used a key such as `RET' that normally
+would make a final candidate choice and exit the minibuffer, then,
+instead of visiting the directory using Dired, COMMAND is restarted,
+but this time in directory FILENAME. That is, you descend into
+directory FILE-OR-DIR.
+
+A non-exiting action such as `C-RET' does not have this special
+behavior. Instead, it always visits the chosen directory."
+ (if (and icicle-find-file-expand-directory-flag
+ (file-directory-p file-or-dir) ; Not just `icicle-looks-like-dir-name-p'.
+ (zerop (minibuffer-depth))
+ (> emacs-major-version 20)) ; Emacs 20 BUG: `default-directory' gets changed.
+ (let ((default-directory (file-name-as-directory file-or-dir))
+ (icicle-show-Completions-initially-flag t))
+ (funcall command))
+ (let ((fn (if read-only-p
+ (if other-window-p #'find-file-read-only-other-window #'find-file-read-only)
+ (if other-window-p #'find-file-other-window #'find-file))))
+ (funcall fn file-or-dir 'WILDCARDS))))
(put 'icicle-find-file-read-only 'icicle-Completions-window-max-height 200)
(defun icicle-find-file-read-only () ; Bound to `C-x C-r' in Icicle mode.
"Visit a file or directory in read-only mode.
-This is `icicle-find-file-no-search' with prefix-arg behavior flipped.
+Other than using read-only mode, this is like `icicle-find-file'."
+ (interactive)
+ (if (fboundp 'icicle-find-file-of-content)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-of-content-ro-action))
+ (icicle-find-file-of-content-1))
+ (let ((current-prefix-arg (not current-prefix-arg))) (icicle-find-file-no-search))))
-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.
+(put 'icicle-find-file-read-only-other-window 'icicle-Completions-window-max-height 200)
+(defun icicle-find-file-read-only-other-window () ; Bound to `C-x 4 r' in Icicle mode.
+ "Same as `icicle-find-file-read-only' except uses another window."
+ (interactive)
+ (if (fboundp 'icicle-find-file-of-content)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-of-content-ro-ow-action))
+ (icicle-find-file-of-content-1))
+ (let ((current-prefix-arg (not current-prefix-arg))) (icicle-find-file-no-search-other-window))))
-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."
+(put 'icicle-find-file-abs-read-only 'icicle-hide-common-match t)
+(put 'icicle-find-file-abs-read-only 'icicle-Completions-window-max-height 200)
+(defun icicle-find-file-abs-read-only ()
+ "Visit a file or directory in read-only mode, given its absolute file name.
+Same as `icicle-find-file-absolute', but visit the target read-only."
(interactive)
- (let ((current-prefix-arg (not current-prefix-arg)))
- (icicle-find-file-no-search)))
+ (if (fboundp 'icicle-find-file-of-content)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-ro-action))
+ (icicle-find-file-abs-of-content-1))
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-no-search-ro-action))
+ (icicle-find-file-abs-no-search-1))))
-(put 'icicle-find-file-read-only-other-window 'icicle-Completions-window-max-height 200)
-(defun icicle-find-file-read-only-other-window () ; Bound to `C-x 4 r' in Icicle mode.
- "Same as `icicle-find-file-read-only' except uses another window."
+(put 'icicle-find-file-abs-read-only-other-window 'icicle-hide-common-match t)
+(put 'icicle-find-file-abs-read-only-other-window 'icicle-Completions-window-max-height 200)
+(defun icicle-find-file-abs-read-only-other-window () ; Bound to `C-x 4 r' in Icicle mode.
+ "Same as `icicle-find-file-abs-read-only' except uses another window."
(interactive)
- (let ((current-prefix-arg (not current-prefix-arg)))
- (icicle-find-file-no-search-other-window)))
+ (if (fboundp 'icicle-find-file-of-content)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-ro-ow-action))
+ (icicle-find-file-abs-of-content-1))
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-no-search-ro-ow-action))
+ (icicle-find-file-abs-no-search-1))))
+
(when (> emacs-major-version 22)
+ (defun icicle-find-file-of-content-action (file)
+ "Action function for commands using `read-file-name' with content searching."
+ (funcall (icicle-find-file-of-content-action-1 nil nil) file))
+
+ (defun icicle-find-file-of-content-other-window-action (file)
+ "Action function for commands using `read-file-name' with content searching."
+ (funcall (icicle-find-file-of-content-action-1 'OTHER-WINDOW-P nil) file))
+
+ (defun icicle-find-file-of-content-ro-action (file)
+ "Read-only action for commands using `read-file-name' with content searching."
+ (funcall (icicle-find-file-of-content-action-1 nil 'READ-ONLY-P) file))
+
+ (defun icicle-find-file-of-content-ro-ow-action (file)
+ "Read-only action for commands using `read-file-name' with content searching."
+ (funcall (icicle-find-file-of-content-action-1 'OTHER-WINDOW-P 'READ-ONLY-P) file))
+
+ (icicle-define-file-command icicle-find-file-of-content-1
+ "Helper for `icicle-find-file-of-content(-other-window)'." ; Doc string
+ ;; Free vars here CURRENT-PREFIX-ARG, `icicle-pref-arg'.
+ ;; FREE here: `icicle-find-file-action-fn'.
+ (lambda (fil) (funcall icicle-find-file-action-fn fil))
+ prompt nil (if (eq major-mode 'dired-mode) ; `read-file-name' args
+ (condition-case nil ; E.g. error because not on file line (ignore)
+ (abbreviate-file-name (dired-get-file-for-visit))
+ (error nil))
+ default-directory)
+ (confirm-nonexistent-file-or-buffer) nil nil
+ (icicle-file-bindings ; Bindings
+ ((icicle-pref-arg current-prefix-arg)
+ (prompt "File or directory: ")
+ (icicle-compute-narrowing-regexp-p t) ; For progressive completion.
+ (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) ; Override user setting.
+ (icicle-multi-completing-p t)
+ (icicle-list-use-nth-parts '(1))
+ (icicle-transform-before-sort-p t)
+ (icicle-existing-bufs (buffer-list))
+ (icicle-new-bufs-to-kill ())
+ (icicle-new-bufs-to-keep ())
+ (cleanup-code ; Use for both undo code and last code.
+ (lambda ()
+ (icicle-unbind-file-candidate-keys)
+ (when (or (and icicle-pref-arg (not icicle-kill-visited-buffers-flag))
+ (and (not icicle-pref-arg) icicle-kill-visited-buffers-flag))
+ (dolist (buf icicle-new-bufs-to-kill)
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (unless (memq buf icicle-new-bufs-to-keep)
+;;; (when (buffer-live-p buf) ; Might have been killed, since both undo code and last code.
+;;; (with-current-buffer buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (kill-buffer buf))))))))
+ (when (and (buffer-live-p buf) (not (memq buf icicle-new-bufs-to-keep))) (kill-buffer buf))))))
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (lambda (files) (let ((enable-recursive-minibuffers t))
+ (dired-other-window (cons (read-string "Dired buffer name: ")
+ (mapcar #'icicle-transform-multi-completion files))))))))
+ (progn (put-text-property 0 1 'icicle-fancy-candidates t prompt) ; First code
+ (setq current-prefix-arg nil) ; Reset, so can use it in action function.
+ (icicle-highlight-lighter)
+ (message "Gathering files...")
+ (icicle-bind-file-candidate-keys))
+ (funcall cleanup-code) ; Undo code
+ (funcall cleanup-code)
+ 'NOT-INTERACTIVE-P)
+
+
(put 'icicle-find-file-of-content 'icicle-Completions-window-max-height 200)
- (icicle-define-file-command icicle-find-file-of-content ; Not bound by default.
+ (defun 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
* 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)" ; Doc string
- (lambda (file) ; Action function
- ;; Free vars here: CURRENT-PREFIX-ARG, INIT-PREF-ARG, THIS-COMMAND, NEW-BUFS--TO-KEEP.
- (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)) ; Else in fundamental mode.
- ;; Add the visited buffer to those we will keep (not kill).
- ;; If FILE uses wildcards then there will be multiple such buffers.
- ;; For a directory, get the Dired buffer instead of using `get-file-buffer'.
- (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) ; `read-file-name' args
- (condition-case nil ; E.g. error because not on file line (ignore)
- (abbreviate-file-name (dired-get-file-for-visit))
- (error nil))
- default-directory)
- (confirm-nonexistent-file-or-buffer) nil nil
+ (interactive)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-of-content-action))
+ (icicle-find-file-of-content-1)))
+
+
+ (put 'icicle-find-file-of-content-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-find-file-of-content-other-window ()
+ "Same as `icicle-find-file-of-content' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-action-fn 'icicle-find-file-of-content-other-window-action))
+ (icicle-find-file-of-content-1)))
+
+ (defun icicle-find-file-abs-of-content-action (file)
+ "File-visiting action function for commands reading absolute file names."
+ (funcall (icicle-find-file-abs-of-content-action-1 nil nil) file))
+
+ (defun icicle-find-file-abs-of-content-other-window-action (file)
+ "File-visiting action function for commands reading absolute file names."
+ (funcall (icicle-find-file-abs-of-content-action-1 'OTHER-WINDOW-P nil) file))
+
+ (defun icicle-find-file-abs-of-content-ro-action (file)
+ "Read-only action function for commands reading absolute file names."
+ (funcall (icicle-find-file-abs-of-content-action-1 nil 'READ-ONLY-P) file))
+
+ (defun icicle-find-file-abs-of-content-ro-ow-action (file)
+ "Read-only action function for commands reading absolute file names."
+ (funcall (icicle-find-file-abs-of-content-action-1 'OTHER-WINDOW-P 'READ-ONLY-P) file))
+
+
+ (put 'icicle-find-file-abs-of-content 'icicle-hide-common-match t)
+ (put 'icicle-find-file-abs-of-content 'icicle-Completions-window-max-height 200)
+ (defun icicle-find-file-abs-of-content () ; Bound (indirectly) to `C-u C-x C-f'.
+ "Visit a file or directory, given its absolute file name.
+That is, unlike `icicle-find-file', the completion candidates here are
+absolute, not relative, file names.
+
+By default, the completion candidates are files in the current
+directory, but you can substitute other candidates by retrieving a
+saved candidate set.
+
+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.
+
+When you use this command with a prefix arg, you can choose also by
+date: Completion candidates include the last modification date.
+
+ NOTE: Using a prefix arg with this command is different from using
+ it with `icicle-find-file', which uses `read-file-name' and thus
+ non-absolute file names. For that command, a prefix arg flips the
+ behavior of option `icicle-kill-visited-buffers-flag'.
+
+Whether or not you use a prefix argument, completion candidates are
+multi-completions, with the first part being the file name and the
+last part being the file contents. If you use a prefix arg then there
+is a middle part, which is the last modification date for the file.
+
+For example, if you do not use a prefix arg then you can match files
+whose names contain `quine' and whose contents contain `curry' using
+this input pattern, where `^G^J' stands for the value of
+`icicle-list-join-string':
+
+quine.*^G^J.*curry
+
+If you use a prefix arg then you can match the subset of those files
+whose dates match `2013 11 21', using this input pattern:
+
+quine.*^G^J2013 11 21^G^J.*curry
+
+And if you use a prefix arg, so you can see the dates in
+`*Completions*', but you do not care to match the date, then you can
+use this input pattern:
+
+quine.*^G^J.*^G^J.*curry
+
+A prefix argument has a different meaning when used when you act on an
+individual completion candidate. It means that you visit that file or
+directory 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, you can use the following keys (`*' means this
+requires library `Bookmark+')\\<minibuffer-local-completion-map>:
+
+ 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 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.
+
+Because absolute file names can be long, with common prefixes, the
+common match portion of each candidate is hidden by default. You can
+toggle this hiding using `\\[icicle-dispatch-C-x.]'."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-action))
+ (icicle-find-file-abs-of-content-1)))
+
+
+ (put 'icicle-find-file-abs-of-content-other-window 'icicle-hide-common-match t)
+ (put 'icicle-find-file-abs-of-content-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-find-file-abs-of-content-other-window () ; Bound (indirectly) to `C-u C-x 4 f'.
+ "Same as `icicle-find-file-abs-of-content' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-other-window-action))
+ (icicle-find-file-abs-of-content-1)))
+
+ (icicle-define-command icicle-find-file-abs-of-content-1
+ "Helper for `icicle-find-file-abs(-other-window)'." ; Doc string
+ (lambda (fil) (funcall icicle-find-file-abs-action-fn fil)) ; FREE here: `icicle-find-file-abs-action-fn'.
+ prompt icicle-abs-file-candidates nil (confirm-nonexistent-file-or-buffer) nil ; `completing-read' args
+ 'file-name-history (if (eq major-mode 'dired-mode)
+ (condition-case nil ; E.g. error because not on file line (ignore)
+ (abbreviate-file-name (dired-get-file-for-visit))
+ (error nil))
+ default-directory)
+ nil
(icicle-file-bindings ; Bindings
- ((init-pref-arg current-prefix-arg)
- (prompt "File or directory: ")
+ ((prompt "File or dir (absolute): ")
+ (icicle-pref-arg current-prefix-arg)
(icicle-compute-narrowing-regexp-p t) ; For progressive completion.
(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-full-cand-fn `(lambda (file)
+ (setq file (if (file-directory-p file)
+ (file-name-as-directory file)
+ file))
+ ,(if icicle-pref-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-show-multi-completion-flag t) ; Override user setting.
(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-existing-bufs (buffer-list))
+ (icicle-new-bufs-to-kill ())
+ (icicle-new-bufs-to-keep ())
+ (cleanup-code ; Use for both undo code and last code.
+ (lambda ()
+ (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)
+ (when icicle-kill-visited-buffers-flag
+ (dolist (buf icicle-new-bufs-to-kill)
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (unless (memq buf icicle-new-bufs-to-keep)
+;;; (when (buffer-live-p buf) ; Might have been killed, since both undo code and last code.
+;;; (with-current-buffer buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (kill-buffer buf))))))))
+ (when (and (buffer-live-p buf) (not (memq buf icicle-new-bufs-to-keep))) (kill-buffer buf))))))
(icicle-all-candidates-list-alt-action-fn ; `M-|'
(lambda (files) (let ((enable-recursive-minibuffers t))
- (dired-other-window (cons (read-string "Dired buffer name: ") files)))))))
- (progn (icicle-bind-file-candidate-keys) ; First code
- (put-text-property 0 1 'icicle-fancy-candidates t prompt)
- (icicle-highlight-lighter))
- nil ; Undo code
- (progn (icicle-unbind-file-candidate-keys) ; Last code
- (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) ; Just visiting can sometimes modify the buffer
- (kill-buffer buf)))))))
+ (dired-other-window (cons (read-string "Dired buffer name: ")
+ (mapcar #'icicle-transform-multi-completion files))))))
+ (icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
+ (icicle-candidate-properties-alist (and icicle-pref-arg '((1 (face icicle-candidate-part)))))
+ ))
+ (progn ; First code
+ (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+ (setq current-prefix-arg nil) ; Reset, so can use it in action function.
+ (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))
+ (funcall cleanup-code) ; Undo code
+ (funcall cleanup-code) ; Last code
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
+
+
+ (put 'icicle-recent-file-of-content 'icicle-hide-common-match t)
+ (put 'icicle-recent-file-of-content 'icicle-Completions-window-max-height 200)
+ (defun icicle-recent-file-of-content ()
+ "Open a recently used file.
+Completion candidates here are absolute, not relative, file 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.
+When you use this command with a prefix arg, you can choose also by
+date: Completion candidates include the last modification date.
- (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 ; Not bound by default.
- "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." ; Doc string
- (lambda (file) ; Action function
- ;; Free vars here: CURRENT-PREFIX-ARG, INIT-PREF-ARG, THIS-COMMAND, NEW-BUFS--TO-KEEP.
- (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)) ; Else in fundamental mode.
- ;; Add the visited buffer to those we will keep (not kill).
- ;; If FILE uses wildcards then there will be multiple such buffers.
- ;; For a directory, get the Dired buffer instead of using `get-file-buffer'.
- (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) ; `read-file-name' args
- (condition-case nil ; E.g. error because not on file line (ignore)
- (abbreviate-file-name (dired-get-file-for-visit))
- (error nil))
- default-directory)
- (confirm-nonexistent-file-or-buffer) nil nil
+Whether or not you use a prefix argument, completion candidates are
+multi-completions, with the first part being the file name and the
+last part being the file contents. If you use a prefix arg then there
+is a middle part, which is the last modification date for the file.
+
+For example, if you do not use a prefix arg then you can match files
+whose names contain `quine' and whose contents contain `curry' using
+this input pattern, where `^G^J' stands for the value of
+`icicle-list-join-string':
+
+quine.*^G^J.*curry
+
+If you use a prefix arg then you can match the subset of those files
+whose dates match `2013 11 21', using this input pattern:
+
+quine.*^G^J2013 11 21^G^J.*curry
+
+And if you use a prefix arg, so you can see the dates in
+`*Completions*', but you do not care to match the date, then you can
+use this input pattern:
+
+quine.*^G^J.*^G^J.*curry
+
+A prefix argument has a different meaning when used when you act on an
+individual completion candidate. It means that you visit that file or
+directory 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, you can use the following keys (`*' means this
+requires library `Bookmark+')\\<minibuffer-local-completion-map>:
+
+ 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.
+
+Because absolute file names can be long, with common prefixes, the
+common match portion of each candidate is hidden by default. You can
+toggle this hiding using `\\[icicle-dispatch-C-x.]'."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-action))
+ (icicle-recent-file-of-content-1)))
+
+
+ (put 'icicle-recent-file-of-content-other-window 'icicle-hide-common-match t)
+ (put 'icicle-recent-file-of-content-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-recent-file-of-content-other-window ()
+ "Same as `icicle-recent-file-of-content' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-other-window-action))
+ (icicle-recent-file-of-content-1)))
+
+ (icicle-define-command icicle-recent-file-of-content-1 ; Command name
+ "Helper for `icicle-recent-file-of-content(-other-window)'." ; Doc string
+ (lambda (fil) (funcall icicle-find-file-abs-action-fn fil)) ; FREE here: `icicle-find-file-abs-action-fn'.
+ prompt icicle-abs-file-candidates nil (confirm-nonexistent-file-or-buffer) nil ; `completing-read' args
+ 'file-name-history (if (eq major-mode 'dired-mode)
+ (condition-case nil ; E.g. error because not on file line (ignore)
+ (abbreviate-file-name (dired-get-file-for-visit))
+ (error nil))
+ (and (boundp 'recentf-list) (car recentf-list)))
+ nil
+ (icicle-file-bindings ; Bindings
+ ((prompt "Recent file (absolute): ")
+ (icicle-pref-arg current-prefix-arg)
+ (icicle-compute-narrowing-regexp-p t) ; For progressive completion.
+ (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-full-cand-fn `(lambda (file)
+ (setq file (if (file-directory-p file)
+ (file-name-as-directory file)
+ file))
+ ,(if icicle-pref-arg
+ '(icicle-make-file+date-candidate file)
+ '(list file))))
+ (icicle-abs-file-candidates
+ (progn (require 'recentf nil t)
+ (when (fboundp 'recentf-mode) (recentf-mode 99))
+ (unless (and (boundp 'recentf-list) (consp recentf-list))
+ (icicle-user-error "Recent-files list is empty"))
+ (mapcar icicle-full-cand-fn recentf-list)))
+ (icicle-show-multi-completion-flag t) ; Override user setting.
+ (icicle-multi-completing-p t)
+ (icicle-list-use-nth-parts '(1))
+ (icicle-transform-before-sort-p t)
+ (icicle-existing-bufs (buffer-list))
+ (icicle-new-bufs-to-kill ())
+ (icicle-new-bufs-to-keep ())
+ (cleanup-code ; Use for both undo code and last code.
+ (lambda ()
+ (icicle-unbind-file-candidate-keys)
+ (when icicle-kill-visited-buffers-flag
+ (dolist (buf icicle-new-bufs-to-kill)
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (unless (memq buf icicle-new-bufs-to-keep)
+;;; (when (buffer-live-p buf) ; Might have been killed, since both undo code and last code.
+;;; (with-current-buffer buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (kill-buffer buf))))))))
+ (when (and (buffer-live-p buf) (not (memq buf icicle-new-bufs-to-keep))) (kill-buffer buf))))))
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (lambda (files) (let ((enable-recursive-minibuffers t))
+ (dired-other-window (cons (read-string "Dired buffer name: ")
+ (mapcar #'icicle-transform-multi-completion files))))))
+
+ (icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
+ (icicle-candidate-properties-alist (and icicle-pref-arg '((1 (face icicle-candidate-part)))))
+ (icicle-sort-comparer 'icicle-latest-access-first-p)
+ (icicle-candidate-alt-action-fn 'icicle-remove-from-recentf-candidate-action)
+ (icicle-use-candidates-only-once-alt-p t)
+ ))
+ (progn ; First code
+ (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+ (setq current-prefix-arg nil) ; Reset, so can use it in action function.
+ (icicle-highlight-lighter)
+ (message "Gathering files...")
+ (icicle-bind-file-candidate-keys))
+ (funcall cleanup-code) ; Undo code
+ (funcall cleanup-code) ; Last code
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
+
+
+ (put 'icicle-locate-file-of-content 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-file-of-content 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-file-of-content 'icicle-hide-common-match t)
+ (put 'icicle-locate-file-of-content 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-file-of-content ()
+ "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.
+
+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-of-content-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-of-content' instead of
+`icicle-locate-file-of-content'.
+
+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 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-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)))
+
+Because you will often use this command in contexts that result in
+many, many completion candidates, the following are turned off by
+default for this command:
+
+ * Icomplete mode. You can toggle this using \\<minibuffer-local-completion-map>\
+`\\[icicle-toggle-icomplete-mode]'.
+ * Icicles incremental completion. You can cycle this using `\\[icicle-cycle-incremental-completion]'.
+
+Because absolute file names can be long, with common prefixes, the
+common match portion of each candidate is hidden by default. You can
+toggle this hiding using `\\[icicle-dispatch-C-x.]'."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-action)
+ (icicle-locate-file-no-symlinks-p nil))
+ (icicle-locate-file-of-content-1)))
+
+
+ (put 'icicle-locate-file-of-content-other-window 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-file-of-content-other-window 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-file-of-content-other-window 'icicle-hide-common-match t)
+ (put 'icicle-locate-file-of-content-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-file-of-content-other-window ()
+ "Same as `icicle-locate-file-of-content' except uses another window.
+See also command `icicle-locate-file-no-symlinks-other-window', which
+does not follow symbolic links."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-other-window-action)
+ (icicle-locate-file-no-symlinks-p nil))
+ (icicle-locate-file-of-content-1)))
+
+
+ (put 'icicle-locate-of-content 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-of-content 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-of-content 'icicle-hide-common-match t)
+ (put 'icicle-locate-of-content 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-of-content ()
+ "Run the external program `locate', then visit files.
+Unlike `icicle-locate-file-of-content' 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-of-content'.
+
+`icicle-locate-of-content' 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-of-content' 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 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 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-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)))
+
+Because you will often use this command in contexts that result in
+many, many completion candidates, the following are turned off by
+default for this command:
+
+ * Icomplete mode
+ * Iciciles incremental completion. You can cycle this using \\<minibuffer-local-completion-map>\
+`\\[icicle-cycle-incremental-completion]'.
+
+Because absolute file names can be long, with common prefixes, the
+common match portion of each candidate is hidden by default. You can
+toggle this hiding using `\\[icicle-dispatch-C-x.]'."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-action)
+ (icicle-locate-file-use-locate-p t))
+ (icicle-locate-file-of-content-1)))
+
+
+ (put 'icicle-locate-of-content-other-window 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-of-content-other-window 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-of-content-other-window 'icicle-hide-common-match t)
+ (put 'icicle-locate-of-content-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-of-content-other-window ()
+ "Same as `icicle-locate-of-content' except uses another window."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-other-window-action)
+ (icicle-locate-file-use-locate-p t))
+ (icicle-locate-file-of-content-1)))
+
+
+ (put 'icicle-locate-file-of-content-no-symlinks 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-file-of-content-no-symlinks 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-file-of-content-no-symlinks 'icicle-hide-common-match t)
+ (put 'icicle-locate-file-of-content-no-symlinks 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-file-of-content-no-symlinks ()
+ "Same as `icicle-locate-file-of-content', except do not follow symlinks."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-action)
+ (icicle-locate-file-no-symlinks-p t))
+ (icicle-locate-file-of-content-1)))
+
+
+ (put 'icicle-locate-file-of-content-no-symlinks-other-window 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-locate-file-of-content-no-symlinks-other-window 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-locate-file-of-content-no-symlinks-other-window 'icicle-hide-common-match t)
+ (put 'icicle-locate-file-of-content-no-symlinks-other-window 'icicle-Completions-window-max-height 200)
+ (defun icicle-locate-file-of-content-no-symlinks-other-window ()
+ "Same as `icicle-locate-file-of-content-no-symlinks', except uses another window."
+ (interactive)
+ (let ((icicle-find-file-abs-action-fn 'icicle-find-file-abs-of-content-other-window-action)
+ (icicle-locate-file-no-symlinks-p t))
+ (icicle-locate-file-of-content-1)))
+
+ (icicle-define-command icicle-locate-file-of-content-1
+ "Helper for `icicle-locate(-file-of-content(-no-symlinks))(-other-window)'." ; Doc string
+ (lambda (fil) (funcall icicle-find-file-abs-action-fn fil)) ; FREE here: `icicle-find-file-abs-action-fn'.
+ prompt icicle-abs-file-candidates nil (confirm-nonexistent-file-or-buffer) nil ; `completing-read' args
+ 'file-name-history (if (eq major-mode 'dired-mode)
+ (condition-case nil ; E.g. error because not on file line (ignore)
+ (abbreviate-file-name (dired-get-file-for-visit))
+ (error nil))
+ default-directory)
+ nil
+ (icicle-file-bindings ; Bindings
+ ((prompt "File (absolute): ")
+ (icicle-pref-arg current-prefix-arg)
+ (icicle-compute-narrowing-regexp-p t) ; For progressive completion.
+ (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)
+ (dirs (and (not icicle-locate-file-use-locate-p)
+ (cond ((and icicle-pref-arg (consp icicle-pref-arg))
+ (icicle-directory-list))
+ ((and icicle-pref-arg
+ (wholenump (prefix-numeric-value
+ icicle-pref-arg)))
+ (read-file-name "Locate under which directory: "
+ nil default-directory nil))
+ (t default-directory))))
+ (icicle-full-cand-fn `(lambda (file)
+ (setq file (if (file-directory-p file)
+ (file-name-as-directory file)
+ file))
+ ,(if icicle-pref-arg
+ '(icicle-make-file+date-candidate file)
+ '(list file))))
+ (IGNORED--FOR-SIDE-EFFECT
+ (progn (icicle-highlight-lighter)
+ (if icicle-locate-file-use-locate-p
+ (require 'locate) ; Hard-require: error if not there.
+ (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-pref-arg #'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) ; Gets `current-prefix-arg'.
+ (dired-repeat-over-lines
+ (count-lines (point-min) (point-max))
+ (lambda () (push (dired-get-filename nil t) cands))) ; FREE here: 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))))))
+ (use-dialog-box nil)
+ (icicle-show-multi-completion-flag t) ; Override user setting.
+ (icicle-multi-completing-p t)
+ (icicle-list-use-nth-parts '(1))
+ (icicle-transform-before-sort-p t)
+ (icicle-existing-bufs (buffer-list))
+ (icicle-new-bufs-to-kill ())
+ (icicle-new-bufs-to-keep ())
+ (icicle-all-candidates-list-alt-action-fn ; `M-|'
+ (lambda (files) (let ((enable-recursive-minibuffers t))
+ (dired-other-window (cons (read-string "Dired buffer name: ")
+ (mapcar #'icicle-transform-multi-completion files))))))
+ (icicle-special-candidate-regexp (or icicle-special-candidate-regexp ".+/$"))
+ (icicle-candidate-properties-alist (and icicle-pref-arg '((1 (face icicle-candidate-part)))))
+ (cleanup-code ; Use for both undo code and last code.
+ (lambda ()
+ (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))
+ (when icicle-kill-visited-buffers-flag
+ (dolist (buf icicle-new-bufs-to-kill)
+;;; $$$$$$ Why were we calling `restore-buffer-modified-p' before killing?
+;;; (unless (memq buf icicle-new-bufs-to-keep)
+;;; (when (buffer-live-p buf) ; Might have been killed, since both undo code and last code.
+;;; (with-current-buffer buf
+;;; (restore-buffer-modified-p nil) ; Just visiting can sometimes modify the buffer
+;;; (kill-buffer buf))))))))
+ (when (and (buffer-live-p buf) (not (memq buf icicle-new-bufs-to-keep))) (kill-buffer buf))))))))
+ (progn ; First code
+ (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+ (setq current-prefix-arg nil) ; Reset, so can use it in action function.
+ (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)))
+ (funcall cleanup-code) ; Undo code
+ (funcall cleanup-code) ; Last code
+ 'NOT-INTERACTIVE-P) ; Not a real command - just a helper function.
+
+
+ (put 'icicle-find-file-of-content-in-tags-table 'icicle-turn-off-icomplete-mode t)
+ (put 'icicle-find-file-of-content-in-tags-table 'icicle-turn-off-incremental-completion t)
+ (put 'icicle-find-file-of-content-in-tags-table 'icicle-Completions-window-max-height 200)
+ (defun i